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