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