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