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