cmpxchg8b fix - added cmpxchg16b
[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, label2;
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             if (mod == 3) {
4313                 label2 = gen_new_label();
4314                 gen_op_mov_reg_T0(ot, R_EAX);
4315                 tcg_gen_br(label2);
4316                 gen_set_label(label1);
4317                 gen_op_mov_reg_T1(ot, rm);
4318                 gen_set_label(label2);
4319             } else {
4320                 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
4321                 gen_op_mov_reg_T0(ot, R_EAX);
4322                 gen_set_label(label1);
4323                 /* always store */
4324                 gen_op_st_T1_A0(ot + s->mem_index);
4325             }
4326             tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
4327             tcg_gen_mov_tl(cpu_cc_dst, cpu_T3);
4328             s->cc_op = CC_OP_SUBB + ot;
4329         }
4330         break;
4331     case 0x1c7: /* cmpxchg8b */
4332         modrm = ldub_code(s->pc++);
4333         mod = (modrm >> 6) & 3;
4334         if ((mod == 3) || ((modrm & 0x38) != 0x8))
4335             goto illegal_op;
4336 #ifdef TARGET_X86_64
4337         if (dflag == 2) {
4338             if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
4339                 goto illegal_op;
4340             gen_jmp_im(pc_start - s->cs_base);
4341             if (s->cc_op != CC_OP_DYNAMIC)
4342                 gen_op_set_cc_op(s->cc_op);
4343             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4344             tcg_gen_helper_0_1(helper_cmpxchg16b, cpu_A0);
4345         } else
4346 #endif        
4347         {
4348             if (!(s->cpuid_features & CPUID_CX8))
4349                 goto illegal_op;
4350             gen_jmp_im(pc_start - s->cs_base);
4351             if (s->cc_op != CC_OP_DYNAMIC)
4352                 gen_op_set_cc_op(s->cc_op);
4353             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4354             tcg_gen_helper_0_1(helper_cmpxchg8b, cpu_A0);
4355         }
4356         s->cc_op = CC_OP_EFLAGS;
4357         break;
4358
4359         /**************************/
4360         /* push/pop */
4361     case 0x50 ... 0x57: /* push */
4362         gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
4363         gen_push_T0(s);
4364         break;
4365     case 0x58 ... 0x5f: /* pop */
4366         if (CODE64(s)) {
4367             ot = dflag ? OT_QUAD : OT_WORD;
4368         } else {
4369             ot = dflag + OT_WORD;
4370         }
4371         gen_pop_T0(s);
4372         /* NOTE: order is important for pop %sp */
4373         gen_pop_update(s);
4374         gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
4375         break;
4376     case 0x60: /* pusha */
4377         if (CODE64(s))
4378             goto illegal_op;
4379         gen_pusha(s);
4380         break;
4381     case 0x61: /* popa */
4382         if (CODE64(s))
4383             goto illegal_op;
4384         gen_popa(s);
4385         break;
4386     case 0x68: /* push Iv */
4387     case 0x6a:
4388         if (CODE64(s)) {
4389             ot = dflag ? OT_QUAD : OT_WORD;
4390         } else {
4391             ot = dflag + OT_WORD;
4392         }
4393         if (b == 0x68)
4394             val = insn_get(s, ot);
4395         else
4396             val = (int8_t)insn_get(s, OT_BYTE);
4397         gen_op_movl_T0_im(val);
4398         gen_push_T0(s);
4399         break;
4400     case 0x8f: /* pop Ev */
4401         if (CODE64(s)) {
4402             ot = dflag ? OT_QUAD : OT_WORD;
4403         } else {
4404             ot = dflag + OT_WORD;
4405         }
4406         modrm = ldub_code(s->pc++);
4407         mod = (modrm >> 6) & 3;
4408         gen_pop_T0(s);
4409         if (mod == 3) {
4410             /* NOTE: order is important for pop %sp */
4411             gen_pop_update(s);
4412             rm = (modrm & 7) | REX_B(s);
4413             gen_op_mov_reg_T0(ot, rm);
4414         } else {
4415             /* NOTE: order is important too for MMU exceptions */
4416             s->popl_esp_hack = 1 << ot;
4417             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4418             s->popl_esp_hack = 0;
4419             gen_pop_update(s);
4420         }
4421         break;
4422     case 0xc8: /* enter */
4423         {
4424             int level;
4425             val = lduw_code(s->pc);
4426             s->pc += 2;
4427             level = ldub_code(s->pc++);
4428             gen_enter(s, val, level);
4429         }
4430         break;
4431     case 0xc9: /* leave */
4432         /* XXX: exception not precise (ESP is updated before potential exception) */
4433         if (CODE64(s)) {
4434             gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
4435             gen_op_mov_reg_T0(OT_QUAD, R_ESP);
4436         } else if (s->ss32) {
4437             gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
4438             gen_op_mov_reg_T0(OT_LONG, R_ESP);
4439         } else {
4440             gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
4441             gen_op_mov_reg_T0(OT_WORD, R_ESP);
4442         }
4443         gen_pop_T0(s);
4444         if (CODE64(s)) {
4445             ot = dflag ? OT_QUAD : OT_WORD;
4446         } else {
4447             ot = dflag + OT_WORD;
4448         }
4449         gen_op_mov_reg_T0(ot, R_EBP);
4450         gen_pop_update(s);
4451         break;
4452     case 0x06: /* push es */
4453     case 0x0e: /* push cs */
4454     case 0x16: /* push ss */
4455     case 0x1e: /* push ds */
4456         if (CODE64(s))
4457             goto illegal_op;
4458         gen_op_movl_T0_seg(b >> 3);
4459         gen_push_T0(s);
4460         break;
4461     case 0x1a0: /* push fs */
4462     case 0x1a8: /* push gs */
4463         gen_op_movl_T0_seg((b >> 3) & 7);
4464         gen_push_T0(s);
4465         break;
4466     case 0x07: /* pop es */
4467     case 0x17: /* pop ss */
4468     case 0x1f: /* pop ds */
4469         if (CODE64(s))
4470             goto illegal_op;
4471         reg = b >> 3;
4472         gen_pop_T0(s);
4473         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4474         gen_pop_update(s);
4475         if (reg == R_SS) {
4476             /* if reg == SS, inhibit interrupts/trace. */
4477             /* If several instructions disable interrupts, only the
4478                _first_ does it */
4479             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4480                 tcg_gen_helper_0_0(helper_set_inhibit_irq);
4481             s->tf = 0;
4482         }
4483         if (s->is_jmp) {
4484             gen_jmp_im(s->pc - s->cs_base);
4485             gen_eob(s);
4486         }
4487         break;
4488     case 0x1a1: /* pop fs */
4489     case 0x1a9: /* pop gs */
4490         gen_pop_T0(s);
4491         gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
4492         gen_pop_update(s);
4493         if (s->is_jmp) {
4494             gen_jmp_im(s->pc - s->cs_base);
4495             gen_eob(s);
4496         }
4497         break;
4498
4499         /**************************/
4500         /* mov */
4501     case 0x88:
4502     case 0x89: /* mov Gv, Ev */
4503         if ((b & 1) == 0)
4504             ot = OT_BYTE;
4505         else
4506             ot = dflag + OT_WORD;
4507         modrm = ldub_code(s->pc++);
4508         reg = ((modrm >> 3) & 7) | rex_r;
4509
4510         /* generate a generic store */
4511         gen_ldst_modrm(s, modrm, ot, reg, 1);
4512         break;
4513     case 0xc6:
4514     case 0xc7: /* mov Ev, Iv */
4515         if ((b & 1) == 0)
4516             ot = OT_BYTE;
4517         else
4518             ot = dflag + OT_WORD;
4519         modrm = ldub_code(s->pc++);
4520         mod = (modrm >> 6) & 3;
4521         if (mod != 3) {
4522             s->rip_offset = insn_const_size(ot);
4523             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4524         }
4525         val = insn_get(s, ot);
4526         gen_op_movl_T0_im(val);
4527         if (mod != 3)
4528             gen_op_st_T0_A0(ot + s->mem_index);
4529         else
4530             gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
4531         break;
4532     case 0x8a:
4533     case 0x8b: /* mov Ev, Gv */
4534         if ((b & 1) == 0)
4535             ot = OT_BYTE;
4536         else
4537             ot = OT_WORD + dflag;
4538         modrm = ldub_code(s->pc++);
4539         reg = ((modrm >> 3) & 7) | rex_r;
4540
4541         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4542         gen_op_mov_reg_T0(ot, reg);
4543         break;
4544     case 0x8e: /* mov seg, Gv */
4545         modrm = ldub_code(s->pc++);
4546         reg = (modrm >> 3) & 7;
4547         if (reg >= 6 || reg == R_CS)
4548             goto illegal_op;
4549         gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
4550         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4551         if (reg == R_SS) {
4552             /* if reg == SS, inhibit interrupts/trace */
4553             /* If several instructions disable interrupts, only the
4554                _first_ does it */
4555             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4556                 tcg_gen_helper_0_0(helper_set_inhibit_irq);
4557             s->tf = 0;
4558         }
4559         if (s->is_jmp) {
4560             gen_jmp_im(s->pc - s->cs_base);
4561             gen_eob(s);
4562         }
4563         break;
4564     case 0x8c: /* mov Gv, seg */
4565         modrm = ldub_code(s->pc++);
4566         reg = (modrm >> 3) & 7;
4567         mod = (modrm >> 6) & 3;
4568         if (reg >= 6)
4569             goto illegal_op;
4570         gen_op_movl_T0_seg(reg);
4571         if (mod == 3)
4572             ot = OT_WORD + dflag;
4573         else
4574             ot = OT_WORD;
4575         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4576         break;
4577
4578     case 0x1b6: /* movzbS Gv, Eb */
4579     case 0x1b7: /* movzwS Gv, Eb */
4580     case 0x1be: /* movsbS Gv, Eb */
4581     case 0x1bf: /* movswS Gv, Eb */
4582         {
4583             int d_ot;
4584             /* d_ot is the size of destination */
4585             d_ot = dflag + OT_WORD;
4586             /* ot is the size of source */
4587             ot = (b & 1) + OT_BYTE;
4588             modrm = ldub_code(s->pc++);
4589             reg = ((modrm >> 3) & 7) | rex_r;
4590             mod = (modrm >> 6) & 3;
4591             rm = (modrm & 7) | REX_B(s);
4592
4593             if (mod == 3) {
4594                 gen_op_mov_TN_reg(ot, 0, rm);
4595                 switch(ot | (b & 8)) {
4596                 case OT_BYTE:
4597                     tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
4598                     break;
4599                 case OT_BYTE | 8:
4600                     tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
4601                     break;
4602                 case OT_WORD:
4603                     tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
4604                     break;
4605                 default:
4606                 case OT_WORD | 8:
4607                     tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
4608                     break;
4609                 }
4610                 gen_op_mov_reg_T0(d_ot, reg);
4611             } else {
4612                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4613                 if (b & 8) {
4614                     gen_op_lds_T0_A0(ot + s->mem_index);
4615                 } else {
4616                     gen_op_ldu_T0_A0(ot + s->mem_index);
4617                 }
4618                 gen_op_mov_reg_T0(d_ot, reg);
4619             }
4620         }
4621         break;
4622
4623     case 0x8d: /* lea */
4624         ot = dflag + OT_WORD;
4625         modrm = ldub_code(s->pc++);
4626         mod = (modrm >> 6) & 3;
4627         if (mod == 3)
4628             goto illegal_op;
4629         reg = ((modrm >> 3) & 7) | rex_r;
4630         /* we must ensure that no segment is added */
4631         s->override = -1;
4632         val = s->addseg;
4633         s->addseg = 0;
4634         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4635         s->addseg = val;
4636         gen_op_mov_reg_A0(ot - OT_WORD, reg);
4637         break;
4638
4639     case 0xa0: /* mov EAX, Ov */
4640     case 0xa1:
4641     case 0xa2: /* mov Ov, EAX */
4642     case 0xa3:
4643         {
4644             target_ulong offset_addr;
4645
4646             if ((b & 1) == 0)
4647                 ot = OT_BYTE;
4648             else
4649                 ot = dflag + OT_WORD;
4650 #ifdef TARGET_X86_64
4651             if (s->aflag == 2) {
4652                 offset_addr = ldq_code(s->pc);
4653                 s->pc += 8;
4654                 gen_op_movq_A0_im(offset_addr);
4655             } else
4656 #endif
4657             {
4658                 if (s->aflag) {
4659                     offset_addr = insn_get(s, OT_LONG);
4660                 } else {
4661                     offset_addr = insn_get(s, OT_WORD);
4662                 }
4663                 gen_op_movl_A0_im(offset_addr);
4664             }
4665             gen_add_A0_ds_seg(s);
4666             if ((b & 2) == 0) {
4667                 gen_op_ld_T0_A0(ot + s->mem_index);
4668                 gen_op_mov_reg_T0(ot, R_EAX);
4669             } else {
4670                 gen_op_mov_TN_reg(ot, 0, R_EAX);
4671                 gen_op_st_T0_A0(ot + s->mem_index);
4672             }
4673         }
4674         break;
4675     case 0xd7: /* xlat */
4676 #ifdef TARGET_X86_64
4677         if (s->aflag == 2) {
4678             gen_op_movq_A0_reg(R_EBX);
4679             gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
4680             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4681             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4682         } else
4683 #endif
4684         {
4685             gen_op_movl_A0_reg(R_EBX);
4686             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
4687             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
4688             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
4689             if (s->aflag == 0)
4690                 gen_op_andl_A0_ffff();
4691             else
4692                 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
4693         }
4694         gen_add_A0_ds_seg(s);
4695         gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
4696         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
4697         break;
4698     case 0xb0 ... 0xb7: /* mov R, Ib */
4699         val = insn_get(s, OT_BYTE);
4700         gen_op_movl_T0_im(val);
4701         gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
4702         break;
4703     case 0xb8 ... 0xbf: /* mov R, Iv */
4704 #ifdef TARGET_X86_64
4705         if (dflag == 2) {
4706             uint64_t tmp;
4707             /* 64 bit case */
4708             tmp = ldq_code(s->pc);
4709             s->pc += 8;
4710             reg = (b & 7) | REX_B(s);
4711             gen_movtl_T0_im(tmp);
4712             gen_op_mov_reg_T0(OT_QUAD, reg);
4713         } else
4714 #endif
4715         {
4716             ot = dflag ? OT_LONG : OT_WORD;
4717             val = insn_get(s, ot);
4718             reg = (b & 7) | REX_B(s);
4719             gen_op_movl_T0_im(val);
4720             gen_op_mov_reg_T0(ot, reg);
4721         }
4722         break;
4723
4724     case 0x91 ... 0x97: /* xchg R, EAX */
4725         ot = dflag + OT_WORD;
4726         reg = (b & 7) | REX_B(s);
4727         rm = R_EAX;
4728         goto do_xchg_reg;
4729     case 0x86:
4730     case 0x87: /* xchg Ev, Gv */
4731         if ((b & 1) == 0)
4732             ot = OT_BYTE;
4733         else
4734             ot = dflag + OT_WORD;
4735         modrm = ldub_code(s->pc++);
4736         reg = ((modrm >> 3) & 7) | rex_r;
4737         mod = (modrm >> 6) & 3;
4738         if (mod == 3) {
4739             rm = (modrm & 7) | REX_B(s);
4740         do_xchg_reg:
4741             gen_op_mov_TN_reg(ot, 0, reg);
4742             gen_op_mov_TN_reg(ot, 1, rm);
4743             gen_op_mov_reg_T0(ot, rm);
4744             gen_op_mov_reg_T1(ot, reg);
4745         } else {
4746             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4747             gen_op_mov_TN_reg(ot, 0, reg);
4748             /* for xchg, lock is implicit */
4749             if (!(prefixes & PREFIX_LOCK))
4750                 tcg_gen_helper_0_0(helper_lock);
4751             gen_op_ld_T1_A0(ot + s->mem_index);
4752             gen_op_st_T0_A0(ot + s->mem_index);
4753             if (!(prefixes & PREFIX_LOCK))
4754                 tcg_gen_helper_0_0(helper_unlock);
4755             gen_op_mov_reg_T1(ot, reg);
4756         }
4757         break;
4758     case 0xc4: /* les Gv */
4759         if (CODE64(s))
4760             goto illegal_op;
4761         op = R_ES;
4762         goto do_lxx;
4763     case 0xc5: /* lds Gv */
4764         if (CODE64(s))
4765             goto illegal_op;
4766         op = R_DS;
4767         goto do_lxx;
4768     case 0x1b2: /* lss Gv */
4769         op = R_SS;
4770         goto do_lxx;
4771     case 0x1b4: /* lfs Gv */
4772         op = R_FS;
4773         goto do_lxx;
4774     case 0x1b5: /* lgs Gv */
4775         op = R_GS;
4776     do_lxx:
4777         ot = dflag ? OT_LONG : OT_WORD;
4778         modrm = ldub_code(s->pc++);
4779         reg = ((modrm >> 3) & 7) | rex_r;
4780         mod = (modrm >> 6) & 3;
4781         if (mod == 3)
4782             goto illegal_op;
4783         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4784         gen_op_ld_T1_A0(ot + s->mem_index);
4785         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4786         /* load the segment first to handle exceptions properly */
4787         gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4788         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4789         /* then put the data */
4790         gen_op_mov_reg_T1(ot, reg);
4791         if (s->is_jmp) {
4792             gen_jmp_im(s->pc - s->cs_base);
4793             gen_eob(s);
4794         }
4795         break;
4796
4797         /************************/
4798         /* shifts */
4799     case 0xc0:
4800     case 0xc1:
4801         /* shift Ev,Ib */
4802         shift = 2;
4803     grp2:
4804         {
4805             if ((b & 1) == 0)
4806                 ot = OT_BYTE;
4807             else
4808                 ot = dflag + OT_WORD;
4809
4810             modrm = ldub_code(s->pc++);
4811             mod = (modrm >> 6) & 3;
4812             op = (modrm >> 3) & 7;
4813
4814             if (mod != 3) {
4815                 if (shift == 2) {
4816                     s->rip_offset = 1;
4817                 }
4818                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4819                 opreg = OR_TMP0;
4820             } else {
4821                 opreg = (modrm & 7) | REX_B(s);
4822             }
4823
4824             /* simpler op */
4825             if (shift == 0) {
4826                 gen_shift(s, op, ot, opreg, OR_ECX);
4827             } else {
4828                 if (shift == 2) {
4829                     shift = ldub_code(s->pc++);
4830                 }
4831                 gen_shifti(s, op, ot, opreg, shift);
4832             }
4833         }
4834         break;
4835     case 0xd0:
4836     case 0xd1:
4837         /* shift Ev,1 */
4838         shift = 1;
4839         goto grp2;
4840     case 0xd2:
4841     case 0xd3:
4842         /* shift Ev,cl */
4843         shift = 0;
4844         goto grp2;
4845
4846     case 0x1a4: /* shld imm */
4847         op = 0;
4848         shift = 1;
4849         goto do_shiftd;
4850     case 0x1a5: /* shld cl */
4851         op = 0;
4852         shift = 0;
4853         goto do_shiftd;
4854     case 0x1ac: /* shrd imm */
4855         op = 1;
4856         shift = 1;
4857         goto do_shiftd;
4858     case 0x1ad: /* shrd cl */
4859         op = 1;
4860         shift = 0;
4861     do_shiftd:
4862         ot = dflag + OT_WORD;
4863         modrm = ldub_code(s->pc++);
4864         mod = (modrm >> 6) & 3;
4865         rm = (modrm & 7) | REX_B(s);
4866         reg = ((modrm >> 3) & 7) | rex_r;
4867         if (mod != 3) {
4868             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4869             opreg = OR_TMP0;
4870         } else {
4871             opreg = rm;
4872         }
4873         gen_op_mov_TN_reg(ot, 1, reg);
4874
4875         if (shift) {
4876             val = ldub_code(s->pc++);
4877             tcg_gen_movi_tl(cpu_T3, val);
4878         } else {
4879             tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_ECX]));
4880         }
4881         gen_shiftd_rm_T1_T3(s, ot, opreg, op);
4882         break;
4883
4884         /************************/
4885         /* floats */
4886     case 0xd8 ... 0xdf:
4887         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4888             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4889             /* XXX: what to do if illegal op ? */
4890             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4891             break;
4892         }
4893         modrm = ldub_code(s->pc++);
4894         mod = (modrm >> 6) & 3;
4895         rm = modrm & 7;
4896         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4897         if (mod != 3) {
4898             /* memory op */
4899             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4900             switch(op) {
4901             case 0x00 ... 0x07: /* fxxxs */
4902             case 0x10 ... 0x17: /* fixxxl */
4903             case 0x20 ... 0x27: /* fxxxl */
4904             case 0x30 ... 0x37: /* fixxx */
4905                 {
4906                     int op1;
4907                     op1 = op & 7;
4908
4909                     switch(op >> 4) {
4910                     case 0:
4911                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4912                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4913                         tcg_gen_helper_0_1(helper_flds_FT0, cpu_tmp2_i32);
4914                         break;
4915                     case 1:
4916                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4917                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4918                         tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
4919                         break;
4920                     case 2:
4921                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
4922                                           (s->mem_index >> 2) - 1);
4923                         tcg_gen_helper_0_1(helper_fldl_FT0, cpu_tmp1_i64);
4924                         break;
4925                     case 3:
4926                     default:
4927                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
4928                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4929                         tcg_gen_helper_0_1(helper_fildl_FT0, cpu_tmp2_i32);
4930                         break;
4931                     }
4932
4933                     tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
4934                     if (op1 == 3) {
4935                         /* fcomp needs pop */
4936                         tcg_gen_helper_0_0(helper_fpop);
4937                     }
4938                 }
4939                 break;
4940             case 0x08: /* flds */
4941             case 0x0a: /* fsts */
4942             case 0x0b: /* fstps */
4943             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4944             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4945             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4946                 switch(op & 7) {
4947                 case 0:
4948                     switch(op >> 4) {
4949                     case 0:
4950                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4951                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4952                         tcg_gen_helper_0_1(helper_flds_ST0, cpu_tmp2_i32);
4953                         break;
4954                     case 1:
4955                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
4956                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4957                         tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
4958                         break;
4959                     case 2:
4960                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
4961                                           (s->mem_index >> 2) - 1);
4962                         tcg_gen_helper_0_1(helper_fldl_ST0, cpu_tmp1_i64);
4963                         break;
4964                     case 3:
4965                     default:
4966                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
4967                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
4968                         tcg_gen_helper_0_1(helper_fildl_ST0, cpu_tmp2_i32);
4969                         break;
4970                     }
4971                     break;
4972                 case 1:
4973                     /* XXX: the corresponding CPUID bit must be tested ! */
4974                     switch(op >> 4) {
4975                     case 1:
4976                         tcg_gen_helper_1_0(helper_fisttl_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 2:
4981                         tcg_gen_helper_1_0(helper_fisttll_ST0, cpu_tmp1_i64);
4982                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
4983                                           (s->mem_index >> 2) - 1);
4984                         break;
4985                     case 3:
4986                     default:
4987                         tcg_gen_helper_1_0(helper_fistt_ST0, cpu_tmp2_i32);
4988                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4989                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
4990                         break;
4991                     }
4992                     tcg_gen_helper_0_0(helper_fpop);
4993                     break;
4994                 default:
4995                     switch(op >> 4) {
4996                     case 0:
4997                         tcg_gen_helper_1_0(helper_fsts_ST0, cpu_tmp2_i32);
4998                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
4999                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
5000                         break;
5001                     case 1:
5002                         tcg_gen_helper_1_0(helper_fistl_ST0, cpu_tmp2_i32);
5003                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5004                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
5005                         break;
5006                     case 2:
5007                         tcg_gen_helper_1_0(helper_fstl_ST0, cpu_tmp1_i64);
5008                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5009                                           (s->mem_index >> 2) - 1);
5010                         break;
5011                     case 3:
5012                     default:
5013                         tcg_gen_helper_1_0(helper_fist_ST0, cpu_tmp2_i32);
5014                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5015                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
5016                         break;
5017                     }
5018                     if ((op & 7) == 3)
5019                         tcg_gen_helper_0_0(helper_fpop);
5020                     break;
5021                 }
5022                 break;
5023             case 0x0c: /* fldenv mem */
5024                 if (s->cc_op != CC_OP_DYNAMIC)
5025                     gen_op_set_cc_op(s->cc_op);
5026                 gen_jmp_im(pc_start - s->cs_base);
5027                 tcg_gen_helper_0_2(helper_fldenv, 
5028                                    cpu_A0, tcg_const_i32(s->dflag));
5029                 break;
5030             case 0x0d: /* fldcw mem */
5031                 gen_op_ld_T0_A0(OT_WORD + s->mem_index);
5032                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5033                 tcg_gen_helper_0_1(helper_fldcw, cpu_tmp2_i32);
5034                 break;
5035             case 0x0e: /* fnstenv mem */
5036                 if (s->cc_op != CC_OP_DYNAMIC)
5037                     gen_op_set_cc_op(s->cc_op);
5038                 gen_jmp_im(pc_start - s->cs_base);
5039                 tcg_gen_helper_0_2(helper_fstenv,
5040                                    cpu_A0, tcg_const_i32(s->dflag));
5041                 break;
5042             case 0x0f: /* fnstcw mem */
5043                 tcg_gen_helper_1_0(helper_fnstcw, cpu_tmp2_i32);
5044                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5045                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
5046                 break;
5047             case 0x1d: /* fldt mem */
5048                 if (s->cc_op != CC_OP_DYNAMIC)
5049                     gen_op_set_cc_op(s->cc_op);
5050                 gen_jmp_im(pc_start - s->cs_base);
5051                 tcg_gen_helper_0_1(helper_fldt_ST0, cpu_A0);
5052                 break;
5053             case 0x1f: /* fstpt mem */
5054                 if (s->cc_op != CC_OP_DYNAMIC)
5055                     gen_op_set_cc_op(s->cc_op);
5056                 gen_jmp_im(pc_start - s->cs_base);
5057                 tcg_gen_helper_0_1(helper_fstt_ST0, cpu_A0);
5058                 tcg_gen_helper_0_0(helper_fpop);
5059                 break;
5060             case 0x2c: /* frstor mem */
5061                 if (s->cc_op != CC_OP_DYNAMIC)
5062                     gen_op_set_cc_op(s->cc_op);
5063                 gen_jmp_im(pc_start - s->cs_base);
5064                 tcg_gen_helper_0_2(helper_frstor,
5065                                    cpu_A0, tcg_const_i32(s->dflag));
5066                 break;
5067             case 0x2e: /* fnsave mem */
5068                 if (s->cc_op != CC_OP_DYNAMIC)
5069                     gen_op_set_cc_op(s->cc_op);
5070                 gen_jmp_im(pc_start - s->cs_base);
5071                 tcg_gen_helper_0_2(helper_fsave,
5072                                    cpu_A0, tcg_const_i32(s->dflag));
5073                 break;
5074             case 0x2f: /* fnstsw mem */
5075                 tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
5076                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5077                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
5078                 break;
5079             case 0x3c: /* fbld */
5080                 if (s->cc_op != CC_OP_DYNAMIC)
5081                     gen_op_set_cc_op(s->cc_op);
5082                 gen_jmp_im(pc_start - s->cs_base);
5083                 tcg_gen_helper_0_1(helper_fbld_ST0, cpu_A0);
5084                 break;
5085             case 0x3e: /* fbstp */
5086                 if (s->cc_op != CC_OP_DYNAMIC)
5087                     gen_op_set_cc_op(s->cc_op);
5088                 gen_jmp_im(pc_start - s->cs_base);
5089                 tcg_gen_helper_0_1(helper_fbst_ST0, cpu_A0);
5090                 tcg_gen_helper_0_0(helper_fpop);
5091                 break;
5092             case 0x3d: /* fildll */
5093                 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
5094                                   (s->mem_index >> 2) - 1);
5095                 tcg_gen_helper_0_1(helper_fildll_ST0, cpu_tmp1_i64);
5096                 break;
5097             case 0x3f: /* fistpll */
5098                 tcg_gen_helper_1_0(helper_fistll_ST0, cpu_tmp1_i64);
5099                 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
5100                                   (s->mem_index >> 2) - 1);
5101                 tcg_gen_helper_0_0(helper_fpop);
5102                 break;
5103             default:
5104                 goto illegal_op;
5105             }
5106         } else {
5107             /* register float ops */
5108             opreg = rm;
5109
5110             switch(op) {
5111             case 0x08: /* fld sti */
5112                 tcg_gen_helper_0_0(helper_fpush);
5113                 tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32((opreg + 1) & 7));
5114                 break;
5115             case 0x09: /* fxchg sti */
5116             case 0x29: /* fxchg4 sti, undocumented op */
5117             case 0x39: /* fxchg7 sti, undocumented op */
5118                 tcg_gen_helper_0_1(helper_fxchg_ST0_STN, tcg_const_i32(opreg));
5119                 break;
5120             case 0x0a: /* grp d9/2 */
5121                 switch(rm) {
5122                 case 0: /* fnop */
5123                     /* check exceptions (FreeBSD FPU probe) */
5124                     if (s->cc_op != CC_OP_DYNAMIC)
5125                         gen_op_set_cc_op(s->cc_op);
5126                     gen_jmp_im(pc_start - s->cs_base);
5127                     tcg_gen_helper_0_0(helper_fwait);
5128                     break;
5129                 default:
5130                     goto illegal_op;
5131                 }
5132                 break;
5133             case 0x0c: /* grp d9/4 */
5134                 switch(rm) {
5135                 case 0: /* fchs */
5136                     tcg_gen_helper_0_0(helper_fchs_ST0);
5137                     break;
5138                 case 1: /* fabs */
5139                     tcg_gen_helper_0_0(helper_fabs_ST0);
5140                     break;
5141                 case 4: /* ftst */
5142                     tcg_gen_helper_0_0(helper_fldz_FT0);
5143                     tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5144                     break;
5145                 case 5: /* fxam */
5146                     tcg_gen_helper_0_0(helper_fxam_ST0);
5147                     break;
5148                 default:
5149                     goto illegal_op;
5150                 }
5151                 break;
5152             case 0x0d: /* grp d9/5 */
5153                 {
5154                     switch(rm) {
5155                     case 0:
5156                         tcg_gen_helper_0_0(helper_fpush);
5157                         tcg_gen_helper_0_0(helper_fld1_ST0);
5158                         break;
5159                     case 1:
5160                         tcg_gen_helper_0_0(helper_fpush);
5161                         tcg_gen_helper_0_0(helper_fldl2t_ST0);
5162                         break;
5163                     case 2:
5164                         tcg_gen_helper_0_0(helper_fpush);
5165                         tcg_gen_helper_0_0(helper_fldl2e_ST0);
5166                         break;
5167                     case 3:
5168                         tcg_gen_helper_0_0(helper_fpush);
5169                         tcg_gen_helper_0_0(helper_fldpi_ST0);
5170                         break;
5171                     case 4:
5172                         tcg_gen_helper_0_0(helper_fpush);
5173                         tcg_gen_helper_0_0(helper_fldlg2_ST0);
5174                         break;
5175                     case 5:
5176                         tcg_gen_helper_0_0(helper_fpush);
5177                         tcg_gen_helper_0_0(helper_fldln2_ST0);
5178                         break;
5179                     case 6:
5180                         tcg_gen_helper_0_0(helper_fpush);
5181                         tcg_gen_helper_0_0(helper_fldz_ST0);
5182                         break;
5183                     default:
5184                         goto illegal_op;
5185                     }
5186                 }
5187                 break;
5188             case 0x0e: /* grp d9/6 */
5189                 switch(rm) {
5190                 case 0: /* f2xm1 */
5191                     tcg_gen_helper_0_0(helper_f2xm1);
5192                     break;
5193                 case 1: /* fyl2x */
5194                     tcg_gen_helper_0_0(helper_fyl2x);
5195                     break;
5196                 case 2: /* fptan */
5197                     tcg_gen_helper_0_0(helper_fptan);
5198                     break;
5199                 case 3: /* fpatan */
5200                     tcg_gen_helper_0_0(helper_fpatan);
5201                     break;
5202                 case 4: /* fxtract */
5203                     tcg_gen_helper_0_0(helper_fxtract);
5204                     break;
5205                 case 5: /* fprem1 */
5206                     tcg_gen_helper_0_0(helper_fprem1);
5207                     break;
5208                 case 6: /* fdecstp */
5209                     tcg_gen_helper_0_0(helper_fdecstp);
5210                     break;
5211                 default:
5212                 case 7: /* fincstp */
5213                     tcg_gen_helper_0_0(helper_fincstp);
5214                     break;
5215                 }
5216                 break;
5217             case 0x0f: /* grp d9/7 */
5218                 switch(rm) {
5219                 case 0: /* fprem */
5220                     tcg_gen_helper_0_0(helper_fprem);
5221                     break;
5222                 case 1: /* fyl2xp1 */
5223                     tcg_gen_helper_0_0(helper_fyl2xp1);
5224                     break;
5225                 case 2: /* fsqrt */
5226                     tcg_gen_helper_0_0(helper_fsqrt);
5227                     break;
5228                 case 3: /* fsincos */
5229                     tcg_gen_helper_0_0(helper_fsincos);
5230                     break;
5231                 case 5: /* fscale */
5232                     tcg_gen_helper_0_0(helper_fscale);
5233                     break;
5234                 case 4: /* frndint */
5235                     tcg_gen_helper_0_0(helper_frndint);
5236                     break;
5237                 case 6: /* fsin */
5238                     tcg_gen_helper_0_0(helper_fsin);
5239                     break;
5240                 default:
5241                 case 7: /* fcos */
5242                     tcg_gen_helper_0_0(helper_fcos);
5243                     break;
5244                 }
5245                 break;
5246             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
5247             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
5248             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
5249                 {
5250                     int op1;
5251
5252                     op1 = op & 7;
5253                     if (op >= 0x20) {
5254                         tcg_gen_helper_0_1(helper_fp_arith_STN_ST0[op1], tcg_const_i32(opreg));
5255                         if (op >= 0x30)
5256                             tcg_gen_helper_0_0(helper_fpop);
5257                     } else {
5258                         tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5259                         tcg_gen_helper_0_0(helper_fp_arith_ST0_FT0[op1]);
5260                     }
5261                 }
5262                 break;
5263             case 0x02: /* fcom */
5264             case 0x22: /* fcom2, undocumented op */
5265                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5266                 tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5267                 break;
5268             case 0x03: /* fcomp */
5269             case 0x23: /* fcomp3, undocumented op */
5270             case 0x32: /* fcomp5, undocumented op */
5271                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5272                 tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5273                 tcg_gen_helper_0_0(helper_fpop);
5274                 break;
5275             case 0x15: /* da/5 */
5276                 switch(rm) {
5277                 case 1: /* fucompp */
5278                     tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
5279                     tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5280                     tcg_gen_helper_0_0(helper_fpop);
5281                     tcg_gen_helper_0_0(helper_fpop);
5282                     break;
5283                 default:
5284                     goto illegal_op;
5285                 }
5286                 break;
5287             case 0x1c:
5288                 switch(rm) {
5289                 case 0: /* feni (287 only, just do nop here) */
5290                     break;
5291                 case 1: /* fdisi (287 only, just do nop here) */
5292                     break;
5293                 case 2: /* fclex */
5294                     tcg_gen_helper_0_0(helper_fclex);
5295                     break;
5296                 case 3: /* fninit */
5297                     tcg_gen_helper_0_0(helper_fninit);
5298                     break;
5299                 case 4: /* fsetpm (287 only, just do nop here) */
5300                     break;
5301                 default:
5302                     goto illegal_op;
5303                 }
5304                 break;
5305             case 0x1d: /* fucomi */
5306                 if (s->cc_op != CC_OP_DYNAMIC)
5307                     gen_op_set_cc_op(s->cc_op);
5308                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5309                 tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
5310                 s->cc_op = CC_OP_EFLAGS;
5311                 break;
5312             case 0x1e: /* fcomi */
5313                 if (s->cc_op != CC_OP_DYNAMIC)
5314                     gen_op_set_cc_op(s->cc_op);
5315                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5316                 tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
5317                 s->cc_op = CC_OP_EFLAGS;
5318                 break;
5319             case 0x28: /* ffree sti */
5320                 tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
5321                 break;
5322             case 0x2a: /* fst sti */
5323                 tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
5324                 break;
5325             case 0x2b: /* fstp sti */
5326             case 0x0b: /* fstp1 sti, undocumented op */
5327             case 0x3a: /* fstp8 sti, undocumented op */
5328             case 0x3b: /* fstp9 sti, undocumented op */
5329                 tcg_gen_helper_0_1(helper_fmov_STN_ST0, tcg_const_i32(opreg));
5330                 tcg_gen_helper_0_0(helper_fpop);
5331                 break;
5332             case 0x2c: /* fucom st(i) */
5333                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5334                 tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5335                 break;
5336             case 0x2d: /* fucomp st(i) */
5337                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5338                 tcg_gen_helper_0_0(helper_fucom_ST0_FT0);
5339                 tcg_gen_helper_0_0(helper_fpop);
5340                 break;
5341             case 0x33: /* de/3 */
5342                 switch(rm) {
5343                 case 1: /* fcompp */
5344                     tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(1));
5345                     tcg_gen_helper_0_0(helper_fcom_ST0_FT0);
5346                     tcg_gen_helper_0_0(helper_fpop);
5347                     tcg_gen_helper_0_0(helper_fpop);
5348                     break;
5349                 default:
5350                     goto illegal_op;
5351                 }
5352                 break;
5353             case 0x38: /* ffreep sti, undocumented op */
5354                 tcg_gen_helper_0_1(helper_ffree_STN, tcg_const_i32(opreg));
5355                 tcg_gen_helper_0_0(helper_fpop);
5356                 break;
5357             case 0x3c: /* df/4 */
5358                 switch(rm) {
5359                 case 0:
5360                     tcg_gen_helper_1_0(helper_fnstsw, cpu_tmp2_i32);
5361                     tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
5362                     gen_op_mov_reg_T0(OT_WORD, R_EAX);
5363                     break;
5364                 default:
5365                     goto illegal_op;
5366                 }
5367                 break;
5368             case 0x3d: /* fucomip */
5369                 if (s->cc_op != CC_OP_DYNAMIC)
5370                     gen_op_set_cc_op(s->cc_op);
5371                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5372                 tcg_gen_helper_0_0(helper_fucomi_ST0_FT0);
5373                 tcg_gen_helper_0_0(helper_fpop);
5374                 s->cc_op = CC_OP_EFLAGS;
5375                 break;
5376             case 0x3e: /* fcomip */
5377                 if (s->cc_op != CC_OP_DYNAMIC)
5378                     gen_op_set_cc_op(s->cc_op);
5379                 tcg_gen_helper_0_1(helper_fmov_FT0_STN, tcg_const_i32(opreg));
5380                 tcg_gen_helper_0_0(helper_fcomi_ST0_FT0);
5381                 tcg_gen_helper_0_0(helper_fpop);
5382                 s->cc_op = CC_OP_EFLAGS;
5383                 break;
5384             case 0x10 ... 0x13: /* fcmovxx */
5385             case 0x18 ... 0x1b:
5386                 {
5387                     int op1, l1;
5388                     const static uint8_t fcmov_cc[8] = {
5389                         (JCC_B << 1),
5390                         (JCC_Z << 1),
5391                         (JCC_BE << 1),
5392                         (JCC_P << 1),
5393                     };
5394                     op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
5395                     gen_setcc(s, op1);
5396                     l1 = gen_new_label();
5397                     tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1);
5398                     tcg_gen_helper_0_1(helper_fmov_ST0_STN, tcg_const_i32(opreg));
5399                     gen_set_label(l1);
5400                 }
5401                 break;
5402             default:
5403                 goto illegal_op;
5404             }
5405         }
5406         break;
5407         /************************/
5408         /* string ops */
5409
5410     case 0xa4: /* movsS */
5411     case 0xa5:
5412         if ((b & 1) == 0)
5413             ot = OT_BYTE;
5414         else
5415             ot = dflag + OT_WORD;
5416
5417         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5418             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5419         } else {
5420             gen_movs(s, ot);
5421         }
5422         break;
5423
5424     case 0xaa: /* stosS */
5425     case 0xab:
5426         if ((b & 1) == 0)
5427             ot = OT_BYTE;
5428         else
5429             ot = dflag + OT_WORD;
5430
5431         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5432             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5433         } else {
5434             gen_stos(s, ot);
5435         }
5436         break;
5437     case 0xac: /* lodsS */
5438     case 0xad:
5439         if ((b & 1) == 0)
5440             ot = OT_BYTE;
5441         else
5442             ot = dflag + OT_WORD;
5443         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5444             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5445         } else {
5446             gen_lods(s, ot);
5447         }
5448         break;
5449     case 0xae: /* scasS */
5450     case 0xaf:
5451         if ((b & 1) == 0)
5452             ot = OT_BYTE;
5453         else
5454             ot = dflag + OT_WORD;
5455         if (prefixes & PREFIX_REPNZ) {
5456             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5457         } else if (prefixes & PREFIX_REPZ) {
5458             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5459         } else {
5460             gen_scas(s, ot);
5461             s->cc_op = CC_OP_SUBB + ot;
5462         }
5463         break;
5464
5465     case 0xa6: /* cmpsS */
5466     case 0xa7:
5467         if ((b & 1) == 0)
5468             ot = OT_BYTE;
5469         else
5470             ot = dflag + OT_WORD;
5471         if (prefixes & PREFIX_REPNZ) {
5472             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
5473         } else if (prefixes & PREFIX_REPZ) {
5474             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
5475         } else {
5476             gen_cmps(s, ot);
5477             s->cc_op = CC_OP_SUBB + ot;
5478         }
5479         break;
5480     case 0x6c: /* insS */
5481     case 0x6d:
5482         if ((b & 1) == 0)
5483             ot = OT_BYTE;
5484         else
5485             ot = dflag ? OT_LONG : OT_WORD;
5486         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5487         gen_op_andl_T0_ffff();
5488         gen_check_io(s, ot, pc_start - s->cs_base, 
5489                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
5490         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5491             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5492         } else {
5493             gen_ins(s, ot);
5494         }
5495         break;
5496     case 0x6e: /* outsS */
5497     case 0x6f:
5498         if ((b & 1) == 0)
5499             ot = OT_BYTE;
5500         else
5501             ot = dflag ? OT_LONG : OT_WORD;
5502         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5503         gen_op_andl_T0_ffff();
5504         gen_check_io(s, ot, pc_start - s->cs_base,
5505                      svm_is_rep(prefixes) | 4);
5506         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5507             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
5508         } else {
5509             gen_outs(s, ot);
5510         }
5511         break;
5512
5513         /************************/
5514         /* port I/O */
5515
5516     case 0xe4:
5517     case 0xe5:
5518         if ((b & 1) == 0)
5519             ot = OT_BYTE;
5520         else
5521             ot = dflag ? OT_LONG : OT_WORD;
5522         val = ldub_code(s->pc++);
5523         gen_op_movl_T0_im(val);
5524         gen_check_io(s, ot, pc_start - s->cs_base,
5525                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
5526         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5527         tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
5528         gen_op_mov_reg_T1(ot, R_EAX);
5529         break;
5530     case 0xe6:
5531     case 0xe7:
5532         if ((b & 1) == 0)
5533             ot = OT_BYTE;
5534         else
5535             ot = dflag ? OT_LONG : OT_WORD;
5536         val = ldub_code(s->pc++);
5537         gen_op_movl_T0_im(val);
5538         gen_check_io(s, ot, pc_start - s->cs_base,
5539                      svm_is_rep(prefixes));
5540         gen_op_mov_TN_reg(ot, 1, R_EAX);
5541
5542         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5543         tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
5544         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
5545         tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
5546         break;
5547     case 0xec:
5548     case 0xed:
5549         if ((b & 1) == 0)
5550             ot = OT_BYTE;
5551         else
5552             ot = dflag ? OT_LONG : OT_WORD;
5553         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5554         gen_op_andl_T0_ffff();
5555         gen_check_io(s, ot, pc_start - s->cs_base,
5556                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
5557         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5558         tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
5559         gen_op_mov_reg_T1(ot, R_EAX);
5560         break;
5561     case 0xee:
5562     case 0xef:
5563         if ((b & 1) == 0)
5564             ot = OT_BYTE;
5565         else
5566             ot = dflag ? OT_LONG : OT_WORD;
5567         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5568         gen_op_andl_T0_ffff();
5569         gen_check_io(s, ot, pc_start - s->cs_base,
5570                      svm_is_rep(prefixes));
5571         gen_op_mov_TN_reg(ot, 1, R_EAX);
5572
5573         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
5574         tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
5575         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
5576         tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
5577         break;
5578
5579         /************************/
5580         /* control */
5581     case 0xc2: /* ret im */
5582         val = ldsw_code(s->pc);
5583         s->pc += 2;
5584         gen_pop_T0(s);
5585         if (CODE64(s) && s->dflag)
5586             s->dflag = 2;
5587         gen_stack_update(s, val + (2 << s->dflag));
5588         if (s->dflag == 0)
5589             gen_op_andl_T0_ffff();
5590         gen_op_jmp_T0();
5591         gen_eob(s);
5592         break;
5593     case 0xc3: /* ret */
5594         gen_pop_T0(s);
5595         gen_pop_update(s);
5596         if (s->dflag == 0)
5597             gen_op_andl_T0_ffff();
5598         gen_op_jmp_T0();
5599         gen_eob(s);
5600         break;
5601     case 0xca: /* lret im */
5602         val = ldsw_code(s->pc);
5603         s->pc += 2;
5604     do_lret:
5605         if (s->pe && !s->vm86) {
5606             if (s->cc_op != CC_OP_DYNAMIC)
5607                 gen_op_set_cc_op(s->cc_op);
5608             gen_jmp_im(pc_start - s->cs_base);
5609             tcg_gen_helper_0_2(helper_lret_protected,
5610                                tcg_const_i32(s->dflag), 
5611                                tcg_const_i32(val));
5612         } else {
5613             gen_stack_A0(s);
5614             /* pop offset */
5615             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5616             if (s->dflag == 0)
5617                 gen_op_andl_T0_ffff();
5618             /* NOTE: keeping EIP updated is not a problem in case of
5619                exception */
5620             gen_op_jmp_T0();
5621             /* pop selector */
5622             gen_op_addl_A0_im(2 << s->dflag);
5623             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5624             gen_op_movl_seg_T0_vm(R_CS);
5625             /* add stack offset */
5626             gen_stack_update(s, val + (4 << s->dflag));
5627         }
5628         gen_eob(s);
5629         break;
5630     case 0xcb: /* lret */
5631         val = 0;
5632         goto do_lret;
5633     case 0xcf: /* iret */
5634         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET))
5635             break;
5636         if (!s->pe) {
5637             /* real mode */
5638             tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5639             s->cc_op = CC_OP_EFLAGS;
5640         } else if (s->vm86) {
5641             if (s->iopl != 3) {
5642                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5643             } else {
5644                 tcg_gen_helper_0_1(helper_iret_real, tcg_const_i32(s->dflag));
5645                 s->cc_op = CC_OP_EFLAGS;
5646             }
5647         } else {
5648             if (s->cc_op != CC_OP_DYNAMIC)
5649                 gen_op_set_cc_op(s->cc_op);
5650             gen_jmp_im(pc_start - s->cs_base);
5651             tcg_gen_helper_0_2(helper_iret_protected,
5652                                tcg_const_i32(s->dflag), 
5653                                tcg_const_i32(s->pc - s->cs_base));
5654             s->cc_op = CC_OP_EFLAGS;
5655         }
5656         gen_eob(s);
5657         break;
5658     case 0xe8: /* call im */
5659         {
5660             if (dflag)
5661                 tval = (int32_t)insn_get(s, OT_LONG);
5662             else
5663                 tval = (int16_t)insn_get(s, OT_WORD);
5664             next_eip = s->pc - s->cs_base;
5665             tval += next_eip;
5666             if (s->dflag == 0)
5667                 tval &= 0xffff;
5668             gen_movtl_T0_im(next_eip);
5669             gen_push_T0(s);
5670             gen_jmp(s, tval);
5671         }
5672         break;
5673     case 0x9a: /* lcall im */
5674         {
5675             unsigned int selector, offset;
5676
5677             if (CODE64(s))
5678                 goto illegal_op;
5679             ot = dflag ? OT_LONG : OT_WORD;
5680             offset = insn_get(s, ot);
5681             selector = insn_get(s, OT_WORD);
5682
5683             gen_op_movl_T0_im(selector);
5684             gen_op_movl_T1_imu(offset);
5685         }
5686         goto do_lcall;
5687     case 0xe9: /* jmp im */
5688         if (dflag)
5689             tval = (int32_t)insn_get(s, OT_LONG);
5690         else
5691             tval = (int16_t)insn_get(s, OT_WORD);
5692         tval += s->pc - s->cs_base;
5693         if (s->dflag == 0)
5694             tval &= 0xffff;
5695         gen_jmp(s, tval);
5696         break;
5697     case 0xea: /* ljmp im */
5698         {
5699             unsigned int selector, offset;
5700
5701             if (CODE64(s))
5702                 goto illegal_op;
5703             ot = dflag ? OT_LONG : OT_WORD;
5704             offset = insn_get(s, ot);
5705             selector = insn_get(s, OT_WORD);
5706
5707             gen_op_movl_T0_im(selector);
5708             gen_op_movl_T1_imu(offset);
5709         }
5710         goto do_ljmp;
5711     case 0xeb: /* jmp Jb */
5712         tval = (int8_t)insn_get(s, OT_BYTE);
5713         tval += s->pc - s->cs_base;
5714         if (s->dflag == 0)
5715             tval &= 0xffff;
5716         gen_jmp(s, tval);
5717         break;
5718     case 0x70 ... 0x7f: /* jcc Jb */
5719         tval = (int8_t)insn_get(s, OT_BYTE);
5720         goto do_jcc;
5721     case 0x180 ... 0x18f: /* jcc Jv */
5722         if (dflag) {
5723             tval = (int32_t)insn_get(s, OT_LONG);
5724         } else {
5725             tval = (int16_t)insn_get(s, OT_WORD);
5726         }
5727     do_jcc:
5728         next_eip = s->pc - s->cs_base;
5729         tval += next_eip;
5730         if (s->dflag == 0)
5731             tval &= 0xffff;
5732         gen_jcc(s, b, tval, next_eip);
5733         break;
5734
5735     case 0x190 ... 0x19f: /* setcc Gv */
5736         modrm = ldub_code(s->pc++);
5737         gen_setcc(s, b);
5738         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
5739         break;
5740     case 0x140 ... 0x14f: /* cmov Gv, Ev */
5741         {
5742             int l1;
5743             ot = dflag + OT_WORD;
5744             modrm = ldub_code(s->pc++);
5745             reg = ((modrm >> 3) & 7) | rex_r;
5746             mod = (modrm >> 6) & 3;
5747             if (mod != 3) {
5748                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5749                 gen_op_ld_T1_A0(ot + s->mem_index);
5750             } else {
5751                 rm = (modrm & 7) | REX_B(s);
5752                 gen_op_mov_TN_reg(ot, 1, rm);
5753             }
5754             if (s->cc_op != CC_OP_DYNAMIC)
5755                 gen_op_set_cc_op(s->cc_op);
5756 #ifdef TARGET_X86_64
5757             if (ot == OT_LONG) {
5758                 /* XXX: specific Intel behaviour ? */
5759                 l1 = gen_new_label();
5760                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
5761                 tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
5762                 gen_set_label(l1);
5763                 tcg_gen_movi_tl(cpu_tmp0, 0);
5764                 tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
5765             } else
5766 #endif
5767             {
5768                 l1 = gen_new_label();
5769                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
5770                 gen_op_mov_reg_T1(ot, reg);
5771                 gen_set_label(l1);
5772             }
5773         }
5774         break;
5775
5776         /************************/
5777         /* flags */
5778     case 0x9c: /* pushf */
5779         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF))
5780             break;
5781         if (s->vm86 && s->iopl != 3) {
5782             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5783         } else {
5784             if (s->cc_op != CC_OP_DYNAMIC)
5785                 gen_op_set_cc_op(s->cc_op);
5786             tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]);
5787             gen_push_T0(s);
5788         }
5789         break;
5790     case 0x9d: /* popf */
5791         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF))
5792             break;
5793         if (s->vm86 && s->iopl != 3) {
5794             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5795         } else {
5796             gen_pop_T0(s);
5797             if (s->cpl == 0) {
5798                 if (s->dflag) {
5799                     tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5800                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
5801                 } else {
5802                     tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5803                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
5804                 }
5805             } else {
5806                 if (s->cpl <= s->iopl) {
5807                     if (s->dflag) {
5808                         tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5809                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
5810                     } else {
5811                         tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5812                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
5813                     }
5814                 } else {
5815                     if (s->dflag) {
5816                         tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5817                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
5818                     } else {
5819                         tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5820                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
5821                     }
5822                 }
5823             }
5824             gen_pop_update(s);
5825             s->cc_op = CC_OP_EFLAGS;
5826             /* abort translation because TF flag may change */
5827             gen_jmp_im(s->pc - s->cs_base);
5828             gen_eob(s);
5829         }
5830         break;
5831     case 0x9e: /* sahf */
5832         if (CODE64(s))
5833             goto illegal_op;
5834         gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5835         if (s->cc_op != CC_OP_DYNAMIC)
5836             gen_op_set_cc_op(s->cc_op);
5837         gen_compute_eflags(cpu_cc_src);
5838         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5839         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
5840         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
5841         s->cc_op = CC_OP_EFLAGS;
5842         break;
5843     case 0x9f: /* lahf */
5844         if (CODE64(s))
5845             goto illegal_op;
5846         if (s->cc_op != CC_OP_DYNAMIC)
5847             gen_op_set_cc_op(s->cc_op);
5848         gen_compute_eflags(cpu_T[0]);
5849         /* Note: gen_compute_eflags() only gives the condition codes */
5850         tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
5851         gen_op_mov_reg_T0(OT_BYTE, R_AH);
5852         break;
5853     case 0xf5: /* cmc */
5854         if (s->cc_op != CC_OP_DYNAMIC)
5855             gen_op_set_cc_op(s->cc_op);
5856         gen_compute_eflags(cpu_cc_src);
5857         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5858         s->cc_op = CC_OP_EFLAGS;
5859         break;
5860     case 0xf8: /* clc */
5861         if (s->cc_op != CC_OP_DYNAMIC)
5862             gen_op_set_cc_op(s->cc_op);
5863         gen_compute_eflags(cpu_cc_src);
5864         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5865         s->cc_op = CC_OP_EFLAGS;
5866         break;
5867     case 0xf9: /* stc */
5868         if (s->cc_op != CC_OP_DYNAMIC)
5869             gen_op_set_cc_op(s->cc_op);
5870         gen_compute_eflags(cpu_cc_src);
5871         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5872         s->cc_op = CC_OP_EFLAGS;
5873         break;
5874     case 0xfc: /* cld */
5875         tcg_gen_movi_i32(cpu_tmp2_i32, 1);
5876         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
5877         break;
5878     case 0xfd: /* std */
5879         tcg_gen_movi_i32(cpu_tmp2_i32, -1);
5880         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
5881         break;
5882
5883         /************************/
5884         /* bit operations */
5885     case 0x1ba: /* bt/bts/btr/btc Gv, im */
5886         ot = dflag + OT_WORD;
5887         modrm = ldub_code(s->pc++);
5888         op = (modrm >> 3) & 7;
5889         mod = (modrm >> 6) & 3;
5890         rm = (modrm & 7) | REX_B(s);
5891         if (mod != 3) {
5892             s->rip_offset = 1;
5893             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5894             gen_op_ld_T0_A0(ot + s->mem_index);
5895         } else {
5896             gen_op_mov_TN_reg(ot, 0, rm);
5897         }
5898         /* load shift */
5899         val = ldub_code(s->pc++);
5900         gen_op_movl_T1_im(val);
5901         if (op < 4)
5902             goto illegal_op;
5903         op -= 4;
5904         goto bt_op;
5905     case 0x1a3: /* bt Gv, Ev */
5906         op = 0;
5907         goto do_btx;
5908     case 0x1ab: /* bts */
5909         op = 1;
5910         goto do_btx;
5911     case 0x1b3: /* btr */
5912         op = 2;
5913         goto do_btx;
5914     case 0x1bb: /* btc */
5915         op = 3;
5916     do_btx:
5917         ot = dflag + OT_WORD;
5918         modrm = ldub_code(s->pc++);
5919         reg = ((modrm >> 3) & 7) | rex_r;
5920         mod = (modrm >> 6) & 3;
5921         rm = (modrm & 7) | REX_B(s);
5922         gen_op_mov_TN_reg(OT_LONG, 1, reg);
5923         if (mod != 3) {
5924             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5925             /* specific case: we need to add a displacement */
5926             gen_exts(ot, cpu_T[1]);
5927             tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
5928             tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
5929             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
5930             gen_op_ld_T0_A0(ot + s->mem_index);
5931         } else {
5932             gen_op_mov_TN_reg(ot, 0, rm);
5933         }
5934     bt_op:
5935         tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
5936         switch(op) {
5937         case 0:
5938             tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
5939             tcg_gen_movi_tl(cpu_cc_dst, 0);
5940             break;
5941         case 1:
5942             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5943             tcg_gen_movi_tl(cpu_tmp0, 1);
5944             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5945             tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5946             break;
5947         case 2:
5948             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5949             tcg_gen_movi_tl(cpu_tmp0, 1);
5950             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5951             tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
5952             tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5953             break;
5954         default:
5955         case 3:
5956             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5957             tcg_gen_movi_tl(cpu_tmp0, 1);
5958             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5959             tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5960             break;
5961         }
5962         s->cc_op = CC_OP_SARB + ot;
5963         if (op != 0) {
5964             if (mod != 3)
5965                 gen_op_st_T0_A0(ot + s->mem_index);
5966             else
5967                 gen_op_mov_reg_T0(ot, rm);
5968             tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
5969             tcg_gen_movi_tl(cpu_cc_dst, 0);
5970         }
5971         break;
5972     case 0x1bc: /* bsf */
5973     case 0x1bd: /* bsr */
5974         {
5975             int label1;
5976             ot = dflag + OT_WORD;
5977             modrm = ldub_code(s->pc++);
5978             reg = ((modrm >> 3) & 7) | rex_r;
5979             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5980             gen_extu(ot, cpu_T[0]);
5981             label1 = gen_new_label();
5982             tcg_gen_movi_tl(cpu_cc_dst, 0);
5983             tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), label1);
5984             if (b & 1) {
5985                 tcg_gen_helper_1_1(helper_bsr, cpu_T[0], cpu_T[0]);
5986             } else {
5987                 tcg_gen_helper_1_1(helper_bsf, cpu_T[0], cpu_T[0]);
5988             }
5989             gen_op_mov_reg_T0(ot, reg);
5990             tcg_gen_movi_tl(cpu_cc_dst, 1);
5991             gen_set_label(label1);
5992             tcg_gen_discard_tl(cpu_cc_src);
5993             s->cc_op = CC_OP_LOGICB + ot;
5994         }
5995         break;
5996         /************************/
5997         /* bcd */
5998     case 0x27: /* daa */
5999         if (CODE64(s))
6000             goto illegal_op;
6001         if (s->cc_op != CC_OP_DYNAMIC)
6002             gen_op_set_cc_op(s->cc_op);
6003         tcg_gen_helper_0_0(helper_daa);
6004         s->cc_op = CC_OP_EFLAGS;
6005         break;
6006     case 0x2f: /* das */
6007         if (CODE64(s))
6008             goto illegal_op;
6009         if (s->cc_op != CC_OP_DYNAMIC)
6010             gen_op_set_cc_op(s->cc_op);
6011         tcg_gen_helper_0_0(helper_das);
6012         s->cc_op = CC_OP_EFLAGS;
6013         break;
6014     case 0x37: /* aaa */
6015         if (CODE64(s))
6016             goto illegal_op;
6017         if (s->cc_op != CC_OP_DYNAMIC)
6018             gen_op_set_cc_op(s->cc_op);
6019         tcg_gen_helper_0_0(helper_aaa);
6020         s->cc_op = CC_OP_EFLAGS;
6021         break;
6022     case 0x3f: /* aas */
6023         if (CODE64(s))
6024             goto illegal_op;
6025         if (s->cc_op != CC_OP_DYNAMIC)
6026             gen_op_set_cc_op(s->cc_op);
6027         tcg_gen_helper_0_0(helper_aas);
6028         s->cc_op = CC_OP_EFLAGS;
6029         break;
6030     case 0xd4: /* aam */
6031         if (CODE64(s))
6032             goto illegal_op;
6033         val = ldub_code(s->pc++);
6034         if (val == 0) {
6035             gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
6036         } else {
6037             tcg_gen_helper_0_1(helper_aam, tcg_const_i32(val));
6038             s->cc_op = CC_OP_LOGICB;
6039         }
6040         break;
6041     case 0xd5: /* aad */
6042         if (CODE64(s))
6043             goto illegal_op;
6044         val = ldub_code(s->pc++);
6045         tcg_gen_helper_0_1(helper_aad, tcg_const_i32(val));
6046         s->cc_op = CC_OP_LOGICB;
6047         break;
6048         /************************/
6049         /* misc */
6050     case 0x90: /* nop */
6051         /* XXX: xchg + rex handling */
6052         /* XXX: correct lock test for all insn */
6053         if (prefixes & PREFIX_LOCK)
6054             goto illegal_op;
6055         if (prefixes & PREFIX_REPZ) {
6056             gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
6057         }
6058         break;
6059     case 0x9b: /* fwait */
6060         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
6061             (HF_MP_MASK | HF_TS_MASK)) {
6062             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6063         } else {
6064             if (s->cc_op != CC_OP_DYNAMIC)
6065                 gen_op_set_cc_op(s->cc_op);
6066             gen_jmp_im(pc_start - s->cs_base);
6067             tcg_gen_helper_0_0(helper_fwait);
6068         }
6069         break;
6070     case 0xcc: /* int3 */
6071         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6072             break;
6073         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
6074         break;
6075     case 0xcd: /* int N */
6076         val = ldub_code(s->pc++);
6077         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6078             break;
6079         if (s->vm86 && s->iopl != 3) {
6080             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6081         } else {
6082             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
6083         }
6084         break;
6085     case 0xce: /* into */
6086         if (CODE64(s))
6087             goto illegal_op;
6088         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
6089             break;
6090         if (s->cc_op != CC_OP_DYNAMIC)
6091             gen_op_set_cc_op(s->cc_op);
6092         gen_jmp_im(pc_start - s->cs_base);
6093         tcg_gen_helper_0_1(helper_into, tcg_const_i32(s->pc - pc_start));
6094         break;
6095     case 0xf1: /* icebp (undocumented, exits to external debugger) */
6096         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP))
6097             break;
6098 #if 1
6099         gen_debug(s, pc_start - s->cs_base);
6100 #else
6101         /* start debug */
6102         tb_flush(cpu_single_env);
6103         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
6104 #endif
6105         break;
6106     case 0xfa: /* cli */
6107         if (!s->vm86) {
6108             if (s->cpl <= s->iopl) {
6109                 tcg_gen_helper_0_0(helper_cli);
6110             } else {
6111                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6112             }
6113         } else {
6114             if (s->iopl == 3) {
6115                 tcg_gen_helper_0_0(helper_cli);
6116             } else {
6117                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6118             }
6119         }
6120         break;
6121     case 0xfb: /* sti */
6122         if (!s->vm86) {
6123             if (s->cpl <= s->iopl) {
6124             gen_sti:
6125                 tcg_gen_helper_0_0(helper_sti);
6126                 /* interruptions are enabled only the first insn after sti */
6127                 /* If several instructions disable interrupts, only the
6128                    _first_ does it */
6129                 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
6130                     tcg_gen_helper_0_0(helper_set_inhibit_irq);
6131                 /* give a chance to handle pending irqs */
6132                 gen_jmp_im(s->pc - s->cs_base);
6133                 gen_eob(s);
6134             } else {
6135                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6136             }
6137         } else {
6138             if (s->iopl == 3) {
6139                 goto gen_sti;
6140             } else {
6141                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6142             }
6143         }
6144         break;
6145     case 0x62: /* bound */
6146         if (CODE64(s))
6147             goto illegal_op;
6148         ot = dflag ? OT_LONG : OT_WORD;
6149         modrm = ldub_code(s->pc++);
6150         reg = (modrm >> 3) & 7;
6151         mod = (modrm >> 6) & 3;
6152         if (mod == 3)
6153             goto illegal_op;
6154         gen_op_mov_TN_reg(ot, 0, reg);
6155         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6156         gen_jmp_im(pc_start - s->cs_base);
6157         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6158         if (ot == OT_WORD)
6159             tcg_gen_helper_0_2(helper_boundw, cpu_A0, cpu_tmp2_i32);
6160         else
6161             tcg_gen_helper_0_2(helper_boundl, cpu_A0, cpu_tmp2_i32);
6162         break;
6163     case 0x1c8 ... 0x1cf: /* bswap reg */
6164         reg = (b & 7) | REX_B(s);
6165 #ifdef TARGET_X86_64
6166         if (dflag == 2) {
6167             gen_op_mov_TN_reg(OT_QUAD, 0, reg);
6168             tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
6169             gen_op_mov_reg_T0(OT_QUAD, reg);
6170         } else
6171         {
6172             TCGv tmp0;
6173             gen_op_mov_TN_reg(OT_LONG, 0, reg);
6174             
6175             tmp0 = tcg_temp_new(TCG_TYPE_I32);
6176             tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
6177             tcg_gen_bswap_i32(tmp0, tmp0);
6178             tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
6179             gen_op_mov_reg_T0(OT_LONG, reg);
6180         }
6181 #else
6182         {
6183             gen_op_mov_TN_reg(OT_LONG, 0, reg);
6184             tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
6185             gen_op_mov_reg_T0(OT_LONG, reg);
6186         }
6187 #endif
6188         break;
6189     case 0xd6: /* salc */
6190         if (CODE64(s))
6191             goto illegal_op;
6192         if (s->cc_op != CC_OP_DYNAMIC)
6193             gen_op_set_cc_op(s->cc_op);
6194         gen_compute_eflags_c(cpu_T[0]);
6195         tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6196         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6197         break;
6198     case 0xe0: /* loopnz */
6199     case 0xe1: /* loopz */
6200     case 0xe2: /* loop */
6201     case 0xe3: /* jecxz */
6202         {
6203             int l1, l2, l3;
6204
6205             tval = (int8_t)insn_get(s, OT_BYTE);
6206             next_eip = s->pc - s->cs_base;
6207             tval += next_eip;
6208             if (s->dflag == 0)
6209                 tval &= 0xffff;
6210
6211             l1 = gen_new_label();
6212             l2 = gen_new_label();
6213             l3 = gen_new_label();
6214             b &= 3;
6215             switch(b) {
6216             case 0: /* loopnz */
6217             case 1: /* loopz */
6218                 if (s->cc_op != CC_OP_DYNAMIC)
6219                     gen_op_set_cc_op(s->cc_op);
6220                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
6221                 gen_op_jz_ecx(s->aflag, l3);
6222                 gen_compute_eflags(cpu_tmp0);
6223                 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
6224                 if (b == 0) {
6225                     tcg_gen_brcond_tl(TCG_COND_EQ, 
6226                                       cpu_tmp0, tcg_const_tl(0), l1);
6227                 } else {
6228                     tcg_gen_brcond_tl(TCG_COND_NE, 
6229                                       cpu_tmp0, tcg_const_tl(0), l1);
6230                 }
6231                 break;
6232             case 2: /* loop */
6233                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
6234                 gen_op_jnz_ecx(s->aflag, l1);
6235                 break;
6236             default:
6237             case 3: /* jcxz */
6238                 gen_op_jz_ecx(s->aflag, l1);
6239                 break;
6240             }
6241
6242             gen_set_label(l3);
6243             gen_jmp_im(next_eip);
6244             tcg_gen_br(l2);
6245
6246             gen_set_label(l1);
6247             gen_jmp_im(tval);
6248             gen_set_label(l2);
6249             gen_eob(s);
6250         }
6251         break;
6252     case 0x130: /* wrmsr */
6253     case 0x132: /* rdmsr */
6254         if (s->cpl != 0) {
6255             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6256         } else {
6257             int retval = 0;
6258             if (b & 2) {
6259                 retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 0);
6260                 tcg_gen_helper_0_0(helper_rdmsr);
6261             } else {
6262                 retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 1);
6263                 tcg_gen_helper_0_0(helper_wrmsr);
6264             }
6265             if(retval)
6266                 gen_eob(s);
6267         }
6268         break;
6269     case 0x131: /* rdtsc */
6270         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RDTSC))
6271             break;
6272         gen_jmp_im(pc_start - s->cs_base);
6273         tcg_gen_helper_0_0(helper_rdtsc);
6274         break;
6275     case 0x133: /* rdpmc */
6276         gen_jmp_im(pc_start - s->cs_base);
6277         tcg_gen_helper_0_0(helper_rdpmc);
6278         break;
6279     case 0x134: /* sysenter */
6280         if (CODE64(s))
6281             goto illegal_op;
6282         if (!s->pe) {
6283             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6284         } else {
6285             if (s->cc_op != CC_OP_DYNAMIC) {
6286                 gen_op_set_cc_op(s->cc_op);
6287                 s->cc_op = CC_OP_DYNAMIC;
6288             }
6289             gen_jmp_im(pc_start - s->cs_base);
6290             tcg_gen_helper_0_0(helper_sysenter);
6291             gen_eob(s);
6292         }
6293         break;
6294     case 0x135: /* sysexit */
6295         if (CODE64(s))
6296             goto illegal_op;
6297         if (!s->pe) {
6298             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6299         } else {
6300             if (s->cc_op != CC_OP_DYNAMIC) {
6301                 gen_op_set_cc_op(s->cc_op);
6302                 s->cc_op = CC_OP_DYNAMIC;
6303             }
6304             gen_jmp_im(pc_start - s->cs_base);
6305             tcg_gen_helper_0_0(helper_sysexit);
6306             gen_eob(s);
6307         }
6308         break;
6309 #ifdef TARGET_X86_64
6310     case 0x105: /* syscall */
6311         /* XXX: is it usable in real mode ? */
6312         if (s->cc_op != CC_OP_DYNAMIC) {
6313             gen_op_set_cc_op(s->cc_op);
6314             s->cc_op = CC_OP_DYNAMIC;
6315         }
6316         gen_jmp_im(pc_start - s->cs_base);
6317         tcg_gen_helper_0_1(helper_syscall, tcg_const_i32(s->pc - pc_start));
6318         gen_eob(s);
6319         break;
6320     case 0x107: /* sysret */
6321         if (!s->pe) {
6322             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6323         } else {
6324             if (s->cc_op != CC_OP_DYNAMIC) {
6325                 gen_op_set_cc_op(s->cc_op);
6326                 s->cc_op = CC_OP_DYNAMIC;
6327             }
6328             gen_jmp_im(pc_start - s->cs_base);
6329             tcg_gen_helper_0_1(helper_sysret, tcg_const_i32(s->dflag));
6330             /* condition codes are modified only in long mode */
6331             if (s->lma)
6332                 s->cc_op = CC_OP_EFLAGS;
6333             gen_eob(s);
6334         }
6335         break;
6336 #endif
6337     case 0x1a2: /* cpuid */
6338         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CPUID))
6339             break;
6340         tcg_gen_helper_0_0(helper_cpuid);
6341         break;
6342     case 0xf4: /* hlt */
6343         if (s->cpl != 0) {
6344             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6345         } else {
6346             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_HLT))
6347                 break;
6348             if (s->cc_op != CC_OP_DYNAMIC)
6349                 gen_op_set_cc_op(s->cc_op);
6350             gen_jmp_im(s->pc - s->cs_base);
6351             tcg_gen_helper_0_0(helper_hlt);
6352             s->is_jmp = 3;
6353         }
6354         break;
6355     case 0x100:
6356         modrm = ldub_code(s->pc++);
6357         mod = (modrm >> 6) & 3;
6358         op = (modrm >> 3) & 7;
6359         switch(op) {
6360         case 0: /* sldt */
6361             if (!s->pe || s->vm86)
6362                 goto illegal_op;
6363             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ))
6364                 break;
6365             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
6366             ot = OT_WORD;
6367             if (mod == 3)
6368                 ot += s->dflag;
6369             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6370             break;
6371         case 2: /* lldt */
6372             if (!s->pe || s->vm86)
6373                 goto illegal_op;
6374             if (s->cpl != 0) {
6375                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6376             } else {
6377                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE))
6378                     break;
6379                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6380                 gen_jmp_im(pc_start - s->cs_base);
6381                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6382                 tcg_gen_helper_0_1(helper_lldt, cpu_tmp2_i32);
6383             }
6384             break;
6385         case 1: /* str */
6386             if (!s->pe || s->vm86)
6387                 goto illegal_op;
6388             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ))
6389                 break;
6390             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
6391             ot = OT_WORD;
6392             if (mod == 3)
6393                 ot += s->dflag;
6394             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
6395             break;
6396         case 3: /* ltr */
6397             if (!s->pe || s->vm86)
6398                 goto illegal_op;
6399             if (s->cpl != 0) {
6400                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6401             } else {
6402                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE))
6403                     break;
6404                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6405                 gen_jmp_im(pc_start - s->cs_base);
6406                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
6407                 tcg_gen_helper_0_1(helper_ltr, cpu_tmp2_i32);
6408             }
6409             break;
6410         case 4: /* verr */
6411         case 5: /* verw */
6412             if (!s->pe || s->vm86)
6413                 goto illegal_op;
6414             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6415             if (s->cc_op != CC_OP_DYNAMIC)
6416                 gen_op_set_cc_op(s->cc_op);
6417             if (op == 4)
6418                 tcg_gen_helper_0_1(helper_verr, cpu_T[0]);
6419             else
6420                 tcg_gen_helper_0_1(helper_verw, cpu_T[0]);
6421             s->cc_op = CC_OP_EFLAGS;
6422             break;
6423         default:
6424             goto illegal_op;
6425         }
6426         break;
6427     case 0x101:
6428         modrm = ldub_code(s->pc++);
6429         mod = (modrm >> 6) & 3;
6430         op = (modrm >> 3) & 7;
6431         rm = modrm & 7;
6432         switch(op) {
6433         case 0: /* sgdt */
6434             if (mod == 3)
6435                 goto illegal_op;
6436             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ))
6437                 break;
6438             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6439             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
6440             gen_op_st_T0_A0(OT_WORD + s->mem_index);
6441             gen_add_A0_im(s, 2);
6442             tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
6443             if (!s->dflag)
6444                 gen_op_andl_T0_im(0xffffff);
6445             gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6446             break;
6447         case 1:
6448             if (mod == 3) {
6449                 switch (rm) {
6450                 case 0: /* monitor */
6451                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
6452                         s->cpl != 0)
6453                         goto illegal_op;
6454                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MONITOR))
6455                         break;
6456                     gen_jmp_im(pc_start - s->cs_base);
6457 #ifdef TARGET_X86_64
6458                     if (s->aflag == 2) {
6459                         gen_op_movq_A0_reg(R_EAX);
6460                     } else
6461 #endif
6462                     {
6463                         gen_op_movl_A0_reg(R_EAX);
6464                         if (s->aflag == 0)
6465                             gen_op_andl_A0_ffff();
6466                     }
6467                     gen_add_A0_ds_seg(s);
6468                     tcg_gen_helper_0_1(helper_monitor, cpu_A0);
6469                     break;
6470                 case 1: /* mwait */
6471                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
6472                         s->cpl != 0)
6473                         goto illegal_op;
6474                     if (s->cc_op != CC_OP_DYNAMIC) {
6475                         gen_op_set_cc_op(s->cc_op);
6476                         s->cc_op = CC_OP_DYNAMIC;
6477                     }
6478                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MWAIT))
6479                         break;
6480                     gen_jmp_im(s->pc - s->cs_base);
6481                     tcg_gen_helper_0_0(helper_mwait);
6482                     gen_eob(s);
6483                     break;
6484                 default:
6485                     goto illegal_op;
6486                 }
6487             } else { /* sidt */
6488                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ))
6489                     break;
6490                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6491                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
6492                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
6493                 gen_add_A0_im(s, 2);
6494                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
6495                 if (!s->dflag)
6496                     gen_op_andl_T0_im(0xffffff);
6497                 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6498             }
6499             break;
6500         case 2: /* lgdt */
6501         case 3: /* lidt */
6502             if (mod == 3) {
6503                 switch(rm) {
6504                 case 0: /* VMRUN */
6505                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMRUN))
6506                         break;
6507                     if (s->cc_op != CC_OP_DYNAMIC)
6508                         gen_op_set_cc_op(s->cc_op);
6509                     gen_jmp_im(s->pc - s->cs_base);
6510                     tcg_gen_helper_0_0(helper_vmrun);
6511                     s->cc_op = CC_OP_EFLAGS;
6512                     gen_eob(s);
6513                     break;
6514                 case 1: /* VMMCALL */
6515                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMMCALL))
6516                          break;
6517                     /* FIXME: cause #UD if hflags & SVM */
6518                     tcg_gen_helper_0_0(helper_vmmcall);
6519                     break;
6520                 case 2: /* VMLOAD */
6521                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMLOAD))
6522                          break;
6523                     tcg_gen_helper_0_0(helper_vmload);
6524                     break;
6525                 case 3: /* VMSAVE */
6526                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMSAVE))
6527                          break;
6528                     tcg_gen_helper_0_0(helper_vmsave);
6529                     break;
6530                 case 4: /* STGI */
6531                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_STGI))
6532                          break;
6533                     tcg_gen_helper_0_0(helper_stgi);
6534                     break;
6535                 case 5: /* CLGI */
6536                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CLGI))
6537                          break;
6538                     tcg_gen_helper_0_0(helper_clgi);
6539                     break;
6540                 case 6: /* SKINIT */
6541                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT))
6542                          break;
6543                     tcg_gen_helper_0_0(helper_skinit);
6544                     break;
6545                 case 7: /* INVLPGA */
6546                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPGA))
6547                          break;
6548                     tcg_gen_helper_0_0(helper_invlpga);
6549                     break;
6550                 default:
6551                     goto illegal_op;
6552                 }
6553             } else if (s->cpl != 0) {
6554                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6555             } else {
6556                 if (gen_svm_check_intercept(s, pc_start,
6557                                             op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE))
6558                     break;
6559                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6560                 gen_op_ld_T1_A0(OT_WORD + s->mem_index);
6561                 gen_add_A0_im(s, 2);
6562                 gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
6563                 if (!s->dflag)
6564                     gen_op_andl_T0_im(0xffffff);
6565                 if (op == 2) {
6566                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
6567                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
6568                 } else {
6569                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
6570                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
6571                 }
6572             }
6573             break;
6574         case 4: /* smsw */
6575             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0))
6576                 break;
6577             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
6578             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
6579             break;
6580         case 6: /* lmsw */
6581             if (s->cpl != 0) {
6582                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6583             } else {
6584                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
6585                     break;
6586                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6587                 tcg_gen_helper_0_1(helper_lmsw, cpu_T[0]);
6588                 gen_jmp_im(s->pc - s->cs_base);
6589                 gen_eob(s);
6590             }
6591             break;
6592         case 7: /* invlpg */
6593             if (s->cpl != 0) {
6594                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6595             } else {
6596                 if (mod == 3) {
6597 #ifdef TARGET_X86_64
6598                     if (CODE64(s) && rm == 0) {
6599                         /* swapgs */
6600                         tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
6601                         tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
6602                         tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
6603                         tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
6604                     } else
6605 #endif
6606                     {
6607                         goto illegal_op;
6608                     }
6609                 } else {
6610                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPG))
6611                         break;
6612                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6613                     tcg_gen_helper_0_1(helper_invlpg, cpu_A0);
6614                     gen_jmp_im(s->pc - s->cs_base);
6615                     gen_eob(s);
6616                 }
6617             }
6618             break;
6619         default:
6620             goto illegal_op;
6621         }
6622         break;
6623     case 0x108: /* invd */
6624     case 0x109: /* wbinvd */
6625         if (s->cpl != 0) {
6626             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6627         } else {
6628             if (gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD))
6629                 break;
6630             /* nothing to do */
6631         }
6632         break;
6633     case 0x63: /* arpl or movslS (x86_64) */
6634 #ifdef TARGET_X86_64
6635         if (CODE64(s)) {
6636             int d_ot;
6637             /* d_ot is the size of destination */
6638             d_ot = dflag + OT_WORD;
6639
6640             modrm = ldub_code(s->pc++);
6641             reg = ((modrm >> 3) & 7) | rex_r;
6642             mod = (modrm >> 6) & 3;
6643             rm = (modrm & 7) | REX_B(s);
6644
6645             if (mod == 3) {
6646                 gen_op_mov_TN_reg(OT_LONG, 0, rm);
6647                 /* sign extend */
6648                 if (d_ot == OT_QUAD)
6649                     tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
6650                 gen_op_mov_reg_T0(d_ot, reg);
6651             } else {
6652                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6653                 if (d_ot == OT_QUAD) {
6654                     gen_op_lds_T0_A0(OT_LONG + s->mem_index);
6655                 } else {
6656                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6657                 }
6658                 gen_op_mov_reg_T0(d_ot, reg);
6659             }
6660         } else
6661 #endif
6662         {
6663             int label1;
6664             if (!s->pe || s->vm86)
6665                 goto illegal_op;
6666             ot = OT_WORD;
6667             modrm = ldub_code(s->pc++);
6668             reg = (modrm >> 3) & 7;
6669             mod = (modrm >> 6) & 3;
6670             rm = modrm & 7;
6671             if (mod != 3) {
6672                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6673                 gen_op_ld_T0_A0(ot + s->mem_index);
6674             } else {
6675                 gen_op_mov_TN_reg(ot, 0, rm);
6676             }
6677             gen_op_mov_TN_reg(ot, 1, reg);
6678             tcg_gen_andi_tl(cpu_tmp0, cpu_T[0], 3);
6679             tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 3);
6680             tcg_gen_movi_tl(cpu_T3, 0);
6681             label1 = gen_new_label();
6682             tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, cpu_T[1], label1);
6683             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~3);
6684             tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
6685             tcg_gen_movi_tl(cpu_T3, CC_Z);
6686             gen_set_label(label1);
6687             if (mod != 3) {
6688                 gen_op_st_T0_A0(ot + s->mem_index);
6689             } else {
6690                 gen_op_mov_reg_T0(ot, rm);
6691             }
6692             if (s->cc_op != CC_OP_DYNAMIC)
6693                 gen_op_set_cc_op(s->cc_op);
6694             gen_compute_eflags(cpu_cc_src);
6695             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6696             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T3);
6697             s->cc_op = CC_OP_EFLAGS;
6698         }
6699         break;
6700     case 0x102: /* lar */
6701     case 0x103: /* lsl */
6702         {
6703             int label1;
6704             if (!s->pe || s->vm86)
6705                 goto illegal_op;
6706             ot = dflag ? OT_LONG : OT_WORD;
6707             modrm = ldub_code(s->pc++);
6708             reg = ((modrm >> 3) & 7) | rex_r;
6709             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
6710             if (s->cc_op != CC_OP_DYNAMIC)
6711                 gen_op_set_cc_op(s->cc_op);
6712             if (b == 0x102)
6713                 tcg_gen_helper_1_1(helper_lar, cpu_T[0], cpu_T[0]);
6714             else
6715                 tcg_gen_helper_1_1(helper_lsl, cpu_T[0], cpu_T[0]);
6716             tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
6717             label1 = gen_new_label();
6718             tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), label1);
6719             gen_op_mov_reg_T0(ot, reg);
6720             gen_set_label(label1);
6721             s->cc_op = CC_OP_EFLAGS;
6722         }
6723         break;
6724     case 0x118:
6725         modrm = ldub_code(s->pc++);
6726         mod = (modrm >> 6) & 3;
6727         op = (modrm >> 3) & 7;
6728         switch(op) {
6729         case 0: /* prefetchnta */
6730         case 1: /* prefetchnt0 */
6731         case 2: /* prefetchnt0 */
6732         case 3: /* prefetchnt0 */
6733             if (mod == 3)
6734                 goto illegal_op;
6735             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6736             /* nothing more to do */
6737             break;
6738         default: /* nop (multi byte) */
6739             gen_nop_modrm(s, modrm);
6740             break;
6741         }
6742         break;
6743     case 0x119 ... 0x11f: /* nop (multi byte) */
6744         modrm = ldub_code(s->pc++);
6745         gen_nop_modrm(s, modrm);
6746         break;
6747     case 0x120: /* mov reg, crN */
6748     case 0x122: /* mov crN, reg */
6749         if (s->cpl != 0) {
6750             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6751         } else {
6752             modrm = ldub_code(s->pc++);
6753             if ((modrm & 0xc0) != 0xc0)
6754                 goto illegal_op;
6755             rm = (modrm & 7) | REX_B(s);
6756             reg = ((modrm >> 3) & 7) | rex_r;
6757             if (CODE64(s))
6758                 ot = OT_QUAD;
6759             else
6760                 ot = OT_LONG;
6761             switch(reg) {
6762             case 0:
6763             case 2:
6764             case 3:
6765             case 4:
6766             case 8:
6767                 if (b & 2) {
6768                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
6769                     gen_op_mov_TN_reg(ot, 0, rm);
6770                     tcg_gen_helper_0_2(helper_movl_crN_T0, 
6771                                        tcg_const_i32(reg), cpu_T[0]);
6772                     gen_jmp_im(s->pc - s->cs_base);
6773                     gen_eob(s);
6774                 } else {
6775                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
6776 #if !defined(CONFIG_USER_ONLY)
6777                     if (reg == 8)
6778                         tcg_gen_helper_1_0(helper_movtl_T0_cr8, cpu_T[0]);
6779                     else
6780 #endif
6781                         tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[reg]));
6782                     gen_op_mov_reg_T0(ot, rm);
6783                 }
6784                 break;
6785             default:
6786                 goto illegal_op;
6787             }
6788         }
6789         break;
6790     case 0x121: /* mov reg, drN */
6791     case 0x123: /* mov drN, reg */
6792         if (s->cpl != 0) {
6793             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6794         } else {
6795             modrm = ldub_code(s->pc++);
6796             if ((modrm & 0xc0) != 0xc0)
6797                 goto illegal_op;
6798             rm = (modrm & 7) | REX_B(s);
6799             reg = ((modrm >> 3) & 7) | rex_r;
6800             if (CODE64(s))
6801                 ot = OT_QUAD;
6802             else
6803                 ot = OT_LONG;
6804             /* XXX: do it dynamically with CR4.DE bit */
6805             if (reg == 4 || reg == 5 || reg >= 8)
6806                 goto illegal_op;
6807             if (b & 2) {
6808                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
6809                 gen_op_mov_TN_reg(ot, 0, rm);
6810                 tcg_gen_helper_0_2(helper_movl_drN_T0,
6811                                    tcg_const_i32(reg), cpu_T[0]);
6812                 gen_jmp_im(s->pc - s->cs_base);
6813                 gen_eob(s);
6814             } else {
6815                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
6816                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
6817                 gen_op_mov_reg_T0(ot, rm);
6818             }
6819         }
6820         break;
6821     case 0x106: /* clts */
6822         if (s->cpl != 0) {
6823             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6824         } else {
6825             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
6826             tcg_gen_helper_0_0(helper_clts);
6827             /* abort block because static cpu state changed */
6828             gen_jmp_im(s->pc - s->cs_base);
6829             gen_eob(s);
6830         }
6831         break;
6832     /* MMX/3DNow!/SSE/SSE2/SSE3 support */
6833     case 0x1c3: /* MOVNTI reg, mem */
6834         if (!(s->cpuid_features & CPUID_SSE2))
6835             goto illegal_op;
6836         ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
6837         modrm = ldub_code(s->pc++);
6838         mod = (modrm >> 6) & 3;
6839         if (mod == 3)
6840             goto illegal_op;
6841         reg = ((modrm >> 3) & 7) | rex_r;
6842         /* generate a generic store */
6843         gen_ldst_modrm(s, modrm, ot, reg, 1);
6844         break;
6845     case 0x1ae:
6846         modrm = ldub_code(s->pc++);
6847         mod = (modrm >> 6) & 3;
6848         op = (modrm >> 3) & 7;
6849         switch(op) {
6850         case 0: /* fxsave */
6851             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6852                 (s->flags & HF_EM_MASK))
6853                 goto illegal_op;
6854             if (s->flags & HF_TS_MASK) {
6855                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6856                 break;
6857             }
6858             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6859             if (s->cc_op != CC_OP_DYNAMIC)
6860                 gen_op_set_cc_op(s->cc_op);
6861             gen_jmp_im(pc_start - s->cs_base);
6862             tcg_gen_helper_0_2(helper_fxsave, 
6863                                cpu_A0, tcg_const_i32((s->dflag == 2)));
6864             break;
6865         case 1: /* fxrstor */
6866             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6867                 (s->flags & HF_EM_MASK))
6868                 goto illegal_op;
6869             if (s->flags & HF_TS_MASK) {
6870                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6871                 break;
6872             }
6873             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6874             if (s->cc_op != CC_OP_DYNAMIC)
6875                 gen_op_set_cc_op(s->cc_op);
6876             gen_jmp_im(pc_start - s->cs_base);
6877             tcg_gen_helper_0_2(helper_fxrstor,
6878                                cpu_A0, tcg_const_i32((s->dflag == 2)));
6879             break;
6880         case 2: /* ldmxcsr */
6881         case 3: /* stmxcsr */
6882             if (s->flags & HF_TS_MASK) {
6883                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6884                 break;
6885             }
6886             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
6887                 mod == 3)
6888                 goto illegal_op;
6889             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6890             if (op == 2) {
6891                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6892                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
6893             } else {
6894                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
6895                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
6896             }
6897             break;
6898         case 5: /* lfence */
6899         case 6: /* mfence */
6900             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
6901                 goto illegal_op;
6902             break;
6903         case 7: /* sfence / clflush */
6904             if ((modrm & 0xc7) == 0xc0) {
6905                 /* sfence */
6906                 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
6907                 if (!(s->cpuid_features & CPUID_SSE))
6908                     goto illegal_op;
6909             } else {
6910                 /* clflush */
6911                 if (!(s->cpuid_features & CPUID_CLFLUSH))
6912                     goto illegal_op;
6913                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6914             }
6915             break;
6916         default:
6917             goto illegal_op;
6918         }
6919         break;
6920     case 0x10d: /* 3DNow! prefetch(w) */
6921         modrm = ldub_code(s->pc++);
6922         mod = (modrm >> 6) & 3;
6923         if (mod == 3)
6924             goto illegal_op;
6925         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6926         /* ignore for now */
6927         break;
6928     case 0x1aa: /* rsm */
6929         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM))
6930             break;
6931         if (!(s->flags & HF_SMM_MASK))
6932             goto illegal_op;
6933         if (s->cc_op != CC_OP_DYNAMIC) {
6934             gen_op_set_cc_op(s->cc_op);
6935             s->cc_op = CC_OP_DYNAMIC;
6936         }
6937         gen_jmp_im(s->pc - s->cs_base);
6938         tcg_gen_helper_0_0(helper_rsm);
6939         gen_eob(s);
6940         break;
6941     case 0x10e ... 0x10f:
6942         /* 3DNow! instructions, ignore prefixes */
6943         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
6944     case 0x110 ... 0x117:
6945     case 0x128 ... 0x12f:
6946     case 0x150 ... 0x177:
6947     case 0x17c ... 0x17f:
6948     case 0x1c2:
6949     case 0x1c4 ... 0x1c6:
6950     case 0x1d0 ... 0x1fe:
6951         gen_sse(s, b, pc_start, rex_r);
6952         break;
6953     default:
6954         goto illegal_op;
6955     }
6956     /* lock generation */
6957     if (s->prefix & PREFIX_LOCK)
6958         tcg_gen_helper_0_0(helper_unlock);
6959     return s->pc;
6960  illegal_op:
6961     if (s->prefix & PREFIX_LOCK)
6962         tcg_gen_helper_0_0(helper_unlock);
6963     /* XXX: ensure that no lock was generated */
6964     gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
6965     return s->pc;
6966 }
6967
6968 static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
6969 {
6970     switch(macro_id) {
6971 #ifdef MACRO_TEST
6972     case MACRO_TEST:
6973         tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]);
6974         break;
6975 #endif
6976     }
6977 }
6978
6979 void optimize_flags_init(void)
6980 {
6981 #if TCG_TARGET_REG_BITS == 32
6982     assert(sizeof(CCTable) == (1 << 3));
6983 #else
6984     assert(sizeof(CCTable) == (1 << 4));
6985 #endif
6986     tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
6987
6988     cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
6989 #if TARGET_LONG_BITS > HOST_LONG_BITS
6990     cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
6991                                   TCG_AREG0, offsetof(CPUState, t0), "T0");
6992     cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
6993                                   TCG_AREG0, offsetof(CPUState, t1), "T1");
6994     cpu_A0 = tcg_global_mem_new(TCG_TYPE_TL,
6995                                 TCG_AREG0, offsetof(CPUState, t2), "A0");
6996 #else
6997     cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
6998     cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
6999     cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
7000 #endif
7001     cpu_T3 = tcg_global_mem_new(TCG_TYPE_TL,
7002                                 TCG_AREG0, offsetof(CPUState, t3), "T3");
7003 #if defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS)
7004     /* XXX: must be suppressed once there are less fixed registers */
7005     cpu_tmp1_i64 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
7006 #endif
7007     cpu_cc_op = tcg_global_mem_new(TCG_TYPE_I32,
7008                                    TCG_AREG0, offsetof(CPUState, cc_op), "cc_op");
7009     cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
7010                                     TCG_AREG0, offsetof(CPUState, cc_src), "cc_src");
7011     cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
7012                                     TCG_AREG0, offsetof(CPUState, cc_dst), "cc_dst");
7013 }
7014
7015 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
7016    basic block 'tb'. If search_pc is TRUE, also generate PC
7017    information for each intermediate instruction. */
7018 static inline int gen_intermediate_code_internal(CPUState *env,
7019                                                  TranslationBlock *tb,
7020                                                  int search_pc)
7021 {
7022     DisasContext dc1, *dc = &dc1;
7023     target_ulong pc_ptr;
7024     uint16_t *gen_opc_end;
7025     int j, lj, cflags;
7026     uint64_t flags;
7027     target_ulong pc_start;
7028     target_ulong cs_base;
7029
7030     /* generate intermediate code */
7031     pc_start = tb->pc;
7032     cs_base = tb->cs_base;
7033     flags = tb->flags;
7034     cflags = tb->cflags;
7035
7036     dc->pe = (flags >> HF_PE_SHIFT) & 1;
7037     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
7038     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
7039     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
7040     dc->f_st = 0;
7041     dc->vm86 = (flags >> VM_SHIFT) & 1;
7042     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
7043     dc->iopl = (flags >> IOPL_SHIFT) & 3;
7044     dc->tf = (flags >> TF_SHIFT) & 1;
7045     dc->singlestep_enabled = env->singlestep_enabled;
7046     dc->cc_op = CC_OP_DYNAMIC;
7047     dc->cs_base = cs_base;
7048     dc->tb = tb;
7049     dc->popl_esp_hack = 0;
7050     /* select memory access functions */
7051     dc->mem_index = 0;
7052     if (flags & HF_SOFTMMU_MASK) {
7053         if (dc->cpl == 3)
7054             dc->mem_index = 2 * 4;
7055         else
7056             dc->mem_index = 1 * 4;
7057     }
7058     dc->cpuid_features = env->cpuid_features;
7059     dc->cpuid_ext_features = env->cpuid_ext_features;
7060     dc->cpuid_ext2_features = env->cpuid_ext2_features;
7061 #ifdef TARGET_X86_64
7062     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
7063     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
7064 #endif
7065     dc->flags = flags;
7066     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
7067                     (flags & HF_INHIBIT_IRQ_MASK)
7068 #ifndef CONFIG_SOFTMMU
7069                     || (flags & HF_SOFTMMU_MASK)
7070 #endif
7071                     );
7072 #if 0
7073     /* check addseg logic */
7074     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
7075         printf("ERROR addseg\n");
7076 #endif
7077
7078     cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
7079 #if !(defined(__i386__) && (TARGET_LONG_BITS <= HOST_LONG_BITS))
7080     cpu_tmp1_i64 = tcg_temp_new(TCG_TYPE_I64);
7081 #endif
7082     cpu_tmp2_i32 = tcg_temp_new(TCG_TYPE_I32);
7083     cpu_tmp3_i32 = tcg_temp_new(TCG_TYPE_I32);
7084     cpu_tmp4 = tcg_temp_new(TCG_TYPE_TL);
7085     cpu_tmp5 = tcg_temp_new(TCG_TYPE_TL);
7086     cpu_tmp6 = tcg_temp_new(TCG_TYPE_TL);
7087     cpu_ptr0 = tcg_temp_new(TCG_TYPE_PTR);
7088     cpu_ptr1 = tcg_temp_new(TCG_TYPE_PTR);
7089
7090     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7091
7092     dc->is_jmp = DISAS_NEXT;
7093     pc_ptr = pc_start;
7094     lj = -1;
7095
7096     for(;;) {
7097         if (env->nb_breakpoints > 0) {
7098             for(j = 0; j < env->nb_breakpoints; j++) {
7099                 if (env->breakpoints[j] == pc_ptr) {
7100                     gen_debug(dc, pc_ptr - dc->cs_base);
7101                     break;
7102                 }
7103             }
7104         }
7105         if (search_pc) {
7106             j = gen_opc_ptr - gen_opc_buf;
7107             if (lj < j) {
7108                 lj++;
7109                 while (lj < j)
7110                     gen_opc_instr_start[lj++] = 0;
7111             }
7112             gen_opc_pc[lj] = pc_ptr;
7113             gen_opc_cc_op[lj] = dc->cc_op;
7114             gen_opc_instr_start[lj] = 1;
7115         }
7116         pc_ptr = disas_insn(dc, pc_ptr);
7117         /* stop translation if indicated */
7118         if (dc->is_jmp)
7119             break;
7120         /* if single step mode, we generate only one instruction and
7121            generate an exception */
7122         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7123            the flag and abort the translation to give the irqs a
7124            change to be happen */
7125         if (dc->tf || dc->singlestep_enabled ||
7126             (flags & HF_INHIBIT_IRQ_MASK) ||
7127             (cflags & CF_SINGLE_INSN)) {
7128             gen_jmp_im(pc_ptr - dc->cs_base);
7129             gen_eob(dc);
7130             break;
7131         }
7132         /* if too long translation, stop generation too */
7133         if (gen_opc_ptr >= gen_opc_end ||
7134             (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
7135             gen_jmp_im(pc_ptr - dc->cs_base);
7136             gen_eob(dc);
7137             break;
7138         }
7139     }
7140     *gen_opc_ptr = INDEX_op_end;
7141     /* we don't forget to fill the last values */
7142     if (search_pc) {
7143         j = gen_opc_ptr - gen_opc_buf;
7144         lj++;
7145         while (lj <= j)
7146             gen_opc_instr_start[lj++] = 0;
7147     }
7148
7149 #ifdef DEBUG_DISAS
7150     if (loglevel & CPU_LOG_TB_CPU) {
7151         cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
7152     }
7153     if (loglevel & CPU_LOG_TB_IN_ASM) {
7154         int disas_flags;
7155         fprintf(logfile, "----------------\n");
7156         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7157 #ifdef TARGET_X86_64
7158         if (dc->code64)
7159             disas_flags = 2;
7160         else
7161 #endif
7162             disas_flags = !dc->code32;
7163         target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
7164         fprintf(logfile, "\n");
7165         if (loglevel & CPU_LOG_TB_OP_OPT) {
7166             fprintf(logfile, "OP before opt:\n");
7167             tcg_dump_ops(&tcg_ctx, logfile);
7168             fprintf(logfile, "\n");
7169         }
7170     }
7171 #endif
7172
7173     if (!search_pc)
7174         tb->size = pc_ptr - pc_start;
7175     return 0;
7176 }
7177
7178 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
7179 {
7180     return gen_intermediate_code_internal(env, tb, 0);
7181 }
7182
7183 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
7184 {
7185     return gen_intermediate_code_internal(env, tb, 1);
7186 }
7187
7188 void gen_pc_load(CPUState *env, TranslationBlock *tb,
7189                 unsigned long searched_pc, int pc_pos, void *puc)
7190 {
7191     int cc_op;
7192 #ifdef DEBUG_DISAS
7193     if (loglevel & CPU_LOG_TB_OP) {
7194         int i;
7195         fprintf(logfile, "RESTORE:\n");
7196         for(i = 0;i <= pc_pos; i++) {
7197             if (gen_opc_instr_start[i]) {
7198                 fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
7199             }
7200         }
7201         fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
7202                 searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
7203                 (uint32_t)tb->cs_base);
7204     }
7205 #endif
7206     env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
7207     cc_op = gen_opc_cc_op[pc_pos];
7208     if (cc_op != CC_OP_DYNAMIC)
7209         env->cc_op = cc_op;
7210 }