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