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