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