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