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