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