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