use TCG for MMX/SSE memory accesses
[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;
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 GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
1292     gen_op_fadd_ST0_FT0,
1293     gen_op_fmul_ST0_FT0,
1294     gen_op_fcom_ST0_FT0,
1295     gen_op_fcom_ST0_FT0,
1296     gen_op_fsub_ST0_FT0,
1297     gen_op_fsubr_ST0_FT0,
1298     gen_op_fdiv_ST0_FT0,
1299     gen_op_fdivr_ST0_FT0,
1300 };
1301
1302 /* NOTE the exception in "r" op ordering */
1303 static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
1304     gen_op_fadd_STN_ST0,
1305     gen_op_fmul_STN_ST0,
1306     NULL,
1307     NULL,
1308     gen_op_fsubr_STN_ST0,
1309     gen_op_fsub_STN_ST0,
1310     gen_op_fdivr_STN_ST0,
1311     gen_op_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 #define SSE_SPECIAL ((GenOpFunc2 *)1)
2414 #define SSE_DUMMY ((GenOpFunc2 *)2)
2415
2416 #define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
2417 #define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
2418                      gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
2419
2420 static GenOpFunc2 *sse_op_table1[256][4] = {
2421     /* 3DNow! extensions */
2422     [0x0e] = { SSE_DUMMY }, /* femms */
2423     [0x0f] = { SSE_DUMMY }, /* pf... */
2424     /* pure SSE operations */
2425     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2426     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2427     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2428     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2429     [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
2430     [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
2431     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2432     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2433
2434     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2435     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2436     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2437     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2438     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2439     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2440     [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
2441     [0x2f] = { gen_op_comiss, gen_op_comisd },
2442     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2443     [0x51] = SSE_FOP(sqrt),
2444     [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
2445     [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
2446     [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
2447     [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
2448     [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
2449     [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
2450     [0x58] = SSE_FOP(add),
2451     [0x59] = SSE_FOP(mul),
2452     [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps,
2453                gen_op_cvtss2sd, gen_op_cvtsd2ss },
2454     [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
2455     [0x5c] = SSE_FOP(sub),
2456     [0x5d] = SSE_FOP(min),
2457     [0x5e] = SSE_FOP(div),
2458     [0x5f] = SSE_FOP(max),
2459
2460     [0xc2] = SSE_FOP(cmpeq),
2461     [0xc6] = { (GenOpFunc2 *)gen_op_shufps, (GenOpFunc2 *)gen_op_shufpd },
2462
2463     /* MMX ops and their SSE extensions */
2464     [0x60] = MMX_OP2(punpcklbw),
2465     [0x61] = MMX_OP2(punpcklwd),
2466     [0x62] = MMX_OP2(punpckldq),
2467     [0x63] = MMX_OP2(packsswb),
2468     [0x64] = MMX_OP2(pcmpgtb),
2469     [0x65] = MMX_OP2(pcmpgtw),
2470     [0x66] = MMX_OP2(pcmpgtl),
2471     [0x67] = MMX_OP2(packuswb),
2472     [0x68] = MMX_OP2(punpckhbw),
2473     [0x69] = MMX_OP2(punpckhwd),
2474     [0x6a] = MMX_OP2(punpckhdq),
2475     [0x6b] = MMX_OP2(packssdw),
2476     [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
2477     [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
2478     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2479     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2480     [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx,
2481                (GenOpFunc2 *)gen_op_pshufd_xmm,
2482                (GenOpFunc2 *)gen_op_pshufhw_xmm,
2483                (GenOpFunc2 *)gen_op_pshuflw_xmm },
2484     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2485     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2486     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2487     [0x74] = MMX_OP2(pcmpeqb),
2488     [0x75] = MMX_OP2(pcmpeqw),
2489     [0x76] = MMX_OP2(pcmpeql),
2490     [0x77] = { SSE_DUMMY }, /* emms */
2491     [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
2492     [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
2493     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2494     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2495     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2496     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2497     [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
2498     [0xd1] = MMX_OP2(psrlw),
2499     [0xd2] = MMX_OP2(psrld),
2500     [0xd3] = MMX_OP2(psrlq),
2501     [0xd4] = MMX_OP2(paddq),
2502     [0xd5] = MMX_OP2(pmullw),
2503     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2504     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2505     [0xd8] = MMX_OP2(psubusb),
2506     [0xd9] = MMX_OP2(psubusw),
2507     [0xda] = MMX_OP2(pminub),
2508     [0xdb] = MMX_OP2(pand),
2509     [0xdc] = MMX_OP2(paddusb),
2510     [0xdd] = MMX_OP2(paddusw),
2511     [0xde] = MMX_OP2(pmaxub),
2512     [0xdf] = MMX_OP2(pandn),
2513     [0xe0] = MMX_OP2(pavgb),
2514     [0xe1] = MMX_OP2(psraw),
2515     [0xe2] = MMX_OP2(psrad),
2516     [0xe3] = MMX_OP2(pavgw),
2517     [0xe4] = MMX_OP2(pmulhuw),
2518     [0xe5] = MMX_OP2(pmulhw),
2519     [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
2520     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2521     [0xe8] = MMX_OP2(psubsb),
2522     [0xe9] = MMX_OP2(psubsw),
2523     [0xea] = MMX_OP2(pminsw),
2524     [0xeb] = MMX_OP2(por),
2525     [0xec] = MMX_OP2(paddsb),
2526     [0xed] = MMX_OP2(paddsw),
2527     [0xee] = MMX_OP2(pmaxsw),
2528     [0xef] = MMX_OP2(pxor),
2529     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2530     [0xf1] = MMX_OP2(psllw),
2531     [0xf2] = MMX_OP2(pslld),
2532     [0xf3] = MMX_OP2(psllq),
2533     [0xf4] = MMX_OP2(pmuludq),
2534     [0xf5] = MMX_OP2(pmaddwd),
2535     [0xf6] = MMX_OP2(psadbw),
2536     [0xf7] = MMX_OP2(maskmov),
2537     [0xf8] = MMX_OP2(psubb),
2538     [0xf9] = MMX_OP2(psubw),
2539     [0xfa] = MMX_OP2(psubl),
2540     [0xfb] = MMX_OP2(psubq),
2541     [0xfc] = MMX_OP2(paddb),
2542     [0xfd] = MMX_OP2(paddw),
2543     [0xfe] = MMX_OP2(paddl),
2544 };
2545
2546 static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
2547     [0 + 2] = MMX_OP2(psrlw),
2548     [0 + 4] = MMX_OP2(psraw),
2549     [0 + 6] = MMX_OP2(psllw),
2550     [8 + 2] = MMX_OP2(psrld),
2551     [8 + 4] = MMX_OP2(psrad),
2552     [8 + 6] = MMX_OP2(pslld),
2553     [16 + 2] = MMX_OP2(psrlq),
2554     [16 + 3] = { NULL, gen_op_psrldq_xmm },
2555     [16 + 6] = MMX_OP2(psllq),
2556     [16 + 7] = { NULL, gen_op_pslldq_xmm },
2557 };
2558
2559 static GenOpFunc1 *sse_op_table3[4 * 3] = {
2560     gen_op_cvtsi2ss,
2561     gen_op_cvtsi2sd,
2562     X86_64_ONLY(gen_op_cvtsq2ss),
2563     X86_64_ONLY(gen_op_cvtsq2sd),
2564
2565     gen_op_cvttss2si,
2566     gen_op_cvttsd2si,
2567     X86_64_ONLY(gen_op_cvttss2sq),
2568     X86_64_ONLY(gen_op_cvttsd2sq),
2569
2570     gen_op_cvtss2si,
2571     gen_op_cvtsd2si,
2572     X86_64_ONLY(gen_op_cvtss2sq),
2573     X86_64_ONLY(gen_op_cvtsd2sq),
2574 };
2575
2576 static GenOpFunc2 *sse_op_table4[8][4] = {
2577     SSE_FOP(cmpeq),
2578     SSE_FOP(cmplt),
2579     SSE_FOP(cmple),
2580     SSE_FOP(cmpunord),
2581     SSE_FOP(cmpneq),
2582     SSE_FOP(cmpnlt),
2583     SSE_FOP(cmpnle),
2584     SSE_FOP(cmpord),
2585 };
2586
2587 static GenOpFunc2 *sse_op_table5[256] = {
2588     [0x0c] = gen_op_pi2fw,
2589     [0x0d] = gen_op_pi2fd,
2590     [0x1c] = gen_op_pf2iw,
2591     [0x1d] = gen_op_pf2id,
2592     [0x8a] = gen_op_pfnacc,
2593     [0x8e] = gen_op_pfpnacc,
2594     [0x90] = gen_op_pfcmpge,
2595     [0x94] = gen_op_pfmin,
2596     [0x96] = gen_op_pfrcp,
2597     [0x97] = gen_op_pfrsqrt,
2598     [0x9a] = gen_op_pfsub,
2599     [0x9e] = gen_op_pfadd,
2600     [0xa0] = gen_op_pfcmpgt,
2601     [0xa4] = gen_op_pfmax,
2602     [0xa6] = gen_op_movq, /* pfrcpit1; no need to actually increase precision */
2603     [0xa7] = gen_op_movq, /* pfrsqit1 */
2604     [0xaa] = gen_op_pfsubr,
2605     [0xae] = gen_op_pfacc,
2606     [0xb0] = gen_op_pfcmpeq,
2607     [0xb4] = gen_op_pfmul,
2608     [0xb6] = gen_op_movq, /* pfrcpit2 */
2609     [0xb7] = gen_op_pmulhrw_mmx,
2610     [0xbb] = gen_op_pswapd,
2611     [0xbf] = gen_op_pavgb_mmx /* pavgusb */
2612 };
2613
2614 static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2615 {
2616     int b1, op1_offset, op2_offset, is_xmm, val, ot;
2617     int modrm, mod, rm, reg, reg_addr, offset_addr;
2618     GenOpFunc2 *sse_op2;
2619     GenOpFunc3 *sse_op3;
2620
2621     b &= 0xff;
2622     if (s->prefix & PREFIX_DATA)
2623         b1 = 1;
2624     else if (s->prefix & PREFIX_REPZ)
2625         b1 = 2;
2626     else if (s->prefix & PREFIX_REPNZ)
2627         b1 = 3;
2628     else
2629         b1 = 0;
2630     sse_op2 = sse_op_table1[b][b1];
2631     if (!sse_op2)
2632         goto illegal_op;
2633     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
2634         is_xmm = 1;
2635     } else {
2636         if (b1 == 0) {
2637             /* MMX case */
2638             is_xmm = 0;
2639         } else {
2640             is_xmm = 1;
2641         }
2642     }
2643     /* simple MMX/SSE operation */
2644     if (s->flags & HF_TS_MASK) {
2645         gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2646         return;
2647     }
2648     if (s->flags & HF_EM_MASK) {
2649     illegal_op:
2650         gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2651         return;
2652     }
2653     if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2654         goto illegal_op;
2655     if (b == 0x0e) {
2656         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
2657             goto illegal_op;
2658         /* femms */
2659         gen_op_emms();
2660         return;
2661     }
2662     if (b == 0x77) {
2663         /* emms */
2664         gen_op_emms();
2665         return;
2666     }
2667     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2668        the static cpu state) */
2669     if (!is_xmm) {
2670         gen_op_enter_mmx();
2671     }
2672
2673     modrm = ldub_code(s->pc++);
2674     reg = ((modrm >> 3) & 7);
2675     if (is_xmm)
2676         reg |= rex_r;
2677     mod = (modrm >> 6) & 3;
2678     if (sse_op2 == SSE_SPECIAL) {
2679         b |= (b1 << 8);
2680         switch(b) {
2681         case 0x0e7: /* movntq */
2682             if (mod == 3)
2683                 goto illegal_op;
2684             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2685             gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
2686             break;
2687         case 0x1e7: /* movntdq */
2688         case 0x02b: /* movntps */
2689         case 0x12b: /* movntps */
2690         case 0x3f0: /* lddqu */
2691             if (mod == 3)
2692                 goto illegal_op;
2693             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2694             gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
2695             break;
2696         case 0x6e: /* movd mm, ea */
2697 #ifdef TARGET_X86_64
2698             if (s->dflag == 2) {
2699                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
2700                 gen_op_movq_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2701             } else
2702 #endif
2703             {
2704                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2705                 gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2706             }
2707             break;
2708         case 0x16e: /* movd xmm, ea */
2709 #ifdef TARGET_X86_64
2710             if (s->dflag == 2) {
2711                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
2712                 gen_op_movq_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2713             } else
2714 #endif
2715             {
2716                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2717                 gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2718             }
2719             break;
2720         case 0x6f: /* movq mm, ea */
2721             if (mod != 3) {
2722                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2723                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
2724             } else {
2725                 rm = (modrm & 7);
2726                 gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
2727                             offsetof(CPUX86State,fpregs[rm].mmx));
2728             }
2729             break;
2730         case 0x010: /* movups */
2731         case 0x110: /* movupd */
2732         case 0x028: /* movaps */
2733         case 0x128: /* movapd */
2734         case 0x16f: /* movdqa xmm, ea */
2735         case 0x26f: /* movdqu xmm, ea */
2736             if (mod != 3) {
2737                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2738                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
2739             } else {
2740                 rm = (modrm & 7) | REX_B(s);
2741                 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
2742                             offsetof(CPUX86State,xmm_regs[rm]));
2743             }
2744             break;
2745         case 0x210: /* movss xmm, ea */
2746             if (mod != 3) {
2747                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2748                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
2749                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2750                 gen_op_movl_T0_0();
2751                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2752                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2753                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2754             } else {
2755                 rm = (modrm & 7) | REX_B(s);
2756                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2757                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2758             }
2759             break;
2760         case 0x310: /* movsd xmm, ea */
2761             if (mod != 3) {
2762                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2763                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2764                 gen_op_movl_T0_0();
2765                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2766                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2767             } else {
2768                 rm = (modrm & 7) | REX_B(s);
2769                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2770                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2771             }
2772             break;
2773         case 0x012: /* movlps */
2774         case 0x112: /* movlpd */
2775             if (mod != 3) {
2776                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2777                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2778             } else {
2779                 /* movhlps */
2780                 rm = (modrm & 7) | REX_B(s);
2781                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2782                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2783             }
2784             break;
2785         case 0x212: /* movsldup */
2786             if (mod != 3) {
2787                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2788                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
2789             } else {
2790                 rm = (modrm & 7) | REX_B(s);
2791                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2792                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2793                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2794                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
2795             }
2796             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2797                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2798             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2799                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2800             break;
2801         case 0x312: /* movddup */
2802             if (mod != 3) {
2803                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2804                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2805             } else {
2806                 rm = (modrm & 7) | REX_B(s);
2807                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2808                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2809             }
2810             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2811                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2812             break;
2813         case 0x016: /* movhps */
2814         case 0x116: /* movhpd */
2815             if (mod != 3) {
2816                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2817                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2818             } else {
2819                 /* movlhps */
2820                 rm = (modrm & 7) | REX_B(s);
2821                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2822                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2823             }
2824             break;
2825         case 0x216: /* movshdup */
2826             if (mod != 3) {
2827                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2828                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
2829             } else {
2830                 rm = (modrm & 7) | REX_B(s);
2831                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2832                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
2833                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2834                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
2835             }
2836             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2837                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2838             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2839                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2840             break;
2841         case 0x7e: /* movd ea, mm */
2842 #ifdef TARGET_X86_64
2843             if (s->dflag == 2) {
2844                 gen_op_movq_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2845                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
2846             } else
2847 #endif
2848             {
2849                 gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2850                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2851             }
2852             break;
2853         case 0x17e: /* movd ea, xmm */
2854 #ifdef TARGET_X86_64
2855             if (s->dflag == 2) {
2856                 gen_op_movq_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2857                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
2858             } else
2859 #endif
2860             {
2861                 gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2862                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2863             }
2864             break;
2865         case 0x27e: /* movq xmm, ea */
2866             if (mod != 3) {
2867                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2868                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2869             } else {
2870                 rm = (modrm & 7) | REX_B(s);
2871                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2872                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2873             }
2874             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2875             break;
2876         case 0x7f: /* movq ea, mm */
2877             if (mod != 3) {
2878                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2879                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
2880             } else {
2881                 rm = (modrm & 7);
2882                 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2883                             offsetof(CPUX86State,fpregs[reg].mmx));
2884             }
2885             break;
2886         case 0x011: /* movups */
2887         case 0x111: /* movupd */
2888         case 0x029: /* movaps */
2889         case 0x129: /* movapd */
2890         case 0x17f: /* movdqa ea, xmm */
2891         case 0x27f: /* movdqu ea, xmm */
2892             if (mod != 3) {
2893                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2894                 gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
2895             } else {
2896                 rm = (modrm & 7) | REX_B(s);
2897                 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
2898                             offsetof(CPUX86State,xmm_regs[reg]));
2899             }
2900             break;
2901         case 0x211: /* movss ea, xmm */
2902             if (mod != 3) {
2903                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2904                 gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2905                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
2906             } else {
2907                 rm = (modrm & 7) | REX_B(s);
2908                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
2909                             offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2910             }
2911             break;
2912         case 0x311: /* movsd ea, xmm */
2913             if (mod != 3) {
2914                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2915                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2916             } else {
2917                 rm = (modrm & 7) | REX_B(s);
2918                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2919                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2920             }
2921             break;
2922         case 0x013: /* movlps */
2923         case 0x113: /* movlpd */
2924             if (mod != 3) {
2925                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2926                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2927             } else {
2928                 goto illegal_op;
2929             }
2930             break;
2931         case 0x017: /* movhps */
2932         case 0x117: /* movhpd */
2933             if (mod != 3) {
2934                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2935                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2936             } else {
2937                 goto illegal_op;
2938             }
2939             break;
2940         case 0x71: /* shift mm, im */
2941         case 0x72:
2942         case 0x73:
2943         case 0x171: /* shift xmm, im */
2944         case 0x172:
2945         case 0x173:
2946             val = ldub_code(s->pc++);
2947             if (is_xmm) {
2948                 gen_op_movl_T0_im(val);
2949                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2950                 gen_op_movl_T0_0();
2951                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
2952                 op1_offset = offsetof(CPUX86State,xmm_t0);
2953             } else {
2954                 gen_op_movl_T0_im(val);
2955                 gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
2956                 gen_op_movl_T0_0();
2957                 gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
2958                 op1_offset = offsetof(CPUX86State,mmx_t0);
2959             }
2960             sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
2961             if (!sse_op2)
2962                 goto illegal_op;
2963             if (is_xmm) {
2964                 rm = (modrm & 7) | REX_B(s);
2965                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2966             } else {
2967                 rm = (modrm & 7);
2968                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2969             }
2970             sse_op2(op2_offset, op1_offset);
2971             break;
2972         case 0x050: /* movmskps */
2973             rm = (modrm & 7) | REX_B(s);
2974             gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
2975             gen_op_mov_reg_T0(OT_LONG, reg);
2976             break;
2977         case 0x150: /* movmskpd */
2978             rm = (modrm & 7) | REX_B(s);
2979             gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
2980             gen_op_mov_reg_T0(OT_LONG, reg);
2981             break;
2982         case 0x02a: /* cvtpi2ps */
2983         case 0x12a: /* cvtpi2pd */
2984             gen_op_enter_mmx();
2985             if (mod != 3) {
2986                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2987                 op2_offset = offsetof(CPUX86State,mmx_t0);
2988                 gen_ldq_env_A0(s->mem_index, op2_offset);
2989             } else {
2990                 rm = (modrm & 7);
2991                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2992             }
2993             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2994             switch(b >> 8) {
2995             case 0x0:
2996                 gen_op_cvtpi2ps(op1_offset, op2_offset);
2997                 break;
2998             default:
2999             case 0x1:
3000                 gen_op_cvtpi2pd(op1_offset, op2_offset);
3001                 break;
3002             }
3003             break;
3004         case 0x22a: /* cvtsi2ss */
3005         case 0x32a: /* cvtsi2sd */
3006             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3007             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3008             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3009             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
3010             break;
3011         case 0x02c: /* cvttps2pi */
3012         case 0x12c: /* cvttpd2pi */
3013         case 0x02d: /* cvtps2pi */
3014         case 0x12d: /* cvtpd2pi */
3015             gen_op_enter_mmx();
3016             if (mod != 3) {
3017                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3018                 op2_offset = offsetof(CPUX86State,xmm_t0);
3019                 gen_ldo_env_A0(s->mem_index, op2_offset);
3020             } else {
3021                 rm = (modrm & 7) | REX_B(s);
3022                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3023             }
3024             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3025             switch(b) {
3026             case 0x02c:
3027                 gen_op_cvttps2pi(op1_offset, op2_offset);
3028                 break;
3029             case 0x12c:
3030                 gen_op_cvttpd2pi(op1_offset, op2_offset);
3031                 break;
3032             case 0x02d:
3033                 gen_op_cvtps2pi(op1_offset, op2_offset);
3034                 break;
3035             case 0x12d:
3036                 gen_op_cvtpd2pi(op1_offset, op2_offset);
3037                 break;
3038             }
3039             break;
3040         case 0x22c: /* cvttss2si */
3041         case 0x32c: /* cvttsd2si */
3042         case 0x22d: /* cvtss2si */
3043         case 0x32d: /* cvtsd2si */
3044             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
3045             if (mod != 3) {
3046                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3047                 if ((b >> 8) & 1) {
3048                     gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
3049                 } else {
3050                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3051                     gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3052                 }
3053                 op2_offset = offsetof(CPUX86State,xmm_t0);
3054             } else {
3055                 rm = (modrm & 7) | REX_B(s);
3056                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3057             }
3058             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
3059                           (b & 1) * 4](op2_offset);
3060             gen_op_mov_reg_T0(ot, reg);
3061             break;
3062         case 0xc4: /* pinsrw */
3063         case 0x1c4:
3064             s->rip_offset = 1;
3065             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3066             val = ldub_code(s->pc++);
3067             if (b1) {
3068                 val &= 7;
3069                 gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
3070             } else {
3071                 val &= 3;
3072                 gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
3073             }
3074             break;
3075         case 0xc5: /* pextrw */
3076         case 0x1c5:
3077             if (mod != 3)
3078                 goto illegal_op;
3079             val = ldub_code(s->pc++);
3080             if (b1) {
3081                 val &= 7;
3082                 rm = (modrm & 7) | REX_B(s);
3083                 gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
3084             } else {
3085                 val &= 3;
3086                 rm = (modrm & 7);
3087                 gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
3088             }
3089             reg = ((modrm >> 3) & 7) | rex_r;
3090             gen_op_mov_reg_T0(OT_LONG, reg);
3091             break;
3092         case 0x1d6: /* movq ea, xmm */
3093             if (mod != 3) {
3094                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3095                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3096             } else {
3097                 rm = (modrm & 7) | REX_B(s);
3098                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
3099                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
3100                 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
3101             }
3102             break;
3103         case 0x2d6: /* movq2dq */
3104             gen_op_enter_mmx();
3105             rm = (modrm & 7);
3106             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
3107                         offsetof(CPUX86State,fpregs[rm].mmx));
3108             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
3109             break;
3110         case 0x3d6: /* movdq2q */
3111             gen_op_enter_mmx();
3112             rm = (modrm & 7) | REX_B(s);
3113             gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
3114                         offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
3115             break;
3116         case 0xd7: /* pmovmskb */
3117         case 0x1d7:
3118             if (mod != 3)
3119                 goto illegal_op;
3120             if (b1) {
3121                 rm = (modrm & 7) | REX_B(s);
3122                 gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
3123             } else {
3124                 rm = (modrm & 7);
3125                 gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
3126             }
3127             reg = ((modrm >> 3) & 7) | rex_r;
3128             gen_op_mov_reg_T0(OT_LONG, reg);
3129             break;
3130         default:
3131             goto illegal_op;
3132         }
3133     } else {
3134         /* generic MMX or SSE operation */
3135         switch(b) {
3136         case 0xf7:
3137             /* maskmov : we must prepare A0 */
3138             if (mod != 3)
3139                 goto illegal_op;
3140 #ifdef TARGET_X86_64
3141             if (s->aflag == 2) {
3142                 gen_op_movq_A0_reg(R_EDI);
3143             } else
3144 #endif
3145             {
3146                 gen_op_movl_A0_reg(R_EDI);
3147                 if (s->aflag == 0)
3148                     gen_op_andl_A0_ffff();
3149             }
3150             gen_add_A0_ds_seg(s);
3151             break;
3152         case 0x70: /* pshufx insn */
3153         case 0xc6: /* pshufx insn */
3154         case 0xc2: /* compare insns */
3155             s->rip_offset = 1;
3156             break;
3157         default:
3158             break;
3159         }
3160         if (is_xmm) {
3161             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3162             if (mod != 3) {
3163                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3164                 op2_offset = offsetof(CPUX86State,xmm_t0);
3165                 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
3166                                 b == 0xc2)) {
3167                     /* specific case for SSE single instructions */
3168                     if (b1 == 2) {
3169                         /* 32 bit access */
3170                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
3171                         gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3172                     } else {
3173                         /* 64 bit access */
3174                         gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
3175                     }
3176                 } else {
3177                     gen_ldo_env_A0(s->mem_index, op2_offset);
3178                 }
3179             } else {
3180                 rm = (modrm & 7) | REX_B(s);
3181                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3182             }
3183         } else {
3184             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3185             if (mod != 3) {
3186                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3187                 op2_offset = offsetof(CPUX86State,mmx_t0);
3188                 gen_ldq_env_A0(s->mem_index, op2_offset);
3189             } else {
3190                 rm = (modrm & 7);
3191                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3192             }
3193         }
3194         switch(b) {
3195         case 0x0f: /* 3DNow! data insns */
3196             if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
3197                 goto illegal_op;
3198             val = ldub_code(s->pc++);
3199             sse_op2 = sse_op_table5[val];
3200             if (!sse_op2)
3201                 goto illegal_op;
3202             sse_op2(op1_offset, op2_offset);
3203             break;
3204         case 0x70: /* pshufx insn */
3205         case 0xc6: /* pshufx insn */
3206             val = ldub_code(s->pc++);
3207             sse_op3 = (GenOpFunc3 *)sse_op2;
3208             sse_op3(op1_offset, op2_offset, val);
3209             break;
3210         case 0xc2:
3211             /* compare insns */
3212             val = ldub_code(s->pc++);
3213             if (val >= 8)
3214                 goto illegal_op;
3215             sse_op2 = sse_op_table4[val][b1];
3216             sse_op2(op1_offset, op2_offset);
3217             break;
3218         default:
3219             sse_op2(op1_offset, op2_offset);
3220             break;
3221         }
3222         if (b == 0x2e || b == 0x2f) {
3223             s->cc_op = CC_OP_EFLAGS;
3224         }
3225     }
3226 }
3227
3228
3229 /* convert one instruction. s->is_jmp is set if the translation must
3230    be stopped. Return the next pc value */
3231 static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3232 {
3233     int b, prefixes, aflag, dflag;
3234     int shift, ot;
3235     int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
3236     target_ulong next_eip, tval;
3237     int rex_w, rex_r;
3238
3239     s->pc = pc_start;
3240     prefixes = 0;
3241     aflag = s->code32;
3242     dflag = s->code32;
3243     s->override = -1;
3244     rex_w = -1;
3245     rex_r = 0;
3246 #ifdef TARGET_X86_64
3247     s->rex_x = 0;
3248     s->rex_b = 0;
3249     x86_64_hregs = 0;
3250 #endif
3251     s->rip_offset = 0; /* for relative ip address */
3252  next_byte:
3253     b = ldub_code(s->pc);
3254     s->pc++;
3255     /* check prefixes */
3256 #ifdef TARGET_X86_64
3257     if (CODE64(s)) {
3258         switch (b) {
3259         case 0xf3:
3260             prefixes |= PREFIX_REPZ;
3261             goto next_byte;
3262         case 0xf2:
3263             prefixes |= PREFIX_REPNZ;
3264             goto next_byte;
3265         case 0xf0:
3266             prefixes |= PREFIX_LOCK;
3267             goto next_byte;
3268         case 0x2e:
3269             s->override = R_CS;
3270             goto next_byte;
3271         case 0x36:
3272             s->override = R_SS;
3273             goto next_byte;
3274         case 0x3e:
3275             s->override = R_DS;
3276             goto next_byte;
3277         case 0x26:
3278             s->override = R_ES;
3279             goto next_byte;
3280         case 0x64:
3281             s->override = R_FS;
3282             goto next_byte;
3283         case 0x65:
3284             s->override = R_GS;
3285             goto next_byte;
3286         case 0x66:
3287             prefixes |= PREFIX_DATA;
3288             goto next_byte;
3289         case 0x67:
3290             prefixes |= PREFIX_ADR;
3291             goto next_byte;
3292         case 0x40 ... 0x4f:
3293             /* REX prefix */
3294             rex_w = (b >> 3) & 1;
3295             rex_r = (b & 0x4) << 1;
3296             s->rex_x = (b & 0x2) << 2;
3297             REX_B(s) = (b & 0x1) << 3;
3298             x86_64_hregs = 1; /* select uniform byte register addressing */
3299             goto next_byte;
3300         }
3301         if (rex_w == 1) {
3302             /* 0x66 is ignored if rex.w is set */
3303             dflag = 2;
3304         } else {
3305             if (prefixes & PREFIX_DATA)
3306                 dflag ^= 1;
3307         }
3308         if (!(prefixes & PREFIX_ADR))
3309             aflag = 2;
3310     } else
3311 #endif
3312     {
3313         switch (b) {
3314         case 0xf3:
3315             prefixes |= PREFIX_REPZ;
3316             goto next_byte;
3317         case 0xf2:
3318             prefixes |= PREFIX_REPNZ;
3319             goto next_byte;
3320         case 0xf0:
3321             prefixes |= PREFIX_LOCK;
3322             goto next_byte;
3323         case 0x2e:
3324             s->override = R_CS;
3325             goto next_byte;
3326         case 0x36:
3327             s->override = R_SS;
3328             goto next_byte;
3329         case 0x3e:
3330             s->override = R_DS;
3331             goto next_byte;
3332         case 0x26:
3333             s->override = R_ES;
3334             goto next_byte;
3335         case 0x64:
3336             s->override = R_FS;
3337             goto next_byte;
3338         case 0x65:
3339             s->override = R_GS;
3340             goto next_byte;
3341         case 0x66:
3342             prefixes |= PREFIX_DATA;
3343             goto next_byte;
3344         case 0x67:
3345             prefixes |= PREFIX_ADR;
3346             goto next_byte;
3347         }
3348         if (prefixes & PREFIX_DATA)
3349             dflag ^= 1;
3350         if (prefixes & PREFIX_ADR)
3351             aflag ^= 1;
3352     }
3353
3354     s->prefix = prefixes;
3355     s->aflag = aflag;
3356     s->dflag = dflag;
3357
3358     /* lock generation */
3359     if (prefixes & PREFIX_LOCK)
3360         gen_op_lock();
3361
3362     /* now check op code */
3363  reswitch:
3364     switch(b) {
3365     case 0x0f:
3366         /**************************/
3367         /* extended op code */
3368         b = ldub_code(s->pc++) | 0x100;
3369         goto reswitch;
3370
3371         /**************************/
3372         /* arith & logic */
3373     case 0x00 ... 0x05:
3374     case 0x08 ... 0x0d:
3375     case 0x10 ... 0x15:
3376     case 0x18 ... 0x1d:
3377     case 0x20 ... 0x25:
3378     case 0x28 ... 0x2d:
3379     case 0x30 ... 0x35:
3380     case 0x38 ... 0x3d:
3381         {
3382             int op, f, val;
3383             op = (b >> 3) & 7;
3384             f = (b >> 1) & 3;
3385
3386             if ((b & 1) == 0)
3387                 ot = OT_BYTE;
3388             else
3389                 ot = dflag + OT_WORD;
3390
3391             switch(f) {
3392             case 0: /* OP Ev, Gv */
3393                 modrm = ldub_code(s->pc++);
3394                 reg = ((modrm >> 3) & 7) | rex_r;
3395                 mod = (modrm >> 6) & 3;
3396                 rm = (modrm & 7) | REX_B(s);
3397                 if (mod != 3) {
3398                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3399                     opreg = OR_TMP0;
3400                 } else if (op == OP_XORL && rm == reg) {
3401                 xor_zero:
3402                     /* xor reg, reg optimisation */
3403                     gen_op_movl_T0_0();
3404                     s->cc_op = CC_OP_LOGICB + ot;
3405                     gen_op_mov_reg_T0(ot, reg);
3406                     gen_op_update1_cc();
3407                     break;
3408                 } else {
3409                     opreg = rm;
3410                 }
3411                 gen_op_mov_TN_reg(ot, 1, reg);
3412                 gen_op(s, op, ot, opreg);
3413                 break;
3414             case 1: /* OP Gv, Ev */
3415                 modrm = ldub_code(s->pc++);
3416                 mod = (modrm >> 6) & 3;
3417                 reg = ((modrm >> 3) & 7) | rex_r;
3418                 rm = (modrm & 7) | REX_B(s);
3419                 if (mod != 3) {
3420                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3421                     gen_op_ld_T1_A0(ot + s->mem_index);
3422                 } else if (op == OP_XORL && rm == reg) {
3423                     goto xor_zero;
3424                 } else {
3425                     gen_op_mov_TN_reg(ot, 1, rm);
3426                 }
3427                 gen_op(s, op, ot, reg);
3428                 break;
3429             case 2: /* OP A, Iv */
3430                 val = insn_get(s, ot);
3431                 gen_op_movl_T1_im(val);
3432                 gen_op(s, op, ot, OR_EAX);
3433                 break;
3434             }
3435         }
3436         break;
3437
3438     case 0x80: /* GRP1 */
3439     case 0x81:
3440     case 0x82:
3441     case 0x83:
3442         {
3443             int val;
3444
3445             if ((b & 1) == 0)
3446                 ot = OT_BYTE;
3447             else
3448                 ot = dflag + OT_WORD;
3449
3450             modrm = ldub_code(s->pc++);
3451             mod = (modrm >> 6) & 3;
3452             rm = (modrm & 7) | REX_B(s);
3453             op = (modrm >> 3) & 7;
3454
3455             if (mod != 3) {
3456                 if (b == 0x83)
3457                     s->rip_offset = 1;
3458                 else
3459                     s->rip_offset = insn_const_size(ot);
3460                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3461                 opreg = OR_TMP0;
3462             } else {
3463                 opreg = rm;
3464             }
3465
3466             switch(b) {
3467             default:
3468             case 0x80:
3469             case 0x81:
3470             case 0x82:
3471                 val = insn_get(s, ot);
3472                 break;
3473             case 0x83:
3474                 val = (int8_t)insn_get(s, OT_BYTE);
3475                 break;
3476             }
3477             gen_op_movl_T1_im(val);
3478             gen_op(s, op, ot, opreg);
3479         }
3480         break;
3481
3482         /**************************/
3483         /* inc, dec, and other misc arith */
3484     case 0x40 ... 0x47: /* inc Gv */
3485         ot = dflag ? OT_LONG : OT_WORD;
3486         gen_inc(s, ot, OR_EAX + (b & 7), 1);
3487         break;
3488     case 0x48 ... 0x4f: /* dec Gv */
3489         ot = dflag ? OT_LONG : OT_WORD;
3490         gen_inc(s, ot, OR_EAX + (b & 7), -1);
3491         break;
3492     case 0xf6: /* GRP3 */
3493     case 0xf7:
3494         if ((b & 1) == 0)
3495             ot = OT_BYTE;
3496         else
3497             ot = dflag + OT_WORD;
3498
3499         modrm = ldub_code(s->pc++);
3500         mod = (modrm >> 6) & 3;
3501         rm = (modrm & 7) | REX_B(s);
3502         op = (modrm >> 3) & 7;
3503         if (mod != 3) {
3504             if (op == 0)
3505                 s->rip_offset = insn_const_size(ot);
3506             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3507             gen_op_ld_T0_A0(ot + s->mem_index);
3508         } else {
3509             gen_op_mov_TN_reg(ot, 0, rm);
3510         }
3511
3512         switch(op) {
3513         case 0: /* test */
3514             val = insn_get(s, ot);
3515             gen_op_movl_T1_im(val);
3516             gen_op_testl_T0_T1_cc();
3517             s->cc_op = CC_OP_LOGICB + ot;
3518             break;
3519         case 2: /* not */
3520             gen_op_notl_T0();
3521             if (mod != 3) {
3522                 gen_op_st_T0_A0(ot + s->mem_index);
3523             } else {
3524                 gen_op_mov_reg_T0(ot, rm);
3525             }
3526             break;
3527         case 3: /* neg */
3528             gen_op_negl_T0();
3529             if (mod != 3) {
3530                 gen_op_st_T0_A0(ot + s->mem_index);
3531             } else {
3532                 gen_op_mov_reg_T0(ot, rm);
3533             }
3534             gen_op_update_neg_cc();
3535             s->cc_op = CC_OP_SUBB + ot;
3536             break;
3537         case 4: /* mul */
3538             switch(ot) {
3539             case OT_BYTE:
3540                 gen_op_mulb_AL_T0();
3541                 s->cc_op = CC_OP_MULB;
3542                 break;
3543             case OT_WORD:
3544                 gen_op_mulw_AX_T0();
3545                 s->cc_op = CC_OP_MULW;
3546                 break;
3547             default:
3548             case OT_LONG:
3549                 gen_op_mull_EAX_T0();
3550                 s->cc_op = CC_OP_MULL;
3551                 break;
3552 #ifdef TARGET_X86_64
3553             case OT_QUAD:
3554                 gen_op_mulq_EAX_T0();
3555                 s->cc_op = CC_OP_MULQ;
3556                 break;
3557 #endif
3558             }
3559             break;
3560         case 5: /* imul */
3561             switch(ot) {
3562             case OT_BYTE:
3563                 gen_op_imulb_AL_T0();
3564                 s->cc_op = CC_OP_MULB;
3565                 break;
3566             case OT_WORD:
3567                 gen_op_imulw_AX_T0();
3568                 s->cc_op = CC_OP_MULW;
3569                 break;
3570             default:
3571             case OT_LONG:
3572                 gen_op_imull_EAX_T0();
3573                 s->cc_op = CC_OP_MULL;
3574                 break;
3575 #ifdef TARGET_X86_64
3576             case OT_QUAD:
3577                 gen_op_imulq_EAX_T0();
3578                 s->cc_op = CC_OP_MULQ;
3579                 break;
3580 #endif
3581             }
3582             break;
3583         case 6: /* div */
3584             switch(ot) {
3585             case OT_BYTE:
3586                 gen_jmp_im(pc_start - s->cs_base);
3587                 gen_op_divb_AL_T0();
3588                 break;
3589             case OT_WORD:
3590                 gen_jmp_im(pc_start - s->cs_base);
3591                 gen_op_divw_AX_T0();
3592                 break;
3593             default:
3594             case OT_LONG:
3595                 gen_jmp_im(pc_start - s->cs_base);
3596 #ifdef MACRO_TEST
3597                 /* XXX: this is just a test */
3598                 tcg_gen_macro_2(cpu_T[0], cpu_T[0], MACRO_TEST);
3599 #else
3600                 tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]);
3601 #endif
3602                 break;
3603 #ifdef TARGET_X86_64
3604             case OT_QUAD:
3605                 gen_jmp_im(pc_start - s->cs_base);
3606                 gen_op_divq_EAX_T0();
3607                 break;
3608 #endif
3609             }
3610             break;
3611         case 7: /* idiv */
3612             switch(ot) {
3613             case OT_BYTE:
3614                 gen_jmp_im(pc_start - s->cs_base);
3615                 gen_op_idivb_AL_T0();
3616                 break;
3617             case OT_WORD:
3618                 gen_jmp_im(pc_start - s->cs_base);
3619                 gen_op_idivw_AX_T0();
3620                 break;
3621             default:
3622             case OT_LONG:
3623                 gen_jmp_im(pc_start - s->cs_base);
3624                 tcg_gen_helper_0_1(helper_idivl_EAX_T0, cpu_T[0]);
3625                 break;
3626 #ifdef TARGET_X86_64
3627             case OT_QUAD:
3628                 gen_jmp_im(pc_start - s->cs_base);
3629                 gen_op_idivq_EAX_T0();
3630                 break;
3631 #endif
3632             }
3633             break;
3634         default:
3635             goto illegal_op;
3636         }
3637         break;
3638
3639     case 0xfe: /* GRP4 */
3640     case 0xff: /* GRP5 */
3641         if ((b & 1) == 0)
3642             ot = OT_BYTE;
3643         else
3644             ot = dflag + OT_WORD;
3645
3646         modrm = ldub_code(s->pc++);
3647         mod = (modrm >> 6) & 3;
3648         rm = (modrm & 7) | REX_B(s);
3649         op = (modrm >> 3) & 7;
3650         if (op >= 2 && b == 0xfe) {
3651             goto illegal_op;
3652         }
3653         if (CODE64(s)) {
3654             if (op == 2 || op == 4) {
3655                 /* operand size for jumps is 64 bit */
3656                 ot = OT_QUAD;
3657             } else if (op == 3 || op == 5) {
3658                 /* for call calls, the operand is 16 or 32 bit, even
3659                    in long mode */
3660                 ot = dflag ? OT_LONG : OT_WORD;
3661             } else if (op == 6) {
3662                 /* default push size is 64 bit */
3663                 ot = dflag ? OT_QUAD : OT_WORD;
3664             }
3665         }
3666         if (mod != 3) {
3667             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3668             if (op >= 2 && op != 3 && op != 5)
3669                 gen_op_ld_T0_A0(ot + s->mem_index);
3670         } else {
3671             gen_op_mov_TN_reg(ot, 0, rm);
3672         }
3673
3674         switch(op) {
3675         case 0: /* inc Ev */
3676             if (mod != 3)
3677                 opreg = OR_TMP0;
3678             else
3679                 opreg = rm;
3680             gen_inc(s, ot, opreg, 1);
3681             break;
3682         case 1: /* dec Ev */
3683             if (mod != 3)
3684                 opreg = OR_TMP0;
3685             else
3686                 opreg = rm;
3687             gen_inc(s, ot, opreg, -1);
3688             break;
3689         case 2: /* call Ev */
3690             /* XXX: optimize if memory (no 'and' is necessary) */
3691             if (s->dflag == 0)
3692                 gen_op_andl_T0_ffff();
3693             next_eip = s->pc - s->cs_base;
3694             gen_movtl_T1_im(next_eip);
3695             gen_push_T1(s);
3696             gen_op_jmp_T0();
3697             gen_eob(s);
3698             break;
3699         case 3: /* lcall Ev */
3700             gen_op_ld_T1_A0(ot + s->mem_index);
3701             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3702             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
3703         do_lcall:
3704             if (s->pe && !s->vm86) {
3705                 if (s->cc_op != CC_OP_DYNAMIC)
3706                     gen_op_set_cc_op(s->cc_op);
3707                 gen_jmp_im(pc_start - s->cs_base);
3708                 gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
3709             } else {
3710                 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
3711             }
3712             gen_eob(s);
3713             break;
3714         case 4: /* jmp Ev */
3715             if (s->dflag == 0)
3716                 gen_op_andl_T0_ffff();
3717             gen_op_jmp_T0();
3718             gen_eob(s);
3719             break;
3720         case 5: /* ljmp Ev */
3721             gen_op_ld_T1_A0(ot + s->mem_index);
3722             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3723             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
3724         do_ljmp:
3725             if (s->pe && !s->vm86) {
3726                 if (s->cc_op != CC_OP_DYNAMIC)
3727                     gen_op_set_cc_op(s->cc_op);
3728                 gen_jmp_im(pc_start - s->cs_base);
3729                 gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
3730             } else {
3731                 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3732                 gen_op_movl_T0_T1();
3733                 gen_op_jmp_T0();
3734             }
3735             gen_eob(s);
3736             break;
3737         case 6: /* push Ev */
3738             gen_push_T0(s);
3739             break;
3740         default:
3741             goto illegal_op;
3742         }
3743         break;
3744
3745     case 0x84: /* test Ev, Gv */
3746     case 0x85:
3747         if ((b & 1) == 0)
3748             ot = OT_BYTE;
3749         else
3750             ot = dflag + OT_WORD;
3751
3752         modrm = ldub_code(s->pc++);
3753         mod = (modrm >> 6) & 3;
3754         rm = (modrm & 7) | REX_B(s);
3755         reg = ((modrm >> 3) & 7) | rex_r;
3756
3757         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3758         gen_op_mov_TN_reg(ot, 1, reg);
3759         gen_op_testl_T0_T1_cc();
3760         s->cc_op = CC_OP_LOGICB + ot;
3761         break;
3762
3763     case 0xa8: /* test eAX, Iv */
3764     case 0xa9:
3765         if ((b & 1) == 0)
3766             ot = OT_BYTE;
3767         else
3768             ot = dflag + OT_WORD;
3769         val = insn_get(s, ot);
3770
3771         gen_op_mov_TN_reg(ot, 0, OR_EAX);
3772         gen_op_movl_T1_im(val);
3773         gen_op_testl_T0_T1_cc();
3774         s->cc_op = CC_OP_LOGICB + ot;
3775         break;
3776
3777     case 0x98: /* CWDE/CBW */
3778 #ifdef TARGET_X86_64
3779         if (dflag == 2) {
3780             gen_op_movslq_RAX_EAX();
3781         } else
3782 #endif
3783         if (dflag == 1)
3784             gen_op_movswl_EAX_AX();
3785         else
3786             gen_op_movsbw_AX_AL();
3787         break;
3788     case 0x99: /* CDQ/CWD */
3789 #ifdef TARGET_X86_64
3790         if (dflag == 2) {
3791             gen_op_movsqo_RDX_RAX();
3792         } else
3793 #endif
3794         if (dflag == 1)
3795             gen_op_movslq_EDX_EAX();
3796         else
3797             gen_op_movswl_DX_AX();
3798         break;
3799     case 0x1af: /* imul Gv, Ev */
3800     case 0x69: /* imul Gv, Ev, I */
3801     case 0x6b:
3802         ot = dflag + OT_WORD;
3803         modrm = ldub_code(s->pc++);
3804         reg = ((modrm >> 3) & 7) | rex_r;
3805         if (b == 0x69)
3806             s->rip_offset = insn_const_size(ot);
3807         else if (b == 0x6b)
3808             s->rip_offset = 1;
3809         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3810         if (b == 0x69) {
3811             val = insn_get(s, ot);
3812             gen_op_movl_T1_im(val);
3813         } else if (b == 0x6b) {
3814             val = (int8_t)insn_get(s, OT_BYTE);
3815             gen_op_movl_T1_im(val);
3816         } else {
3817             gen_op_mov_TN_reg(ot, 1, reg);
3818         }
3819
3820 #ifdef TARGET_X86_64
3821         if (ot == OT_QUAD) {
3822             gen_op_imulq_T0_T1();
3823         } else
3824 #endif
3825         if (ot == OT_LONG) {
3826             gen_op_imull_T0_T1();
3827         } else {
3828             gen_op_imulw_T0_T1();
3829         }
3830         gen_op_mov_reg_T0(ot, reg);
3831         s->cc_op = CC_OP_MULB + ot;
3832         break;
3833     case 0x1c0:
3834     case 0x1c1: /* xadd Ev, Gv */
3835         if ((b & 1) == 0)
3836             ot = OT_BYTE;
3837         else
3838             ot = dflag + OT_WORD;
3839         modrm = ldub_code(s->pc++);
3840         reg = ((modrm >> 3) & 7) | rex_r;
3841         mod = (modrm >> 6) & 3;
3842         if (mod == 3) {
3843             rm = (modrm & 7) | REX_B(s);
3844             gen_op_mov_TN_reg(ot, 0, reg);
3845             gen_op_mov_TN_reg(ot, 1, rm);
3846             gen_op_addl_T0_T1();
3847             gen_op_mov_reg_T1(ot, reg);
3848             gen_op_mov_reg_T0(ot, rm);
3849         } else {
3850             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3851             gen_op_mov_TN_reg(ot, 0, reg);
3852             gen_op_ld_T1_A0(ot + s->mem_index);
3853             gen_op_addl_T0_T1();
3854             gen_op_st_T0_A0(ot + s->mem_index);
3855             gen_op_mov_reg_T1(ot, reg);
3856         }
3857         gen_op_update2_cc();
3858         s->cc_op = CC_OP_ADDB + ot;
3859         break;
3860     case 0x1b0:
3861     case 0x1b1: /* cmpxchg Ev, Gv */
3862         if ((b & 1) == 0)
3863             ot = OT_BYTE;
3864         else
3865             ot = dflag + OT_WORD;
3866         modrm = ldub_code(s->pc++);
3867         reg = ((modrm >> 3) & 7) | rex_r;
3868         mod = (modrm >> 6) & 3;
3869         gen_op_mov_TN_reg(ot, 1, reg);
3870         if (mod == 3) {
3871             rm = (modrm & 7) | REX_B(s);
3872             gen_op_mov_TN_reg(ot, 0, rm);
3873             gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
3874             gen_op_mov_reg_T0(ot, rm);
3875         } else {
3876             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3877             gen_op_ld_T0_A0(ot + s->mem_index);
3878             gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
3879         }
3880         s->cc_op = CC_OP_SUBB + ot;
3881         break;
3882     case 0x1c7: /* cmpxchg8b */
3883         modrm = ldub_code(s->pc++);
3884         mod = (modrm >> 6) & 3;
3885         if ((mod == 3) || ((modrm & 0x38) != 0x8))
3886             goto illegal_op;
3887         gen_jmp_im(pc_start - s->cs_base);
3888         if (s->cc_op != CC_OP_DYNAMIC)
3889             gen_op_set_cc_op(s->cc_op);
3890         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3891         gen_op_cmpxchg8b();
3892         s->cc_op = CC_OP_EFLAGS;
3893         break;
3894
3895         /**************************/
3896         /* push/pop */
3897     case 0x50 ... 0x57: /* push */
3898         gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
3899         gen_push_T0(s);
3900         break;
3901     case 0x58 ... 0x5f: /* pop */
3902         if (CODE64(s)) {
3903             ot = dflag ? OT_QUAD : OT_WORD;
3904         } else {
3905             ot = dflag + OT_WORD;
3906         }
3907         gen_pop_T0(s);
3908         /* NOTE: order is important for pop %sp */
3909         gen_pop_update(s);
3910         gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
3911         break;
3912     case 0x60: /* pusha */
3913         if (CODE64(s))
3914             goto illegal_op;
3915         gen_pusha(s);
3916         break;
3917     case 0x61: /* popa */
3918         if (CODE64(s))
3919             goto illegal_op;
3920         gen_popa(s);
3921         break;
3922     case 0x68: /* push Iv */
3923     case 0x6a:
3924         if (CODE64(s)) {
3925             ot = dflag ? OT_QUAD : OT_WORD;
3926         } else {
3927             ot = dflag + OT_WORD;
3928         }
3929         if (b == 0x68)
3930             val = insn_get(s, ot);
3931         else
3932             val = (int8_t)insn_get(s, OT_BYTE);
3933         gen_op_movl_T0_im(val);
3934         gen_push_T0(s);
3935         break;
3936     case 0x8f: /* pop Ev */
3937         if (CODE64(s)) {
3938             ot = dflag ? OT_QUAD : OT_WORD;
3939         } else {
3940             ot = dflag + OT_WORD;
3941         }
3942         modrm = ldub_code(s->pc++);
3943         mod = (modrm >> 6) & 3;
3944         gen_pop_T0(s);
3945         if (mod == 3) {
3946             /* NOTE: order is important for pop %sp */
3947             gen_pop_update(s);
3948             rm = (modrm & 7) | REX_B(s);
3949             gen_op_mov_reg_T0(ot, rm);
3950         } else {
3951             /* NOTE: order is important too for MMU exceptions */
3952             s->popl_esp_hack = 1 << ot;
3953             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3954             s->popl_esp_hack = 0;
3955             gen_pop_update(s);
3956         }
3957         break;
3958     case 0xc8: /* enter */
3959         {
3960             int level;
3961             val = lduw_code(s->pc);
3962             s->pc += 2;
3963             level = ldub_code(s->pc++);
3964             gen_enter(s, val, level);
3965         }
3966         break;
3967     case 0xc9: /* leave */
3968         /* XXX: exception not precise (ESP is updated before potential exception) */
3969         if (CODE64(s)) {
3970             gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
3971             gen_op_mov_reg_T0(OT_QUAD, R_ESP);
3972         } else if (s->ss32) {
3973             gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
3974             gen_op_mov_reg_T0(OT_LONG, R_ESP);
3975         } else {
3976             gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
3977             gen_op_mov_reg_T0(OT_WORD, R_ESP);
3978         }
3979         gen_pop_T0(s);
3980         if (CODE64(s)) {
3981             ot = dflag ? OT_QUAD : OT_WORD;
3982         } else {
3983             ot = dflag + OT_WORD;
3984         }
3985         gen_op_mov_reg_T0(ot, R_EBP);
3986         gen_pop_update(s);
3987         break;
3988     case 0x06: /* push es */
3989     case 0x0e: /* push cs */
3990     case 0x16: /* push ss */
3991     case 0x1e: /* push ds */
3992         if (CODE64(s))
3993             goto illegal_op;
3994         gen_op_movl_T0_seg(b >> 3);
3995         gen_push_T0(s);
3996         break;
3997     case 0x1a0: /* push fs */
3998     case 0x1a8: /* push gs */
3999         gen_op_movl_T0_seg((b >> 3) & 7);
4000         gen_push_T0(s);
4001         break;
4002     case 0x07: /* pop es */
4003     case 0x17: /* pop ss */
4004     case 0x1f: /* pop ds */
4005         if (CODE64(s))
4006             goto illegal_op;
4007         reg = b >> 3;
4008         gen_pop_T0(s);
4009         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4010         gen_pop_update(s);
4011         if (reg == R_SS) {
4012             /* if reg == SS, inhibit interrupts/trace. */
4013             /* If several instructions disable interrupts, only the
4014                _first_ does it */
4015             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4016                 gen_op_set_inhibit_irq();
4017             s->tf = 0;
4018         }
4019         if (s->is_jmp) {
4020             gen_jmp_im(s->pc - s->cs_base);
4021             gen_eob(s);
4022         }
4023         break;
4024     case 0x1a1: /* pop fs */
4025     case 0x1a9: /* pop gs */
4026         gen_pop_T0(s);
4027         gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
4028         gen_pop_update(s);
4029         if (s->is_jmp) {
4030             gen_jmp_im(s->pc - s->cs_base);
4031             gen_eob(s);
4032         }
4033         break;
4034
4035         /**************************/
4036         /* mov */
4037     case 0x88:
4038     case 0x89: /* mov Gv, Ev */
4039         if ((b & 1) == 0)
4040             ot = OT_BYTE;
4041         else
4042             ot = dflag + OT_WORD;
4043         modrm = ldub_code(s->pc++);
4044         reg = ((modrm >> 3) & 7) | rex_r;
4045
4046         /* generate a generic store */
4047         gen_ldst_modrm(s, modrm, ot, reg, 1);
4048         break;
4049     case 0xc6:
4050     case 0xc7: /* mov Ev, Iv */
4051         if ((b & 1) == 0)
4052             ot = OT_BYTE;
4053         else
4054             ot = dflag + OT_WORD;
4055         modrm = ldub_code(s->pc++);
4056         mod = (modrm >> 6) & 3;
4057         if (mod != 3) {
4058             s->rip_offset = insn_const_size(ot);
4059             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4060         }
4061         val = insn_get(s, ot);
4062         gen_op_movl_T0_im(val);
4063         if (mod != 3)
4064             gen_op_st_T0_A0(ot + s->mem_index);
4065         else
4066             gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
4067         break;
4068     case 0x8a:
4069     case 0x8b: /* mov Ev, Gv */
4070         if ((b & 1) == 0)
4071             ot = OT_BYTE;
4072         else
4073             ot = OT_WORD + dflag;
4074         modrm = ldub_code(s->pc++);
4075         reg = ((modrm >> 3) & 7) | rex_r;
4076
4077         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
4078         gen_op_mov_reg_T0(ot, reg);
4079         break;
4080     case 0x8e: /* mov seg, Gv */
4081         modrm = ldub_code(s->pc++);
4082         reg = (modrm >> 3) & 7;
4083         if (reg >= 6 || reg == R_CS)
4084             goto illegal_op;
4085         gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
4086         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
4087         if (reg == R_SS) {
4088             /* if reg == SS, inhibit interrupts/trace */
4089             /* If several instructions disable interrupts, only the
4090                _first_ does it */
4091             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
4092                 gen_op_set_inhibit_irq();
4093             s->tf = 0;
4094         }
4095         if (s->is_jmp) {
4096             gen_jmp_im(s->pc - s->cs_base);
4097             gen_eob(s);
4098         }
4099         break;
4100     case 0x8c: /* mov Gv, seg */
4101         modrm = ldub_code(s->pc++);
4102         reg = (modrm >> 3) & 7;
4103         mod = (modrm >> 6) & 3;
4104         if (reg >= 6)
4105             goto illegal_op;
4106         gen_op_movl_T0_seg(reg);
4107         if (mod == 3)
4108             ot = OT_WORD + dflag;
4109         else
4110             ot = OT_WORD;
4111         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
4112         break;
4113
4114     case 0x1b6: /* movzbS Gv, Eb */
4115     case 0x1b7: /* movzwS Gv, Eb */
4116     case 0x1be: /* movsbS Gv, Eb */
4117     case 0x1bf: /* movswS Gv, Eb */
4118         {
4119             int d_ot;
4120             /* d_ot is the size of destination */
4121             d_ot = dflag + OT_WORD;
4122             /* ot is the size of source */
4123             ot = (b & 1) + OT_BYTE;
4124             modrm = ldub_code(s->pc++);
4125             reg = ((modrm >> 3) & 7) | rex_r;
4126             mod = (modrm >> 6) & 3;
4127             rm = (modrm & 7) | REX_B(s);
4128
4129             if (mod == 3) {
4130                 gen_op_mov_TN_reg(ot, 0, rm);
4131                 switch(ot | (b & 8)) {
4132                 case OT_BYTE:
4133                     gen_op_movzbl_T0_T0();
4134                     break;
4135                 case OT_BYTE | 8:
4136                     gen_op_movsbl_T0_T0();
4137                     break;
4138                 case OT_WORD:
4139                     gen_op_movzwl_T0_T0();
4140                     break;
4141                 default:
4142                 case OT_WORD | 8:
4143                     gen_op_movswl_T0_T0();
4144                     break;
4145                 }
4146                 gen_op_mov_reg_T0(d_ot, reg);
4147             } else {
4148                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4149                 if (b & 8) {
4150                     gen_op_lds_T0_A0(ot + s->mem_index);
4151                 } else {
4152                     gen_op_ldu_T0_A0(ot + s->mem_index);
4153                 }
4154                 gen_op_mov_reg_T0(d_ot, reg);
4155             }
4156         }
4157         break;
4158
4159     case 0x8d: /* lea */
4160         ot = dflag + OT_WORD;
4161         modrm = ldub_code(s->pc++);
4162         mod = (modrm >> 6) & 3;
4163         if (mod == 3)
4164             goto illegal_op;
4165         reg = ((modrm >> 3) & 7) | rex_r;
4166         /* we must ensure that no segment is added */
4167         s->override = -1;
4168         val = s->addseg;
4169         s->addseg = 0;
4170         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4171         s->addseg = val;
4172         gen_op_mov_reg_A0(ot - OT_WORD, reg);
4173         break;
4174
4175     case 0xa0: /* mov EAX, Ov */
4176     case 0xa1:
4177     case 0xa2: /* mov Ov, EAX */
4178     case 0xa3:
4179         {
4180             target_ulong offset_addr;
4181
4182             if ((b & 1) == 0)
4183                 ot = OT_BYTE;
4184             else
4185                 ot = dflag + OT_WORD;
4186 #ifdef TARGET_X86_64
4187             if (s->aflag == 2) {
4188                 offset_addr = ldq_code(s->pc);
4189                 s->pc += 8;
4190                 gen_op_movq_A0_im(offset_addr);
4191             } else
4192 #endif
4193             {
4194                 if (s->aflag) {
4195                     offset_addr = insn_get(s, OT_LONG);
4196                 } else {
4197                     offset_addr = insn_get(s, OT_WORD);
4198                 }
4199                 gen_op_movl_A0_im(offset_addr);
4200             }
4201             gen_add_A0_ds_seg(s);
4202             if ((b & 2) == 0) {
4203                 gen_op_ld_T0_A0(ot + s->mem_index);
4204                 gen_op_mov_reg_T0(ot, R_EAX);
4205             } else {
4206                 gen_op_mov_TN_reg(ot, 0, R_EAX);
4207                 gen_op_st_T0_A0(ot + s->mem_index);
4208             }
4209         }
4210         break;
4211     case 0xd7: /* xlat */
4212 #ifdef TARGET_X86_64
4213         if (s->aflag == 2) {
4214             gen_op_movq_A0_reg(R_EBX);
4215             gen_op_addq_A0_AL();
4216         } else
4217 #endif
4218         {
4219             gen_op_movl_A0_reg(R_EBX);
4220             gen_op_addl_A0_AL();
4221             if (s->aflag == 0)
4222                 gen_op_andl_A0_ffff();
4223         }
4224         gen_add_A0_ds_seg(s);
4225         gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
4226         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
4227         break;
4228     case 0xb0 ... 0xb7: /* mov R, Ib */
4229         val = insn_get(s, OT_BYTE);
4230         gen_op_movl_T0_im(val);
4231         gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
4232         break;
4233     case 0xb8 ... 0xbf: /* mov R, Iv */
4234 #ifdef TARGET_X86_64
4235         if (dflag == 2) {
4236             uint64_t tmp;
4237             /* 64 bit case */
4238             tmp = ldq_code(s->pc);
4239             s->pc += 8;
4240             reg = (b & 7) | REX_B(s);
4241             gen_movtl_T0_im(tmp);
4242             gen_op_mov_reg_T0(OT_QUAD, reg);
4243         } else
4244 #endif
4245         {
4246             ot = dflag ? OT_LONG : OT_WORD;
4247             val = insn_get(s, ot);
4248             reg = (b & 7) | REX_B(s);
4249             gen_op_movl_T0_im(val);
4250             gen_op_mov_reg_T0(ot, reg);
4251         }
4252         break;
4253
4254     case 0x91 ... 0x97: /* xchg R, EAX */
4255         ot = dflag + OT_WORD;
4256         reg = (b & 7) | REX_B(s);
4257         rm = R_EAX;
4258         goto do_xchg_reg;
4259     case 0x86:
4260     case 0x87: /* xchg Ev, Gv */
4261         if ((b & 1) == 0)
4262             ot = OT_BYTE;
4263         else
4264             ot = dflag + OT_WORD;
4265         modrm = ldub_code(s->pc++);
4266         reg = ((modrm >> 3) & 7) | rex_r;
4267         mod = (modrm >> 6) & 3;
4268         if (mod == 3) {
4269             rm = (modrm & 7) | REX_B(s);
4270         do_xchg_reg:
4271             gen_op_mov_TN_reg(ot, 0, reg);
4272             gen_op_mov_TN_reg(ot, 1, rm);
4273             gen_op_mov_reg_T0(ot, rm);
4274             gen_op_mov_reg_T1(ot, reg);
4275         } else {
4276             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4277             gen_op_mov_TN_reg(ot, 0, reg);
4278             /* for xchg, lock is implicit */
4279             if (!(prefixes & PREFIX_LOCK))
4280                 gen_op_lock();
4281             gen_op_ld_T1_A0(ot + s->mem_index);
4282             gen_op_st_T0_A0(ot + s->mem_index);
4283             if (!(prefixes & PREFIX_LOCK))
4284                 gen_op_unlock();
4285             gen_op_mov_reg_T1(ot, reg);
4286         }
4287         break;
4288     case 0xc4: /* les Gv */
4289         if (CODE64(s))
4290             goto illegal_op;
4291         op = R_ES;
4292         goto do_lxx;
4293     case 0xc5: /* lds Gv */
4294         if (CODE64(s))
4295             goto illegal_op;
4296         op = R_DS;
4297         goto do_lxx;
4298     case 0x1b2: /* lss Gv */
4299         op = R_SS;
4300         goto do_lxx;
4301     case 0x1b4: /* lfs Gv */
4302         op = R_FS;
4303         goto do_lxx;
4304     case 0x1b5: /* lgs Gv */
4305         op = R_GS;
4306     do_lxx:
4307         ot = dflag ? OT_LONG : OT_WORD;
4308         modrm = ldub_code(s->pc++);
4309         reg = ((modrm >> 3) & 7) | rex_r;
4310         mod = (modrm >> 6) & 3;
4311         if (mod == 3)
4312             goto illegal_op;
4313         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4314         gen_op_ld_T1_A0(ot + s->mem_index);
4315         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4316         /* load the segment first to handle exceptions properly */
4317         gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
4318         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4319         /* then put the data */
4320         gen_op_mov_reg_T1(ot, reg);
4321         if (s->is_jmp) {
4322             gen_jmp_im(s->pc - s->cs_base);
4323             gen_eob(s);
4324         }
4325         break;
4326
4327         /************************/
4328         /* shifts */
4329     case 0xc0:
4330     case 0xc1:
4331         /* shift Ev,Ib */
4332         shift = 2;
4333     grp2:
4334         {
4335             if ((b & 1) == 0)
4336                 ot = OT_BYTE;
4337             else
4338                 ot = dflag + OT_WORD;
4339
4340             modrm = ldub_code(s->pc++);
4341             mod = (modrm >> 6) & 3;
4342             op = (modrm >> 3) & 7;
4343
4344             if (mod != 3) {
4345                 if (shift == 2) {
4346                     s->rip_offset = 1;
4347                 }
4348                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4349                 opreg = OR_TMP0;
4350             } else {
4351                 opreg = (modrm & 7) | REX_B(s);
4352             }
4353
4354             /* simpler op */
4355             if (shift == 0) {
4356                 gen_shift(s, op, ot, opreg, OR_ECX);
4357             } else {
4358                 if (shift == 2) {
4359                     shift = ldub_code(s->pc++);
4360                 }
4361                 gen_shifti(s, op, ot, opreg, shift);
4362             }
4363         }
4364         break;
4365     case 0xd0:
4366     case 0xd1:
4367         /* shift Ev,1 */
4368         shift = 1;
4369         goto grp2;
4370     case 0xd2:
4371     case 0xd3:
4372         /* shift Ev,cl */
4373         shift = 0;
4374         goto grp2;
4375
4376     case 0x1a4: /* shld imm */
4377         op = 0;
4378         shift = 1;
4379         goto do_shiftd;
4380     case 0x1a5: /* shld cl */
4381         op = 0;
4382         shift = 0;
4383         goto do_shiftd;
4384     case 0x1ac: /* shrd imm */
4385         op = 1;
4386         shift = 1;
4387         goto do_shiftd;
4388     case 0x1ad: /* shrd cl */
4389         op = 1;
4390         shift = 0;
4391     do_shiftd:
4392         ot = dflag + OT_WORD;
4393         modrm = ldub_code(s->pc++);
4394         mod = (modrm >> 6) & 3;
4395         rm = (modrm & 7) | REX_B(s);
4396         reg = ((modrm >> 3) & 7) | rex_r;
4397
4398         if (mod != 3) {
4399             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4400             gen_op_ld_T0_A0(ot + s->mem_index);
4401         } else {
4402             gen_op_mov_TN_reg(ot, 0, rm);
4403         }
4404         gen_op_mov_TN_reg(ot, 1, reg);
4405
4406         if (shift) {
4407             val = ldub_code(s->pc++);
4408             if (ot == OT_QUAD)
4409                 val &= 0x3f;
4410             else
4411                 val &= 0x1f;
4412             if (val) {
4413                 if (mod == 3)
4414                     gen_op_shiftd_T0_T1_im_cc[ot][op](val);
4415                 else
4416                     gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
4417                 if (op == 0 && ot != OT_WORD)
4418                     s->cc_op = CC_OP_SHLB + ot;
4419                 else
4420                     s->cc_op = CC_OP_SARB + ot;
4421             }
4422         } else {
4423             if (s->cc_op != CC_OP_DYNAMIC)
4424                 gen_op_set_cc_op(s->cc_op);
4425             if (mod == 3)
4426                 gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
4427             else
4428                 gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
4429             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
4430         }
4431         if (mod == 3) {
4432             gen_op_mov_reg_T0(ot, rm);
4433         }
4434         break;
4435
4436         /************************/
4437         /* floats */
4438     case 0xd8 ... 0xdf:
4439         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4440             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4441             /* XXX: what to do if illegal op ? */
4442             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4443             break;
4444         }
4445         modrm = ldub_code(s->pc++);
4446         mod = (modrm >> 6) & 3;
4447         rm = modrm & 7;
4448         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4449         if (mod != 3) {
4450             /* memory op */
4451             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4452             switch(op) {
4453             case 0x00 ... 0x07: /* fxxxs */
4454             case 0x10 ... 0x17: /* fixxxl */
4455             case 0x20 ... 0x27: /* fxxxl */
4456             case 0x30 ... 0x37: /* fixxx */
4457                 {
4458                     int op1;
4459                     op1 = op & 7;
4460
4461                     switch(op >> 4) {
4462                     case 0:
4463                         gen_op_flds_FT0_A0();
4464                         break;
4465                     case 1:
4466                         gen_op_fildl_FT0_A0();
4467                         break;
4468                     case 2:
4469                         gen_op_fldl_FT0_A0();
4470                         break;
4471                     case 3:
4472                     default:
4473                         gen_op_fild_FT0_A0();
4474                         break;
4475                     }
4476
4477                     gen_op_fp_arith_ST0_FT0[op1]();
4478                     if (op1 == 3) {
4479                         /* fcomp needs pop */
4480                         gen_op_fpop();
4481                     }
4482                 }
4483                 break;
4484             case 0x08: /* flds */
4485             case 0x0a: /* fsts */
4486             case 0x0b: /* fstps */
4487             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4488             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4489             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4490                 switch(op & 7) {
4491                 case 0:
4492                     switch(op >> 4) {
4493                     case 0:
4494                         gen_op_flds_ST0_A0();
4495                         break;
4496                     case 1:
4497                         gen_op_fildl_ST0_A0();
4498                         break;
4499                     case 2:
4500                         gen_op_fldl_ST0_A0();
4501                         break;
4502                     case 3:
4503                     default:
4504                         gen_op_fild_ST0_A0();
4505                         break;
4506                     }
4507                     break;
4508                 case 1:
4509                     switch(op >> 4) {
4510                     case 1:
4511                         gen_op_fisttl_ST0_A0();
4512                         break;
4513                     case 2:
4514                         gen_op_fisttll_ST0_A0();
4515                         break;
4516                     case 3:
4517                     default:
4518                         gen_op_fistt_ST0_A0();
4519                     }
4520                     gen_op_fpop();
4521                     break;
4522                 default:
4523                     switch(op >> 4) {
4524                     case 0:
4525                         gen_op_fsts_ST0_A0();
4526                         break;
4527                     case 1:
4528                         gen_op_fistl_ST0_A0();
4529                         break;
4530                     case 2:
4531                         gen_op_fstl_ST0_A0();
4532                         break;
4533                     case 3:
4534                     default:
4535                         gen_op_fist_ST0_A0();
4536                         break;
4537                     }
4538                     if ((op & 7) == 3)
4539                         gen_op_fpop();
4540                     break;
4541                 }
4542                 break;
4543             case 0x0c: /* fldenv mem */
4544                 gen_op_fldenv_A0(s->dflag);
4545                 break;
4546             case 0x0d: /* fldcw mem */
4547                 gen_op_fldcw_A0();
4548                 break;
4549             case 0x0e: /* fnstenv mem */
4550                 gen_op_fnstenv_A0(s->dflag);
4551                 break;
4552             case 0x0f: /* fnstcw mem */
4553                 gen_op_fnstcw_A0();
4554                 break;
4555             case 0x1d: /* fldt mem */
4556                 gen_op_fldt_ST0_A0();
4557                 break;
4558             case 0x1f: /* fstpt mem */
4559                 gen_op_fstt_ST0_A0();
4560                 gen_op_fpop();
4561                 break;
4562             case 0x2c: /* frstor mem */
4563                 gen_op_frstor_A0(s->dflag);
4564                 break;
4565             case 0x2e: /* fnsave mem */
4566                 gen_op_fnsave_A0(s->dflag);
4567                 break;
4568             case 0x2f: /* fnstsw mem */
4569                 gen_op_fnstsw_A0();
4570                 break;
4571             case 0x3c: /* fbld */
4572                 gen_op_fbld_ST0_A0();
4573                 break;
4574             case 0x3e: /* fbstp */
4575                 gen_op_fbst_ST0_A0();
4576                 gen_op_fpop();
4577                 break;
4578             case 0x3d: /* fildll */
4579                 gen_op_fildll_ST0_A0();
4580                 break;
4581             case 0x3f: /* fistpll */
4582                 gen_op_fistll_ST0_A0();
4583                 gen_op_fpop();
4584                 break;
4585             default:
4586                 goto illegal_op;
4587             }
4588         } else {
4589             /* register float ops */
4590             opreg = rm;
4591
4592             switch(op) {
4593             case 0x08: /* fld sti */
4594                 gen_op_fpush();
4595                 gen_op_fmov_ST0_STN((opreg + 1) & 7);
4596                 break;
4597             case 0x09: /* fxchg sti */
4598             case 0x29: /* fxchg4 sti, undocumented op */
4599             case 0x39: /* fxchg7 sti, undocumented op */
4600                 gen_op_fxchg_ST0_STN(opreg);
4601                 break;
4602             case 0x0a: /* grp d9/2 */
4603                 switch(rm) {
4604                 case 0: /* fnop */
4605                     /* check exceptions (FreeBSD FPU probe) */
4606                     if (s->cc_op != CC_OP_DYNAMIC)
4607                         gen_op_set_cc_op(s->cc_op);
4608                     gen_jmp_im(pc_start - s->cs_base);
4609                     gen_op_fwait();
4610                     break;
4611                 default:
4612                     goto illegal_op;
4613                 }
4614                 break;
4615             case 0x0c: /* grp d9/4 */
4616                 switch(rm) {
4617                 case 0: /* fchs */
4618                     gen_op_fchs_ST0();
4619                     break;
4620                 case 1: /* fabs */
4621                     gen_op_fabs_ST0();
4622                     break;
4623                 case 4: /* ftst */
4624                     gen_op_fldz_FT0();
4625                     gen_op_fcom_ST0_FT0();
4626                     break;
4627                 case 5: /* fxam */
4628                     gen_op_fxam_ST0();
4629                     break;
4630                 default:
4631                     goto illegal_op;
4632                 }
4633                 break;
4634             case 0x0d: /* grp d9/5 */
4635                 {
4636                     switch(rm) {
4637                     case 0:
4638                         gen_op_fpush();
4639                         gen_op_fld1_ST0();
4640                         break;
4641                     case 1:
4642                         gen_op_fpush();
4643                         gen_op_fldl2t_ST0();
4644                         break;
4645                     case 2:
4646                         gen_op_fpush();
4647                         gen_op_fldl2e_ST0();
4648                         break;
4649                     case 3:
4650                         gen_op_fpush();
4651                         gen_op_fldpi_ST0();
4652                         break;
4653                     case 4:
4654                         gen_op_fpush();
4655                         gen_op_fldlg2_ST0();
4656                         break;
4657                     case 5:
4658                         gen_op_fpush();
4659                         gen_op_fldln2_ST0();
4660                         break;
4661                     case 6:
4662                         gen_op_fpush();
4663                         gen_op_fldz_ST0();
4664                         break;
4665                     default:
4666                         goto illegal_op;
4667                     }
4668                 }
4669                 break;
4670             case 0x0e: /* grp d9/6 */
4671                 switch(rm) {
4672                 case 0: /* f2xm1 */
4673                     gen_op_f2xm1();
4674                     break;
4675                 case 1: /* fyl2x */
4676                     gen_op_fyl2x();
4677                     break;
4678                 case 2: /* fptan */
4679                     gen_op_fptan();
4680                     break;
4681                 case 3: /* fpatan */
4682                     gen_op_fpatan();
4683                     break;
4684                 case 4: /* fxtract */
4685                     gen_op_fxtract();
4686                     break;
4687                 case 5: /* fprem1 */
4688                     gen_op_fprem1();
4689                     break;
4690                 case 6: /* fdecstp */
4691                     gen_op_fdecstp();
4692                     break;
4693                 default:
4694                 case 7: /* fincstp */
4695                     gen_op_fincstp();
4696                     break;
4697                 }
4698                 break;
4699             case 0x0f: /* grp d9/7 */
4700                 switch(rm) {
4701                 case 0: /* fprem */
4702                     gen_op_fprem();
4703                     break;
4704                 case 1: /* fyl2xp1 */
4705                     gen_op_fyl2xp1();
4706                     break;
4707                 case 2: /* fsqrt */
4708                     gen_op_fsqrt();
4709                     break;
4710                 case 3: /* fsincos */
4711                     gen_op_fsincos();
4712                     break;
4713                 case 5: /* fscale */
4714                     gen_op_fscale();
4715                     break;
4716                 case 4: /* frndint */
4717                     gen_op_frndint();
4718                     break;
4719                 case 6: /* fsin */
4720                     gen_op_fsin();
4721                     break;
4722                 default:
4723                 case 7: /* fcos */
4724                     gen_op_fcos();
4725                     break;
4726                 }
4727                 break;
4728             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4729             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4730             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4731                 {
4732                     int op1;
4733
4734                     op1 = op & 7;
4735                     if (op >= 0x20) {
4736                         gen_op_fp_arith_STN_ST0[op1](opreg);
4737                         if (op >= 0x30)
4738                             gen_op_fpop();
4739                     } else {
4740                         gen_op_fmov_FT0_STN(opreg);
4741                         gen_op_fp_arith_ST0_FT0[op1]();
4742                     }
4743                 }
4744                 break;
4745             case 0x02: /* fcom */
4746             case 0x22: /* fcom2, undocumented op */
4747                 gen_op_fmov_FT0_STN(opreg);
4748                 gen_op_fcom_ST0_FT0();
4749                 break;
4750             case 0x03: /* fcomp */
4751             case 0x23: /* fcomp3, undocumented op */
4752             case 0x32: /* fcomp5, undocumented op */
4753                 gen_op_fmov_FT0_STN(opreg);
4754                 gen_op_fcom_ST0_FT0();
4755                 gen_op_fpop();
4756                 break;
4757             case 0x15: /* da/5 */
4758                 switch(rm) {
4759                 case 1: /* fucompp */
4760                     gen_op_fmov_FT0_STN(1);
4761                     gen_op_fucom_ST0_FT0();
4762                     gen_op_fpop();
4763                     gen_op_fpop();
4764                     break;
4765                 default:
4766                     goto illegal_op;
4767                 }
4768                 break;
4769             case 0x1c:
4770                 switch(rm) {
4771                 case 0: /* feni (287 only, just do nop here) */
4772                     break;
4773                 case 1: /* fdisi (287 only, just do nop here) */
4774                     break;
4775                 case 2: /* fclex */
4776                     gen_op_fclex();
4777                     break;
4778                 case 3: /* fninit */
4779                     gen_op_fninit();
4780                     break;
4781                 case 4: /* fsetpm (287 only, just do nop here) */
4782                     break;
4783                 default:
4784                     goto illegal_op;
4785                 }
4786                 break;
4787             case 0x1d: /* fucomi */
4788                 if (s->cc_op != CC_OP_DYNAMIC)
4789                     gen_op_set_cc_op(s->cc_op);
4790                 gen_op_fmov_FT0_STN(opreg);
4791                 gen_op_fucomi_ST0_FT0();
4792                 s->cc_op = CC_OP_EFLAGS;
4793                 break;
4794             case 0x1e: /* fcomi */
4795                 if (s->cc_op != CC_OP_DYNAMIC)
4796                     gen_op_set_cc_op(s->cc_op);
4797                 gen_op_fmov_FT0_STN(opreg);
4798                 gen_op_fcomi_ST0_FT0();
4799                 s->cc_op = CC_OP_EFLAGS;
4800                 break;
4801             case 0x28: /* ffree sti */
4802                 gen_op_ffree_STN(opreg);
4803                 break;
4804             case 0x2a: /* fst sti */
4805                 gen_op_fmov_STN_ST0(opreg);
4806                 break;
4807             case 0x2b: /* fstp sti */
4808             case 0x0b: /* fstp1 sti, undocumented op */
4809             case 0x3a: /* fstp8 sti, undocumented op */
4810             case 0x3b: /* fstp9 sti, undocumented op */
4811                 gen_op_fmov_STN_ST0(opreg);
4812                 gen_op_fpop();
4813                 break;
4814             case 0x2c: /* fucom st(i) */
4815                 gen_op_fmov_FT0_STN(opreg);
4816                 gen_op_fucom_ST0_FT0();
4817                 break;
4818             case 0x2d: /* fucomp st(i) */
4819                 gen_op_fmov_FT0_STN(opreg);
4820                 gen_op_fucom_ST0_FT0();
4821                 gen_op_fpop();
4822                 break;
4823             case 0x33: /* de/3 */
4824                 switch(rm) {
4825                 case 1: /* fcompp */
4826                     gen_op_fmov_FT0_STN(1);
4827                     gen_op_fcom_ST0_FT0();
4828                     gen_op_fpop();
4829                     gen_op_fpop();
4830                     break;
4831                 default:
4832                     goto illegal_op;
4833                 }
4834                 break;
4835             case 0x38: /* ffreep sti, undocumented op */
4836                 gen_op_ffree_STN(opreg);
4837                 gen_op_fpop();
4838                 break;
4839             case 0x3c: /* df/4 */
4840                 switch(rm) {
4841                 case 0:
4842                     gen_op_fnstsw_EAX();
4843                     break;
4844                 default:
4845                     goto illegal_op;
4846                 }
4847                 break;
4848             case 0x3d: /* fucomip */
4849                 if (s->cc_op != CC_OP_DYNAMIC)
4850                     gen_op_set_cc_op(s->cc_op);
4851                 gen_op_fmov_FT0_STN(opreg);
4852                 gen_op_fucomi_ST0_FT0();
4853                 gen_op_fpop();
4854                 s->cc_op = CC_OP_EFLAGS;
4855                 break;
4856             case 0x3e: /* fcomip */
4857                 if (s->cc_op != CC_OP_DYNAMIC)
4858                     gen_op_set_cc_op(s->cc_op);
4859                 gen_op_fmov_FT0_STN(opreg);
4860                 gen_op_fcomi_ST0_FT0();
4861                 gen_op_fpop();
4862                 s->cc_op = CC_OP_EFLAGS;
4863                 break;
4864             case 0x10 ... 0x13: /* fcmovxx */
4865             case 0x18 ... 0x1b:
4866                 {
4867                     int op1;
4868                     const static uint8_t fcmov_cc[8] = {
4869                         (JCC_B << 1),
4870                         (JCC_Z << 1),
4871                         (JCC_BE << 1),
4872                         (JCC_P << 1),
4873                     };
4874                     op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
4875                     gen_setcc(s, op1);
4876                     gen_op_fcmov_ST0_STN_T0(opreg);
4877                 }
4878                 break;
4879             default:
4880                 goto illegal_op;
4881             }
4882         }
4883         break;
4884         /************************/
4885         /* string ops */
4886
4887     case 0xa4: /* movsS */
4888     case 0xa5:
4889         if ((b & 1) == 0)
4890             ot = OT_BYTE;
4891         else
4892             ot = dflag + OT_WORD;
4893
4894         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4895             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4896         } else {
4897             gen_movs(s, ot);
4898         }
4899         break;
4900
4901     case 0xaa: /* stosS */
4902     case 0xab:
4903         if ((b & 1) == 0)
4904             ot = OT_BYTE;
4905         else
4906             ot = dflag + OT_WORD;
4907
4908         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4909             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4910         } else {
4911             gen_stos(s, ot);
4912         }
4913         break;
4914     case 0xac: /* lodsS */
4915     case 0xad:
4916         if ((b & 1) == 0)
4917             ot = OT_BYTE;
4918         else
4919             ot = dflag + OT_WORD;
4920         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4921             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4922         } else {
4923             gen_lods(s, ot);
4924         }
4925         break;
4926     case 0xae: /* scasS */
4927     case 0xaf:
4928         if ((b & 1) == 0)
4929             ot = OT_BYTE;
4930         else
4931             ot = dflag + OT_WORD;
4932         if (prefixes & PREFIX_REPNZ) {
4933             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4934         } else if (prefixes & PREFIX_REPZ) {
4935             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4936         } else {
4937             gen_scas(s, ot);
4938             s->cc_op = CC_OP_SUBB + ot;
4939         }
4940         break;
4941
4942     case 0xa6: /* cmpsS */
4943     case 0xa7:
4944         if ((b & 1) == 0)
4945             ot = OT_BYTE;
4946         else
4947             ot = dflag + OT_WORD;
4948         if (prefixes & PREFIX_REPNZ) {
4949             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4950         } else if (prefixes & PREFIX_REPZ) {
4951             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4952         } else {
4953             gen_cmps(s, ot);
4954             s->cc_op = CC_OP_SUBB + ot;
4955         }
4956         break;
4957     case 0x6c: /* insS */
4958     case 0x6d:
4959         if ((b & 1) == 0)
4960             ot = OT_BYTE;
4961         else
4962             ot = dflag ? OT_LONG : OT_WORD;
4963         gen_check_io(s, ot, 1, pc_start - s->cs_base);
4964         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
4965         gen_op_andl_T0_ffff();
4966         if (gen_svm_check_io(s, pc_start,
4967                              SVM_IOIO_TYPE_MASK | (1 << (4+ot)) |
4968                              svm_is_rep(prefixes) | 4 | (1 << (7+s->aflag))))
4969             break;
4970         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4971             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4972         } else {
4973             gen_ins(s, ot);
4974         }
4975         break;
4976     case 0x6e: /* outsS */
4977     case 0x6f:
4978         if ((b & 1) == 0)
4979             ot = OT_BYTE;
4980         else
4981             ot = dflag ? OT_LONG : OT_WORD;
4982         gen_check_io(s, ot, 1, pc_start - s->cs_base);
4983         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
4984         gen_op_andl_T0_ffff();
4985         if (gen_svm_check_io(s, pc_start,
4986                              (1 << (4+ot)) | svm_is_rep(prefixes) |
4987                              4 | (1 << (7+s->aflag))))
4988             break;
4989         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4990             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4991         } else {
4992             gen_outs(s, ot);
4993         }
4994         break;
4995
4996         /************************/
4997         /* port I/O */
4998
4999     case 0xe4:
5000     case 0xe5:
5001         if ((b & 1) == 0)
5002             ot = OT_BYTE;
5003         else
5004             ot = dflag ? OT_LONG : OT_WORD;
5005         val = ldub_code(s->pc++);
5006         gen_op_movl_T0_im(val);
5007         gen_check_io(s, ot, 0, pc_start - s->cs_base);
5008         if (gen_svm_check_io(s, pc_start,
5009                              SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
5010                              (1 << (4+ot))))
5011             break;
5012         gen_op_in[ot]();
5013         gen_op_mov_reg_T1(ot, R_EAX);
5014         break;
5015     case 0xe6:
5016     case 0xe7:
5017         if ((b & 1) == 0)
5018             ot = OT_BYTE;
5019         else
5020             ot = dflag ? OT_LONG : OT_WORD;
5021         val = ldub_code(s->pc++);
5022         gen_op_movl_T0_im(val);
5023         gen_check_io(s, ot, 0, pc_start - s->cs_base);
5024         if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) |
5025                              (1 << (4+ot))))
5026             break;
5027         gen_op_mov_TN_reg(ot, 1, R_EAX);
5028         gen_op_out[ot]();
5029         break;
5030     case 0xec:
5031     case 0xed:
5032         if ((b & 1) == 0)
5033             ot = OT_BYTE;
5034         else
5035             ot = dflag ? OT_LONG : OT_WORD;
5036         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5037         gen_op_andl_T0_ffff();
5038         gen_check_io(s, ot, 0, pc_start - s->cs_base);
5039         if (gen_svm_check_io(s, pc_start,
5040                              SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) |
5041                              (1 << (4+ot))))
5042             break;
5043         gen_op_in[ot]();
5044         gen_op_mov_reg_T1(ot, R_EAX);
5045         break;
5046     case 0xee:
5047     case 0xef:
5048         if ((b & 1) == 0)
5049             ot = OT_BYTE;
5050         else
5051             ot = dflag ? OT_LONG : OT_WORD;
5052         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
5053         gen_op_andl_T0_ffff();
5054         gen_check_io(s, ot, 0, pc_start - s->cs_base);
5055         if (gen_svm_check_io(s, pc_start,
5056                              svm_is_rep(prefixes) | (1 << (4+ot))))
5057             break;
5058         gen_op_mov_TN_reg(ot, 1, R_EAX);
5059         gen_op_out[ot]();
5060         break;
5061
5062         /************************/
5063         /* control */
5064     case 0xc2: /* ret im */
5065         val = ldsw_code(s->pc);
5066         s->pc += 2;
5067         gen_pop_T0(s);
5068         if (CODE64(s) && s->dflag)
5069             s->dflag = 2;
5070         gen_stack_update(s, val + (2 << s->dflag));
5071         if (s->dflag == 0)
5072             gen_op_andl_T0_ffff();
5073         gen_op_jmp_T0();
5074         gen_eob(s);
5075         break;
5076     case 0xc3: /* ret */
5077         gen_pop_T0(s);
5078         gen_pop_update(s);
5079         if (s->dflag == 0)
5080             gen_op_andl_T0_ffff();
5081         gen_op_jmp_T0();
5082         gen_eob(s);
5083         break;
5084     case 0xca: /* lret im */
5085         val = ldsw_code(s->pc);
5086         s->pc += 2;
5087     do_lret:
5088         if (s->pe && !s->vm86) {
5089             if (s->cc_op != CC_OP_DYNAMIC)
5090                 gen_op_set_cc_op(s->cc_op);
5091             gen_jmp_im(pc_start - s->cs_base);
5092             gen_op_lret_protected(s->dflag, val);
5093         } else {
5094             gen_stack_A0(s);
5095             /* pop offset */
5096             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5097             if (s->dflag == 0)
5098                 gen_op_andl_T0_ffff();
5099             /* NOTE: keeping EIP updated is not a problem in case of
5100                exception */
5101             gen_op_jmp_T0();
5102             /* pop selector */
5103             gen_op_addl_A0_im(2 << s->dflag);
5104             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
5105             gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
5106             /* add stack offset */
5107             gen_stack_update(s, val + (4 << s->dflag));
5108         }
5109         gen_eob(s);
5110         break;
5111     case 0xcb: /* lret */
5112         val = 0;
5113         goto do_lret;
5114     case 0xcf: /* iret */
5115         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET))
5116             break;
5117         if (!s->pe) {
5118             /* real mode */
5119             gen_op_iret_real(s->dflag);
5120             s->cc_op = CC_OP_EFLAGS;
5121         } else if (s->vm86) {
5122             if (s->iopl != 3) {
5123                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5124             } else {
5125                 gen_op_iret_real(s->dflag);
5126                 s->cc_op = CC_OP_EFLAGS;
5127             }
5128         } else {
5129             if (s->cc_op != CC_OP_DYNAMIC)
5130                 gen_op_set_cc_op(s->cc_op);
5131             gen_jmp_im(pc_start - s->cs_base);
5132             gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
5133             s->cc_op = CC_OP_EFLAGS;
5134         }
5135         gen_eob(s);
5136         break;
5137     case 0xe8: /* call im */
5138         {
5139             if (dflag)
5140                 tval = (int32_t)insn_get(s, OT_LONG);
5141             else
5142                 tval = (int16_t)insn_get(s, OT_WORD);
5143             next_eip = s->pc - s->cs_base;
5144             tval += next_eip;
5145             if (s->dflag == 0)
5146                 tval &= 0xffff;
5147             gen_movtl_T0_im(next_eip);
5148             gen_push_T0(s);
5149             gen_jmp(s, tval);
5150         }
5151         break;
5152     case 0x9a: /* lcall im */
5153         {
5154             unsigned int selector, offset;
5155
5156             if (CODE64(s))
5157                 goto illegal_op;
5158             ot = dflag ? OT_LONG : OT_WORD;
5159             offset = insn_get(s, ot);
5160             selector = insn_get(s, OT_WORD);
5161
5162             gen_op_movl_T0_im(selector);
5163             gen_op_movl_T1_imu(offset);
5164         }
5165         goto do_lcall;
5166     case 0xe9: /* jmp im */
5167         if (dflag)
5168             tval = (int32_t)insn_get(s, OT_LONG);
5169         else
5170             tval = (int16_t)insn_get(s, OT_WORD);
5171         tval += s->pc - s->cs_base;
5172         if (s->dflag == 0)
5173             tval &= 0xffff;
5174         gen_jmp(s, tval);
5175         break;
5176     case 0xea: /* ljmp im */
5177         {
5178             unsigned int selector, offset;
5179
5180             if (CODE64(s))
5181                 goto illegal_op;
5182             ot = dflag ? OT_LONG : OT_WORD;
5183             offset = insn_get(s, ot);
5184             selector = insn_get(s, OT_WORD);
5185
5186             gen_op_movl_T0_im(selector);
5187             gen_op_movl_T1_imu(offset);
5188         }
5189         goto do_ljmp;
5190     case 0xeb: /* jmp Jb */
5191         tval = (int8_t)insn_get(s, OT_BYTE);
5192         tval += s->pc - s->cs_base;
5193         if (s->dflag == 0)
5194             tval &= 0xffff;
5195         gen_jmp(s, tval);
5196         break;
5197     case 0x70 ... 0x7f: /* jcc Jb */
5198         tval = (int8_t)insn_get(s, OT_BYTE);
5199         goto do_jcc;
5200     case 0x180 ... 0x18f: /* jcc Jv */
5201         if (dflag) {
5202             tval = (int32_t)insn_get(s, OT_LONG);
5203         } else {
5204             tval = (int16_t)insn_get(s, OT_WORD);
5205         }
5206     do_jcc:
5207         next_eip = s->pc - s->cs_base;
5208         tval += next_eip;
5209         if (s->dflag == 0)
5210             tval &= 0xffff;
5211         gen_jcc(s, b, tval, next_eip);
5212         break;
5213
5214     case 0x190 ... 0x19f: /* setcc Gv */
5215         modrm = ldub_code(s->pc++);
5216         gen_setcc(s, b);
5217         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
5218         break;
5219     case 0x140 ... 0x14f: /* cmov Gv, Ev */
5220         ot = dflag + OT_WORD;
5221         modrm = ldub_code(s->pc++);
5222         reg = ((modrm >> 3) & 7) | rex_r;
5223         mod = (modrm >> 6) & 3;
5224         gen_setcc(s, b);
5225         if (mod != 3) {
5226             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5227             gen_op_ld_T1_A0(ot + s->mem_index);
5228         } else {
5229             rm = (modrm & 7) | REX_B(s);
5230             gen_op_mov_TN_reg(ot, 1, rm);
5231         }
5232         gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
5233         break;
5234
5235         /************************/
5236         /* flags */
5237     case 0x9c: /* pushf */
5238         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF))
5239             break;
5240         if (s->vm86 && s->iopl != 3) {
5241             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5242         } else {
5243             if (s->cc_op != CC_OP_DYNAMIC)
5244                 gen_op_set_cc_op(s->cc_op);
5245             gen_op_movl_T0_eflags();
5246             gen_push_T0(s);
5247         }
5248         break;
5249     case 0x9d: /* popf */
5250         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF))
5251             break;
5252         if (s->vm86 && s->iopl != 3) {
5253             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5254         } else {
5255             gen_pop_T0(s);
5256             if (s->cpl == 0) {
5257                 if (s->dflag) {
5258                     gen_op_movl_eflags_T0_cpl0();
5259                 } else {
5260                     gen_op_movw_eflags_T0_cpl0();
5261                 }
5262             } else {
5263                 if (s->cpl <= s->iopl) {
5264                     if (s->dflag) {
5265                         gen_op_movl_eflags_T0_io();
5266                     } else {
5267                         gen_op_movw_eflags_T0_io();
5268                     }
5269                 } else {
5270                     if (s->dflag) {
5271                         gen_op_movl_eflags_T0();
5272                     } else {
5273                         gen_op_movw_eflags_T0();
5274                     }
5275                 }
5276             }
5277             gen_pop_update(s);
5278             s->cc_op = CC_OP_EFLAGS;
5279             /* abort translation because TF flag may change */
5280             gen_jmp_im(s->pc - s->cs_base);
5281             gen_eob(s);
5282         }
5283         break;
5284     case 0x9e: /* sahf */
5285         if (CODE64(s))
5286             goto illegal_op;
5287         gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5288         if (s->cc_op != CC_OP_DYNAMIC)
5289             gen_op_set_cc_op(s->cc_op);
5290         gen_op_movb_eflags_T0();
5291         s->cc_op = CC_OP_EFLAGS;
5292         break;
5293     case 0x9f: /* lahf */
5294         if (CODE64(s))
5295             goto illegal_op;
5296         if (s->cc_op != CC_OP_DYNAMIC)
5297             gen_op_set_cc_op(s->cc_op);
5298         gen_op_movl_T0_eflags();
5299         gen_op_mov_reg_T0(OT_BYTE, R_AH);
5300         break;
5301     case 0xf5: /* cmc */
5302         if (s->cc_op != CC_OP_DYNAMIC)
5303             gen_op_set_cc_op(s->cc_op);
5304         gen_op_cmc();
5305         s->cc_op = CC_OP_EFLAGS;
5306         break;
5307     case 0xf8: /* clc */
5308         if (s->cc_op != CC_OP_DYNAMIC)
5309             gen_op_set_cc_op(s->cc_op);
5310         gen_op_clc();
5311         s->cc_op = CC_OP_EFLAGS;
5312         break;
5313     case 0xf9: /* stc */
5314         if (s->cc_op != CC_OP_DYNAMIC)
5315             gen_op_set_cc_op(s->cc_op);
5316         gen_op_stc();
5317         s->cc_op = CC_OP_EFLAGS;
5318         break;
5319     case 0xfc: /* cld */
5320         gen_op_cld();
5321         break;
5322     case 0xfd: /* std */
5323         gen_op_std();
5324         break;
5325
5326         /************************/
5327         /* bit operations */
5328     case 0x1ba: /* bt/bts/btr/btc Gv, im */
5329         ot = dflag + OT_WORD;
5330         modrm = ldub_code(s->pc++);
5331         op = (modrm >> 3) & 7;
5332         mod = (modrm >> 6) & 3;
5333         rm = (modrm & 7) | REX_B(s);
5334         if (mod != 3) {
5335             s->rip_offset = 1;
5336             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5337             gen_op_ld_T0_A0(ot + s->mem_index);
5338         } else {
5339             gen_op_mov_TN_reg(ot, 0, rm);
5340         }
5341         /* load shift */
5342         val = ldub_code(s->pc++);
5343         gen_op_movl_T1_im(val);
5344         if (op < 4)
5345             goto illegal_op;
5346         op -= 4;
5347         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5348         s->cc_op = CC_OP_SARB + ot;
5349         if (op != 0) {
5350             if (mod != 3)
5351                 gen_op_st_T0_A0(ot + s->mem_index);
5352             else
5353                 gen_op_mov_reg_T0(ot, rm);
5354             gen_op_update_bt_cc();
5355         }
5356         break;
5357     case 0x1a3: /* bt Gv, Ev */
5358         op = 0;
5359         goto do_btx;
5360     case 0x1ab: /* bts */
5361         op = 1;
5362         goto do_btx;
5363     case 0x1b3: /* btr */
5364         op = 2;
5365         goto do_btx;
5366     case 0x1bb: /* btc */
5367         op = 3;
5368     do_btx:
5369         ot = dflag + OT_WORD;
5370         modrm = ldub_code(s->pc++);
5371         reg = ((modrm >> 3) & 7) | rex_r;
5372         mod = (modrm >> 6) & 3;
5373         rm = (modrm & 7) | REX_B(s);
5374         gen_op_mov_TN_reg(OT_LONG, 1, reg);
5375         if (mod != 3) {
5376             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5377             /* specific case: we need to add a displacement */
5378             gen_op_add_bit_A0_T1[ot - OT_WORD]();
5379             gen_op_ld_T0_A0(ot + s->mem_index);
5380         } else {
5381             gen_op_mov_TN_reg(ot, 0, rm);
5382         }
5383         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5384         s->cc_op = CC_OP_SARB + ot;
5385         if (op != 0) {
5386             if (mod != 3)
5387                 gen_op_st_T0_A0(ot + s->mem_index);
5388             else
5389                 gen_op_mov_reg_T0(ot, rm);
5390             gen_op_update_bt_cc();
5391         }
5392         break;
5393     case 0x1bc: /* bsf */
5394     case 0x1bd: /* bsr */
5395         ot = dflag + OT_WORD;
5396         modrm = ldub_code(s->pc++);
5397         reg = ((modrm >> 3) & 7) | rex_r;
5398         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5399         /* NOTE: in order to handle the 0 case, we must load the
5400            result. It could be optimized with a generated jump */
5401         gen_op_mov_TN_reg(ot, 1, reg);
5402         gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
5403         gen_op_mov_reg_T1(ot, reg);
5404         s->cc_op = CC_OP_LOGICB + ot;
5405         break;
5406         /************************/
5407         /* bcd */
5408     case 0x27: /* daa */
5409         if (CODE64(s))
5410             goto illegal_op;
5411         if (s->cc_op != CC_OP_DYNAMIC)
5412             gen_op_set_cc_op(s->cc_op);
5413         gen_op_daa();
5414         s->cc_op = CC_OP_EFLAGS;
5415         break;
5416     case 0x2f: /* das */
5417         if (CODE64(s))
5418             goto illegal_op;
5419         if (s->cc_op != CC_OP_DYNAMIC)
5420             gen_op_set_cc_op(s->cc_op);
5421         gen_op_das();
5422         s->cc_op = CC_OP_EFLAGS;
5423         break;
5424     case 0x37: /* aaa */
5425         if (CODE64(s))
5426             goto illegal_op;
5427         if (s->cc_op != CC_OP_DYNAMIC)
5428             gen_op_set_cc_op(s->cc_op);
5429         gen_op_aaa();
5430         s->cc_op = CC_OP_EFLAGS;
5431         break;
5432     case 0x3f: /* aas */
5433         if (CODE64(s))
5434             goto illegal_op;
5435         if (s->cc_op != CC_OP_DYNAMIC)
5436             gen_op_set_cc_op(s->cc_op);
5437         gen_op_aas();
5438         s->cc_op = CC_OP_EFLAGS;
5439         break;
5440     case 0xd4: /* aam */
5441         if (CODE64(s))
5442             goto illegal_op;
5443         val = ldub_code(s->pc++);
5444         if (val == 0) {
5445             gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
5446         } else {
5447             gen_op_aam(val);
5448             s->cc_op = CC_OP_LOGICB;
5449         }
5450         break;
5451     case 0xd5: /* aad */
5452         if (CODE64(s))
5453             goto illegal_op;
5454         val = ldub_code(s->pc++);
5455         gen_op_aad(val);
5456         s->cc_op = CC_OP_LOGICB;
5457         break;
5458         /************************/
5459         /* misc */
5460     case 0x90: /* nop */
5461         /* XXX: xchg + rex handling */
5462         /* XXX: correct lock test for all insn */
5463         if (prefixes & PREFIX_LOCK)
5464             goto illegal_op;
5465         if (prefixes & PREFIX_REPZ) {
5466             gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
5467         }
5468         break;
5469     case 0x9b: /* fwait */
5470         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
5471             (HF_MP_MASK | HF_TS_MASK)) {
5472             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5473         } else {
5474             if (s->cc_op != CC_OP_DYNAMIC)
5475                 gen_op_set_cc_op(s->cc_op);
5476             gen_jmp_im(pc_start - s->cs_base);
5477             gen_op_fwait();
5478         }
5479         break;
5480     case 0xcc: /* int3 */
5481         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
5482             break;
5483         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
5484         break;
5485     case 0xcd: /* int N */
5486         val = ldub_code(s->pc++);
5487         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
5488             break;
5489         if (s->vm86 && s->iopl != 3) {
5490             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5491         } else {
5492             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
5493         }
5494         break;
5495     case 0xce: /* into */
5496         if (CODE64(s))
5497             goto illegal_op;
5498         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT))
5499             break;
5500         if (s->cc_op != CC_OP_DYNAMIC)
5501             gen_op_set_cc_op(s->cc_op);
5502         gen_jmp_im(pc_start - s->cs_base);
5503         gen_op_into(s->pc - pc_start);
5504         break;
5505     case 0xf1: /* icebp (undocumented, exits to external debugger) */
5506         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP))
5507             break;
5508 #if 1
5509         gen_debug(s, pc_start - s->cs_base);
5510 #else
5511         /* start debug */
5512         tb_flush(cpu_single_env);
5513         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
5514 #endif
5515         break;
5516     case 0xfa: /* cli */
5517         if (!s->vm86) {
5518             if (s->cpl <= s->iopl) {
5519                 gen_op_cli();
5520             } else {
5521                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5522             }
5523         } else {
5524             if (s->iopl == 3) {
5525                 gen_op_cli();
5526             } else {
5527                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5528             }
5529         }
5530         break;
5531     case 0xfb: /* sti */
5532         if (!s->vm86) {
5533             if (s->cpl <= s->iopl) {
5534             gen_sti:
5535                 gen_op_sti();
5536                 /* interruptions are enabled only the first insn after sti */
5537                 /* If several instructions disable interrupts, only the
5538                    _first_ does it */
5539                 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5540                     gen_op_set_inhibit_irq();
5541                 /* give a chance to handle pending irqs */
5542                 gen_jmp_im(s->pc - s->cs_base);
5543                 gen_eob(s);
5544             } else {
5545                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5546             }
5547         } else {
5548             if (s->iopl == 3) {
5549                 goto gen_sti;
5550             } else {
5551                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5552             }
5553         }
5554         break;
5555     case 0x62: /* bound */
5556         if (CODE64(s))
5557             goto illegal_op;
5558         ot = dflag ? OT_LONG : OT_WORD;
5559         modrm = ldub_code(s->pc++);
5560         reg = (modrm >> 3) & 7;
5561         mod = (modrm >> 6) & 3;
5562         if (mod == 3)
5563             goto illegal_op;
5564         gen_op_mov_TN_reg(ot, 0, reg);
5565         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5566         gen_jmp_im(pc_start - s->cs_base);
5567         if (ot == OT_WORD)
5568             gen_op_boundw();
5569         else
5570             gen_op_boundl();
5571         break;
5572     case 0x1c8 ... 0x1cf: /* bswap reg */
5573         reg = (b & 7) | REX_B(s);
5574 #ifdef TARGET_X86_64
5575         if (dflag == 2) {
5576             gen_op_mov_TN_reg(OT_QUAD, 0, reg);
5577             tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
5578             gen_op_mov_reg_T0(OT_QUAD, reg);
5579         } else
5580         {
5581             TCGv tmp0;
5582             gen_op_mov_TN_reg(OT_LONG, 0, reg);
5583             
5584             tmp0 = tcg_temp_new(TCG_TYPE_I32);
5585             tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
5586             tcg_gen_bswap_i32(tmp0, tmp0);
5587             tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
5588             gen_op_mov_reg_T0(OT_LONG, reg);
5589         }
5590 #else
5591         {
5592             gen_op_mov_TN_reg(OT_LONG, 0, reg);
5593             tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
5594             gen_op_mov_reg_T0(OT_LONG, reg);
5595         }
5596 #endif
5597         break;
5598     case 0xd6: /* salc */
5599         if (CODE64(s))
5600             goto illegal_op;
5601         if (s->cc_op != CC_OP_DYNAMIC)
5602             gen_op_set_cc_op(s->cc_op);
5603         gen_op_salc();
5604         break;
5605     case 0xe0: /* loopnz */
5606     case 0xe1: /* loopz */
5607         if (s->cc_op != CC_OP_DYNAMIC)
5608             gen_op_set_cc_op(s->cc_op);
5609         /* FALL THRU */
5610     case 0xe2: /* loop */
5611     case 0xe3: /* jecxz */
5612         {
5613             int l1, l2;
5614
5615             tval = (int8_t)insn_get(s, OT_BYTE);
5616             next_eip = s->pc - s->cs_base;
5617             tval += next_eip;
5618             if (s->dflag == 0)
5619                 tval &= 0xffff;
5620
5621             l1 = gen_new_label();
5622             l2 = gen_new_label();
5623             b &= 3;
5624             if (b == 3) {
5625                 gen_op_jz_ecx[s->aflag](l1);
5626             } else {
5627                 gen_op_dec_ECX[s->aflag]();
5628                 if (b <= 1)
5629                     gen_op_mov_T0_cc();
5630                 gen_op_loop[s->aflag][b](l1);
5631             }
5632
5633             gen_jmp_im(next_eip);
5634             gen_op_jmp_label(l2);
5635             gen_set_label(l1);
5636             gen_jmp_im(tval);
5637             gen_set_label(l2);
5638             gen_eob(s);
5639         }
5640         break;
5641     case 0x130: /* wrmsr */
5642     case 0x132: /* rdmsr */
5643         if (s->cpl != 0) {
5644             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5645         } else {
5646             int retval = 0;
5647             if (b & 2) {
5648                 retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 0);
5649                 gen_op_rdmsr();
5650             } else {
5651                 retval = gen_svm_check_intercept_param(s, pc_start, SVM_EXIT_MSR, 1);
5652                 gen_op_wrmsr();
5653             }
5654             if(retval)
5655                 gen_eob(s);
5656         }
5657         break;
5658     case 0x131: /* rdtsc */
5659         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RDTSC))
5660             break;
5661         gen_jmp_im(pc_start - s->cs_base);
5662         gen_op_rdtsc();
5663         break;
5664     case 0x133: /* rdpmc */
5665         gen_jmp_im(pc_start - s->cs_base);
5666         gen_op_rdpmc();
5667         break;
5668     case 0x134: /* sysenter */
5669         if (CODE64(s))
5670             goto illegal_op;
5671         if (!s->pe) {
5672             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5673         } else {
5674             if (s->cc_op != CC_OP_DYNAMIC) {
5675                 gen_op_set_cc_op(s->cc_op);
5676                 s->cc_op = CC_OP_DYNAMIC;
5677             }
5678             gen_jmp_im(pc_start - s->cs_base);
5679             gen_op_sysenter();
5680             gen_eob(s);
5681         }
5682         break;
5683     case 0x135: /* sysexit */
5684         if (CODE64(s))
5685             goto illegal_op;
5686         if (!s->pe) {
5687             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5688         } else {
5689             if (s->cc_op != CC_OP_DYNAMIC) {
5690                 gen_op_set_cc_op(s->cc_op);
5691                 s->cc_op = CC_OP_DYNAMIC;
5692             }
5693             gen_jmp_im(pc_start - s->cs_base);
5694             gen_op_sysexit();
5695             gen_eob(s);
5696         }
5697         break;
5698 #ifdef TARGET_X86_64
5699     case 0x105: /* syscall */
5700         /* XXX: is it usable in real mode ? */
5701         if (s->cc_op != CC_OP_DYNAMIC) {
5702             gen_op_set_cc_op(s->cc_op);
5703             s->cc_op = CC_OP_DYNAMIC;
5704         }
5705         gen_jmp_im(pc_start - s->cs_base);
5706         gen_op_syscall(s->pc - pc_start);
5707         gen_eob(s);
5708         break;
5709     case 0x107: /* sysret */
5710         if (!s->pe) {
5711             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5712         } else {
5713             if (s->cc_op != CC_OP_DYNAMIC) {
5714                 gen_op_set_cc_op(s->cc_op);
5715                 s->cc_op = CC_OP_DYNAMIC;
5716             }
5717             gen_jmp_im(pc_start - s->cs_base);
5718             gen_op_sysret(s->dflag);
5719             /* condition codes are modified only in long mode */
5720             if (s->lma)
5721                 s->cc_op = CC_OP_EFLAGS;
5722             gen_eob(s);
5723         }
5724         break;
5725 #endif
5726     case 0x1a2: /* cpuid */
5727         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CPUID))
5728             break;
5729         gen_op_cpuid();
5730         break;
5731     case 0xf4: /* hlt */
5732         if (s->cpl != 0) {
5733             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5734         } else {
5735             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_HLT))
5736                 break;
5737             if (s->cc_op != CC_OP_DYNAMIC)
5738                 gen_op_set_cc_op(s->cc_op);
5739             gen_jmp_im(s->pc - s->cs_base);
5740             gen_op_hlt();
5741             s->is_jmp = 3;
5742         }
5743         break;
5744     case 0x100:
5745         modrm = ldub_code(s->pc++);
5746         mod = (modrm >> 6) & 3;
5747         op = (modrm >> 3) & 7;
5748         switch(op) {
5749         case 0: /* sldt */
5750             if (!s->pe || s->vm86)
5751                 goto illegal_op;
5752             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ))
5753                 break;
5754             gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
5755             ot = OT_WORD;
5756             if (mod == 3)
5757                 ot += s->dflag;
5758             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5759             break;
5760         case 2: /* lldt */
5761             if (!s->pe || s->vm86)
5762                 goto illegal_op;
5763             if (s->cpl != 0) {
5764                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5765             } else {
5766                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE))
5767                     break;
5768                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5769                 gen_jmp_im(pc_start - s->cs_base);
5770                 gen_op_lldt_T0();
5771             }
5772             break;
5773         case 1: /* str */
5774             if (!s->pe || s->vm86)
5775                 goto illegal_op;
5776             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ))
5777                 break;
5778             gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
5779             ot = OT_WORD;
5780             if (mod == 3)
5781                 ot += s->dflag;
5782             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5783             break;
5784         case 3: /* ltr */
5785             if (!s->pe || s->vm86)
5786                 goto illegal_op;
5787             if (s->cpl != 0) {
5788                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5789             } else {
5790                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE))
5791                     break;
5792                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5793                 gen_jmp_im(pc_start - s->cs_base);
5794                 gen_op_ltr_T0();
5795             }
5796             break;
5797         case 4: /* verr */
5798         case 5: /* verw */
5799             if (!s->pe || s->vm86)
5800                 goto illegal_op;
5801             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5802             if (s->cc_op != CC_OP_DYNAMIC)
5803                 gen_op_set_cc_op(s->cc_op);
5804             if (op == 4)
5805                 gen_op_verr();
5806             else
5807                 gen_op_verw();
5808             s->cc_op = CC_OP_EFLAGS;
5809             break;
5810         default:
5811             goto illegal_op;
5812         }
5813         break;
5814     case 0x101:
5815         modrm = ldub_code(s->pc++);
5816         mod = (modrm >> 6) & 3;
5817         op = (modrm >> 3) & 7;
5818         rm = modrm & 7;
5819         switch(op) {
5820         case 0: /* sgdt */
5821             if (mod == 3)
5822                 goto illegal_op;
5823             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ))
5824                 break;
5825             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5826             gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit));
5827             gen_op_st_T0_A0(OT_WORD + s->mem_index);
5828             gen_add_A0_im(s, 2);
5829             gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base));
5830             if (!s->dflag)
5831                 gen_op_andl_T0_im(0xffffff);
5832             gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
5833             break;
5834         case 1:
5835             if (mod == 3) {
5836                 switch (rm) {
5837                 case 0: /* monitor */
5838                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
5839                         s->cpl != 0)
5840                         goto illegal_op;
5841                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MONITOR))
5842                         break;
5843                     gen_jmp_im(pc_start - s->cs_base);
5844 #ifdef TARGET_X86_64
5845                     if (s->aflag == 2) {
5846                         gen_op_movq_A0_reg(R_EBX);
5847                         gen_op_addq_A0_AL();
5848                     } else
5849 #endif
5850                     {
5851                         gen_op_movl_A0_reg(R_EBX);
5852                         gen_op_addl_A0_AL();
5853                         if (s->aflag == 0)
5854                             gen_op_andl_A0_ffff();
5855                     }
5856                     gen_add_A0_ds_seg(s);
5857                     gen_op_monitor();
5858                     break;
5859                 case 1: /* mwait */
5860                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
5861                         s->cpl != 0)
5862                         goto illegal_op;
5863                     if (s->cc_op != CC_OP_DYNAMIC) {
5864                         gen_op_set_cc_op(s->cc_op);
5865                         s->cc_op = CC_OP_DYNAMIC;
5866                     }
5867                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_MWAIT))
5868                         break;
5869                     gen_jmp_im(s->pc - s->cs_base);
5870                     gen_op_mwait();
5871                     gen_eob(s);
5872                     break;
5873                 default:
5874                     goto illegal_op;
5875                 }
5876             } else { /* sidt */
5877                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ))
5878                     break;
5879                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5880                 gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit));
5881                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
5882                 gen_add_A0_im(s, 2);
5883                 gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base));
5884                 if (!s->dflag)
5885                     gen_op_andl_T0_im(0xffffff);
5886                 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
5887             }
5888             break;
5889         case 2: /* lgdt */
5890         case 3: /* lidt */
5891             if (mod == 3) {
5892                 switch(rm) {
5893                 case 0: /* VMRUN */
5894                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMRUN))
5895                         break;
5896                     if (s->cc_op != CC_OP_DYNAMIC)
5897                         gen_op_set_cc_op(s->cc_op);
5898                     gen_jmp_im(s->pc - s->cs_base);
5899                     gen_op_vmrun();
5900                     s->cc_op = CC_OP_EFLAGS;
5901                     gen_eob(s);
5902                     break;
5903                 case 1: /* VMMCALL */
5904                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMMCALL))
5905                          break;
5906                     /* FIXME: cause #UD if hflags & SVM */
5907                     gen_op_vmmcall();
5908                     break;
5909                 case 2: /* VMLOAD */
5910                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMLOAD))
5911                          break;
5912                     gen_op_vmload();
5913                     break;
5914                 case 3: /* VMSAVE */
5915                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_VMSAVE))
5916                          break;
5917                     gen_op_vmsave();
5918                     break;
5919                 case 4: /* STGI */
5920                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_STGI))
5921                          break;
5922                     gen_op_stgi();
5923                     break;
5924                 case 5: /* CLGI */
5925                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_CLGI))
5926                          break;
5927                     gen_op_clgi();
5928                     break;
5929                 case 6: /* SKINIT */
5930                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT))
5931                          break;
5932                     gen_op_skinit();
5933                     break;
5934                 case 7: /* INVLPGA */
5935                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPGA))
5936                          break;
5937                     gen_op_invlpga();
5938                     break;
5939                 default:
5940                     goto illegal_op;
5941                 }
5942             } else if (s->cpl != 0) {
5943                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5944             } else {
5945                 if (gen_svm_check_intercept(s, pc_start,
5946                                             op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE))
5947                     break;
5948                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5949                 gen_op_ld_T1_A0(OT_WORD + s->mem_index);
5950                 gen_add_A0_im(s, 2);
5951                 gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
5952                 if (!s->dflag)
5953                     gen_op_andl_T0_im(0xffffff);
5954                 if (op == 2) {
5955                     gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
5956                     gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
5957                 } else {
5958                     gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
5959                     gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
5960                 }
5961             }
5962             break;
5963         case 4: /* smsw */
5964             if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0))
5965                 break;
5966             gen_op_movl_T0_env(offsetof(CPUX86State,cr[0]));
5967             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
5968             break;
5969         case 6: /* lmsw */
5970             if (s->cpl != 0) {
5971                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5972             } else {
5973                 if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0))
5974                     break;
5975                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5976                 gen_op_lmsw_T0();
5977                 gen_jmp_im(s->pc - s->cs_base);
5978                 gen_eob(s);
5979             }
5980             break;
5981         case 7: /* invlpg */
5982             if (s->cpl != 0) {
5983                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5984             } else {
5985                 if (mod == 3) {
5986 #ifdef TARGET_X86_64
5987                     if (CODE64(s) && rm == 0) {
5988                         /* swapgs */
5989                         gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
5990                         gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
5991                         gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
5992                         gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
5993                     } else
5994 #endif
5995                     {
5996                         goto illegal_op;
5997                     }
5998                 } else {
5999                     if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_INVLPG))
6000                         break;
6001                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6002                     gen_op_invlpg_A0();
6003                     gen_jmp_im(s->pc - s->cs_base);
6004                     gen_eob(s);
6005                 }
6006             }
6007             break;
6008         default:
6009             goto illegal_op;
6010         }
6011         break;
6012     case 0x108: /* invd */
6013     case 0x109: /* wbinvd */
6014         if (s->cpl != 0) {
6015             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6016         } else {
6017             if (gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD))
6018                 break;
6019             /* nothing to do */
6020         }
6021         break;
6022     case 0x63: /* arpl or movslS (x86_64) */
6023 #ifdef TARGET_X86_64
6024         if (CODE64(s)) {
6025             int d_ot;
6026             /* d_ot is the size of destination */
6027             d_ot = dflag + OT_WORD;
6028
6029             modrm = ldub_code(s->pc++);
6030             reg = ((modrm >> 3) & 7) | rex_r;
6031             mod = (modrm >> 6) & 3;
6032             rm = (modrm & 7) | REX_B(s);
6033
6034             if (mod == 3) {
6035                 gen_op_mov_TN_reg(OT_LONG, 0, rm);
6036                 /* sign extend */
6037                 if (d_ot == OT_QUAD)
6038                     gen_op_movslq_T0_T0();
6039                 gen_op_mov_reg_T0(d_ot, reg);
6040             } else {
6041                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6042                 if (d_ot == OT_QUAD) {
6043                     gen_op_lds_T0_A0(OT_LONG + s->mem_index);
6044                 } else {
6045                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6046                 }
6047                 gen_op_mov_reg_T0(d_ot, reg);
6048             }
6049         } else
6050 #endif
6051         {
6052             if (!s->pe || s->vm86)
6053                 goto illegal_op;
6054             ot = dflag ? OT_LONG : OT_WORD;
6055             modrm = ldub_code(s->pc++);
6056             reg = (modrm >> 3) & 7;
6057             mod = (modrm >> 6) & 3;
6058             rm = modrm & 7;
6059             if (mod != 3) {
6060                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6061                 gen_op_ld_T0_A0(ot + s->mem_index);
6062             } else {
6063                 gen_op_mov_TN_reg(ot, 0, rm);
6064             }
6065             if (s->cc_op != CC_OP_DYNAMIC)
6066                 gen_op_set_cc_op(s->cc_op);
6067             gen_op_arpl();
6068             s->cc_op = CC_OP_EFLAGS;
6069             if (mod != 3) {
6070                 gen_op_st_T0_A0(ot + s->mem_index);
6071             } else {
6072                 gen_op_mov_reg_T0(ot, rm);
6073             }
6074             gen_op_arpl_update();
6075         }
6076         break;
6077     case 0x102: /* lar */
6078     case 0x103: /* lsl */
6079         if (!s->pe || s->vm86)
6080             goto illegal_op;
6081         ot = dflag ? OT_LONG : OT_WORD;
6082         modrm = ldub_code(s->pc++);
6083         reg = ((modrm >> 3) & 7) | rex_r;
6084         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
6085         gen_op_mov_TN_reg(ot, 1, reg);
6086         if (s->cc_op != CC_OP_DYNAMIC)
6087             gen_op_set_cc_op(s->cc_op);
6088         if (b == 0x102)
6089             gen_op_lar();
6090         else
6091             gen_op_lsl();
6092         s->cc_op = CC_OP_EFLAGS;
6093         gen_op_mov_reg_T1(ot, reg);
6094         break;
6095     case 0x118:
6096         modrm = ldub_code(s->pc++);
6097         mod = (modrm >> 6) & 3;
6098         op = (modrm >> 3) & 7;
6099         switch(op) {
6100         case 0: /* prefetchnta */
6101         case 1: /* prefetchnt0 */
6102         case 2: /* prefetchnt0 */
6103         case 3: /* prefetchnt0 */
6104             if (mod == 3)
6105                 goto illegal_op;
6106             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6107             /* nothing more to do */
6108             break;
6109         default: /* nop (multi byte) */
6110             gen_nop_modrm(s, modrm);
6111             break;
6112         }
6113         break;
6114     case 0x119 ... 0x11f: /* nop (multi byte) */
6115         modrm = ldub_code(s->pc++);
6116         gen_nop_modrm(s, modrm);
6117         break;
6118     case 0x120: /* mov reg, crN */
6119     case 0x122: /* mov crN, reg */
6120         if (s->cpl != 0) {
6121             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6122         } else {
6123             modrm = ldub_code(s->pc++);
6124             if ((modrm & 0xc0) != 0xc0)
6125                 goto illegal_op;
6126             rm = (modrm & 7) | REX_B(s);
6127             reg = ((modrm >> 3) & 7) | rex_r;
6128             if (CODE64(s))
6129                 ot = OT_QUAD;
6130             else
6131                 ot = OT_LONG;
6132             switch(reg) {
6133             case 0:
6134             case 2:
6135             case 3:
6136             case 4:
6137             case 8:
6138                 if (b & 2) {
6139                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
6140                     gen_op_mov_TN_reg(ot, 0, rm);
6141                     gen_op_movl_crN_T0(reg);
6142                     gen_jmp_im(s->pc - s->cs_base);
6143                     gen_eob(s);
6144                 } else {
6145                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0 + reg);
6146 #if !defined(CONFIG_USER_ONLY)
6147                     if (reg == 8)
6148                         gen_op_movtl_T0_cr8();
6149                     else
6150 #endif
6151                         gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
6152                     gen_op_mov_reg_T0(ot, rm);
6153                 }
6154                 break;
6155             default:
6156                 goto illegal_op;
6157             }
6158         }
6159         break;
6160     case 0x121: /* mov reg, drN */
6161     case 0x123: /* mov drN, reg */
6162         if (s->cpl != 0) {
6163             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6164         } else {
6165             modrm = ldub_code(s->pc++);
6166             if ((modrm & 0xc0) != 0xc0)
6167                 goto illegal_op;
6168             rm = (modrm & 7) | REX_B(s);
6169             reg = ((modrm >> 3) & 7) | rex_r;
6170             if (CODE64(s))
6171                 ot = OT_QUAD;
6172             else
6173                 ot = OT_LONG;
6174             /* XXX: do it dynamically with CR4.DE bit */
6175             if (reg == 4 || reg == 5 || reg >= 8)
6176                 goto illegal_op;
6177             if (b & 2) {
6178                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
6179                 gen_op_mov_TN_reg(ot, 0, rm);
6180                 gen_op_movl_drN_T0(reg);
6181                 gen_jmp_im(s->pc - s->cs_base);
6182                 gen_eob(s);
6183             } else {
6184                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
6185                 gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
6186                 gen_op_mov_reg_T0(ot, rm);
6187             }
6188         }
6189         break;
6190     case 0x106: /* clts */
6191         if (s->cpl != 0) {
6192             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6193         } else {
6194             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
6195             gen_op_clts();
6196             /* abort block because static cpu state changed */
6197             gen_jmp_im(s->pc - s->cs_base);
6198             gen_eob(s);
6199         }
6200         break;
6201     /* MMX/3DNow!/SSE/SSE2/SSE3 support */
6202     case 0x1c3: /* MOVNTI reg, mem */
6203         if (!(s->cpuid_features & CPUID_SSE2))
6204             goto illegal_op;
6205         ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
6206         modrm = ldub_code(s->pc++);
6207         mod = (modrm >> 6) & 3;
6208         if (mod == 3)
6209             goto illegal_op;
6210         reg = ((modrm >> 3) & 7) | rex_r;
6211         /* generate a generic store */
6212         gen_ldst_modrm(s, modrm, ot, reg, 1);
6213         break;
6214     case 0x1ae:
6215         modrm = ldub_code(s->pc++);
6216         mod = (modrm >> 6) & 3;
6217         op = (modrm >> 3) & 7;
6218         switch(op) {
6219         case 0: /* fxsave */
6220             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6221                 (s->flags & HF_EM_MASK))
6222                 goto illegal_op;
6223             if (s->flags & HF_TS_MASK) {
6224                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6225                 break;
6226             }
6227             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6228             gen_op_fxsave_A0((s->dflag == 2));
6229             break;
6230         case 1: /* fxrstor */
6231             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
6232                 (s->flags & HF_EM_MASK))
6233                 goto illegal_op;
6234             if (s->flags & HF_TS_MASK) {
6235                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6236                 break;
6237             }
6238             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6239             gen_op_fxrstor_A0((s->dflag == 2));
6240             break;
6241         case 2: /* ldmxcsr */
6242         case 3: /* stmxcsr */
6243             if (s->flags & HF_TS_MASK) {
6244                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
6245                 break;
6246             }
6247             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
6248                 mod == 3)
6249                 goto illegal_op;
6250             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6251             if (op == 2) {
6252                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
6253                 gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
6254             } else {
6255                 gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
6256                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
6257             }
6258             break;
6259         case 5: /* lfence */
6260         case 6: /* mfence */
6261             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
6262                 goto illegal_op;
6263             break;
6264         case 7: /* sfence / clflush */
6265             if ((modrm & 0xc7) == 0xc0) {
6266                 /* sfence */
6267                 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
6268                 if (!(s->cpuid_features & CPUID_SSE))
6269                     goto illegal_op;
6270             } else {
6271                 /* clflush */
6272                 if (!(s->cpuid_features & CPUID_CLFLUSH))
6273                     goto illegal_op;
6274                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6275             }
6276             break;
6277         default:
6278             goto illegal_op;
6279         }
6280         break;
6281     case 0x10d: /* 3DNow! prefetch(w) */
6282         modrm = ldub_code(s->pc++);
6283         mod = (modrm >> 6) & 3;
6284         if (mod == 3)
6285             goto illegal_op;
6286         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
6287         /* ignore for now */
6288         break;
6289     case 0x1aa: /* rsm */
6290         if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM))
6291             break;
6292         if (!(s->flags & HF_SMM_MASK))
6293             goto illegal_op;
6294         if (s->cc_op != CC_OP_DYNAMIC) {
6295             gen_op_set_cc_op(s->cc_op);
6296             s->cc_op = CC_OP_DYNAMIC;
6297         }
6298         gen_jmp_im(s->pc - s->cs_base);
6299         gen_op_rsm();
6300         gen_eob(s);
6301         break;
6302     case 0x10e ... 0x10f:
6303         /* 3DNow! instructions, ignore prefixes */
6304         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
6305     case 0x110 ... 0x117:
6306     case 0x128 ... 0x12f:
6307     case 0x150 ... 0x177:
6308     case 0x17c ... 0x17f:
6309     case 0x1c2:
6310     case 0x1c4 ... 0x1c6:
6311     case 0x1d0 ... 0x1fe:
6312         gen_sse(s, b, pc_start, rex_r);
6313         break;
6314     default:
6315         goto illegal_op;
6316     }
6317     /* lock generation */
6318     if (s->prefix & PREFIX_LOCK)
6319         gen_op_unlock();
6320     return s->pc;
6321  illegal_op:
6322     if (s->prefix & PREFIX_LOCK)
6323         gen_op_unlock();
6324     /* XXX: ensure that no lock was generated */
6325     gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
6326     return s->pc;
6327 }
6328
6329 #define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
6330 #define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
6331
6332 /* flags read by an operation */
6333 static uint16_t opc_read_flags[NB_OPS] = {
6334     [INDEX_op_aas] = CC_A,
6335     [INDEX_op_aaa] = CC_A,
6336     [INDEX_op_das] = CC_A | CC_C,
6337     [INDEX_op_daa] = CC_A | CC_C,
6338
6339     /* subtle: due to the incl/decl implementation, C is used */
6340     [INDEX_op_update_inc_cc] = CC_C,
6341
6342     [INDEX_op_into] = CC_O,
6343
6344     [INDEX_op_jb_subb] = CC_C,
6345     [INDEX_op_jb_subw] = CC_C,
6346     [INDEX_op_jb_subl] = CC_C,
6347
6348     [INDEX_op_jz_subb] = CC_Z,
6349     [INDEX_op_jz_subw] = CC_Z,
6350     [INDEX_op_jz_subl] = CC_Z,
6351
6352     [INDEX_op_jbe_subb] = CC_Z | CC_C,
6353     [INDEX_op_jbe_subw] = CC_Z | CC_C,
6354     [INDEX_op_jbe_subl] = CC_Z | CC_C,
6355
6356     [INDEX_op_js_subb] = CC_S,
6357     [INDEX_op_js_subw] = CC_S,
6358     [INDEX_op_js_subl] = CC_S,
6359
6360     [INDEX_op_jl_subb] = CC_O | CC_S,
6361     [INDEX_op_jl_subw] = CC_O | CC_S,
6362     [INDEX_op_jl_subl] = CC_O | CC_S,
6363
6364     [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
6365     [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
6366     [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
6367
6368     [INDEX_op_loopnzw] = CC_Z,
6369     [INDEX_op_loopnzl] = CC_Z,
6370     [INDEX_op_loopzw] = CC_Z,
6371     [INDEX_op_loopzl] = CC_Z,
6372
6373     [INDEX_op_seto_T0_cc] = CC_O,
6374     [INDEX_op_setb_T0_cc] = CC_C,
6375     [INDEX_op_setz_T0_cc] = CC_Z,
6376     [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
6377     [INDEX_op_sets_T0_cc] = CC_S,
6378     [INDEX_op_setp_T0_cc] = CC_P,
6379     [INDEX_op_setl_T0_cc] = CC_O | CC_S,
6380     [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
6381
6382     [INDEX_op_setb_T0_subb] = CC_C,
6383     [INDEX_op_setb_T0_subw] = CC_C,
6384     [INDEX_op_setb_T0_subl] = CC_C,
6385
6386     [INDEX_op_setz_T0_subb] = CC_Z,
6387     [INDEX_op_setz_T0_subw] = CC_Z,
6388     [INDEX_op_setz_T0_subl] = CC_Z,
6389
6390     [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
6391     [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
6392     [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
6393
6394     [INDEX_op_sets_T0_subb] = CC_S,
6395     [INDEX_op_sets_T0_subw] = CC_S,
6396     [INDEX_op_sets_T0_subl] = CC_S,
6397
6398     [INDEX_op_setl_T0_subb] = CC_O | CC_S,
6399     [INDEX_op_setl_T0_subw] = CC_O | CC_S,
6400     [INDEX_op_setl_T0_subl] = CC_O | CC_S,
6401
6402     [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
6403     [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
6404     [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
6405
6406     [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
6407     [INDEX_op_cmc] = CC_C,
6408     [INDEX_op_salc] = CC_C,
6409
6410     /* needed for correct flag optimisation before string ops */
6411     [INDEX_op_jnz_ecxw] = CC_OSZAPC,
6412     [INDEX_op_jnz_ecxl] = CC_OSZAPC,
6413     [INDEX_op_jz_ecxw] = CC_OSZAPC,
6414     [INDEX_op_jz_ecxl] = CC_OSZAPC,
6415
6416 #ifdef TARGET_X86_64
6417     [INDEX_op_jb_subq] = CC_C,
6418     [INDEX_op_jz_subq] = CC_Z,
6419     [INDEX_op_jbe_subq] = CC_Z | CC_C,
6420     [INDEX_op_js_subq] = CC_S,
6421     [INDEX_op_jl_subq] = CC_O | CC_S,
6422     [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
6423
6424     [INDEX_op_loopnzq] = CC_Z,
6425     [INDEX_op_loopzq] = CC_Z,
6426
6427     [INDEX_op_setb_T0_subq] = CC_C,
6428     [INDEX_op_setz_T0_subq] = CC_Z,
6429     [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
6430     [INDEX_op_sets_T0_subq] = CC_S,
6431     [INDEX_op_setl_T0_subq] = CC_O | CC_S,
6432     [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
6433
6434     [INDEX_op_jnz_ecxq] = CC_OSZAPC,
6435     [INDEX_op_jz_ecxq] = CC_OSZAPC,
6436 #endif
6437
6438 #define DEF_READF(SUFFIX)\
6439     [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6440     [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6441     [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6442     X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6443     [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6444     [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6445     [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6446     X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6447 \
6448     [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6449     [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6450     [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
6451     X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6452     [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6453     [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6454     [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6455     X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
6456
6457     DEF_READF( )
6458     DEF_READF(_raw)
6459 #ifndef CONFIG_USER_ONLY
6460     DEF_READF(_kernel)
6461     DEF_READF(_user)
6462 #endif
6463 };
6464
6465 /* flags written by an operation */
6466 static uint16_t opc_write_flags[NB_OPS] = {
6467     [INDEX_op_update2_cc] = CC_OSZAPC,
6468     [INDEX_op_update1_cc] = CC_OSZAPC,
6469     [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
6470     [INDEX_op_update_neg_cc] = CC_OSZAPC,
6471     /* subtle: due to the incl/decl implementation, C is used */
6472     [INDEX_op_update_inc_cc] = CC_OSZAPC,
6473     [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
6474
6475     [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
6476     [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
6477     [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
6478     X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
6479     [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
6480     [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
6481     [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
6482     X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
6483     [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
6484     [INDEX_op_imull_T0_T1] = CC_OSZAPC,
6485     X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
6486
6487     /* sse */
6488     [INDEX_op_ucomiss] = CC_OSZAPC,
6489     [INDEX_op_ucomisd] = CC_OSZAPC,
6490     [INDEX_op_comiss] = CC_OSZAPC,
6491     [INDEX_op_comisd] = CC_OSZAPC,
6492
6493     /* bcd */
6494     [INDEX_op_aam] = CC_OSZAPC,
6495     [INDEX_op_aad] = CC_OSZAPC,
6496     [INDEX_op_aas] = CC_OSZAPC,
6497     [INDEX_op_aaa] = CC_OSZAPC,
6498     [INDEX_op_das] = CC_OSZAPC,
6499     [INDEX_op_daa] = CC_OSZAPC,
6500
6501     [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
6502     [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
6503     [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
6504     [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
6505     [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
6506     [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
6507     [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
6508     [INDEX_op_clc] = CC_C,
6509     [INDEX_op_stc] = CC_C,
6510     [INDEX_op_cmc] = CC_C,
6511
6512     [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
6513     [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
6514     X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
6515     [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
6516     [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
6517     X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
6518     [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
6519     [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
6520     X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
6521     [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
6522     [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
6523     X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
6524
6525     [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
6526     [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
6527     X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
6528     [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
6529     [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
6530     X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
6531
6532     [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
6533     [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
6534     [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
6535     X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
6536
6537     [INDEX_op_cmpxchg8b] = CC_Z,
6538     [INDEX_op_lar] = CC_Z,
6539     [INDEX_op_lsl] = CC_Z,
6540     [INDEX_op_verr] = CC_Z,
6541     [INDEX_op_verw] = CC_Z,
6542     [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6543     [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6544
6545 #define DEF_WRITEF(SUFFIX)\
6546     [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6547     [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6548     [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6549     X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6550     [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6551     [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6552     [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6553     X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6554 \
6555     [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6556     [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6557     [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6558     X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6559     [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6560     [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6561     [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6562     X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6563 \
6564     [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6565     [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6566     [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6567     X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6568     [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6569     [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6570     [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6571     X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6572 \
6573     [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6574     [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6575     [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6576     X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6577 \
6578     [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6579     [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6580     [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6581     X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6582 \
6583     [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6584     [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6585     [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6586     X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6587 \
6588     [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6589     [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6590     X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6591     [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6592     [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6593     X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6594 \
6595     [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6596     [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6597     X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6598     [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6599     [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6600     X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6601 \
6602     [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6603     [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6604     [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6605     X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
6606
6607
6608     DEF_WRITEF( )
6609     DEF_WRITEF(_raw)
6610 #ifndef CONFIG_USER_ONLY
6611     DEF_WRITEF(_kernel)
6612     DEF_WRITEF(_user)
6613 #endif
6614 };
6615
6616 /* simpler form of an operation if no flags need to be generated */
6617 static uint16_t opc_simpler[NB_OPS] = {
6618     [INDEX_op_update2_cc] = INDEX_op_nop,
6619     [INDEX_op_update1_cc] = INDEX_op_nop,
6620     [INDEX_op_update_neg_cc] = INDEX_op_nop,
6621 #if 0
6622     /* broken: CC_OP logic must be rewritten */
6623     [INDEX_op_update_inc_cc] = INDEX_op_nop,
6624 #endif
6625
6626     [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
6627     [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
6628     [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
6629     X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
6630
6631     [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
6632     [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
6633     [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
6634     X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
6635
6636     [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
6637     [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
6638     [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
6639     X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
6640
6641 #define DEF_SIMPLER(SUFFIX)\
6642     [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
6643     [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
6644     [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
6645     X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
6646 \
6647     [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
6648     [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
6649     [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
6650     X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
6651
6652     DEF_SIMPLER( )
6653     DEF_SIMPLER(_raw)
6654 #ifndef CONFIG_USER_ONLY
6655     DEF_SIMPLER(_kernel)
6656     DEF_SIMPLER(_user)
6657 #endif
6658 };
6659
6660 static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
6661 {
6662     switch(macro_id) {
6663 #ifdef MACRO_TEST
6664     case MACRO_TEST:
6665         tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]);
6666         break;
6667 #endif
6668     }
6669 }
6670
6671 void optimize_flags_init(void)
6672 {
6673     int i;
6674     /* put default values in arrays */
6675     for(i = 0; i < NB_OPS; i++) {
6676         if (opc_simpler[i] == 0)
6677             opc_simpler[i] = i;
6678     }
6679
6680     tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
6681
6682     cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
6683 #if TARGET_LONG_BITS > HOST_LONG_BITS
6684     cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
6685                                   TCG_AREG0, offsetof(CPUState, t0), "T0");
6686     cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
6687                                   TCG_AREG0, offsetof(CPUState, t1), "T1");
6688     cpu_A0 = tcg_global_mem_new(TCG_TYPE_TL,
6689                                 TCG_AREG0, offsetof(CPUState, t2), "A0");
6690 #else
6691     cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
6692     cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
6693     cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
6694     cpu_tmp1 = tcg_global_reg2_new_hack(TCG_TYPE_I64, TCG_AREG1, TCG_AREG2, "tmp1");
6695 #endif
6696     /* the helpers are only registered to print debug info */
6697     TCG_HELPER(helper_divl_EAX_T0);
6698     TCG_HELPER(helper_idivl_EAX_T0);
6699 }
6700
6701 /* CPU flags computation optimization: we move backward thru the
6702    generated code to see which flags are needed. The operation is
6703    modified if suitable */
6704 static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
6705 {
6706     uint16_t *opc_ptr;
6707     int live_flags, write_flags, op;
6708
6709     opc_ptr = opc_buf + opc_buf_len;
6710     /* live_flags contains the flags needed by the next instructions
6711        in the code. At the end of the block, we consider that all the
6712        flags are live. */
6713     live_flags = CC_OSZAPC;
6714     while (opc_ptr > opc_buf) {
6715         op = *--opc_ptr;
6716         /* if none of the flags written by the instruction is used,
6717            then we can try to find a simpler instruction */
6718         write_flags = opc_write_flags[op];
6719         if ((live_flags & write_flags) == 0) {
6720             *opc_ptr = opc_simpler[op];
6721         }
6722         /* compute the live flags before the instruction */
6723         live_flags &= ~write_flags;
6724         live_flags |= opc_read_flags[op];
6725     }
6726 }
6727
6728 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
6729    basic block 'tb'. If search_pc is TRUE, also generate PC
6730    information for each intermediate instruction. */
6731 static inline int gen_intermediate_code_internal(CPUState *env,
6732                                                  TranslationBlock *tb,
6733                                                  int search_pc)
6734 {
6735     DisasContext dc1, *dc = &dc1;
6736     target_ulong pc_ptr;
6737     uint16_t *gen_opc_end;
6738     int j, lj, cflags;
6739     uint64_t flags;
6740     target_ulong pc_start;
6741     target_ulong cs_base;
6742
6743     /* generate intermediate code */
6744     pc_start = tb->pc;
6745     cs_base = tb->cs_base;
6746     flags = tb->flags;
6747     cflags = tb->cflags;
6748
6749     dc->pe = (flags >> HF_PE_SHIFT) & 1;
6750     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
6751     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
6752     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
6753     dc->f_st = 0;
6754     dc->vm86 = (flags >> VM_SHIFT) & 1;
6755     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
6756     dc->iopl = (flags >> IOPL_SHIFT) & 3;
6757     dc->tf = (flags >> TF_SHIFT) & 1;
6758     dc->singlestep_enabled = env->singlestep_enabled;
6759     dc->cc_op = CC_OP_DYNAMIC;
6760     dc->cs_base = cs_base;
6761     dc->tb = tb;
6762     dc->popl_esp_hack = 0;
6763     /* select memory access functions */
6764     dc->mem_index = 0;
6765     if (flags & HF_SOFTMMU_MASK) {
6766         if (dc->cpl == 3)
6767             dc->mem_index = 2 * 4;
6768         else
6769             dc->mem_index = 1 * 4;
6770     }
6771     dc->cpuid_features = env->cpuid_features;
6772     dc->cpuid_ext_features = env->cpuid_ext_features;
6773     dc->cpuid_ext2_features = env->cpuid_ext2_features;
6774 #ifdef TARGET_X86_64
6775     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
6776     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
6777 #endif
6778     dc->flags = flags;
6779     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
6780                     (flags & HF_INHIBIT_IRQ_MASK)
6781 #ifndef CONFIG_SOFTMMU
6782                     || (flags & HF_SOFTMMU_MASK)
6783 #endif
6784                     );
6785 #if 0
6786     /* check addseg logic */
6787     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
6788         printf("ERROR addseg\n");
6789 #endif
6790
6791     cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
6792 #if TARGET_LONG_BITS > HOST_LONG_BITS
6793     cpu_tmp1 = tcg_temp_new(TCG_TYPE_I64);
6794 #endif
6795
6796     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6797
6798     dc->is_jmp = DISAS_NEXT;
6799     pc_ptr = pc_start;
6800     lj = -1;
6801
6802     for(;;) {
6803         if (env->nb_breakpoints > 0) {
6804             for(j = 0; j < env->nb_breakpoints; j++) {
6805                 if (env->breakpoints[j] == pc_ptr) {
6806                     gen_debug(dc, pc_ptr - dc->cs_base);
6807                     break;
6808                 }
6809             }
6810         }
6811         if (search_pc) {
6812             j = gen_opc_ptr - gen_opc_buf;
6813             if (lj < j) {
6814                 lj++;
6815                 while (lj < j)
6816                     gen_opc_instr_start[lj++] = 0;
6817             }
6818             gen_opc_pc[lj] = pc_ptr;
6819             gen_opc_cc_op[lj] = dc->cc_op;
6820             gen_opc_instr_start[lj] = 1;
6821         }
6822         pc_ptr = disas_insn(dc, pc_ptr);
6823         /* stop translation if indicated */
6824         if (dc->is_jmp)
6825             break;
6826         /* if single step mode, we generate only one instruction and
6827            generate an exception */
6828         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
6829            the flag and abort the translation to give the irqs a
6830            change to be happen */
6831         if (dc->tf || dc->singlestep_enabled ||
6832             (flags & HF_INHIBIT_IRQ_MASK) ||
6833             (cflags & CF_SINGLE_INSN)) {
6834             gen_jmp_im(pc_ptr - dc->cs_base);
6835             gen_eob(dc);
6836             break;
6837         }
6838         /* if too long translation, stop generation too */
6839         if (gen_opc_ptr >= gen_opc_end ||
6840             (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
6841             gen_jmp_im(pc_ptr - dc->cs_base);
6842             gen_eob(dc);
6843             break;
6844         }
6845     }
6846     *gen_opc_ptr = INDEX_op_end;
6847     /* we don't forget to fill the last values */
6848     if (search_pc) {
6849         j = gen_opc_ptr - gen_opc_buf;
6850         lj++;
6851         while (lj <= j)
6852             gen_opc_instr_start[lj++] = 0;
6853     }
6854
6855 #ifdef DEBUG_DISAS
6856     if (loglevel & CPU_LOG_TB_CPU) {
6857         cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
6858     }
6859     if (loglevel & CPU_LOG_TB_IN_ASM) {
6860         int disas_flags;
6861         fprintf(logfile, "----------------\n");
6862         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6863 #ifdef TARGET_X86_64
6864         if (dc->code64)
6865             disas_flags = 2;
6866         else
6867 #endif
6868             disas_flags = !dc->code32;
6869         target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
6870         fprintf(logfile, "\n");
6871         if (loglevel & CPU_LOG_TB_OP_OPT) {
6872             fprintf(logfile, "OP before opt:\n");
6873             tcg_dump_ops(&tcg_ctx, logfile);
6874             fprintf(logfile, "\n");
6875         }
6876     }
6877 #endif
6878
6879     /* optimize flag computations */
6880     optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
6881
6882     if (!search_pc)
6883         tb->size = pc_ptr - pc_start;
6884     return 0;
6885 }
6886
6887 int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
6888 {
6889     return gen_intermediate_code_internal(env, tb, 0);
6890 }
6891
6892 int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
6893 {
6894     return gen_intermediate_code_internal(env, tb, 1);
6895 }
6896
6897 void gen_pc_load(CPUState *env, TranslationBlock *tb,
6898                 unsigned long searched_pc, int pc_pos, void *puc)
6899 {
6900     int cc_op;
6901 #ifdef DEBUG_DISAS
6902     if (loglevel & CPU_LOG_TB_OP) {
6903         int i;
6904         fprintf(logfile, "RESTORE:\n");
6905         for(i = 0;i <= pc_pos; i++) {
6906             if (gen_opc_instr_start[i]) {
6907                 fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
6908             }
6909         }
6910         fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
6911                 searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
6912                 (uint32_t)tb->cs_base);
6913     }
6914 #endif
6915     env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
6916     cc_op = gen_opc_cc_op[pc_pos];
6917     if (cc_op != CC_OP_DYNAMIC)
6918         env->cc_op = cc_op;
6919 }