Annotation of qemu/target-i386/translate.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.