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

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: 
1.1.1.2   root     1703: static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
                   1704: {
                   1705:     TranslationBlock *tb;
                   1706:     target_ulong pc;
                   1707: 
                   1708:     pc = s->cs_base + eip;
                   1709:     tb = s->tb;
                   1710:     /* NOTE: we handle the case where the TB spans two pages here */
                   1711:     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
                   1712:         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
                   1713:         /* jump to same page: we can use a direct jump */
                   1714:         if (tb_num == 0)
                   1715:             gen_op_goto_tb0(TBPARAM(tb));
                   1716:         else
                   1717:             gen_op_goto_tb1(TBPARAM(tb));
                   1718:         gen_jmp_im(eip);
                   1719:         gen_op_movl_T0_im((long)tb + tb_num);
                   1720:         gen_op_exit_tb();
                   1721:     } else {
                   1722:         /* jump to another page: currently not optimized */
                   1723:         gen_jmp_im(eip);
                   1724:         gen_eob(s);
                   1725:     }
                   1726: }
                   1727: 
1.1       root     1728: static inline void gen_jcc(DisasContext *s, int b, 
                   1729:                            target_ulong val, target_ulong next_eip)
                   1730: {
                   1731:     TranslationBlock *tb;
                   1732:     int inv, jcc_op;
                   1733:     GenOpFunc1 *func;
                   1734:     target_ulong tmp;
                   1735:     int l1, l2;
                   1736: 
                   1737:     inv = b & 1;
                   1738:     jcc_op = (b >> 1) & 7;
                   1739:     
                   1740:     if (s->jmp_opt) {
                   1741:         switch(s->cc_op) {
                   1742:             /* we optimize the cmp/jcc case */
                   1743:         case CC_OP_SUBB:
                   1744:         case CC_OP_SUBW:
                   1745:         case CC_OP_SUBL:
                   1746:         case CC_OP_SUBQ:
                   1747:             func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
                   1748:             break;
                   1749:             
                   1750:             /* some jumps are easy to compute */
                   1751:         case CC_OP_ADDB:
                   1752:         case CC_OP_ADDW:
                   1753:         case CC_OP_ADDL:
                   1754:         case CC_OP_ADDQ:
                   1755: 
                   1756:         case CC_OP_ADCB:
                   1757:         case CC_OP_ADCW:
                   1758:         case CC_OP_ADCL:
                   1759:         case CC_OP_ADCQ:
                   1760: 
                   1761:         case CC_OP_SBBB:
                   1762:         case CC_OP_SBBW:
                   1763:         case CC_OP_SBBL:
                   1764:         case CC_OP_SBBQ:
                   1765: 
                   1766:         case CC_OP_LOGICB:
                   1767:         case CC_OP_LOGICW:
                   1768:         case CC_OP_LOGICL:
                   1769:         case CC_OP_LOGICQ:
                   1770: 
                   1771:         case CC_OP_INCB:
                   1772:         case CC_OP_INCW:
                   1773:         case CC_OP_INCL:
                   1774:         case CC_OP_INCQ:
                   1775: 
                   1776:         case CC_OP_DECB:
                   1777:         case CC_OP_DECW:
                   1778:         case CC_OP_DECL:
                   1779:         case CC_OP_DECQ:
                   1780: 
                   1781:         case CC_OP_SHLB:
                   1782:         case CC_OP_SHLW:
                   1783:         case CC_OP_SHLL:
                   1784:         case CC_OP_SHLQ:
                   1785: 
                   1786:         case CC_OP_SARB:
                   1787:         case CC_OP_SARW:
                   1788:         case CC_OP_SARL:
                   1789:         case CC_OP_SARQ:
                   1790:             switch(jcc_op) {
                   1791:             case JCC_Z:
                   1792:                 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
                   1793:                 break;
                   1794:             case JCC_S:
                   1795:                 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
                   1796:                 break;
                   1797:             default:
                   1798:                 func = NULL;
                   1799:                 break;
                   1800:             }
                   1801:             break;
                   1802:         default:
                   1803:             func = NULL;
                   1804:             break;
                   1805:         }
                   1806: 
1.1.1.2   root     1807:         if (s->cc_op != CC_OP_DYNAMIC) {
1.1       root     1808:             gen_op_set_cc_op(s->cc_op);
1.1.1.2   root     1809:             s->cc_op = CC_OP_DYNAMIC;
                   1810:         }
1.1       root     1811: 
                   1812:         if (!func) {
                   1813:             gen_setcc_slow[jcc_op]();
                   1814:             func = gen_op_jnz_T0_label;
                   1815:         }
                   1816:     
                   1817:         if (inv) {
                   1818:             tmp = val;
                   1819:             val = next_eip;
                   1820:             next_eip = tmp;
                   1821:         }
                   1822:         tb = s->tb;
                   1823: 
                   1824:         l1 = gen_new_label();
                   1825:         func(l1);
                   1826: 
1.1.1.2   root     1827:         gen_goto_tb(s, 0, next_eip);
1.1       root     1828: 
                   1829:         gen_set_label(l1);
1.1.1.2   root     1830:         gen_goto_tb(s, 1, val);
1.1       root     1831: 
                   1832:         s->is_jmp = 3;
                   1833:     } else {
                   1834: 
                   1835:         if (s->cc_op != CC_OP_DYNAMIC) {
                   1836:             gen_op_set_cc_op(s->cc_op);
                   1837:             s->cc_op = CC_OP_DYNAMIC;
                   1838:         }
                   1839:         gen_setcc_slow[jcc_op]();
                   1840:         if (inv) {
                   1841:             tmp = val;
                   1842:             val = next_eip;
                   1843:             next_eip = tmp;
                   1844:         }
                   1845:         l1 = gen_new_label();
                   1846:         l2 = gen_new_label();
                   1847:         gen_op_jnz_T0_label(l1);
                   1848:         gen_jmp_im(next_eip);
                   1849:         gen_op_jmp_label(l2);
                   1850:         gen_set_label(l1);
                   1851:         gen_jmp_im(val);
                   1852:         gen_set_label(l2);
                   1853:         gen_eob(s);
                   1854:     }
                   1855: }
                   1856: 
                   1857: static void gen_setcc(DisasContext *s, int b)
                   1858: {
                   1859:     int inv, jcc_op;
                   1860:     GenOpFunc *func;
                   1861: 
                   1862:     inv = b & 1;
                   1863:     jcc_op = (b >> 1) & 7;
                   1864:     switch(s->cc_op) {
                   1865:         /* we optimize the cmp/jcc case */
                   1866:     case CC_OP_SUBB:
                   1867:     case CC_OP_SUBW:
                   1868:     case CC_OP_SUBL:
                   1869:     case CC_OP_SUBQ:
                   1870:         func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
                   1871:         if (!func)
                   1872:             goto slow_jcc;
                   1873:         break;
                   1874:         
                   1875:         /* some jumps are easy to compute */
                   1876:     case CC_OP_ADDB:
                   1877:     case CC_OP_ADDW:
                   1878:     case CC_OP_ADDL:
                   1879:     case CC_OP_ADDQ:
                   1880: 
                   1881:     case CC_OP_LOGICB:
                   1882:     case CC_OP_LOGICW:
                   1883:     case CC_OP_LOGICL:
                   1884:     case CC_OP_LOGICQ:
                   1885: 
                   1886:     case CC_OP_INCB:
                   1887:     case CC_OP_INCW:
                   1888:     case CC_OP_INCL:
                   1889:     case CC_OP_INCQ:
                   1890: 
                   1891:     case CC_OP_DECB:
                   1892:     case CC_OP_DECW:
                   1893:     case CC_OP_DECL:
                   1894:     case CC_OP_DECQ:
                   1895: 
                   1896:     case CC_OP_SHLB:
                   1897:     case CC_OP_SHLW:
                   1898:     case CC_OP_SHLL:
                   1899:     case CC_OP_SHLQ:
                   1900:         switch(jcc_op) {
                   1901:         case JCC_Z:
                   1902:             func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
                   1903:             break;
                   1904:         case JCC_S:
                   1905:             func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
                   1906:             break;
                   1907:         default:
                   1908:             goto slow_jcc;
                   1909:         }
                   1910:         break;
                   1911:     default:
                   1912:     slow_jcc:
                   1913:         if (s->cc_op != CC_OP_DYNAMIC)
                   1914:             gen_op_set_cc_op(s->cc_op);
                   1915:         func = gen_setcc_slow[jcc_op];
                   1916:         break;
                   1917:     }
                   1918:     func();
                   1919:     if (inv) {
                   1920:         gen_op_xor_T0_1();
                   1921:     }
                   1922: }
                   1923: 
                   1924: /* move T0 to seg_reg and compute if the CPU state may change. Never
                   1925:    call this function with seg_reg == R_CS */
                   1926: static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
                   1927: {
                   1928:     if (s->pe && !s->vm86) {
                   1929:         /* XXX: optimize by finding processor state dynamically */
                   1930:         if (s->cc_op != CC_OP_DYNAMIC)
                   1931:             gen_op_set_cc_op(s->cc_op);
                   1932:         gen_jmp_im(cur_eip);
                   1933:         gen_op_movl_seg_T0(seg_reg);
                   1934:         /* abort translation because the addseg value may change or
                   1935:            because ss32 may change. For R_SS, translation must always
                   1936:            stop as a special handling must be done to disable hardware
                   1937:            interrupts for the next instruction */
                   1938:         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
                   1939:             s->is_jmp = 3;
                   1940:     } else {
                   1941:         gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
                   1942:         if (seg_reg == R_SS)
                   1943:             s->is_jmp = 3;
                   1944:     }
                   1945: }
                   1946: 
                   1947: static inline void gen_stack_update(DisasContext *s, int addend)
                   1948: {
                   1949: #ifdef TARGET_X86_64
                   1950:     if (CODE64(s)) {
                   1951:         if (addend == 8)
                   1952:             gen_op_addq_ESP_8();
                   1953:         else 
                   1954:             gen_op_addq_ESP_im(addend);
                   1955:     } else
                   1956: #endif
                   1957:     if (s->ss32) {
                   1958:         if (addend == 2)
                   1959:             gen_op_addl_ESP_2();
                   1960:         else if (addend == 4)
                   1961:             gen_op_addl_ESP_4();
                   1962:         else 
                   1963:             gen_op_addl_ESP_im(addend);
                   1964:     } else {
                   1965:         if (addend == 2)
                   1966:             gen_op_addw_ESP_2();
                   1967:         else if (addend == 4)
                   1968:             gen_op_addw_ESP_4();
                   1969:         else
                   1970:             gen_op_addw_ESP_im(addend);
                   1971:     }
                   1972: }
                   1973: 
                   1974: /* generate a push. It depends on ss32, addseg and dflag */
                   1975: static void gen_push_T0(DisasContext *s)
                   1976: {
                   1977: #ifdef TARGET_X86_64
                   1978:     if (CODE64(s)) {
                   1979:         gen_op_movq_A0_reg[R_ESP]();
                   1980:         if (s->dflag) {
                   1981:             gen_op_subq_A0_8();
                   1982:             gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
                   1983:         } else {
                   1984:             gen_op_subq_A0_2();
                   1985:             gen_op_st_T0_A0[OT_WORD + s->mem_index]();
                   1986:         }
                   1987:         gen_op_movq_ESP_A0();
                   1988:     } else 
                   1989: #endif
                   1990:     {
                   1991:         gen_op_movl_A0_reg[R_ESP]();
                   1992:         if (!s->dflag)
                   1993:             gen_op_subl_A0_2();
                   1994:         else
                   1995:             gen_op_subl_A0_4();
                   1996:         if (s->ss32) {
                   1997:             if (s->addseg) {
                   1998:                 gen_op_movl_T1_A0();
                   1999:                 gen_op_addl_A0_SS();
                   2000:             }
                   2001:         } else {
                   2002:             gen_op_andl_A0_ffff();
                   2003:             gen_op_movl_T1_A0();
                   2004:             gen_op_addl_A0_SS();
                   2005:         }
                   2006:         gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
                   2007:         if (s->ss32 && !s->addseg)
                   2008:             gen_op_movl_ESP_A0();
                   2009:         else
                   2010:             gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
                   2011:     }
                   2012: }
                   2013: 
                   2014: /* generate a push. It depends on ss32, addseg and dflag */
                   2015: /* slower version for T1, only used for call Ev */
                   2016: static void gen_push_T1(DisasContext *s)
                   2017: {
                   2018: #ifdef TARGET_X86_64
                   2019:     if (CODE64(s)) {
                   2020:         gen_op_movq_A0_reg[R_ESP]();
                   2021:         if (s->dflag) {
                   2022:             gen_op_subq_A0_8();
                   2023:             gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
                   2024:         } else {
                   2025:             gen_op_subq_A0_2();
                   2026:             gen_op_st_T0_A0[OT_WORD + s->mem_index]();
                   2027:         }
                   2028:         gen_op_movq_ESP_A0();
                   2029:     } else 
                   2030: #endif
                   2031:     {
                   2032:         gen_op_movl_A0_reg[R_ESP]();
                   2033:         if (!s->dflag)
                   2034:             gen_op_subl_A0_2();
                   2035:         else
                   2036:             gen_op_subl_A0_4();
                   2037:         if (s->ss32) {
                   2038:             if (s->addseg) {
                   2039:                 gen_op_addl_A0_SS();
                   2040:             }
                   2041:         } else {
                   2042:             gen_op_andl_A0_ffff();
                   2043:             gen_op_addl_A0_SS();
                   2044:         }
                   2045:         gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
                   2046:         
                   2047:         if (s->ss32 && !s->addseg)
                   2048:             gen_op_movl_ESP_A0();
                   2049:         else
                   2050:             gen_stack_update(s, (-2) << s->dflag);
                   2051:     }
                   2052: }
                   2053: 
                   2054: /* two step pop is necessary for precise exceptions */
                   2055: static void gen_pop_T0(DisasContext *s)
                   2056: {
                   2057: #ifdef TARGET_X86_64
                   2058:     if (CODE64(s)) {
                   2059:         gen_op_movq_A0_reg[R_ESP]();
                   2060:         gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
                   2061:     } else 
                   2062: #endif
                   2063:     {
                   2064:         gen_op_movl_A0_reg[R_ESP]();
                   2065:         if (s->ss32) {
                   2066:             if (s->addseg)
                   2067:                 gen_op_addl_A0_SS();
                   2068:         } else {
                   2069:             gen_op_andl_A0_ffff();
                   2070:             gen_op_addl_A0_SS();
                   2071:         }
                   2072:         gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
                   2073:     }
                   2074: }
                   2075: 
                   2076: static void gen_pop_update(DisasContext *s)
                   2077: {
                   2078: #ifdef TARGET_X86_64
                   2079:     if (CODE64(s) && s->dflag) {
                   2080:         gen_stack_update(s, 8);
                   2081:     } else
                   2082: #endif
                   2083:     {
                   2084:         gen_stack_update(s, 2 << s->dflag);
                   2085:     }
                   2086: }
                   2087: 
                   2088: static void gen_stack_A0(DisasContext *s)
                   2089: {
                   2090:     gen_op_movl_A0_ESP();
                   2091:     if (!s->ss32)
                   2092:         gen_op_andl_A0_ffff();
                   2093:     gen_op_movl_T1_A0();
                   2094:     if (s->addseg)
                   2095:         gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
                   2096: }
                   2097: 
                   2098: /* NOTE: wrap around in 16 bit not fully handled */
                   2099: static void gen_pusha(DisasContext *s)
                   2100: {
                   2101:     int i;
                   2102:     gen_op_movl_A0_ESP();
                   2103:     gen_op_addl_A0_im(-16 <<  s->dflag);
                   2104:     if (!s->ss32)
                   2105:         gen_op_andl_A0_ffff();
                   2106:     gen_op_movl_T1_A0();
                   2107:     if (s->addseg)
                   2108:         gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
                   2109:     for(i = 0;i < 8; i++) {
                   2110:         gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
                   2111:         gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
                   2112:         gen_op_addl_A0_im(2 <<  s->dflag);
                   2113:     }
                   2114:     gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
                   2115: }
                   2116: 
                   2117: /* NOTE: wrap around in 16 bit not fully handled */
                   2118: static void gen_popa(DisasContext *s)
                   2119: {
                   2120:     int i;
                   2121:     gen_op_movl_A0_ESP();
                   2122:     if (!s->ss32)
                   2123:         gen_op_andl_A0_ffff();
                   2124:     gen_op_movl_T1_A0();
                   2125:     gen_op_addl_T1_im(16 <<  s->dflag);
                   2126:     if (s->addseg)
                   2127:         gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
                   2128:     for(i = 0;i < 8; i++) {
                   2129:         /* ESP is not reloaded */
                   2130:         if (i != 3) {
                   2131:             gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
                   2132:             gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
                   2133:         }
                   2134:         gen_op_addl_A0_im(2 <<  s->dflag);
                   2135:     }
                   2136:     gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
                   2137: }
                   2138: 
                   2139: static void gen_enter(DisasContext *s, int esp_addend, int level)
                   2140: {
                   2141:     int ot, opsize;
                   2142: 
                   2143:     level &= 0x1f;
                   2144: #ifdef TARGET_X86_64
                   2145:     if (CODE64(s)) {
                   2146:         ot = s->dflag ? OT_QUAD : OT_WORD;
                   2147:         opsize = 1 << ot;
                   2148:         
                   2149:         gen_op_movl_A0_ESP();
                   2150:         gen_op_addq_A0_im(-opsize);
                   2151:         gen_op_movl_T1_A0();
                   2152: 
                   2153:         /* push bp */
                   2154:         gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
                   2155:         gen_op_st_T0_A0[ot + s->mem_index]();
                   2156:         if (level) {
                   2157:             gen_op_enter64_level(level, (ot == OT_QUAD));
                   2158:         }
                   2159:         gen_op_mov_reg_T1[ot][R_EBP]();
                   2160:         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
                   2161:         gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
                   2162:     } else 
                   2163: #endif
                   2164:     {
                   2165:         ot = s->dflag + OT_WORD;
                   2166:         opsize = 2 << s->dflag;
                   2167:         
                   2168:         gen_op_movl_A0_ESP();
                   2169:         gen_op_addl_A0_im(-opsize);
                   2170:         if (!s->ss32)
                   2171:             gen_op_andl_A0_ffff();
                   2172:         gen_op_movl_T1_A0();
                   2173:         if (s->addseg)
                   2174:             gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
                   2175:         /* push bp */
                   2176:         gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
                   2177:         gen_op_st_T0_A0[ot + s->mem_index]();
                   2178:         if (level) {
                   2179:             gen_op_enter_level(level, s->dflag);
                   2180:         }
                   2181:         gen_op_mov_reg_T1[ot][R_EBP]();
                   2182:         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
                   2183:         gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
                   2184:     }
                   2185: }
                   2186: 
                   2187: static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
                   2188: {
                   2189:     if (s->cc_op != CC_OP_DYNAMIC)
                   2190:         gen_op_set_cc_op(s->cc_op);
                   2191:     gen_jmp_im(cur_eip);
                   2192:     gen_op_raise_exception(trapno);
                   2193:     s->is_jmp = 3;
                   2194: }
                   2195: 
                   2196: /* an interrupt is different from an exception because of the
                   2197:    priviledge checks */
                   2198: static void gen_interrupt(DisasContext *s, int intno, 
                   2199:                           target_ulong cur_eip, target_ulong next_eip)
                   2200: {
                   2201:     if (s->cc_op != CC_OP_DYNAMIC)
                   2202:         gen_op_set_cc_op(s->cc_op);
                   2203:     gen_jmp_im(cur_eip);
                   2204:     gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip));
                   2205:     s->is_jmp = 3;
                   2206: }
                   2207: 
                   2208: static void gen_debug(DisasContext *s, target_ulong cur_eip)
                   2209: {
                   2210:     if (s->cc_op != CC_OP_DYNAMIC)
                   2211:         gen_op_set_cc_op(s->cc_op);
                   2212:     gen_jmp_im(cur_eip);
                   2213:     gen_op_debug();
                   2214:     s->is_jmp = 3;
                   2215: }
                   2216: 
                   2217: /* generate a generic end of block. Trace exception is also generated
                   2218:    if needed */
                   2219: static void gen_eob(DisasContext *s)
                   2220: {
                   2221:     if (s->cc_op != CC_OP_DYNAMIC)
                   2222:         gen_op_set_cc_op(s->cc_op);
                   2223:     if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
                   2224:         gen_op_reset_inhibit_irq();
                   2225:     }
                   2226:     if (s->singlestep_enabled) {
                   2227:         gen_op_debug();
                   2228:     } else if (s->tf) {
                   2229:         gen_op_raise_exception(EXCP01_SSTP);
                   2230:     } else {
                   2231:         gen_op_movl_T0_0();
                   2232:         gen_op_exit_tb();
                   2233:     }
                   2234:     s->is_jmp = 3;
                   2235: }
                   2236: 
                   2237: /* generate a jump to eip. No segment change must happen before as a
                   2238:    direct call to the next block may occur */
                   2239: static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
                   2240: {
                   2241:     if (s->jmp_opt) {
1.1.1.2   root     2242:         if (s->cc_op != CC_OP_DYNAMIC) {
1.1       root     2243:             gen_op_set_cc_op(s->cc_op);
1.1.1.2   root     2244:             s->cc_op = CC_OP_DYNAMIC;
                   2245:         }
                   2246:         gen_goto_tb(s, tb_num, eip);
1.1       root     2247:         s->is_jmp = 3;
                   2248:     } else {
                   2249:         gen_jmp_im(eip);
                   2250:         gen_eob(s);
                   2251:     }
                   2252: }
                   2253: 
                   2254: static void gen_jmp(DisasContext *s, target_ulong eip)
                   2255: {
                   2256:     gen_jmp_tb(s, eip, 0);
                   2257: }
                   2258: 
                   2259: static void gen_movtl_T0_im(target_ulong val)
                   2260: {
                   2261: #ifdef TARGET_X86_64    
                   2262:     if ((int32_t)val == val) {
                   2263:         gen_op_movl_T0_im(val);
                   2264:     } else {
                   2265:         gen_op_movq_T0_im64(val >> 32, val);
                   2266:     }
                   2267: #else
                   2268:     gen_op_movl_T0_im(val);
                   2269: #endif
                   2270: }
                   2271: 
                   2272: static void gen_movtl_T1_im(target_ulong val)
                   2273: {
                   2274: #ifdef TARGET_X86_64    
                   2275:     if ((int32_t)val == val) {
                   2276:         gen_op_movl_T1_im(val);
                   2277:     } else {
                   2278:         gen_op_movq_T1_im64(val >> 32, val);
                   2279:     }
                   2280: #else
                   2281:     gen_op_movl_T1_im(val);
                   2282: #endif
                   2283: }
                   2284: 
                   2285: static void gen_add_A0_im(DisasContext *s, int val)
                   2286: {
                   2287: #ifdef TARGET_X86_64
                   2288:     if (CODE64(s))
                   2289:         gen_op_addq_A0_im(val);
                   2290:     else
                   2291: #endif
                   2292:         gen_op_addl_A0_im(val);
                   2293: }
                   2294: 
                   2295: static GenOpFunc1 *gen_ldq_env_A0[3] = {
                   2296:     gen_op_ldq_raw_env_A0,
                   2297: #ifndef CONFIG_USER_ONLY
                   2298:     gen_op_ldq_kernel_env_A0,
                   2299:     gen_op_ldq_user_env_A0,
                   2300: #endif
                   2301: };
                   2302: 
                   2303: static GenOpFunc1 *gen_stq_env_A0[3] = {
                   2304:     gen_op_stq_raw_env_A0,
                   2305: #ifndef CONFIG_USER_ONLY
                   2306:     gen_op_stq_kernel_env_A0,
                   2307:     gen_op_stq_user_env_A0,
                   2308: #endif
                   2309: };
                   2310: 
                   2311: static GenOpFunc1 *gen_ldo_env_A0[3] = {
                   2312:     gen_op_ldo_raw_env_A0,
                   2313: #ifndef CONFIG_USER_ONLY
                   2314:     gen_op_ldo_kernel_env_A0,
                   2315:     gen_op_ldo_user_env_A0,
                   2316: #endif
                   2317: };
                   2318: 
                   2319: static GenOpFunc1 *gen_sto_env_A0[3] = {
                   2320:     gen_op_sto_raw_env_A0,
                   2321: #ifndef CONFIG_USER_ONLY
                   2322:     gen_op_sto_kernel_env_A0,
                   2323:     gen_op_sto_user_env_A0,
                   2324: #endif
                   2325: };
                   2326: 
                   2327: #define SSE_SPECIAL ((GenOpFunc2 *)1)
                   2328: 
                   2329: #define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
                   2330: #define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
                   2331:                      gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
                   2332: 
                   2333: static GenOpFunc2 *sse_op_table1[256][4] = {
                   2334:     /* pure SSE operations */
                   2335:     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
                   2336:     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
1.1.1.3 ! root     2337:     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
1.1       root     2338:     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
                   2339:     [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
                   2340:     [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
                   2341:     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
                   2342:     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
                   2343: 
                   2344:     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
                   2345:     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
                   2346:     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
                   2347:     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
                   2348:     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
                   2349:     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
                   2350:     [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
                   2351:     [0x2f] = { gen_op_comiss, gen_op_comisd },
                   2352:     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
                   2353:     [0x51] = SSE_FOP(sqrt),
                   2354:     [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
                   2355:     [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
                   2356:     [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
                   2357:     [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
                   2358:     [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
                   2359:     [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
                   2360:     [0x58] = SSE_FOP(add),
                   2361:     [0x59] = SSE_FOP(mul),
                   2362:     [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps, 
                   2363:                gen_op_cvtss2sd, gen_op_cvtsd2ss },
                   2364:     [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
                   2365:     [0x5c] = SSE_FOP(sub),
                   2366:     [0x5d] = SSE_FOP(min),
                   2367:     [0x5e] = SSE_FOP(div),
                   2368:     [0x5f] = SSE_FOP(max),
                   2369: 
                   2370:     [0xc2] = SSE_FOP(cmpeq),
                   2371:     [0xc6] = { (GenOpFunc2 *)gen_op_shufps, (GenOpFunc2 *)gen_op_shufpd },
                   2372: 
                   2373:     /* MMX ops and their SSE extensions */
                   2374:     [0x60] = MMX_OP2(punpcklbw),
                   2375:     [0x61] = MMX_OP2(punpcklwd),
                   2376:     [0x62] = MMX_OP2(punpckldq),
                   2377:     [0x63] = MMX_OP2(packsswb),
                   2378:     [0x64] = MMX_OP2(pcmpgtb),
                   2379:     [0x65] = MMX_OP2(pcmpgtw),
                   2380:     [0x66] = MMX_OP2(pcmpgtl),
                   2381:     [0x67] = MMX_OP2(packuswb),
                   2382:     [0x68] = MMX_OP2(punpckhbw),
                   2383:     [0x69] = MMX_OP2(punpckhwd),
                   2384:     [0x6a] = MMX_OP2(punpckhdq),
                   2385:     [0x6b] = MMX_OP2(packssdw),
                   2386:     [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
                   2387:     [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
                   2388:     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
                   2389:     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
                   2390:     [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx, 
                   2391:                (GenOpFunc2 *)gen_op_pshufd_xmm, 
                   2392:                (GenOpFunc2 *)gen_op_pshufhw_xmm, 
                   2393:                (GenOpFunc2 *)gen_op_pshuflw_xmm },
                   2394:     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
                   2395:     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
                   2396:     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
                   2397:     [0x74] = MMX_OP2(pcmpeqb),
                   2398:     [0x75] = MMX_OP2(pcmpeqw),
                   2399:     [0x76] = MMX_OP2(pcmpeql),
                   2400:     [0x77] = { SSE_SPECIAL }, /* emms */
                   2401:     [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
                   2402:     [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
                   2403:     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
                   2404:     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
                   2405:     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
                   2406:     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
                   2407:     [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
                   2408:     [0xd1] = MMX_OP2(psrlw),
                   2409:     [0xd2] = MMX_OP2(psrld),
                   2410:     [0xd3] = MMX_OP2(psrlq),
                   2411:     [0xd4] = MMX_OP2(paddq),
                   2412:     [0xd5] = MMX_OP2(pmullw),
                   2413:     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
                   2414:     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
                   2415:     [0xd8] = MMX_OP2(psubusb),
                   2416:     [0xd9] = MMX_OP2(psubusw),
                   2417:     [0xda] = MMX_OP2(pminub),
                   2418:     [0xdb] = MMX_OP2(pand),
                   2419:     [0xdc] = MMX_OP2(paddusb),
                   2420:     [0xdd] = MMX_OP2(paddusw),
                   2421:     [0xde] = MMX_OP2(pmaxub),
                   2422:     [0xdf] = MMX_OP2(pandn),
                   2423:     [0xe0] = MMX_OP2(pavgb),
                   2424:     [0xe1] = MMX_OP2(psraw),
                   2425:     [0xe2] = MMX_OP2(psrad),
                   2426:     [0xe3] = MMX_OP2(pavgw),
                   2427:     [0xe4] = MMX_OP2(pmulhuw),
                   2428:     [0xe5] = MMX_OP2(pmulhw),
                   2429:     [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
                   2430:     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
                   2431:     [0xe8] = MMX_OP2(psubsb),
                   2432:     [0xe9] = MMX_OP2(psubsw),
                   2433:     [0xea] = MMX_OP2(pminsw),
                   2434:     [0xeb] = MMX_OP2(por),
                   2435:     [0xec] = MMX_OP2(paddsb),
                   2436:     [0xed] = MMX_OP2(paddsw),
                   2437:     [0xee] = MMX_OP2(pmaxsw),
                   2438:     [0xef] = MMX_OP2(pxor),
1.1.1.3 ! root     2439:     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
1.1       root     2440:     [0xf1] = MMX_OP2(psllw),
                   2441:     [0xf2] = MMX_OP2(pslld),
                   2442:     [0xf3] = MMX_OP2(psllq),
                   2443:     [0xf4] = MMX_OP2(pmuludq),
                   2444:     [0xf5] = MMX_OP2(pmaddwd),
                   2445:     [0xf6] = MMX_OP2(psadbw),
                   2446:     [0xf7] = MMX_OP2(maskmov),
                   2447:     [0xf8] = MMX_OP2(psubb),
                   2448:     [0xf9] = MMX_OP2(psubw),
                   2449:     [0xfa] = MMX_OP2(psubl),
                   2450:     [0xfb] = MMX_OP2(psubq),
                   2451:     [0xfc] = MMX_OP2(paddb),
                   2452:     [0xfd] = MMX_OP2(paddw),
                   2453:     [0xfe] = MMX_OP2(paddl),
                   2454: };
                   2455: 
                   2456: static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
                   2457:     [0 + 2] = MMX_OP2(psrlw),
                   2458:     [0 + 4] = MMX_OP2(psraw),
                   2459:     [0 + 6] = MMX_OP2(psllw),
                   2460:     [8 + 2] = MMX_OP2(psrld),
                   2461:     [8 + 4] = MMX_OP2(psrad),
                   2462:     [8 + 6] = MMX_OP2(pslld),
                   2463:     [16 + 2] = MMX_OP2(psrlq),
                   2464:     [16 + 3] = { NULL, gen_op_psrldq_xmm },
                   2465:     [16 + 6] = MMX_OP2(psllq),
                   2466:     [16 + 7] = { NULL, gen_op_pslldq_xmm },
                   2467: };
                   2468: 
                   2469: static GenOpFunc1 *sse_op_table3[4 * 3] = {
                   2470:     gen_op_cvtsi2ss,
                   2471:     gen_op_cvtsi2sd,
                   2472:     X86_64_ONLY(gen_op_cvtsq2ss),
                   2473:     X86_64_ONLY(gen_op_cvtsq2sd),
                   2474:     
                   2475:     gen_op_cvttss2si,
                   2476:     gen_op_cvttsd2si,
                   2477:     X86_64_ONLY(gen_op_cvttss2sq),
                   2478:     X86_64_ONLY(gen_op_cvttsd2sq),
                   2479: 
                   2480:     gen_op_cvtss2si,
                   2481:     gen_op_cvtsd2si,
                   2482:     X86_64_ONLY(gen_op_cvtss2sq),
                   2483:     X86_64_ONLY(gen_op_cvtsd2sq),
                   2484: };
                   2485:     
                   2486: static GenOpFunc2 *sse_op_table4[8][4] = {
                   2487:     SSE_FOP(cmpeq),
                   2488:     SSE_FOP(cmplt),
                   2489:     SSE_FOP(cmple),
                   2490:     SSE_FOP(cmpunord),
                   2491:     SSE_FOP(cmpneq),
                   2492:     SSE_FOP(cmpnlt),
                   2493:     SSE_FOP(cmpnle),
                   2494:     SSE_FOP(cmpord),
                   2495: };
                   2496:     
                   2497: static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                   2498: {
                   2499:     int b1, op1_offset, op2_offset, is_xmm, val, ot;
                   2500:     int modrm, mod, rm, reg, reg_addr, offset_addr;
                   2501:     GenOpFunc2 *sse_op2;
                   2502:     GenOpFunc3 *sse_op3;
                   2503: 
                   2504:     b &= 0xff;
                   2505:     if (s->prefix & PREFIX_DATA) 
                   2506:         b1 = 1;
                   2507:     else if (s->prefix & PREFIX_REPZ) 
                   2508:         b1 = 2;
                   2509:     else if (s->prefix & PREFIX_REPNZ) 
                   2510:         b1 = 3;
                   2511:     else
                   2512:         b1 = 0;
                   2513:     sse_op2 = sse_op_table1[b][b1];
                   2514:     if (!sse_op2) 
                   2515:         goto illegal_op;
                   2516:     if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
                   2517:         is_xmm = 1;
                   2518:     } else {
                   2519:         if (b1 == 0) {
                   2520:             /* MMX case */
                   2521:             is_xmm = 0;
                   2522:         } else {
                   2523:             is_xmm = 1;
                   2524:         }
                   2525:     }
                   2526:     /* simple MMX/SSE operation */
                   2527:     if (s->flags & HF_TS_MASK) {
                   2528:         gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   2529:         return;
                   2530:     }
                   2531:     if (s->flags & HF_EM_MASK) {
                   2532:     illegal_op:
                   2533:         gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
                   2534:         return;
                   2535:     }
                   2536:     if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
                   2537:         goto illegal_op;
                   2538:     if (b == 0x77) {
                   2539:         /* emms */
                   2540:         gen_op_emms();
                   2541:         return;
                   2542:     }
                   2543:     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
                   2544:        the static cpu state) */
                   2545:     if (!is_xmm) {
                   2546:         gen_op_enter_mmx();
                   2547:     }
                   2548: 
                   2549:     modrm = ldub_code(s->pc++);
                   2550:     reg = ((modrm >> 3) & 7);
                   2551:     if (is_xmm)
                   2552:         reg |= rex_r;
                   2553:     mod = (modrm >> 6) & 3;
                   2554:     if (sse_op2 == SSE_SPECIAL) {
                   2555:         b |= (b1 << 8);
                   2556:         switch(b) {
                   2557:         case 0x0e7: /* movntq */
                   2558:             if (mod == 3) 
                   2559:                 goto illegal_op;
                   2560:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2561:             gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
                   2562:             break;
                   2563:         case 0x1e7: /* movntdq */
                   2564:         case 0x02b: /* movntps */
                   2565:         case 0x12b: /* movntps */
1.1.1.3 ! root     2566:         case 0x3f0: /* lddqu */
        !          2567:             if (mod == 3)
1.1       root     2568:                 goto illegal_op;
                   2569:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2570:             gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
                   2571:             break;
                   2572:         case 0x6e: /* movd mm, ea */
                   2573:             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
                   2574:             gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
                   2575:             break;
                   2576:         case 0x16e: /* movd xmm, ea */
                   2577:             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
                   2578:             gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
                   2579:             break;
                   2580:         case 0x6f: /* movq mm, ea */
                   2581:             if (mod != 3) {
                   2582:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2583:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
                   2584:             } else {
                   2585:                 rm = (modrm & 7);
                   2586:                 gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
                   2587:                             offsetof(CPUX86State,fpregs[rm].mmx));
                   2588:             }
                   2589:             break;
                   2590:         case 0x010: /* movups */
                   2591:         case 0x110: /* movupd */
                   2592:         case 0x028: /* movaps */
                   2593:         case 0x128: /* movapd */
                   2594:         case 0x16f: /* movdqa xmm, ea */
                   2595:         case 0x26f: /* movdqu xmm, ea */
                   2596:             if (mod != 3) {
                   2597:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2598:                 gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
                   2599:             } else {
                   2600:                 rm = (modrm & 7) | REX_B(s);
                   2601:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
                   2602:                             offsetof(CPUX86State,xmm_regs[rm]));
                   2603:             }
                   2604:             break;
                   2605:         case 0x210: /* movss xmm, ea */
                   2606:             if (mod != 3) {
                   2607:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2608:                 gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
                   2609:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   2610:                 gen_op_movl_T0_0();
                   2611:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
                   2612:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
                   2613:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
                   2614:             } else {
                   2615:                 rm = (modrm & 7) | REX_B(s);
                   2616:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
                   2617:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
                   2618:             }
                   2619:             break;
                   2620:         case 0x310: /* movsd xmm, ea */
                   2621:             if (mod != 3) {
                   2622:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2623:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2624:                 gen_op_movl_T0_0();
                   2625:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
                   2626:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
                   2627:             } else {
                   2628:                 rm = (modrm & 7) | REX_B(s);
                   2629:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   2630:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   2631:             }
                   2632:             break;
                   2633:         case 0x012: /* movlps */
                   2634:         case 0x112: /* movlpd */
                   2635:             if (mod != 3) {
                   2636:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2637:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2638:             } else {
                   2639:                 /* movhlps */
                   2640:                 rm = (modrm & 7) | REX_B(s);
                   2641:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   2642:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
                   2643:             }
                   2644:             break;
1.1.1.3 ! root     2645:         case 0x212: /* movsldup */
        !          2646:             if (mod != 3) {
        !          2647:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
        !          2648:                 gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
        !          2649:             } else {
        !          2650:                 rm = (modrm & 7) | REX_B(s);
        !          2651:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
        !          2652:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
        !          2653:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
        !          2654:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
        !          2655:             }
        !          2656:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
        !          2657:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
        !          2658:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
        !          2659:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
        !          2660:             break;
        !          2661:         case 0x312: /* movddup */
        !          2662:             if (mod != 3) {
        !          2663:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
        !          2664:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
        !          2665:             } else {
        !          2666:                 rm = (modrm & 7) | REX_B(s);
        !          2667:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
        !          2668:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
        !          2669:             }
        !          2670:             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
        !          2671:                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
        !          2672:             break;
1.1       root     2673:         case 0x016: /* movhps */
                   2674:         case 0x116: /* movhpd */
                   2675:             if (mod != 3) {
                   2676:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2677:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
                   2678:             } else {
                   2679:                 /* movlhps */
                   2680:                 rm = (modrm & 7) | REX_B(s);
                   2681:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
                   2682:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   2683:             }
                   2684:             break;
                   2685:         case 0x216: /* movshdup */
                   2686:             if (mod != 3) {
                   2687:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2688:                 gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
                   2689:             } else {
                   2690:                 rm = (modrm & 7) | REX_B(s);
                   2691:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
                   2692:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
                   2693:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
                   2694:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
                   2695:             }
                   2696:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
                   2697:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
                   2698:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
                   2699:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
                   2700:             break;
                   2701:         case 0x7e: /* movd ea, mm */
                   2702:             gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
                   2703:             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
                   2704:             break;
                   2705:         case 0x17e: /* movd ea, xmm */
                   2706:             gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
                   2707:             gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
                   2708:             break;
                   2709:         case 0x27e: /* movq xmm, ea */
                   2710:             if (mod != 3) {
                   2711:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2712:                 gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2713:             } else {
                   2714:                 rm = (modrm & 7) | REX_B(s);
                   2715:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
                   2716:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
                   2717:             }
                   2718:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
                   2719:             break;
                   2720:         case 0x7f: /* movq ea, mm */
                   2721:             if (mod != 3) {
                   2722:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2723:                 gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
                   2724:             } else {
                   2725:                 rm = (modrm & 7);
                   2726:                 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
                   2727:                             offsetof(CPUX86State,fpregs[reg].mmx));
                   2728:             }
                   2729:             break;
                   2730:         case 0x011: /* movups */
                   2731:         case 0x111: /* movupd */
                   2732:         case 0x029: /* movaps */
                   2733:         case 0x129: /* movapd */
                   2734:         case 0x17f: /* movdqa ea, xmm */
                   2735:         case 0x27f: /* movdqu ea, xmm */
                   2736:             if (mod != 3) {
                   2737:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2738:                 gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
                   2739:             } else {
                   2740:                 rm = (modrm & 7) | REX_B(s);
                   2741:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
                   2742:                             offsetof(CPUX86State,xmm_regs[reg]));
                   2743:             }
                   2744:             break;
                   2745:         case 0x211: /* movss ea, xmm */
                   2746:             if (mod != 3) {
                   2747:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2748:                 gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   2749:                 gen_op_st_T0_A0[OT_LONG + s->mem_index]();
                   2750:             } else {
                   2751:                 rm = (modrm & 7) | REX_B(s);
                   2752:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
                   2753:                             offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                   2754:             }
                   2755:             break;
                   2756:         case 0x311: /* movsd ea, xmm */
                   2757:             if (mod != 3) {
                   2758:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2759:                 gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2760:             } else {
                   2761:                 rm = (modrm & 7) | REX_B(s);
                   2762:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
                   2763:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2764:             }
                   2765:             break;
                   2766:         case 0x013: /* movlps */
                   2767:         case 0x113: /* movlpd */
                   2768:             if (mod != 3) {
                   2769:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2770:                 gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2771:             } else {
                   2772:                 goto illegal_op;
                   2773:             }
                   2774:             break;
                   2775:         case 0x017: /* movhps */
                   2776:         case 0x117: /* movhpd */
                   2777:             if (mod != 3) {
                   2778:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2779:                 gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
                   2780:             } else {
                   2781:                 goto illegal_op;
                   2782:             }
                   2783:             break;
                   2784:         case 0x71: /* shift mm, im */
                   2785:         case 0x72:
                   2786:         case 0x73:
                   2787:         case 0x171: /* shift xmm, im */
                   2788:         case 0x172:
                   2789:         case 0x173:
                   2790:             val = ldub_code(s->pc++);
                   2791:             if (is_xmm) {
                   2792:                 gen_op_movl_T0_im(val);
                   2793:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                   2794:                 gen_op_movl_T0_0();
                   2795:                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
                   2796:                 op1_offset = offsetof(CPUX86State,xmm_t0);
                   2797:             } else {
                   2798:                 gen_op_movl_T0_im(val);
                   2799:                 gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
                   2800:                 gen_op_movl_T0_0();
                   2801:                 gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
                   2802:                 op1_offset = offsetof(CPUX86State,mmx_t0);
                   2803:             }
                   2804:             sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
                   2805:             if (!sse_op2)
                   2806:                 goto illegal_op;
                   2807:             if (is_xmm) {
                   2808:                 rm = (modrm & 7) | REX_B(s);
                   2809:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   2810:             } else {
                   2811:                 rm = (modrm & 7);
                   2812:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   2813:             }
                   2814:             sse_op2(op2_offset, op1_offset);
                   2815:             break;
                   2816:         case 0x050: /* movmskps */
                   2817:             rm = (modrm & 7) | REX_B(s);
                   2818:             gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
                   2819:             gen_op_mov_reg_T0[OT_LONG][reg]();
                   2820:             break;
                   2821:         case 0x150: /* movmskpd */
                   2822:             rm = (modrm & 7) | REX_B(s);
                   2823:             gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
                   2824:             gen_op_mov_reg_T0[OT_LONG][reg]();
                   2825:             break;
                   2826:         case 0x02a: /* cvtpi2ps */
                   2827:         case 0x12a: /* cvtpi2pd */
                   2828:             gen_op_enter_mmx();
                   2829:             if (mod != 3) {
                   2830:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2831:                 op2_offset = offsetof(CPUX86State,mmx_t0);
                   2832:                 gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
                   2833:             } else {
                   2834:                 rm = (modrm & 7);
                   2835:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   2836:             }
                   2837:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   2838:             switch(b >> 8) {
                   2839:             case 0x0:
                   2840:                 gen_op_cvtpi2ps(op1_offset, op2_offset);
                   2841:                 break;
                   2842:             default:
                   2843:             case 0x1:
                   2844:                 gen_op_cvtpi2pd(op1_offset, op2_offset);
                   2845:                 break;
                   2846:             }
                   2847:             break;
                   2848:         case 0x22a: /* cvtsi2ss */
                   2849:         case 0x32a: /* cvtsi2sd */
                   2850:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   2851:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   2852:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   2853:             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
                   2854:             break;
                   2855:         case 0x02c: /* cvttps2pi */
                   2856:         case 0x12c: /* cvttpd2pi */
                   2857:         case 0x02d: /* cvtps2pi */
                   2858:         case 0x12d: /* cvtpd2pi */
                   2859:             gen_op_enter_mmx();
                   2860:             if (mod != 3) {
                   2861:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2862:                 op2_offset = offsetof(CPUX86State,xmm_t0);
                   2863:                 gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
                   2864:             } else {
                   2865:                 rm = (modrm & 7) | REX_B(s);
                   2866:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   2867:             }
                   2868:             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
                   2869:             switch(b) {
                   2870:             case 0x02c:
                   2871:                 gen_op_cvttps2pi(op1_offset, op2_offset);
                   2872:                 break;
                   2873:             case 0x12c:
                   2874:                 gen_op_cvttpd2pi(op1_offset, op2_offset);
                   2875:                 break;
                   2876:             case 0x02d:
                   2877:                 gen_op_cvtps2pi(op1_offset, op2_offset);
                   2878:                 break;
                   2879:             case 0x12d:
                   2880:                 gen_op_cvtpd2pi(op1_offset, op2_offset);
                   2881:                 break;
                   2882:             }
                   2883:             break;
                   2884:         case 0x22c: /* cvttss2si */
                   2885:         case 0x32c: /* cvttsd2si */
                   2886:         case 0x22d: /* cvtss2si */
                   2887:         case 0x32d: /* cvtsd2si */
                   2888:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
                   2889:             if (mod != 3) {
                   2890:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2891:                 if ((b >> 8) & 1) {
                   2892:                     gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
                   2893:                 } else {
                   2894:                     gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
                   2895:                     gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                   2896:                 }
                   2897:                 op2_offset = offsetof(CPUX86State,xmm_t0);
                   2898:             } else {
                   2899:                 rm = (modrm & 7) | REX_B(s);
                   2900:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   2901:             }
                   2902:             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 + 
                   2903:                           (b & 1) * 4](op2_offset);
                   2904:             gen_op_mov_reg_T0[ot][reg]();
                   2905:             break;
                   2906:         case 0xc4: /* pinsrw */
                   2907:         case 0x1c4: 
                   2908:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   2909:             val = ldub_code(s->pc++);
                   2910:             if (b1) {
                   2911:                 val &= 7;
                   2912:                 gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
                   2913:             } else {
                   2914:                 val &= 3;
                   2915:                 gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
                   2916:             }
                   2917:             break;
                   2918:         case 0xc5: /* pextrw */
                   2919:         case 0x1c5: 
                   2920:             if (mod != 3)
                   2921:                 goto illegal_op;
                   2922:             val = ldub_code(s->pc++);
                   2923:             if (b1) {
                   2924:                 val &= 7;
                   2925:                 rm = (modrm & 7) | REX_B(s);
                   2926:                 gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
                   2927:             } else {
                   2928:                 val &= 3;
                   2929:                 rm = (modrm & 7);
                   2930:                 gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
                   2931:             }
                   2932:             reg = ((modrm >> 3) & 7) | rex_r;
                   2933:             gen_op_mov_reg_T0[OT_LONG][reg]();
                   2934:             break;
                   2935:         case 0x1d6: /* movq ea, xmm */
                   2936:             if (mod != 3) {
                   2937:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2938:                 gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2939:             } else {
                   2940:                 rm = (modrm & 7) | REX_B(s);
                   2941:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
                   2942:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2943:                 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
                   2944:             }
                   2945:             break;
                   2946:         case 0x2d6: /* movq2dq */
                   2947:             gen_op_enter_mmx();
                   2948:             rm = (modrm & 7) | REX_B(s);
                   2949:             gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
                   2950:                         offsetof(CPUX86State,fpregs[reg & 7].mmx));
                   2951:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
                   2952:             break;
                   2953:         case 0x3d6: /* movdq2q */
                   2954:             gen_op_enter_mmx();
                   2955:             rm = (modrm & 7);
                   2956:             gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
                   2957:                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
                   2958:             break;
                   2959:         case 0xd7: /* pmovmskb */
                   2960:         case 0x1d7:
                   2961:             if (mod != 3)
                   2962:                 goto illegal_op;
                   2963:             if (b1) {
                   2964:                 rm = (modrm & 7) | REX_B(s);
                   2965:                 gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
                   2966:             } else {
                   2967:                 rm = (modrm & 7);
                   2968:                 gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
                   2969:             }
                   2970:             reg = ((modrm >> 3) & 7) | rex_r;
                   2971:             gen_op_mov_reg_T0[OT_LONG][reg]();
                   2972:             break;
                   2973:         default:
                   2974:             goto illegal_op;
                   2975:         }
                   2976:     } else {
                   2977:         /* generic MMX or SSE operation */
                   2978:         if (b == 0xf7) {
                   2979:             /* maskmov : we must prepare A0 */
                   2980:             if (mod != 3) 
                   2981:                 goto illegal_op;
                   2982: #ifdef TARGET_X86_64
                   2983:             if (s->aflag == 2) {
                   2984:                 gen_op_movq_A0_reg[R_EDI]();
                   2985:             } else 
                   2986: #endif
                   2987:             {
                   2988:                 gen_op_movl_A0_reg[R_EDI]();
                   2989:                 if (s->aflag == 0)
                   2990:                     gen_op_andl_A0_ffff();
                   2991:             }
                   2992:             gen_add_A0_ds_seg(s);
                   2993:         }
                   2994:         if (is_xmm) {
                   2995:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
                   2996:             if (mod != 3) {
                   2997:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   2998:                 op2_offset = offsetof(CPUX86State,xmm_t0);
                   2999:                 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f) ||
                   3000:                                 b == 0xc2)) {
                   3001:                     /* specific case for SSE single instructions */
                   3002:                     if (b1 == 2) {
                   3003:                         /* 32 bit access */
                   3004:                         gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
                   3005:                         gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                   3006:                     } else {
                   3007:                         /* 64 bit access */
                   3008:                         gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
                   3009:                     }
                   3010:                 } else {
                   3011:                     gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
                   3012:                 }
                   3013:             } else {
                   3014:                 rm = (modrm & 7) | REX_B(s);
                   3015:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
                   3016:             }
                   3017:         } else {
                   3018:             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
                   3019:             if (mod != 3) {
                   3020:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3021:                 op2_offset = offsetof(CPUX86State,mmx_t0);
                   3022:                 gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
                   3023:             } else {
                   3024:                 rm = (modrm & 7);
                   3025:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
                   3026:             }
                   3027:         }
                   3028:         switch(b) {
                   3029:         case 0x70: /* pshufx insn */
                   3030:         case 0xc6: /* pshufx insn */
                   3031:             val = ldub_code(s->pc++);
                   3032:             sse_op3 = (GenOpFunc3 *)sse_op2;
                   3033:             sse_op3(op1_offset, op2_offset, val);
                   3034:             break;
                   3035:         case 0xc2:
                   3036:             /* compare insns */
                   3037:             val = ldub_code(s->pc++);
                   3038:             if (val >= 8)
                   3039:                 goto illegal_op;
                   3040:             sse_op2 = sse_op_table4[val][b1];
                   3041:             sse_op2(op1_offset, op2_offset);
                   3042:             break;
                   3043:         default:
                   3044:             sse_op2(op1_offset, op2_offset);
                   3045:             break;
                   3046:         }
                   3047:         if (b == 0x2e || b == 0x2f) {
                   3048:             s->cc_op = CC_OP_EFLAGS;
                   3049:         }
                   3050:     }
                   3051: }
                   3052: 
                   3053: 
                   3054: /* convert one instruction. s->is_jmp is set if the translation must
                   3055:    be stopped. Return the next pc value */
                   3056: static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                   3057: {
                   3058:     int b, prefixes, aflag, dflag;
                   3059:     int shift, ot;
                   3060:     int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
                   3061:     target_ulong next_eip, tval;
                   3062:     int rex_w, rex_r;
                   3063: 
                   3064:     s->pc = pc_start;
                   3065:     prefixes = 0;
                   3066:     aflag = s->code32;
                   3067:     dflag = s->code32;
                   3068:     s->override = -1;
                   3069:     rex_w = -1;
                   3070:     rex_r = 0;
                   3071: #ifdef TARGET_X86_64
                   3072:     s->rex_x = 0;
                   3073:     s->rex_b = 0;
                   3074:     x86_64_hregs = 0; 
                   3075: #endif
                   3076:     s->rip_offset = 0; /* for relative ip address */
                   3077:  next_byte:
                   3078:     b = ldub_code(s->pc);
                   3079:     s->pc++;
                   3080:     /* check prefixes */
                   3081: #ifdef TARGET_X86_64
                   3082:     if (CODE64(s)) {
                   3083:         switch (b) {
                   3084:         case 0xf3:
                   3085:             prefixes |= PREFIX_REPZ;
                   3086:             goto next_byte;
                   3087:         case 0xf2:
                   3088:             prefixes |= PREFIX_REPNZ;
                   3089:             goto next_byte;
                   3090:         case 0xf0:
                   3091:             prefixes |= PREFIX_LOCK;
                   3092:             goto next_byte;
                   3093:         case 0x2e:
                   3094:             s->override = R_CS;
                   3095:             goto next_byte;
                   3096:         case 0x36:
                   3097:             s->override = R_SS;
                   3098:             goto next_byte;
                   3099:         case 0x3e:
                   3100:             s->override = R_DS;
                   3101:             goto next_byte;
                   3102:         case 0x26:
                   3103:             s->override = R_ES;
                   3104:             goto next_byte;
                   3105:         case 0x64:
                   3106:             s->override = R_FS;
                   3107:             goto next_byte;
                   3108:         case 0x65:
                   3109:             s->override = R_GS;
                   3110:             goto next_byte;
                   3111:         case 0x66:
                   3112:             prefixes |= PREFIX_DATA;
                   3113:             goto next_byte;
                   3114:         case 0x67:
                   3115:             prefixes |= PREFIX_ADR;
                   3116:             goto next_byte;
                   3117:         case 0x40 ... 0x4f:
                   3118:             /* REX prefix */
                   3119:             rex_w = (b >> 3) & 1;
                   3120:             rex_r = (b & 0x4) << 1;
                   3121:             s->rex_x = (b & 0x2) << 2;
                   3122:             REX_B(s) = (b & 0x1) << 3;
                   3123:             x86_64_hregs = 1; /* select uniform byte register addressing */
                   3124:             goto next_byte;
                   3125:         }
                   3126:         if (rex_w == 1) {
                   3127:             /* 0x66 is ignored if rex.w is set */
                   3128:             dflag = 2;
                   3129:         } else {
                   3130:             if (prefixes & PREFIX_DATA)
                   3131:                 dflag ^= 1;
                   3132:         }
                   3133:         if (!(prefixes & PREFIX_ADR))
                   3134:             aflag = 2;
                   3135:     } else 
                   3136: #endif
                   3137:     {
                   3138:         switch (b) {
                   3139:         case 0xf3:
                   3140:             prefixes |= PREFIX_REPZ;
                   3141:             goto next_byte;
                   3142:         case 0xf2:
                   3143:             prefixes |= PREFIX_REPNZ;
                   3144:             goto next_byte;
                   3145:         case 0xf0:
                   3146:             prefixes |= PREFIX_LOCK;
                   3147:             goto next_byte;
                   3148:         case 0x2e:
                   3149:             s->override = R_CS;
                   3150:             goto next_byte;
                   3151:         case 0x36:
                   3152:             s->override = R_SS;
                   3153:             goto next_byte;
                   3154:         case 0x3e:
                   3155:             s->override = R_DS;
                   3156:             goto next_byte;
                   3157:         case 0x26:
                   3158:             s->override = R_ES;
                   3159:             goto next_byte;
                   3160:         case 0x64:
                   3161:             s->override = R_FS;
                   3162:             goto next_byte;
                   3163:         case 0x65:
                   3164:             s->override = R_GS;
                   3165:             goto next_byte;
                   3166:         case 0x66:
                   3167:             prefixes |= PREFIX_DATA;
                   3168:             goto next_byte;
                   3169:         case 0x67:
                   3170:             prefixes |= PREFIX_ADR;
                   3171:             goto next_byte;
                   3172:         }
                   3173:         if (prefixes & PREFIX_DATA)
                   3174:             dflag ^= 1;
                   3175:         if (prefixes & PREFIX_ADR)
                   3176:             aflag ^= 1;
                   3177:     }
                   3178: 
                   3179:     s->prefix = prefixes;
                   3180:     s->aflag = aflag;
                   3181:     s->dflag = dflag;
                   3182: 
                   3183:     /* lock generation */
                   3184:     if (prefixes & PREFIX_LOCK)
                   3185:         gen_op_lock();
                   3186: 
                   3187:     /* now check op code */
                   3188:  reswitch:
                   3189:     switch(b) {
                   3190:     case 0x0f:
                   3191:         /**************************/
                   3192:         /* extended op code */
                   3193:         b = ldub_code(s->pc++) | 0x100;
                   3194:         goto reswitch;
                   3195:         
                   3196:         /**************************/
                   3197:         /* arith & logic */
                   3198:     case 0x00 ... 0x05:
                   3199:     case 0x08 ... 0x0d:
                   3200:     case 0x10 ... 0x15:
                   3201:     case 0x18 ... 0x1d:
                   3202:     case 0x20 ... 0x25:
                   3203:     case 0x28 ... 0x2d:
                   3204:     case 0x30 ... 0x35:
                   3205:     case 0x38 ... 0x3d:
                   3206:         {
                   3207:             int op, f, val;
                   3208:             op = (b >> 3) & 7;
                   3209:             f = (b >> 1) & 3;
                   3210: 
                   3211:             if ((b & 1) == 0)
                   3212:                 ot = OT_BYTE;
                   3213:             else
                   3214:                 ot = dflag + OT_WORD;
                   3215:             
                   3216:             switch(f) {
                   3217:             case 0: /* OP Ev, Gv */
                   3218:                 modrm = ldub_code(s->pc++);
                   3219:                 reg = ((modrm >> 3) & 7) | rex_r;
                   3220:                 mod = (modrm >> 6) & 3;
                   3221:                 rm = (modrm & 7) | REX_B(s);
                   3222:                 if (mod != 3) {
                   3223:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3224:                     opreg = OR_TMP0;
                   3225:                 } else if (op == OP_XORL && rm == reg) {
                   3226:                 xor_zero:
                   3227:                     /* xor reg, reg optimisation */
                   3228:                     gen_op_movl_T0_0();
                   3229:                     s->cc_op = CC_OP_LOGICB + ot;
                   3230:                     gen_op_mov_reg_T0[ot][reg]();
                   3231:                     gen_op_update1_cc();
                   3232:                     break;
                   3233:                 } else {
                   3234:                     opreg = rm;
                   3235:                 }
                   3236:                 gen_op_mov_TN_reg[ot][1][reg]();
                   3237:                 gen_op(s, op, ot, opreg);
                   3238:                 break;
                   3239:             case 1: /* OP Gv, Ev */
                   3240:                 modrm = ldub_code(s->pc++);
                   3241:                 mod = (modrm >> 6) & 3;
                   3242:                 reg = ((modrm >> 3) & 7) | rex_r;
                   3243:                 rm = (modrm & 7) | REX_B(s);
                   3244:                 if (mod != 3) {
                   3245:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3246:                     gen_op_ld_T1_A0[ot + s->mem_index]();
                   3247:                 } else if (op == OP_XORL && rm == reg) {
                   3248:                     goto xor_zero;
                   3249:                 } else {
                   3250:                     gen_op_mov_TN_reg[ot][1][rm]();
                   3251:                 }
                   3252:                 gen_op(s, op, ot, reg);
                   3253:                 break;
                   3254:             case 2: /* OP A, Iv */
                   3255:                 val = insn_get(s, ot);
                   3256:                 gen_op_movl_T1_im(val);
                   3257:                 gen_op(s, op, ot, OR_EAX);
                   3258:                 break;
                   3259:             }
                   3260:         }
                   3261:         break;
                   3262: 
                   3263:     case 0x80: /* GRP1 */
                   3264:     case 0x81:
                   3265:     case 0x82:
                   3266:     case 0x83:
                   3267:         {
                   3268:             int val;
                   3269: 
                   3270:             if ((b & 1) == 0)
                   3271:                 ot = OT_BYTE;
                   3272:             else
                   3273:                 ot = dflag + OT_WORD;
                   3274:             
                   3275:             modrm = ldub_code(s->pc++);
                   3276:             mod = (modrm >> 6) & 3;
                   3277:             rm = (modrm & 7) | REX_B(s);
                   3278:             op = (modrm >> 3) & 7;
                   3279:             
                   3280:             if (mod != 3) {
                   3281:                 if (b == 0x83)
                   3282:                     s->rip_offset = 1;
                   3283:                 else
                   3284:                     s->rip_offset = insn_const_size(ot);
                   3285:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3286:                 opreg = OR_TMP0;
                   3287:             } else {
                   3288:                 opreg = rm;
                   3289:             }
                   3290: 
                   3291:             switch(b) {
                   3292:             default:
                   3293:             case 0x80:
                   3294:             case 0x81:
                   3295:             case 0x82:
                   3296:                 val = insn_get(s, ot);
                   3297:                 break;
                   3298:             case 0x83:
                   3299:                 val = (int8_t)insn_get(s, OT_BYTE);
                   3300:                 break;
                   3301:             }
                   3302:             gen_op_movl_T1_im(val);
                   3303:             gen_op(s, op, ot, opreg);
                   3304:         }
                   3305:         break;
                   3306: 
                   3307:         /**************************/
                   3308:         /* inc, dec, and other misc arith */
                   3309:     case 0x40 ... 0x47: /* inc Gv */
                   3310:         ot = dflag ? OT_LONG : OT_WORD;
                   3311:         gen_inc(s, ot, OR_EAX + (b & 7), 1);
                   3312:         break;
                   3313:     case 0x48 ... 0x4f: /* dec Gv */
                   3314:         ot = dflag ? OT_LONG : OT_WORD;
                   3315:         gen_inc(s, ot, OR_EAX + (b & 7), -1);
                   3316:         break;
                   3317:     case 0xf6: /* GRP3 */
                   3318:     case 0xf7:
                   3319:         if ((b & 1) == 0)
                   3320:             ot = OT_BYTE;
                   3321:         else
                   3322:             ot = dflag + OT_WORD;
                   3323: 
                   3324:         modrm = ldub_code(s->pc++);
                   3325:         mod = (modrm >> 6) & 3;
                   3326:         rm = (modrm & 7) | REX_B(s);
                   3327:         op = (modrm >> 3) & 7;
                   3328:         if (mod != 3) {
                   3329:             if (op == 0)
                   3330:                 s->rip_offset = insn_const_size(ot);
                   3331:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3332:             gen_op_ld_T0_A0[ot + s->mem_index]();
                   3333:         } else {
                   3334:             gen_op_mov_TN_reg[ot][0][rm]();
                   3335:         }
                   3336: 
                   3337:         switch(op) {
                   3338:         case 0: /* test */
                   3339:             val = insn_get(s, ot);
                   3340:             gen_op_movl_T1_im(val);
                   3341:             gen_op_testl_T0_T1_cc();
                   3342:             s->cc_op = CC_OP_LOGICB + ot;
                   3343:             break;
                   3344:         case 2: /* not */
                   3345:             gen_op_notl_T0();
                   3346:             if (mod != 3) {
                   3347:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   3348:             } else {
                   3349:                 gen_op_mov_reg_T0[ot][rm]();
                   3350:             }
                   3351:             break;
                   3352:         case 3: /* neg */
                   3353:             gen_op_negl_T0();
                   3354:             if (mod != 3) {
                   3355:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   3356:             } else {
                   3357:                 gen_op_mov_reg_T0[ot][rm]();
                   3358:             }
                   3359:             gen_op_update_neg_cc();
                   3360:             s->cc_op = CC_OP_SUBB + ot;
                   3361:             break;
                   3362:         case 4: /* mul */
                   3363:             switch(ot) {
                   3364:             case OT_BYTE:
                   3365:                 gen_op_mulb_AL_T0();
                   3366:                 s->cc_op = CC_OP_MULB;
                   3367:                 break;
                   3368:             case OT_WORD:
                   3369:                 gen_op_mulw_AX_T0();
                   3370:                 s->cc_op = CC_OP_MULW;
                   3371:                 break;
                   3372:             default:
                   3373:             case OT_LONG:
                   3374:                 gen_op_mull_EAX_T0();
                   3375:                 s->cc_op = CC_OP_MULL;
                   3376:                 break;
                   3377: #ifdef TARGET_X86_64
                   3378:             case OT_QUAD:
                   3379:                 gen_op_mulq_EAX_T0();
                   3380:                 s->cc_op = CC_OP_MULQ;
                   3381:                 break;
                   3382: #endif
                   3383:             }
                   3384:             break;
                   3385:         case 5: /* imul */
                   3386:             switch(ot) {
                   3387:             case OT_BYTE:
                   3388:                 gen_op_imulb_AL_T0();
                   3389:                 s->cc_op = CC_OP_MULB;
                   3390:                 break;
                   3391:             case OT_WORD:
                   3392:                 gen_op_imulw_AX_T0();
                   3393:                 s->cc_op = CC_OP_MULW;
                   3394:                 break;
                   3395:             default:
                   3396:             case OT_LONG:
                   3397:                 gen_op_imull_EAX_T0();
                   3398:                 s->cc_op = CC_OP_MULL;
                   3399:                 break;
                   3400: #ifdef TARGET_X86_64
                   3401:             case OT_QUAD:
                   3402:                 gen_op_imulq_EAX_T0();
                   3403:                 s->cc_op = CC_OP_MULQ;
                   3404:                 break;
                   3405: #endif
                   3406:             }
                   3407:             break;
                   3408:         case 6: /* div */
                   3409:             switch(ot) {
                   3410:             case OT_BYTE:
                   3411:                 gen_jmp_im(pc_start - s->cs_base);
                   3412:                 gen_op_divb_AL_T0();
                   3413:                 break;
                   3414:             case OT_WORD:
                   3415:                 gen_jmp_im(pc_start - s->cs_base);
                   3416:                 gen_op_divw_AX_T0();
                   3417:                 break;
                   3418:             default:
                   3419:             case OT_LONG:
                   3420:                 gen_jmp_im(pc_start - s->cs_base);
                   3421:                 gen_op_divl_EAX_T0();
                   3422:                 break;
                   3423: #ifdef TARGET_X86_64
                   3424:             case OT_QUAD:
                   3425:                 gen_jmp_im(pc_start - s->cs_base);
                   3426:                 gen_op_divq_EAX_T0();
                   3427:                 break;
                   3428: #endif
                   3429:             }
                   3430:             break;
                   3431:         case 7: /* idiv */
                   3432:             switch(ot) {
                   3433:             case OT_BYTE:
                   3434:                 gen_jmp_im(pc_start - s->cs_base);
                   3435:                 gen_op_idivb_AL_T0();
                   3436:                 break;
                   3437:             case OT_WORD:
                   3438:                 gen_jmp_im(pc_start - s->cs_base);
                   3439:                 gen_op_idivw_AX_T0();
                   3440:                 break;
                   3441:             default:
                   3442:             case OT_LONG:
                   3443:                 gen_jmp_im(pc_start - s->cs_base);
                   3444:                 gen_op_idivl_EAX_T0();
                   3445:                 break;
                   3446: #ifdef TARGET_X86_64
                   3447:             case OT_QUAD:
                   3448:                 gen_jmp_im(pc_start - s->cs_base);
                   3449:                 gen_op_idivq_EAX_T0();
                   3450:                 break;
                   3451: #endif
                   3452:             }
                   3453:             break;
                   3454:         default:
                   3455:             goto illegal_op;
                   3456:         }
                   3457:         break;
                   3458: 
                   3459:     case 0xfe: /* GRP4 */
                   3460:     case 0xff: /* GRP5 */
                   3461:         if ((b & 1) == 0)
                   3462:             ot = OT_BYTE;
                   3463:         else
                   3464:             ot = dflag + OT_WORD;
                   3465: 
                   3466:         modrm = ldub_code(s->pc++);
                   3467:         mod = (modrm >> 6) & 3;
                   3468:         rm = (modrm & 7) | REX_B(s);
                   3469:         op = (modrm >> 3) & 7;
                   3470:         if (op >= 2 && b == 0xfe) {
                   3471:             goto illegal_op;
                   3472:         }
                   3473:         if (CODE64(s)) {
                   3474:             if (op == 2 || op == 4) {
                   3475:                 /* operand size for jumps is 64 bit */
                   3476:                 ot = OT_QUAD;
                   3477:             } else if (op == 3 || op == 5) {
                   3478:                 /* for call calls, the operand is 16 or 32 bit, even
                   3479:                    in long mode */
                   3480:                 ot = dflag ? OT_LONG : OT_WORD;
                   3481:             } else if (op == 6) {
                   3482:                 /* default push size is 64 bit */
                   3483:                 ot = dflag ? OT_QUAD : OT_WORD;
                   3484:             }
                   3485:         }
                   3486:         if (mod != 3) {
                   3487:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3488:             if (op >= 2 && op != 3 && op != 5)
                   3489:                 gen_op_ld_T0_A0[ot + s->mem_index]();
                   3490:         } else {
                   3491:             gen_op_mov_TN_reg[ot][0][rm]();
                   3492:         }
                   3493: 
                   3494:         switch(op) {
                   3495:         case 0: /* inc Ev */
                   3496:             if (mod != 3)
                   3497:                 opreg = OR_TMP0;
                   3498:             else
                   3499:                 opreg = rm;
                   3500:             gen_inc(s, ot, opreg, 1);
                   3501:             break;
                   3502:         case 1: /* dec Ev */
                   3503:             if (mod != 3)
                   3504:                 opreg = OR_TMP0;
                   3505:             else
                   3506:                 opreg = rm;
                   3507:             gen_inc(s, ot, opreg, -1);
                   3508:             break;
                   3509:         case 2: /* call Ev */
                   3510:             /* XXX: optimize if memory (no 'and' is necessary) */
                   3511:             if (s->dflag == 0)
                   3512:                 gen_op_andl_T0_ffff();
                   3513:             next_eip = s->pc - s->cs_base;
                   3514:             gen_movtl_T1_im(next_eip);
                   3515:             gen_push_T1(s);
                   3516:             gen_op_jmp_T0();
                   3517:             gen_eob(s);
                   3518:             break;
                   3519:         case 3: /* lcall Ev */
                   3520:             gen_op_ld_T1_A0[ot + s->mem_index]();
                   3521:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
                   3522:             gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
                   3523:         do_lcall:
                   3524:             if (s->pe && !s->vm86) {
                   3525:                 if (s->cc_op != CC_OP_DYNAMIC)
                   3526:                     gen_op_set_cc_op(s->cc_op);
                   3527:                 gen_jmp_im(pc_start - s->cs_base);
                   3528:                 gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
                   3529:             } else {
                   3530:                 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
                   3531:             }
                   3532:             gen_eob(s);
                   3533:             break;
                   3534:         case 4: /* jmp Ev */
                   3535:             if (s->dflag == 0)
                   3536:                 gen_op_andl_T0_ffff();
                   3537:             gen_op_jmp_T0();
                   3538:             gen_eob(s);
                   3539:             break;
                   3540:         case 5: /* ljmp Ev */
                   3541:             gen_op_ld_T1_A0[ot + s->mem_index]();
                   3542:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
                   3543:             gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
                   3544:         do_ljmp:
                   3545:             if (s->pe && !s->vm86) {
                   3546:                 if (s->cc_op != CC_OP_DYNAMIC)
                   3547:                     gen_op_set_cc_op(s->cc_op);
                   3548:                 gen_jmp_im(pc_start - s->cs_base);
                   3549:                 gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
                   3550:             } else {
                   3551:                 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
                   3552:                 gen_op_movl_T0_T1();
                   3553:                 gen_op_jmp_T0();
                   3554:             }
                   3555:             gen_eob(s);
                   3556:             break;
                   3557:         case 6: /* push Ev */
                   3558:             gen_push_T0(s);
                   3559:             break;
                   3560:         default:
                   3561:             goto illegal_op;
                   3562:         }
                   3563:         break;
                   3564: 
                   3565:     case 0x84: /* test Ev, Gv */
                   3566:     case 0x85: 
                   3567:         if ((b & 1) == 0)
                   3568:             ot = OT_BYTE;
                   3569:         else
                   3570:             ot = dflag + OT_WORD;
                   3571: 
                   3572:         modrm = ldub_code(s->pc++);
                   3573:         mod = (modrm >> 6) & 3;
                   3574:         rm = (modrm & 7) | REX_B(s);
                   3575:         reg = ((modrm >> 3) & 7) | rex_r;
                   3576:         
                   3577:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   3578:         gen_op_mov_TN_reg[ot][1][reg]();
                   3579:         gen_op_testl_T0_T1_cc();
                   3580:         s->cc_op = CC_OP_LOGICB + ot;
                   3581:         break;
                   3582:         
                   3583:     case 0xa8: /* test eAX, Iv */
                   3584:     case 0xa9:
                   3585:         if ((b & 1) == 0)
                   3586:             ot = OT_BYTE;
                   3587:         else
                   3588:             ot = dflag + OT_WORD;
                   3589:         val = insn_get(s, ot);
                   3590: 
                   3591:         gen_op_mov_TN_reg[ot][0][OR_EAX]();
                   3592:         gen_op_movl_T1_im(val);
                   3593:         gen_op_testl_T0_T1_cc();
                   3594:         s->cc_op = CC_OP_LOGICB + ot;
                   3595:         break;
                   3596:         
                   3597:     case 0x98: /* CWDE/CBW */
                   3598: #ifdef TARGET_X86_64
                   3599:         if (dflag == 2) {
                   3600:             gen_op_movslq_RAX_EAX();
                   3601:         } else
                   3602: #endif
                   3603:         if (dflag == 1)
                   3604:             gen_op_movswl_EAX_AX();
                   3605:         else
                   3606:             gen_op_movsbw_AX_AL();
                   3607:         break;
                   3608:     case 0x99: /* CDQ/CWD */
                   3609: #ifdef TARGET_X86_64
                   3610:         if (dflag == 2) {
                   3611:             gen_op_movsqo_RDX_RAX();
                   3612:         } else
                   3613: #endif
                   3614:         if (dflag == 1)
                   3615:             gen_op_movslq_EDX_EAX();
                   3616:         else
                   3617:             gen_op_movswl_DX_AX();
                   3618:         break;
                   3619:     case 0x1af: /* imul Gv, Ev */
                   3620:     case 0x69: /* imul Gv, Ev, I */
                   3621:     case 0x6b:
                   3622:         ot = dflag + OT_WORD;
                   3623:         modrm = ldub_code(s->pc++);
                   3624:         reg = ((modrm >> 3) & 7) | rex_r;
                   3625:         if (b == 0x69)
                   3626:             s->rip_offset = insn_const_size(ot);
                   3627:         else if (b == 0x6b)
                   3628:             s->rip_offset = 1;
                   3629:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   3630:         if (b == 0x69) {
                   3631:             val = insn_get(s, ot);
                   3632:             gen_op_movl_T1_im(val);
                   3633:         } else if (b == 0x6b) {
                   3634:             val = (int8_t)insn_get(s, OT_BYTE);
                   3635:             gen_op_movl_T1_im(val);
                   3636:         } else {
                   3637:             gen_op_mov_TN_reg[ot][1][reg]();
                   3638:         }
                   3639: 
                   3640: #ifdef TARGET_X86_64
                   3641:         if (ot == OT_QUAD) {
                   3642:             gen_op_imulq_T0_T1();
                   3643:         } else
                   3644: #endif
                   3645:         if (ot == OT_LONG) {
                   3646:             gen_op_imull_T0_T1();
                   3647:         } else {
                   3648:             gen_op_imulw_T0_T1();
                   3649:         }
                   3650:         gen_op_mov_reg_T0[ot][reg]();
                   3651:         s->cc_op = CC_OP_MULB + ot;
                   3652:         break;
                   3653:     case 0x1c0:
                   3654:     case 0x1c1: /* xadd Ev, Gv */
                   3655:         if ((b & 1) == 0)
                   3656:             ot = OT_BYTE;
                   3657:         else
                   3658:             ot = dflag + OT_WORD;
                   3659:         modrm = ldub_code(s->pc++);
                   3660:         reg = ((modrm >> 3) & 7) | rex_r;
                   3661:         mod = (modrm >> 6) & 3;
                   3662:         if (mod == 3) {
                   3663:             rm = (modrm & 7) | REX_B(s);
                   3664:             gen_op_mov_TN_reg[ot][0][reg]();
                   3665:             gen_op_mov_TN_reg[ot][1][rm]();
                   3666:             gen_op_addl_T0_T1();
                   3667:             gen_op_mov_reg_T1[ot][reg]();
                   3668:             gen_op_mov_reg_T0[ot][rm]();
                   3669:         } else {
                   3670:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3671:             gen_op_mov_TN_reg[ot][0][reg]();
                   3672:             gen_op_ld_T1_A0[ot + s->mem_index]();
                   3673:             gen_op_addl_T0_T1();
                   3674:             gen_op_st_T0_A0[ot + s->mem_index]();
                   3675:             gen_op_mov_reg_T1[ot][reg]();
                   3676:         }
                   3677:         gen_op_update2_cc();
                   3678:         s->cc_op = CC_OP_ADDB + ot;
                   3679:         break;
                   3680:     case 0x1b0:
                   3681:     case 0x1b1: /* cmpxchg Ev, Gv */
                   3682:         if ((b & 1) == 0)
                   3683:             ot = OT_BYTE;
                   3684:         else
                   3685:             ot = dflag + OT_WORD;
                   3686:         modrm = ldub_code(s->pc++);
                   3687:         reg = ((modrm >> 3) & 7) | rex_r;
                   3688:         mod = (modrm >> 6) & 3;
                   3689:         gen_op_mov_TN_reg[ot][1][reg]();
                   3690:         if (mod == 3) {
                   3691:             rm = (modrm & 7) | REX_B(s);
                   3692:             gen_op_mov_TN_reg[ot][0][rm]();
                   3693:             gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
                   3694:             gen_op_mov_reg_T0[ot][rm]();
                   3695:         } else {
                   3696:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3697:             gen_op_ld_T0_A0[ot + s->mem_index]();
                   3698:             gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
                   3699:         }
                   3700:         s->cc_op = CC_OP_SUBB + ot;
                   3701:         break;
                   3702:     case 0x1c7: /* cmpxchg8b */
                   3703:         modrm = ldub_code(s->pc++);
                   3704:         mod = (modrm >> 6) & 3;
                   3705:         if (mod == 3)
                   3706:             goto illegal_op;
                   3707:         if (s->cc_op != CC_OP_DYNAMIC)
                   3708:             gen_op_set_cc_op(s->cc_op);
                   3709:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3710:         gen_op_cmpxchg8b();
                   3711:         s->cc_op = CC_OP_EFLAGS;
                   3712:         break;
                   3713:         
                   3714:         /**************************/
                   3715:         /* push/pop */
                   3716:     case 0x50 ... 0x57: /* push */
                   3717:         gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
                   3718:         gen_push_T0(s);
                   3719:         break;
                   3720:     case 0x58 ... 0x5f: /* pop */
                   3721:         if (CODE64(s)) {
                   3722:             ot = dflag ? OT_QUAD : OT_WORD;
                   3723:         } else {
                   3724:             ot = dflag + OT_WORD;
                   3725:         }
                   3726:         gen_pop_T0(s);
                   3727:         /* NOTE: order is important for pop %sp */
                   3728:         gen_pop_update(s);
                   3729:         gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
                   3730:         break;
                   3731:     case 0x60: /* pusha */
                   3732:         if (CODE64(s))
                   3733:             goto illegal_op;
                   3734:         gen_pusha(s);
                   3735:         break;
                   3736:     case 0x61: /* popa */
                   3737:         if (CODE64(s))
                   3738:             goto illegal_op;
                   3739:         gen_popa(s);
                   3740:         break;
                   3741:     case 0x68: /* push Iv */
                   3742:     case 0x6a:
                   3743:         if (CODE64(s)) {
                   3744:             ot = dflag ? OT_QUAD : OT_WORD;
                   3745:         } else {
                   3746:             ot = dflag + OT_WORD;
                   3747:         }
                   3748:         if (b == 0x68)
                   3749:             val = insn_get(s, ot);
                   3750:         else
                   3751:             val = (int8_t)insn_get(s, OT_BYTE);
                   3752:         gen_op_movl_T0_im(val);
                   3753:         gen_push_T0(s);
                   3754:         break;
                   3755:     case 0x8f: /* pop Ev */
                   3756:         if (CODE64(s)) {
                   3757:             ot = dflag ? OT_QUAD : OT_WORD;
                   3758:         } else {
                   3759:             ot = dflag + OT_WORD;
                   3760:         }
                   3761:         modrm = ldub_code(s->pc++);
                   3762:         mod = (modrm >> 6) & 3;
                   3763:         gen_pop_T0(s);
                   3764:         if (mod == 3) {
                   3765:             /* NOTE: order is important for pop %sp */
                   3766:             gen_pop_update(s);
                   3767:             rm = (modrm & 7) | REX_B(s);
                   3768:             gen_op_mov_reg_T0[ot][rm]();
                   3769:         } else {
                   3770:             /* NOTE: order is important too for MMU exceptions */
                   3771:             s->popl_esp_hack = 1 << ot;
                   3772:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   3773:             s->popl_esp_hack = 0;
                   3774:             gen_pop_update(s);
                   3775:         }
                   3776:         break;
                   3777:     case 0xc8: /* enter */
                   3778:         {
                   3779:             int level;
                   3780:             val = lduw_code(s->pc);
                   3781:             s->pc += 2;
                   3782:             level = ldub_code(s->pc++);
                   3783:             gen_enter(s, val, level);
                   3784:         }
                   3785:         break;
                   3786:     case 0xc9: /* leave */
                   3787:         /* XXX: exception not precise (ESP is updated before potential exception) */
                   3788:         if (CODE64(s)) {
                   3789:             gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
                   3790:             gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
                   3791:         } else if (s->ss32) {
                   3792:             gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
                   3793:             gen_op_mov_reg_T0[OT_LONG][R_ESP]();
                   3794:         } else {
                   3795:             gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
                   3796:             gen_op_mov_reg_T0[OT_WORD][R_ESP]();
                   3797:         }
                   3798:         gen_pop_T0(s);
                   3799:         if (CODE64(s)) {
                   3800:             ot = dflag ? OT_QUAD : OT_WORD;
                   3801:         } else {
                   3802:             ot = dflag + OT_WORD;
                   3803:         }
                   3804:         gen_op_mov_reg_T0[ot][R_EBP]();
                   3805:         gen_pop_update(s);
                   3806:         break;
                   3807:     case 0x06: /* push es */
                   3808:     case 0x0e: /* push cs */
                   3809:     case 0x16: /* push ss */
                   3810:     case 0x1e: /* push ds */
                   3811:         if (CODE64(s))
                   3812:             goto illegal_op;
                   3813:         gen_op_movl_T0_seg(b >> 3);
                   3814:         gen_push_T0(s);
                   3815:         break;
                   3816:     case 0x1a0: /* push fs */
                   3817:     case 0x1a8: /* push gs */
                   3818:         gen_op_movl_T0_seg((b >> 3) & 7);
                   3819:         gen_push_T0(s);
                   3820:         break;
                   3821:     case 0x07: /* pop es */
                   3822:     case 0x17: /* pop ss */
                   3823:     case 0x1f: /* pop ds */
                   3824:         if (CODE64(s))
                   3825:             goto illegal_op;
                   3826:         reg = b >> 3;
                   3827:         gen_pop_T0(s);
                   3828:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
                   3829:         gen_pop_update(s);
                   3830:         if (reg == R_SS) {
                   3831:             /* if reg == SS, inhibit interrupts/trace. */
                   3832:             /* If several instructions disable interrupts, only the
                   3833:                _first_ does it */
                   3834:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
                   3835:                 gen_op_set_inhibit_irq();
                   3836:             s->tf = 0;
                   3837:         }
                   3838:         if (s->is_jmp) {
                   3839:             gen_jmp_im(s->pc - s->cs_base);
                   3840:             gen_eob(s);
                   3841:         }
                   3842:         break;
                   3843:     case 0x1a1: /* pop fs */
                   3844:     case 0x1a9: /* pop gs */
                   3845:         gen_pop_T0(s);
                   3846:         gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
                   3847:         gen_pop_update(s);
                   3848:         if (s->is_jmp) {
                   3849:             gen_jmp_im(s->pc - s->cs_base);
                   3850:             gen_eob(s);
                   3851:         }
                   3852:         break;
                   3853: 
                   3854:         /**************************/
                   3855:         /* mov */
                   3856:     case 0x88:
                   3857:     case 0x89: /* mov Gv, Ev */
                   3858:         if ((b & 1) == 0)
                   3859:             ot = OT_BYTE;
                   3860:         else
                   3861:             ot = dflag + OT_WORD;
                   3862:         modrm = ldub_code(s->pc++);
                   3863:         reg = ((modrm >> 3) & 7) | rex_r;
                   3864:         
                   3865:         /* generate a generic store */
                   3866:         gen_ldst_modrm(s, modrm, ot, reg, 1);
                   3867:         break;
                   3868:     case 0xc6:
                   3869:     case 0xc7: /* mov Ev, Iv */
                   3870:         if ((b & 1) == 0)
                   3871:             ot = OT_BYTE;
                   3872:         else
                   3873:             ot = dflag + OT_WORD;
                   3874:         modrm = ldub_code(s->pc++);
                   3875:         mod = (modrm >> 6) & 3;
                   3876:         if (mod != 3) {
                   3877:             s->rip_offset = insn_const_size(ot);
                   3878:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3879:         }
                   3880:         val = insn_get(s, ot);
                   3881:         gen_op_movl_T0_im(val);
                   3882:         if (mod != 3)
                   3883:             gen_op_st_T0_A0[ot + s->mem_index]();
                   3884:         else
                   3885:             gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
                   3886:         break;
                   3887:     case 0x8a:
                   3888:     case 0x8b: /* mov Ev, Gv */
                   3889:         if ((b & 1) == 0)
                   3890:             ot = OT_BYTE;
                   3891:         else
                   3892:             ot = OT_WORD + dflag;
                   3893:         modrm = ldub_code(s->pc++);
                   3894:         reg = ((modrm >> 3) & 7) | rex_r;
                   3895:         
                   3896:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   3897:         gen_op_mov_reg_T0[ot][reg]();
                   3898:         break;
                   3899:     case 0x8e: /* mov seg, Gv */
                   3900:         modrm = ldub_code(s->pc++);
                   3901:         reg = (modrm >> 3) & 7;
                   3902:         if (reg >= 6 || reg == R_CS)
                   3903:             goto illegal_op;
                   3904:         gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   3905:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
                   3906:         if (reg == R_SS) {
                   3907:             /* if reg == SS, inhibit interrupts/trace */
                   3908:             /* If several instructions disable interrupts, only the
                   3909:                _first_ does it */
                   3910:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
                   3911:                 gen_op_set_inhibit_irq();
                   3912:             s->tf = 0;
                   3913:         }
                   3914:         if (s->is_jmp) {
                   3915:             gen_jmp_im(s->pc - s->cs_base);
                   3916:             gen_eob(s);
                   3917:         }
                   3918:         break;
                   3919:     case 0x8c: /* mov Gv, seg */
                   3920:         modrm = ldub_code(s->pc++);
                   3921:         reg = (modrm >> 3) & 7;
                   3922:         mod = (modrm >> 6) & 3;
                   3923:         if (reg >= 6)
                   3924:             goto illegal_op;
                   3925:         gen_op_movl_T0_seg(reg);
                   3926:         if (mod == 3)
                   3927:             ot = OT_WORD + dflag;
                   3928:         else
                   3929:             ot = OT_WORD;
                   3930:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   3931:         break;
                   3932: 
                   3933:     case 0x1b6: /* movzbS Gv, Eb */
                   3934:     case 0x1b7: /* movzwS Gv, Eb */
                   3935:     case 0x1be: /* movsbS Gv, Eb */
                   3936:     case 0x1bf: /* movswS Gv, Eb */
                   3937:         {
                   3938:             int d_ot;
                   3939:             /* d_ot is the size of destination */
                   3940:             d_ot = dflag + OT_WORD;
                   3941:             /* ot is the size of source */
                   3942:             ot = (b & 1) + OT_BYTE;
                   3943:             modrm = ldub_code(s->pc++);
                   3944:             reg = ((modrm >> 3) & 7) | rex_r;
                   3945:             mod = (modrm >> 6) & 3;
                   3946:             rm = (modrm & 7) | REX_B(s);
                   3947:             
                   3948:             if (mod == 3) {
                   3949:                 gen_op_mov_TN_reg[ot][0][rm]();
                   3950:                 switch(ot | (b & 8)) {
                   3951:                 case OT_BYTE:
                   3952:                     gen_op_movzbl_T0_T0();
                   3953:                     break;
                   3954:                 case OT_BYTE | 8:
                   3955:                     gen_op_movsbl_T0_T0();
                   3956:                     break;
                   3957:                 case OT_WORD:
                   3958:                     gen_op_movzwl_T0_T0();
                   3959:                     break;
                   3960:                 default:
                   3961:                 case OT_WORD | 8:
                   3962:                     gen_op_movswl_T0_T0();
                   3963:                     break;
                   3964:                 }
                   3965:                 gen_op_mov_reg_T0[d_ot][reg]();
                   3966:             } else {
                   3967:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3968:                 if (b & 8) {
                   3969:                     gen_op_lds_T0_A0[ot + s->mem_index]();
                   3970:                 } else {
                   3971:                     gen_op_ldu_T0_A0[ot + s->mem_index]();
                   3972:                 }
                   3973:                 gen_op_mov_reg_T0[d_ot][reg]();
                   3974:             }
                   3975:         }
                   3976:         break;
                   3977: 
                   3978:     case 0x8d: /* lea */
                   3979:         ot = dflag + OT_WORD;
                   3980:         modrm = ldub_code(s->pc++);
                   3981:         mod = (modrm >> 6) & 3;
                   3982:         if (mod == 3)
                   3983:             goto illegal_op;
                   3984:         reg = ((modrm >> 3) & 7) | rex_r;
                   3985:         /* we must ensure that no segment is added */
                   3986:         s->override = -1;
                   3987:         val = s->addseg;
                   3988:         s->addseg = 0;
                   3989:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   3990:         s->addseg = val;
                   3991:         gen_op_mov_reg_A0[ot - OT_WORD][reg]();
                   3992:         break;
                   3993:         
                   3994:     case 0xa0: /* mov EAX, Ov */
                   3995:     case 0xa1:
                   3996:     case 0xa2: /* mov Ov, EAX */
                   3997:     case 0xa3:
                   3998:         {
                   3999:             target_ulong offset_addr;
                   4000: 
                   4001:             if ((b & 1) == 0)
                   4002:                 ot = OT_BYTE;
                   4003:             else
                   4004:                 ot = dflag + OT_WORD;
                   4005: #ifdef TARGET_X86_64
                   4006:             if (s->aflag == 2) {
                   4007:                 offset_addr = ldq_code(s->pc);
                   4008:                 s->pc += 8;
                   4009:                 if (offset_addr == (int32_t)offset_addr)
                   4010:                     gen_op_movq_A0_im(offset_addr);
                   4011:                 else
                   4012:                     gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
                   4013:             } else 
                   4014: #endif
                   4015:             {
                   4016:                 if (s->aflag) {
                   4017:                     offset_addr = insn_get(s, OT_LONG);
                   4018:                 } else {
                   4019:                     offset_addr = insn_get(s, OT_WORD);
                   4020:                 }
                   4021:                 gen_op_movl_A0_im(offset_addr);
                   4022:             }
                   4023:             gen_add_A0_ds_seg(s);
                   4024:             if ((b & 2) == 0) {
                   4025:                 gen_op_ld_T0_A0[ot + s->mem_index]();
                   4026:                 gen_op_mov_reg_T0[ot][R_EAX]();
                   4027:             } else {
                   4028:                 gen_op_mov_TN_reg[ot][0][R_EAX]();
                   4029:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   4030:             }
                   4031:         }
                   4032:         break;
                   4033:     case 0xd7: /* xlat */
                   4034: #ifdef TARGET_X86_64
                   4035:         if (s->aflag == 2) {
                   4036:             gen_op_movq_A0_reg[R_EBX]();
                   4037:             gen_op_addq_A0_AL();
                   4038:         } else 
                   4039: #endif
                   4040:         {
                   4041:             gen_op_movl_A0_reg[R_EBX]();
                   4042:             gen_op_addl_A0_AL();
                   4043:             if (s->aflag == 0)
                   4044:                 gen_op_andl_A0_ffff();
                   4045:         }
                   4046:         gen_add_A0_ds_seg(s);
                   4047:         gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
                   4048:         gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
                   4049:         break;
                   4050:     case 0xb0 ... 0xb7: /* mov R, Ib */
                   4051:         val = insn_get(s, OT_BYTE);
                   4052:         gen_op_movl_T0_im(val);
                   4053:         gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
                   4054:         break;
                   4055:     case 0xb8 ... 0xbf: /* mov R, Iv */
                   4056: #ifdef TARGET_X86_64
                   4057:         if (dflag == 2) {
                   4058:             uint64_t tmp;
                   4059:             /* 64 bit case */
                   4060:             tmp = ldq_code(s->pc);
                   4061:             s->pc += 8;
                   4062:             reg = (b & 7) | REX_B(s);
                   4063:             gen_movtl_T0_im(tmp);
                   4064:             gen_op_mov_reg_T0[OT_QUAD][reg]();
                   4065:         } else 
                   4066: #endif
                   4067:         {
                   4068:             ot = dflag ? OT_LONG : OT_WORD;
                   4069:             val = insn_get(s, ot);
                   4070:             reg = (b & 7) | REX_B(s);
                   4071:             gen_op_movl_T0_im(val);
                   4072:             gen_op_mov_reg_T0[ot][reg]();
                   4073:         }
                   4074:         break;
                   4075: 
                   4076:     case 0x91 ... 0x97: /* xchg R, EAX */
                   4077:         ot = dflag + OT_WORD;
                   4078:         reg = (b & 7) | REX_B(s);
                   4079:         rm = R_EAX;
                   4080:         goto do_xchg_reg;
                   4081:     case 0x86:
                   4082:     case 0x87: /* xchg Ev, Gv */
                   4083:         if ((b & 1) == 0)
                   4084:             ot = OT_BYTE;
                   4085:         else
                   4086:             ot = dflag + OT_WORD;
                   4087:         modrm = ldub_code(s->pc++);
                   4088:         reg = ((modrm >> 3) & 7) | rex_r;
                   4089:         mod = (modrm >> 6) & 3;
                   4090:         if (mod == 3) {
                   4091:             rm = (modrm & 7) | REX_B(s);
                   4092:         do_xchg_reg:
                   4093:             gen_op_mov_TN_reg[ot][0][reg]();
                   4094:             gen_op_mov_TN_reg[ot][1][rm]();
                   4095:             gen_op_mov_reg_T0[ot][rm]();
                   4096:             gen_op_mov_reg_T1[ot][reg]();
                   4097:         } else {
                   4098:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4099:             gen_op_mov_TN_reg[ot][0][reg]();
                   4100:             /* for xchg, lock is implicit */
                   4101:             if (!(prefixes & PREFIX_LOCK))
                   4102:                 gen_op_lock();
                   4103:             gen_op_ld_T1_A0[ot + s->mem_index]();
                   4104:             gen_op_st_T0_A0[ot + s->mem_index]();
                   4105:             if (!(prefixes & PREFIX_LOCK))
                   4106:                 gen_op_unlock();
                   4107:             gen_op_mov_reg_T1[ot][reg]();
                   4108:         }
                   4109:         break;
                   4110:     case 0xc4: /* les Gv */
                   4111:         if (CODE64(s))
                   4112:             goto illegal_op;
                   4113:         op = R_ES;
                   4114:         goto do_lxx;
                   4115:     case 0xc5: /* lds Gv */
                   4116:         if (CODE64(s))
                   4117:             goto illegal_op;
                   4118:         op = R_DS;
                   4119:         goto do_lxx;
                   4120:     case 0x1b2: /* lss Gv */
                   4121:         op = R_SS;
                   4122:         goto do_lxx;
                   4123:     case 0x1b4: /* lfs Gv */
                   4124:         op = R_FS;
                   4125:         goto do_lxx;
                   4126:     case 0x1b5: /* lgs Gv */
                   4127:         op = R_GS;
                   4128:     do_lxx:
                   4129:         ot = dflag ? OT_LONG : OT_WORD;
                   4130:         modrm = ldub_code(s->pc++);
                   4131:         reg = ((modrm >> 3) & 7) | rex_r;
                   4132:         mod = (modrm >> 6) & 3;
                   4133:         if (mod == 3)
                   4134:             goto illegal_op;
                   4135:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4136:         gen_op_ld_T1_A0[ot + s->mem_index]();
                   4137:         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
                   4138:         /* load the segment first to handle exceptions properly */
                   4139:         gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
                   4140:         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
                   4141:         /* then put the data */
                   4142:         gen_op_mov_reg_T1[ot][reg]();
                   4143:         if (s->is_jmp) {
                   4144:             gen_jmp_im(s->pc - s->cs_base);
                   4145:             gen_eob(s);
                   4146:         }
                   4147:         break;
                   4148:         
                   4149:         /************************/
                   4150:         /* shifts */
                   4151:     case 0xc0:
                   4152:     case 0xc1:
                   4153:         /* shift Ev,Ib */
                   4154:         shift = 2;
                   4155:     grp2:
                   4156:         {
                   4157:             if ((b & 1) == 0)
                   4158:                 ot = OT_BYTE;
                   4159:             else
                   4160:                 ot = dflag + OT_WORD;
                   4161:             
                   4162:             modrm = ldub_code(s->pc++);
                   4163:             mod = (modrm >> 6) & 3;
                   4164:             op = (modrm >> 3) & 7;
                   4165:             
                   4166:             if (mod != 3) {
                   4167:                 if (shift == 2) {
                   4168:                     s->rip_offset = 1;
                   4169:                 }
                   4170:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4171:                 opreg = OR_TMP0;
                   4172:             } else {
                   4173:                 opreg = (modrm & 7) | REX_B(s);
                   4174:             }
                   4175: 
                   4176:             /* simpler op */
                   4177:             if (shift == 0) {
                   4178:                 gen_shift(s, op, ot, opreg, OR_ECX);
                   4179:             } else {
                   4180:                 if (shift == 2) {
                   4181:                     shift = ldub_code(s->pc++);
                   4182:                 }
                   4183:                 gen_shifti(s, op, ot, opreg, shift);
                   4184:             }
                   4185:         }
                   4186:         break;
                   4187:     case 0xd0:
                   4188:     case 0xd1:
                   4189:         /* shift Ev,1 */
                   4190:         shift = 1;
                   4191:         goto grp2;
                   4192:     case 0xd2:
                   4193:     case 0xd3:
                   4194:         /* shift Ev,cl */
                   4195:         shift = 0;
                   4196:         goto grp2;
                   4197: 
                   4198:     case 0x1a4: /* shld imm */
                   4199:         op = 0;
                   4200:         shift = 1;
                   4201:         goto do_shiftd;
                   4202:     case 0x1a5: /* shld cl */
                   4203:         op = 0;
                   4204:         shift = 0;
                   4205:         goto do_shiftd;
                   4206:     case 0x1ac: /* shrd imm */
                   4207:         op = 1;
                   4208:         shift = 1;
                   4209:         goto do_shiftd;
                   4210:     case 0x1ad: /* shrd cl */
                   4211:         op = 1;
                   4212:         shift = 0;
                   4213:     do_shiftd:
                   4214:         ot = dflag + OT_WORD;
                   4215:         modrm = ldub_code(s->pc++);
                   4216:         mod = (modrm >> 6) & 3;
                   4217:         rm = (modrm & 7) | REX_B(s);
                   4218:         reg = ((modrm >> 3) & 7) | rex_r;
                   4219:         
                   4220:         if (mod != 3) {
                   4221:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4222:             gen_op_ld_T0_A0[ot + s->mem_index]();
                   4223:         } else {
                   4224:             gen_op_mov_TN_reg[ot][0][rm]();
                   4225:         }
                   4226:         gen_op_mov_TN_reg[ot][1][reg]();
                   4227:         
                   4228:         if (shift) {
                   4229:             val = ldub_code(s->pc++);
                   4230:             if (ot == OT_QUAD)
                   4231:                 val &= 0x3f;
                   4232:             else
                   4233:                 val &= 0x1f;
                   4234:             if (val) {
                   4235:                 if (mod == 3)
                   4236:                     gen_op_shiftd_T0_T1_im_cc[ot][op](val);
                   4237:                 else
                   4238:                     gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
                   4239:                 if (op == 0 && ot != OT_WORD)
                   4240:                     s->cc_op = CC_OP_SHLB + ot;
                   4241:                 else
                   4242:                     s->cc_op = CC_OP_SARB + ot;
                   4243:             }
                   4244:         } else {
                   4245:             if (s->cc_op != CC_OP_DYNAMIC)
                   4246:                 gen_op_set_cc_op(s->cc_op);
                   4247:             if (mod == 3)
                   4248:                 gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
                   4249:             else
                   4250:                 gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
                   4251:             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
                   4252:         }
                   4253:         if (mod == 3) {
                   4254:             gen_op_mov_reg_T0[ot][rm]();
                   4255:         }
                   4256:         break;
                   4257: 
                   4258:         /************************/
                   4259:         /* floats */
                   4260:     case 0xd8 ... 0xdf: 
                   4261:         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
                   4262:             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
                   4263:             /* XXX: what to do if illegal op ? */
                   4264:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   4265:             break;
                   4266:         }
                   4267:         modrm = ldub_code(s->pc++);
                   4268:         mod = (modrm >> 6) & 3;
                   4269:         rm = modrm & 7;
                   4270:         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
                   4271:         if (mod != 3) {
                   4272:             /* memory op */
                   4273:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   4274:             switch(op) {
                   4275:             case 0x00 ... 0x07: /* fxxxs */
                   4276:             case 0x10 ... 0x17: /* fixxxl */
                   4277:             case 0x20 ... 0x27: /* fxxxl */
                   4278:             case 0x30 ... 0x37: /* fixxx */
                   4279:                 {
                   4280:                     int op1;
                   4281:                     op1 = op & 7;
                   4282: 
                   4283:                     switch(op >> 4) {
                   4284:                     case 0:
                   4285:                         gen_op_flds_FT0_A0();
                   4286:                         break;
                   4287:                     case 1:
                   4288:                         gen_op_fildl_FT0_A0();
                   4289:                         break;
                   4290:                     case 2:
                   4291:                         gen_op_fldl_FT0_A0();
                   4292:                         break;
                   4293:                     case 3:
                   4294:                     default:
                   4295:                         gen_op_fild_FT0_A0();
                   4296:                         break;
                   4297:                     }
                   4298:                     
                   4299:                     gen_op_fp_arith_ST0_FT0[op1]();
                   4300:                     if (op1 == 3) {
                   4301:                         /* fcomp needs pop */
                   4302:                         gen_op_fpop();
                   4303:                     }
                   4304:                 }
                   4305:                 break;
                   4306:             case 0x08: /* flds */
                   4307:             case 0x0a: /* fsts */
                   4308:             case 0x0b: /* fstps */
1.1.1.3 ! root     4309:             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
        !          4310:             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
        !          4311:             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
1.1       root     4312:                 switch(op & 7) {
                   4313:                 case 0:
                   4314:                     switch(op >> 4) {
                   4315:                     case 0:
                   4316:                         gen_op_flds_ST0_A0();
                   4317:                         break;
                   4318:                     case 1:
                   4319:                         gen_op_fildl_ST0_A0();
                   4320:                         break;
                   4321:                     case 2:
                   4322:                         gen_op_fldl_ST0_A0();
                   4323:                         break;
                   4324:                     case 3:
                   4325:                     default:
                   4326:                         gen_op_fild_ST0_A0();
                   4327:                         break;
                   4328:                     }
                   4329:                     break;
1.1.1.3 ! root     4330:                 case 1:
        !          4331:                     switch(op >> 4) {
        !          4332:                     case 1:
        !          4333:                         gen_op_fisttl_ST0_A0();
        !          4334:                         break;
        !          4335:                     case 2:
        !          4336:                         gen_op_fisttll_ST0_A0();
        !          4337:                         break;
        !          4338:                     case 3:
        !          4339:                     default:
        !          4340:                         gen_op_fistt_ST0_A0();
        !          4341:                     }
        !          4342:                     gen_op_fpop();
        !          4343:                     break;
1.1       root     4344:                 default:
                   4345:                     switch(op >> 4) {
                   4346:                     case 0:
                   4347:                         gen_op_fsts_ST0_A0();
                   4348:                         break;
                   4349:                     case 1:
                   4350:                         gen_op_fistl_ST0_A0();
                   4351:                         break;
                   4352:                     case 2:
                   4353:                         gen_op_fstl_ST0_A0();
                   4354:                         break;
                   4355:                     case 3:
                   4356:                     default:
                   4357:                         gen_op_fist_ST0_A0();
                   4358:                         break;
                   4359:                     }
                   4360:                     if ((op & 7) == 3)
                   4361:                         gen_op_fpop();
                   4362:                     break;
                   4363:                 }
                   4364:                 break;
                   4365:             case 0x0c: /* fldenv mem */
                   4366:                 gen_op_fldenv_A0(s->dflag);
                   4367:                 break;
                   4368:             case 0x0d: /* fldcw mem */
                   4369:                 gen_op_fldcw_A0();
                   4370:                 break;
                   4371:             case 0x0e: /* fnstenv mem */
                   4372:                 gen_op_fnstenv_A0(s->dflag);
                   4373:                 break;
                   4374:             case 0x0f: /* fnstcw mem */
                   4375:                 gen_op_fnstcw_A0();
                   4376:                 break;
                   4377:             case 0x1d: /* fldt mem */
                   4378:                 gen_op_fldt_ST0_A0();
                   4379:                 break;
                   4380:             case 0x1f: /* fstpt mem */
                   4381:                 gen_op_fstt_ST0_A0();
                   4382:                 gen_op_fpop();
                   4383:                 break;
                   4384:             case 0x2c: /* frstor mem */
                   4385:                 gen_op_frstor_A0(s->dflag);
                   4386:                 break;
                   4387:             case 0x2e: /* fnsave mem */
                   4388:                 gen_op_fnsave_A0(s->dflag);
                   4389:                 break;
                   4390:             case 0x2f: /* fnstsw mem */
                   4391:                 gen_op_fnstsw_A0();
                   4392:                 break;
                   4393:             case 0x3c: /* fbld */
                   4394:                 gen_op_fbld_ST0_A0();
                   4395:                 break;
                   4396:             case 0x3e: /* fbstp */
                   4397:                 gen_op_fbst_ST0_A0();
                   4398:                 gen_op_fpop();
                   4399:                 break;
                   4400:             case 0x3d: /* fildll */
                   4401:                 gen_op_fildll_ST0_A0();
                   4402:                 break;
                   4403:             case 0x3f: /* fistpll */
                   4404:                 gen_op_fistll_ST0_A0();
                   4405:                 gen_op_fpop();
                   4406:                 break;
                   4407:             default:
                   4408:                 goto illegal_op;
                   4409:             }
                   4410:         } else {
                   4411:             /* register float ops */
                   4412:             opreg = rm;
                   4413: 
                   4414:             switch(op) {
                   4415:             case 0x08: /* fld sti */
                   4416:                 gen_op_fpush();
                   4417:                 gen_op_fmov_ST0_STN((opreg + 1) & 7);
                   4418:                 break;
                   4419:             case 0x09: /* fxchg sti */
                   4420:             case 0x29: /* fxchg4 sti, undocumented op */
                   4421:             case 0x39: /* fxchg7 sti, undocumented op */
                   4422:                 gen_op_fxchg_ST0_STN(opreg);
                   4423:                 break;
                   4424:             case 0x0a: /* grp d9/2 */
                   4425:                 switch(rm) {
                   4426:                 case 0: /* fnop */
                   4427:                     /* check exceptions (FreeBSD FPU probe) */
                   4428:                     if (s->cc_op != CC_OP_DYNAMIC)
                   4429:                         gen_op_set_cc_op(s->cc_op);
                   4430:                     gen_jmp_im(pc_start - s->cs_base);
                   4431:                     gen_op_fwait();
                   4432:                     break;
                   4433:                 default:
                   4434:                     goto illegal_op;
                   4435:                 }
                   4436:                 break;
                   4437:             case 0x0c: /* grp d9/4 */
                   4438:                 switch(rm) {
                   4439:                 case 0: /* fchs */
                   4440:                     gen_op_fchs_ST0();
                   4441:                     break;
                   4442:                 case 1: /* fabs */
                   4443:                     gen_op_fabs_ST0();
                   4444:                     break;
                   4445:                 case 4: /* ftst */
                   4446:                     gen_op_fldz_FT0();
                   4447:                     gen_op_fcom_ST0_FT0();
                   4448:                     break;
                   4449:                 case 5: /* fxam */
                   4450:                     gen_op_fxam_ST0();
                   4451:                     break;
                   4452:                 default:
                   4453:                     goto illegal_op;
                   4454:                 }
                   4455:                 break;
                   4456:             case 0x0d: /* grp d9/5 */
                   4457:                 {
                   4458:                     switch(rm) {
                   4459:                     case 0:
                   4460:                         gen_op_fpush();
                   4461:                         gen_op_fld1_ST0();
                   4462:                         break;
                   4463:                     case 1:
                   4464:                         gen_op_fpush();
                   4465:                         gen_op_fldl2t_ST0();
                   4466:                         break;
                   4467:                     case 2:
                   4468:                         gen_op_fpush();
                   4469:                         gen_op_fldl2e_ST0();
                   4470:                         break;
                   4471:                     case 3:
                   4472:                         gen_op_fpush();
                   4473:                         gen_op_fldpi_ST0();
                   4474:                         break;
                   4475:                     case 4:
                   4476:                         gen_op_fpush();
                   4477:                         gen_op_fldlg2_ST0();
                   4478:                         break;
                   4479:                     case 5:
                   4480:                         gen_op_fpush();
                   4481:                         gen_op_fldln2_ST0();
                   4482:                         break;
                   4483:                     case 6:
                   4484:                         gen_op_fpush();
                   4485:                         gen_op_fldz_ST0();
                   4486:                         break;
                   4487:                     default:
                   4488:                         goto illegal_op;
                   4489:                     }
                   4490:                 }
                   4491:                 break;
                   4492:             case 0x0e: /* grp d9/6 */
                   4493:                 switch(rm) {
                   4494:                 case 0: /* f2xm1 */
                   4495:                     gen_op_f2xm1();
                   4496:                     break;
                   4497:                 case 1: /* fyl2x */
                   4498:                     gen_op_fyl2x();
                   4499:                     break;
                   4500:                 case 2: /* fptan */
                   4501:                     gen_op_fptan();
                   4502:                     break;
                   4503:                 case 3: /* fpatan */
                   4504:                     gen_op_fpatan();
                   4505:                     break;
                   4506:                 case 4: /* fxtract */
                   4507:                     gen_op_fxtract();
                   4508:                     break;
                   4509:                 case 5: /* fprem1 */
                   4510:                     gen_op_fprem1();
                   4511:                     break;
                   4512:                 case 6: /* fdecstp */
                   4513:                     gen_op_fdecstp();
                   4514:                     break;
                   4515:                 default:
                   4516:                 case 7: /* fincstp */
                   4517:                     gen_op_fincstp();
                   4518:                     break;
                   4519:                 }
                   4520:                 break;
                   4521:             case 0x0f: /* grp d9/7 */
                   4522:                 switch(rm) {
                   4523:                 case 0: /* fprem */
                   4524:                     gen_op_fprem();
                   4525:                     break;
                   4526:                 case 1: /* fyl2xp1 */
                   4527:                     gen_op_fyl2xp1();
                   4528:                     break;
                   4529:                 case 2: /* fsqrt */
                   4530:                     gen_op_fsqrt();
                   4531:                     break;
                   4532:                 case 3: /* fsincos */
                   4533:                     gen_op_fsincos();
                   4534:                     break;
                   4535:                 case 5: /* fscale */
                   4536:                     gen_op_fscale();
                   4537:                     break;
                   4538:                 case 4: /* frndint */
                   4539:                     gen_op_frndint();
                   4540:                     break;
                   4541:                 case 6: /* fsin */
                   4542:                     gen_op_fsin();
                   4543:                     break;
                   4544:                 default:
                   4545:                 case 7: /* fcos */
                   4546:                     gen_op_fcos();
                   4547:                     break;
                   4548:                 }
                   4549:                 break;
                   4550:             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
                   4551:             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
                   4552:             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
                   4553:                 {
                   4554:                     int op1;
                   4555:                     
                   4556:                     op1 = op & 7;
                   4557:                     if (op >= 0x20) {
                   4558:                         gen_op_fp_arith_STN_ST0[op1](opreg);
                   4559:                         if (op >= 0x30)
                   4560:                             gen_op_fpop();
                   4561:                     } else {
                   4562:                         gen_op_fmov_FT0_STN(opreg);
                   4563:                         gen_op_fp_arith_ST0_FT0[op1]();
                   4564:                     }
                   4565:                 }
                   4566:                 break;
                   4567:             case 0x02: /* fcom */
                   4568:             case 0x22: /* fcom2, undocumented op */
                   4569:                 gen_op_fmov_FT0_STN(opreg);
                   4570:                 gen_op_fcom_ST0_FT0();
                   4571:                 break;
                   4572:             case 0x03: /* fcomp */
                   4573:             case 0x23: /* fcomp3, undocumented op */
                   4574:             case 0x32: /* fcomp5, undocumented op */
                   4575:                 gen_op_fmov_FT0_STN(opreg);
                   4576:                 gen_op_fcom_ST0_FT0();
                   4577:                 gen_op_fpop();
                   4578:                 break;
                   4579:             case 0x15: /* da/5 */
                   4580:                 switch(rm) {
                   4581:                 case 1: /* fucompp */
                   4582:                     gen_op_fmov_FT0_STN(1);
                   4583:                     gen_op_fucom_ST0_FT0();
                   4584:                     gen_op_fpop();
                   4585:                     gen_op_fpop();
                   4586:                     break;
                   4587:                 default:
                   4588:                     goto illegal_op;
                   4589:                 }
                   4590:                 break;
                   4591:             case 0x1c:
                   4592:                 switch(rm) {
                   4593:                 case 0: /* feni (287 only, just do nop here) */
                   4594:                     break;
                   4595:                 case 1: /* fdisi (287 only, just do nop here) */
                   4596:                     break;
                   4597:                 case 2: /* fclex */
                   4598:                     gen_op_fclex();
                   4599:                     break;
                   4600:                 case 3: /* fninit */
                   4601:                     gen_op_fninit();
                   4602:                     break;
                   4603:                 case 4: /* fsetpm (287 only, just do nop here) */
                   4604:                     break;
                   4605:                 default:
                   4606:                     goto illegal_op;
                   4607:                 }
                   4608:                 break;
                   4609:             case 0x1d: /* fucomi */
                   4610:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4611:                     gen_op_set_cc_op(s->cc_op);
                   4612:                 gen_op_fmov_FT0_STN(opreg);
                   4613:                 gen_op_fucomi_ST0_FT0();
                   4614:                 s->cc_op = CC_OP_EFLAGS;
                   4615:                 break;
                   4616:             case 0x1e: /* fcomi */
                   4617:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4618:                     gen_op_set_cc_op(s->cc_op);
                   4619:                 gen_op_fmov_FT0_STN(opreg);
                   4620:                 gen_op_fcomi_ST0_FT0();
                   4621:                 s->cc_op = CC_OP_EFLAGS;
                   4622:                 break;
                   4623:             case 0x28: /* ffree sti */
                   4624:                 gen_op_ffree_STN(opreg);
                   4625:                 break; 
                   4626:             case 0x2a: /* fst sti */
                   4627:                 gen_op_fmov_STN_ST0(opreg);
                   4628:                 break;
                   4629:             case 0x2b: /* fstp sti */
                   4630:             case 0x0b: /* fstp1 sti, undocumented op */
                   4631:             case 0x3a: /* fstp8 sti, undocumented op */
                   4632:             case 0x3b: /* fstp9 sti, undocumented op */
                   4633:                 gen_op_fmov_STN_ST0(opreg);
                   4634:                 gen_op_fpop();
                   4635:                 break;
                   4636:             case 0x2c: /* fucom st(i) */
                   4637:                 gen_op_fmov_FT0_STN(opreg);
                   4638:                 gen_op_fucom_ST0_FT0();
                   4639:                 break;
                   4640:             case 0x2d: /* fucomp st(i) */
                   4641:                 gen_op_fmov_FT0_STN(opreg);
                   4642:                 gen_op_fucom_ST0_FT0();
                   4643:                 gen_op_fpop();
                   4644:                 break;
                   4645:             case 0x33: /* de/3 */
                   4646:                 switch(rm) {
                   4647:                 case 1: /* fcompp */
                   4648:                     gen_op_fmov_FT0_STN(1);
                   4649:                     gen_op_fcom_ST0_FT0();
                   4650:                     gen_op_fpop();
                   4651:                     gen_op_fpop();
                   4652:                     break;
                   4653:                 default:
                   4654:                     goto illegal_op;
                   4655:                 }
                   4656:                 break;
                   4657:             case 0x38: /* ffreep sti, undocumented op */
                   4658:                 gen_op_ffree_STN(opreg);
                   4659:                 gen_op_fpop();
                   4660:                 break;
                   4661:             case 0x3c: /* df/4 */
                   4662:                 switch(rm) {
                   4663:                 case 0:
                   4664:                     gen_op_fnstsw_EAX();
                   4665:                     break;
                   4666:                 default:
                   4667:                     goto illegal_op;
                   4668:                 }
                   4669:                 break;
                   4670:             case 0x3d: /* fucomip */
                   4671:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4672:                     gen_op_set_cc_op(s->cc_op);
                   4673:                 gen_op_fmov_FT0_STN(opreg);
                   4674:                 gen_op_fucomi_ST0_FT0();
                   4675:                 gen_op_fpop();
                   4676:                 s->cc_op = CC_OP_EFLAGS;
                   4677:                 break;
                   4678:             case 0x3e: /* fcomip */
                   4679:                 if (s->cc_op != CC_OP_DYNAMIC)
                   4680:                     gen_op_set_cc_op(s->cc_op);
                   4681:                 gen_op_fmov_FT0_STN(opreg);
                   4682:                 gen_op_fcomi_ST0_FT0();
                   4683:                 gen_op_fpop();
                   4684:                 s->cc_op = CC_OP_EFLAGS;
                   4685:                 break;
                   4686:             case 0x10 ... 0x13: /* fcmovxx */
                   4687:             case 0x18 ... 0x1b:
                   4688:                 {
                   4689:                     int op1;
                   4690:                     const static uint8_t fcmov_cc[8] = {
                   4691:                         (JCC_B << 1),
                   4692:                         (JCC_Z << 1),
                   4693:                         (JCC_BE << 1),
                   4694:                         (JCC_P << 1),
                   4695:                     };
                   4696:                     op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
                   4697:                     gen_setcc(s, op1);
                   4698:                     gen_op_fcmov_ST0_STN_T0(opreg);
                   4699:                 }
                   4700:                 break;
                   4701:             default:
                   4702:                 goto illegal_op;
                   4703:             }
                   4704:         }
                   4705: #ifdef USE_CODE_COPY
                   4706:         s->tb->cflags |= CF_TB_FP_USED;
                   4707: #endif
                   4708:         break;
                   4709:         /************************/
                   4710:         /* string ops */
                   4711: 
                   4712:     case 0xa4: /* movsS */
                   4713:     case 0xa5:
                   4714:         if ((b & 1) == 0)
                   4715:             ot = OT_BYTE;
                   4716:         else
                   4717:             ot = dflag + OT_WORD;
                   4718: 
                   4719:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   4720:             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   4721:         } else {
                   4722:             gen_movs(s, ot);
                   4723:         }
                   4724:         break;
                   4725:         
                   4726:     case 0xaa: /* stosS */
                   4727:     case 0xab:
                   4728:         if ((b & 1) == 0)
                   4729:             ot = OT_BYTE;
                   4730:         else
                   4731:             ot = dflag + OT_WORD;
                   4732: 
                   4733:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   4734:             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   4735:         } else {
                   4736:             gen_stos(s, ot);
                   4737:         }
                   4738:         break;
                   4739:     case 0xac: /* lodsS */
                   4740:     case 0xad:
                   4741:         if ((b & 1) == 0)
                   4742:             ot = OT_BYTE;
                   4743:         else
                   4744:             ot = dflag + OT_WORD;
                   4745:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   4746:             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   4747:         } else {
                   4748:             gen_lods(s, ot);
                   4749:         }
                   4750:         break;
                   4751:     case 0xae: /* scasS */
                   4752:     case 0xaf:
                   4753:         if ((b & 1) == 0)
                   4754:             ot = OT_BYTE;
                   4755:         else
                   4756:             ot = dflag + OT_WORD;
                   4757:         if (prefixes & PREFIX_REPNZ) {
                   4758:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
                   4759:         } else if (prefixes & PREFIX_REPZ) {
                   4760:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
                   4761:         } else {
                   4762:             gen_scas(s, ot);
                   4763:             s->cc_op = CC_OP_SUBB + ot;
                   4764:         }
                   4765:         break;
                   4766: 
                   4767:     case 0xa6: /* cmpsS */
                   4768:     case 0xa7:
                   4769:         if ((b & 1) == 0)
                   4770:             ot = OT_BYTE;
                   4771:         else
                   4772:             ot = dflag + OT_WORD;
                   4773:         if (prefixes & PREFIX_REPNZ) {
                   4774:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
                   4775:         } else if (prefixes & PREFIX_REPZ) {
                   4776:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
                   4777:         } else {
                   4778:             gen_cmps(s, ot);
                   4779:             s->cc_op = CC_OP_SUBB + ot;
                   4780:         }
                   4781:         break;
                   4782:     case 0x6c: /* insS */
                   4783:     case 0x6d:
                   4784:         if ((b & 1) == 0)
                   4785:             ot = OT_BYTE;
                   4786:         else
                   4787:             ot = dflag ? OT_LONG : OT_WORD;
                   4788:         gen_check_io(s, ot, 1, pc_start - s->cs_base);
                   4789:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   4790:             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   4791:         } else {
                   4792:             gen_ins(s, ot);
                   4793:         }
                   4794:         break;
                   4795:     case 0x6e: /* outsS */
                   4796:     case 0x6f:
                   4797:         if ((b & 1) == 0)
                   4798:             ot = OT_BYTE;
                   4799:         else
                   4800:             ot = dflag ? OT_LONG : OT_WORD;
                   4801:         gen_check_io(s, ot, 1, pc_start - s->cs_base);
                   4802:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
                   4803:             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
                   4804:         } else {
                   4805:             gen_outs(s, ot);
                   4806:         }
                   4807:         break;
                   4808: 
                   4809:         /************************/
                   4810:         /* port I/O */
                   4811:     case 0xe4:
                   4812:     case 0xe5:
                   4813:         if ((b & 1) == 0)
                   4814:             ot = OT_BYTE;
                   4815:         else
                   4816:             ot = dflag ? OT_LONG : OT_WORD;
                   4817:         val = ldub_code(s->pc++);
                   4818:         gen_op_movl_T0_im(val);
                   4819:         gen_check_io(s, ot, 0, pc_start - s->cs_base);
                   4820:         gen_op_in[ot]();
                   4821:         gen_op_mov_reg_T1[ot][R_EAX]();
                   4822:         break;
                   4823:     case 0xe6:
                   4824:     case 0xe7:
                   4825:         if ((b & 1) == 0)
                   4826:             ot = OT_BYTE;
                   4827:         else
                   4828:             ot = dflag ? OT_LONG : OT_WORD;
                   4829:         val = ldub_code(s->pc++);
                   4830:         gen_op_movl_T0_im(val);
                   4831:         gen_check_io(s, ot, 0, pc_start - s->cs_base);
                   4832:         gen_op_mov_TN_reg[ot][1][R_EAX]();
                   4833:         gen_op_out[ot]();
                   4834:         break;
                   4835:     case 0xec:
                   4836:     case 0xed:
                   4837:         if ((b & 1) == 0)
                   4838:             ot = OT_BYTE;
                   4839:         else
                   4840:             ot = dflag ? OT_LONG : OT_WORD;
                   4841:         gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
                   4842:         gen_op_andl_T0_ffff();
                   4843:         gen_check_io(s, ot, 0, pc_start - s->cs_base);
                   4844:         gen_op_in[ot]();
                   4845:         gen_op_mov_reg_T1[ot][R_EAX]();
                   4846:         break;
                   4847:     case 0xee:
                   4848:     case 0xef:
                   4849:         if ((b & 1) == 0)
                   4850:             ot = OT_BYTE;
                   4851:         else
                   4852:             ot = dflag ? OT_LONG : OT_WORD;
                   4853:         gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
                   4854:         gen_op_andl_T0_ffff();
                   4855:         gen_check_io(s, ot, 0, pc_start - s->cs_base);
                   4856:         gen_op_mov_TN_reg[ot][1][R_EAX]();
                   4857:         gen_op_out[ot]();
                   4858:         break;
                   4859: 
                   4860:         /************************/
                   4861:         /* control */
                   4862:     case 0xc2: /* ret im */
                   4863:         val = ldsw_code(s->pc);
                   4864:         s->pc += 2;
                   4865:         gen_pop_T0(s);
                   4866:         if (CODE64(s) && s->dflag)
                   4867:             s->dflag = 2;
                   4868:         gen_stack_update(s, val + (2 << s->dflag));
                   4869:         if (s->dflag == 0)
                   4870:             gen_op_andl_T0_ffff();
                   4871:         gen_op_jmp_T0();
                   4872:         gen_eob(s);
                   4873:         break;
                   4874:     case 0xc3: /* ret */
                   4875:         gen_pop_T0(s);
                   4876:         gen_pop_update(s);
                   4877:         if (s->dflag == 0)
                   4878:             gen_op_andl_T0_ffff();
                   4879:         gen_op_jmp_T0();
                   4880:         gen_eob(s);
                   4881:         break;
                   4882:     case 0xca: /* lret im */
                   4883:         val = ldsw_code(s->pc);
                   4884:         s->pc += 2;
                   4885:     do_lret:
                   4886:         if (s->pe && !s->vm86) {
                   4887:             if (s->cc_op != CC_OP_DYNAMIC)
                   4888:                 gen_op_set_cc_op(s->cc_op);
                   4889:             gen_jmp_im(pc_start - s->cs_base);
                   4890:             gen_op_lret_protected(s->dflag, val);
                   4891:         } else {
                   4892:             gen_stack_A0(s);
                   4893:             /* pop offset */
                   4894:             gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
                   4895:             if (s->dflag == 0)
                   4896:                 gen_op_andl_T0_ffff();
                   4897:             /* NOTE: keeping EIP updated is not a problem in case of
                   4898:                exception */
                   4899:             gen_op_jmp_T0();
                   4900:             /* pop selector */
                   4901:             gen_op_addl_A0_im(2 << s->dflag);
                   4902:             gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
                   4903:             gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
                   4904:             /* add stack offset */
                   4905:             gen_stack_update(s, val + (4 << s->dflag));
                   4906:         }
                   4907:         gen_eob(s);
                   4908:         break;
                   4909:     case 0xcb: /* lret */
                   4910:         val = 0;
                   4911:         goto do_lret;
                   4912:     case 0xcf: /* iret */
                   4913:         if (!s->pe) {
                   4914:             /* real mode */
                   4915:             gen_op_iret_real(s->dflag);
                   4916:             s->cc_op = CC_OP_EFLAGS;
                   4917:         } else if (s->vm86) {
                   4918:             if (s->iopl != 3) {
                   4919:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   4920:             } else {
                   4921:                 gen_op_iret_real(s->dflag);
                   4922:                 s->cc_op = CC_OP_EFLAGS;
                   4923:             }
                   4924:         } else {
                   4925:             if (s->cc_op != CC_OP_DYNAMIC)
                   4926:                 gen_op_set_cc_op(s->cc_op);
                   4927:             gen_jmp_im(pc_start - s->cs_base);
                   4928:             gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
                   4929:             s->cc_op = CC_OP_EFLAGS;
                   4930:         }
                   4931:         gen_eob(s);
                   4932:         break;
                   4933:     case 0xe8: /* call im */
                   4934:         {
                   4935:             if (dflag)
                   4936:                 tval = (int32_t)insn_get(s, OT_LONG);
                   4937:             else
                   4938:                 tval = (int16_t)insn_get(s, OT_WORD);
                   4939:             next_eip = s->pc - s->cs_base;
                   4940:             tval += next_eip;
                   4941:             if (s->dflag == 0)
                   4942:                 tval &= 0xffff;
                   4943:             gen_movtl_T0_im(next_eip);
                   4944:             gen_push_T0(s);
                   4945:             gen_jmp(s, tval);
                   4946:         }
                   4947:         break;
                   4948:     case 0x9a: /* lcall im */
                   4949:         {
                   4950:             unsigned int selector, offset;
                   4951:             
                   4952:             if (CODE64(s))
                   4953:                 goto illegal_op;
                   4954:             ot = dflag ? OT_LONG : OT_WORD;
                   4955:             offset = insn_get(s, ot);
                   4956:             selector = insn_get(s, OT_WORD);
                   4957:             
                   4958:             gen_op_movl_T0_im(selector);
                   4959:             gen_op_movl_T1_imu(offset);
                   4960:         }
                   4961:         goto do_lcall;
                   4962:     case 0xe9: /* jmp im */
                   4963:         if (dflag)
                   4964:             tval = (int32_t)insn_get(s, OT_LONG);
                   4965:         else
                   4966:             tval = (int16_t)insn_get(s, OT_WORD);
                   4967:         tval += s->pc - s->cs_base;
                   4968:         if (s->dflag == 0)
                   4969:             tval &= 0xffff;
                   4970:         gen_jmp(s, tval);
                   4971:         break;
                   4972:     case 0xea: /* ljmp im */
                   4973:         {
                   4974:             unsigned int selector, offset;
                   4975: 
                   4976:             if (CODE64(s))
                   4977:                 goto illegal_op;
                   4978:             ot = dflag ? OT_LONG : OT_WORD;
                   4979:             offset = insn_get(s, ot);
                   4980:             selector = insn_get(s, OT_WORD);
                   4981:             
                   4982:             gen_op_movl_T0_im(selector);
                   4983:             gen_op_movl_T1_imu(offset);
                   4984:         }
                   4985:         goto do_ljmp;
                   4986:     case 0xeb: /* jmp Jb */
                   4987:         tval = (int8_t)insn_get(s, OT_BYTE);
                   4988:         tval += s->pc - s->cs_base;
                   4989:         if (s->dflag == 0)
                   4990:             tval &= 0xffff;
                   4991:         gen_jmp(s, tval);
                   4992:         break;
                   4993:     case 0x70 ... 0x7f: /* jcc Jb */
                   4994:         tval = (int8_t)insn_get(s, OT_BYTE);
                   4995:         goto do_jcc;
                   4996:     case 0x180 ... 0x18f: /* jcc Jv */
                   4997:         if (dflag) {
                   4998:             tval = (int32_t)insn_get(s, OT_LONG);
                   4999:         } else {
                   5000:             tval = (int16_t)insn_get(s, OT_WORD); 
                   5001:         }
                   5002:     do_jcc:
                   5003:         next_eip = s->pc - s->cs_base;
                   5004:         tval += next_eip;
                   5005:         if (s->dflag == 0)
                   5006:             tval &= 0xffff;
                   5007:         gen_jcc(s, b, tval, next_eip);
                   5008:         break;
                   5009: 
                   5010:     case 0x190 ... 0x19f: /* setcc Gv */
                   5011:         modrm = ldub_code(s->pc++);
                   5012:         gen_setcc(s, b);
                   5013:         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
                   5014:         break;
                   5015:     case 0x140 ... 0x14f: /* cmov Gv, Ev */
                   5016:         ot = dflag + OT_WORD;
                   5017:         modrm = ldub_code(s->pc++);
                   5018:         reg = ((modrm >> 3) & 7) | rex_r;
                   5019:         mod = (modrm >> 6) & 3;
                   5020:         gen_setcc(s, b);
                   5021:         if (mod != 3) {
                   5022:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5023:             gen_op_ld_T1_A0[ot + s->mem_index]();
                   5024:         } else {
                   5025:             rm = (modrm & 7) | REX_B(s);
                   5026:             gen_op_mov_TN_reg[ot][1][rm]();
                   5027:         }
                   5028:         gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
                   5029:         break;
                   5030:         
                   5031:         /************************/
                   5032:         /* flags */
                   5033:     case 0x9c: /* pushf */
                   5034:         if (s->vm86 && s->iopl != 3) {
                   5035:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5036:         } else {
                   5037:             if (s->cc_op != CC_OP_DYNAMIC)
                   5038:                 gen_op_set_cc_op(s->cc_op);
                   5039:             gen_op_movl_T0_eflags();
                   5040:             gen_push_T0(s);
                   5041:         }
                   5042:         break;
                   5043:     case 0x9d: /* popf */
                   5044:         if (s->vm86 && s->iopl != 3) {
                   5045:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5046:         } else {
                   5047:             gen_pop_T0(s);
                   5048:             if (s->cpl == 0) {
                   5049:                 if (s->dflag) {
                   5050:                     gen_op_movl_eflags_T0_cpl0();
                   5051:                 } else {
                   5052:                     gen_op_movw_eflags_T0_cpl0();
                   5053:                 }
                   5054:             } else {
                   5055:                 if (s->cpl <= s->iopl) {
                   5056:                     if (s->dflag) {
                   5057:                         gen_op_movl_eflags_T0_io();
                   5058:                     } else {
                   5059:                         gen_op_movw_eflags_T0_io();
                   5060:                     }
                   5061:                 } else {
                   5062:                     if (s->dflag) {
                   5063:                         gen_op_movl_eflags_T0();
                   5064:                     } else {
                   5065:                         gen_op_movw_eflags_T0();
                   5066:                     }
                   5067:                 }
                   5068:             }
                   5069:             gen_pop_update(s);
                   5070:             s->cc_op = CC_OP_EFLAGS;
                   5071:             /* abort translation because TF flag may change */
                   5072:             gen_jmp_im(s->pc - s->cs_base);
                   5073:             gen_eob(s);
                   5074:         }
                   5075:         break;
                   5076:     case 0x9e: /* sahf */
                   5077:         if (CODE64(s))
                   5078:             goto illegal_op;
                   5079:         gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
                   5080:         if (s->cc_op != CC_OP_DYNAMIC)
                   5081:             gen_op_set_cc_op(s->cc_op);
                   5082:         gen_op_movb_eflags_T0();
                   5083:         s->cc_op = CC_OP_EFLAGS;
                   5084:         break;
                   5085:     case 0x9f: /* lahf */
                   5086:         if (CODE64(s))
                   5087:             goto illegal_op;
                   5088:         if (s->cc_op != CC_OP_DYNAMIC)
                   5089:             gen_op_set_cc_op(s->cc_op);
                   5090:         gen_op_movl_T0_eflags();
                   5091:         gen_op_mov_reg_T0[OT_BYTE][R_AH]();
                   5092:         break;
                   5093:     case 0xf5: /* cmc */
                   5094:         if (s->cc_op != CC_OP_DYNAMIC)
                   5095:             gen_op_set_cc_op(s->cc_op);
                   5096:         gen_op_cmc();
                   5097:         s->cc_op = CC_OP_EFLAGS;
                   5098:         break;
                   5099:     case 0xf8: /* clc */
                   5100:         if (s->cc_op != CC_OP_DYNAMIC)
                   5101:             gen_op_set_cc_op(s->cc_op);
                   5102:         gen_op_clc();
                   5103:         s->cc_op = CC_OP_EFLAGS;
                   5104:         break;
                   5105:     case 0xf9: /* stc */
                   5106:         if (s->cc_op != CC_OP_DYNAMIC)
                   5107:             gen_op_set_cc_op(s->cc_op);
                   5108:         gen_op_stc();
                   5109:         s->cc_op = CC_OP_EFLAGS;
                   5110:         break;
                   5111:     case 0xfc: /* cld */
                   5112:         gen_op_cld();
                   5113:         break;
                   5114:     case 0xfd: /* std */
                   5115:         gen_op_std();
                   5116:         break;
                   5117: 
                   5118:         /************************/
                   5119:         /* bit operations */
                   5120:     case 0x1ba: /* bt/bts/btr/btc Gv, im */
                   5121:         ot = dflag + OT_WORD;
                   5122:         modrm = ldub_code(s->pc++);
1.1.1.3 ! root     5123:         op = (modrm >> 3) & 7;
1.1       root     5124:         mod = (modrm >> 6) & 3;
                   5125:         rm = (modrm & 7) | REX_B(s);
                   5126:         if (mod != 3) {
                   5127:             s->rip_offset = 1;
                   5128:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5129:             gen_op_ld_T0_A0[ot + s->mem_index]();
                   5130:         } else {
                   5131:             gen_op_mov_TN_reg[ot][0][rm]();
                   5132:         }
                   5133:         /* load shift */
                   5134:         val = ldub_code(s->pc++);
                   5135:         gen_op_movl_T1_im(val);
                   5136:         if (op < 4)
                   5137:             goto illegal_op;
                   5138:         op -= 4;
                   5139:         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
                   5140:         s->cc_op = CC_OP_SARB + ot;
                   5141:         if (op != 0) {
                   5142:             if (mod != 3)
                   5143:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   5144:             else
                   5145:                 gen_op_mov_reg_T0[ot][rm]();
                   5146:             gen_op_update_bt_cc();
                   5147:         }
                   5148:         break;
                   5149:     case 0x1a3: /* bt Gv, Ev */
                   5150:         op = 0;
                   5151:         goto do_btx;
                   5152:     case 0x1ab: /* bts */
                   5153:         op = 1;
                   5154:         goto do_btx;
                   5155:     case 0x1b3: /* btr */
                   5156:         op = 2;
                   5157:         goto do_btx;
                   5158:     case 0x1bb: /* btc */
                   5159:         op = 3;
                   5160:     do_btx:
                   5161:         ot = dflag + OT_WORD;
                   5162:         modrm = ldub_code(s->pc++);
                   5163:         reg = ((modrm >> 3) & 7) | rex_r;
                   5164:         mod = (modrm >> 6) & 3;
                   5165:         rm = (modrm & 7) | REX_B(s);
                   5166:         gen_op_mov_TN_reg[OT_LONG][1][reg]();
                   5167:         if (mod != 3) {
                   5168:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5169:             /* specific case: we need to add a displacement */
                   5170:             gen_op_add_bit_A0_T1[ot - OT_WORD]();
                   5171:             gen_op_ld_T0_A0[ot + s->mem_index]();
                   5172:         } else {
                   5173:             gen_op_mov_TN_reg[ot][0][rm]();
                   5174:         }
                   5175:         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
                   5176:         s->cc_op = CC_OP_SARB + ot;
                   5177:         if (op != 0) {
                   5178:             if (mod != 3)
                   5179:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   5180:             else
                   5181:                 gen_op_mov_reg_T0[ot][rm]();
                   5182:             gen_op_update_bt_cc();
                   5183:         }
                   5184:         break;
                   5185:     case 0x1bc: /* bsf */
                   5186:     case 0x1bd: /* bsr */
                   5187:         ot = dflag + OT_WORD;
                   5188:         modrm = ldub_code(s->pc++);
                   5189:         reg = ((modrm >> 3) & 7) | rex_r;
                   5190:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   5191:         /* NOTE: in order to handle the 0 case, we must load the
                   5192:            result. It could be optimized with a generated jump */
                   5193:         gen_op_mov_TN_reg[ot][1][reg]();
                   5194:         gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
                   5195:         gen_op_mov_reg_T1[ot][reg]();
                   5196:         s->cc_op = CC_OP_LOGICB + ot;
                   5197:         break;
                   5198:         /************************/
                   5199:         /* bcd */
                   5200:     case 0x27: /* daa */
                   5201:         if (CODE64(s))
                   5202:             goto illegal_op;
                   5203:         if (s->cc_op != CC_OP_DYNAMIC)
                   5204:             gen_op_set_cc_op(s->cc_op);
                   5205:         gen_op_daa();
                   5206:         s->cc_op = CC_OP_EFLAGS;
                   5207:         break;
                   5208:     case 0x2f: /* das */
                   5209:         if (CODE64(s))
                   5210:             goto illegal_op;
                   5211:         if (s->cc_op != CC_OP_DYNAMIC)
                   5212:             gen_op_set_cc_op(s->cc_op);
                   5213:         gen_op_das();
                   5214:         s->cc_op = CC_OP_EFLAGS;
                   5215:         break;
                   5216:     case 0x37: /* aaa */
                   5217:         if (CODE64(s))
                   5218:             goto illegal_op;
                   5219:         if (s->cc_op != CC_OP_DYNAMIC)
                   5220:             gen_op_set_cc_op(s->cc_op);
                   5221:         gen_op_aaa();
                   5222:         s->cc_op = CC_OP_EFLAGS;
                   5223:         break;
                   5224:     case 0x3f: /* aas */
                   5225:         if (CODE64(s))
                   5226:             goto illegal_op;
                   5227:         if (s->cc_op != CC_OP_DYNAMIC)
                   5228:             gen_op_set_cc_op(s->cc_op);
                   5229:         gen_op_aas();
                   5230:         s->cc_op = CC_OP_EFLAGS;
                   5231:         break;
                   5232:     case 0xd4: /* aam */
                   5233:         if (CODE64(s))
                   5234:             goto illegal_op;
                   5235:         val = ldub_code(s->pc++);
                   5236:         gen_op_aam(val);
                   5237:         s->cc_op = CC_OP_LOGICB;
                   5238:         break;
                   5239:     case 0xd5: /* aad */
                   5240:         if (CODE64(s))
                   5241:             goto illegal_op;
                   5242:         val = ldub_code(s->pc++);
                   5243:         gen_op_aad(val);
                   5244:         s->cc_op = CC_OP_LOGICB;
                   5245:         break;
                   5246:         /************************/
                   5247:         /* misc */
                   5248:     case 0x90: /* nop */
                   5249:         /* XXX: xchg + rex handling */
                   5250:         /* XXX: correct lock test for all insn */
                   5251:         if (prefixes & PREFIX_LOCK)
                   5252:             goto illegal_op;
                   5253:         break;
                   5254:     case 0x9b: /* fwait */
                   5255:         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 
                   5256:             (HF_MP_MASK | HF_TS_MASK)) {
                   5257:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   5258:         } else {
                   5259:             if (s->cc_op != CC_OP_DYNAMIC)
                   5260:                 gen_op_set_cc_op(s->cc_op);
                   5261:             gen_jmp_im(pc_start - s->cs_base);
                   5262:             gen_op_fwait();
                   5263:         }
                   5264:         break;
                   5265:     case 0xcc: /* int3 */
                   5266:         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
                   5267:         break;
                   5268:     case 0xcd: /* int N */
                   5269:         val = ldub_code(s->pc++);
                   5270:         if (s->vm86 && s->iopl != 3) {
                   5271:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 
                   5272:         } else {
                   5273:             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
                   5274:         }
                   5275:         break;
                   5276:     case 0xce: /* into */
                   5277:         if (CODE64(s))
                   5278:             goto illegal_op;
                   5279:         if (s->cc_op != CC_OP_DYNAMIC)
                   5280:             gen_op_set_cc_op(s->cc_op);
                   5281:         gen_jmp_im(pc_start - s->cs_base);
                   5282:         gen_op_into(s->pc - pc_start);
                   5283:         break;
                   5284:     case 0xf1: /* icebp (undocumented, exits to external debugger) */
                   5285: #if 1
                   5286:         gen_debug(s, pc_start - s->cs_base);
                   5287: #else
                   5288:         /* start debug */
                   5289:         tb_flush(cpu_single_env);
                   5290:         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
                   5291: #endif
                   5292:         break;
                   5293:     case 0xfa: /* cli */
                   5294:         if (!s->vm86) {
                   5295:             if (s->cpl <= s->iopl) {
                   5296:                 gen_op_cli();
                   5297:             } else {
                   5298:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5299:             }
                   5300:         } else {
                   5301:             if (s->iopl == 3) {
                   5302:                 gen_op_cli();
                   5303:             } else {
                   5304:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5305:             }
                   5306:         }
                   5307:         break;
                   5308:     case 0xfb: /* sti */
                   5309:         if (!s->vm86) {
                   5310:             if (s->cpl <= s->iopl) {
                   5311:             gen_sti:
                   5312:                 gen_op_sti();
                   5313:                 /* interruptions are enabled only the first insn after sti */
                   5314:                 /* If several instructions disable interrupts, only the
                   5315:                    _first_ does it */
                   5316:                 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
                   5317:                     gen_op_set_inhibit_irq();
                   5318:                 /* give a chance to handle pending irqs */
                   5319:                 gen_jmp_im(s->pc - s->cs_base);
                   5320:                 gen_eob(s);
                   5321:             } else {
                   5322:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5323:             }
                   5324:         } else {
                   5325:             if (s->iopl == 3) {
                   5326:                 goto gen_sti;
                   5327:             } else {
                   5328:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5329:             }
                   5330:         }
                   5331:         break;
                   5332:     case 0x62: /* bound */
                   5333:         if (CODE64(s))
                   5334:             goto illegal_op;
                   5335:         ot = dflag ? OT_LONG : OT_WORD;
                   5336:         modrm = ldub_code(s->pc++);
                   5337:         reg = (modrm >> 3) & 7;
                   5338:         mod = (modrm >> 6) & 3;
                   5339:         if (mod == 3)
                   5340:             goto illegal_op;
                   5341:         gen_op_mov_TN_reg[ot][0][reg]();
                   5342:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5343:         gen_jmp_im(pc_start - s->cs_base);
                   5344:         if (ot == OT_WORD)
                   5345:             gen_op_boundw();
                   5346:         else
                   5347:             gen_op_boundl();
                   5348:         break;
                   5349:     case 0x1c8 ... 0x1cf: /* bswap reg */
                   5350:         reg = (b & 7) | REX_B(s);
                   5351: #ifdef TARGET_X86_64
                   5352:         if (dflag == 2) {
                   5353:             gen_op_mov_TN_reg[OT_QUAD][0][reg]();
                   5354:             gen_op_bswapq_T0();
                   5355:             gen_op_mov_reg_T0[OT_QUAD][reg]();
                   5356:         } else 
                   5357: #endif
                   5358:         {
                   5359:             gen_op_mov_TN_reg[OT_LONG][0][reg]();
                   5360:             gen_op_bswapl_T0();
                   5361:             gen_op_mov_reg_T0[OT_LONG][reg]();
                   5362:         }
                   5363:         break;
                   5364:     case 0xd6: /* salc */
                   5365:         if (CODE64(s))
                   5366:             goto illegal_op;
                   5367:         if (s->cc_op != CC_OP_DYNAMIC)
                   5368:             gen_op_set_cc_op(s->cc_op);
                   5369:         gen_op_salc();
                   5370:         break;
                   5371:     case 0xe0: /* loopnz */
                   5372:     case 0xe1: /* loopz */
                   5373:         if (s->cc_op != CC_OP_DYNAMIC)
                   5374:             gen_op_set_cc_op(s->cc_op);
                   5375:         /* FALL THRU */
                   5376:     case 0xe2: /* loop */
                   5377:     case 0xe3: /* jecxz */
                   5378:         {
                   5379:             int l1, l2;
                   5380: 
                   5381:             tval = (int8_t)insn_get(s, OT_BYTE);
                   5382:             next_eip = s->pc - s->cs_base;
                   5383:             tval += next_eip;
                   5384:             if (s->dflag == 0)
                   5385:                 tval &= 0xffff;
                   5386:             
                   5387:             l1 = gen_new_label();
                   5388:             l2 = gen_new_label();
                   5389:             b &= 3;
                   5390:             if (b == 3) {
                   5391:                 gen_op_jz_ecx[s->aflag](l1);
                   5392:             } else {
                   5393:                 gen_op_dec_ECX[s->aflag]();
                   5394:                 if (b <= 1)
                   5395:                     gen_op_mov_T0_cc();
                   5396:                 gen_op_loop[s->aflag][b](l1);
                   5397:             }
                   5398: 
                   5399:             gen_jmp_im(next_eip);
                   5400:             gen_op_jmp_label(l2);
                   5401:             gen_set_label(l1);
                   5402:             gen_jmp_im(tval);
                   5403:             gen_set_label(l2);
                   5404:             gen_eob(s);
                   5405:         }
                   5406:         break;
                   5407:     case 0x130: /* wrmsr */
                   5408:     case 0x132: /* rdmsr */
                   5409:         if (s->cpl != 0) {
                   5410:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5411:         } else {
                   5412:             if (b & 2)
                   5413:                 gen_op_rdmsr();
                   5414:             else
                   5415:                 gen_op_wrmsr();
                   5416:         }
                   5417:         break;
                   5418:     case 0x131: /* rdtsc */
                   5419:         gen_jmp_im(pc_start - s->cs_base);
                   5420:         gen_op_rdtsc();
                   5421:         break;
                   5422:     case 0x134: /* sysenter */
                   5423:         if (CODE64(s))
                   5424:             goto illegal_op;
                   5425:         if (!s->pe) {
                   5426:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5427:         } else {
                   5428:             if (s->cc_op != CC_OP_DYNAMIC) {
                   5429:                 gen_op_set_cc_op(s->cc_op);
                   5430:                 s->cc_op = CC_OP_DYNAMIC;
                   5431:             }
                   5432:             gen_jmp_im(pc_start - s->cs_base);
                   5433:             gen_op_sysenter();
                   5434:             gen_eob(s);
                   5435:         }
                   5436:         break;
                   5437:     case 0x135: /* sysexit */
                   5438:         if (CODE64(s))
                   5439:             goto illegal_op;
                   5440:         if (!s->pe) {
                   5441:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5442:         } else {
                   5443:             if (s->cc_op != CC_OP_DYNAMIC) {
                   5444:                 gen_op_set_cc_op(s->cc_op);
                   5445:                 s->cc_op = CC_OP_DYNAMIC;
                   5446:             }
                   5447:             gen_jmp_im(pc_start - s->cs_base);
                   5448:             gen_op_sysexit();
                   5449:             gen_eob(s);
                   5450:         }
                   5451:         break;
                   5452: #ifdef TARGET_X86_64
                   5453:     case 0x105: /* syscall */
                   5454:         /* XXX: is it usable in real mode ? */
                   5455:         if (s->cc_op != CC_OP_DYNAMIC) {
                   5456:             gen_op_set_cc_op(s->cc_op);
                   5457:             s->cc_op = CC_OP_DYNAMIC;
                   5458:         }
                   5459:         gen_jmp_im(pc_start - s->cs_base);
                   5460:         gen_op_syscall(s->pc - pc_start);
                   5461:         gen_eob(s);
                   5462:         break;
                   5463:     case 0x107: /* sysret */
                   5464:         if (!s->pe) {
                   5465:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5466:         } else {
                   5467:             if (s->cc_op != CC_OP_DYNAMIC) {
                   5468:                 gen_op_set_cc_op(s->cc_op);
                   5469:                 s->cc_op = CC_OP_DYNAMIC;
                   5470:             }
                   5471:             gen_jmp_im(pc_start - s->cs_base);
                   5472:             gen_op_sysret(s->dflag);
                   5473:             /* condition codes are modified only in long mode */
                   5474:             if (s->lma)
                   5475:                 s->cc_op = CC_OP_EFLAGS;
                   5476:             gen_eob(s);
                   5477:         }
                   5478:         break;
                   5479: #endif
                   5480:     case 0x1a2: /* cpuid */
                   5481:         gen_op_cpuid();
                   5482:         break;
                   5483:     case 0xf4: /* hlt */
                   5484:         if (s->cpl != 0) {
                   5485:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5486:         } else {
                   5487:             if (s->cc_op != CC_OP_DYNAMIC)
                   5488:                 gen_op_set_cc_op(s->cc_op);
                   5489:             gen_jmp_im(s->pc - s->cs_base);
                   5490:             gen_op_hlt();
                   5491:             s->is_jmp = 3;
                   5492:         }
                   5493:         break;
                   5494:     case 0x100:
                   5495:         modrm = ldub_code(s->pc++);
                   5496:         mod = (modrm >> 6) & 3;
                   5497:         op = (modrm >> 3) & 7;
                   5498:         switch(op) {
                   5499:         case 0: /* sldt */
                   5500:             if (!s->pe || s->vm86)
                   5501:                 goto illegal_op;
                   5502:             gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
                   5503:             ot = OT_WORD;
                   5504:             if (mod == 3)
                   5505:                 ot += s->dflag;
                   5506:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   5507:             break;
                   5508:         case 2: /* lldt */
                   5509:             if (!s->pe || s->vm86)
                   5510:                 goto illegal_op;
                   5511:             if (s->cpl != 0) {
                   5512:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5513:             } else {
                   5514:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   5515:                 gen_jmp_im(pc_start - s->cs_base);
                   5516:                 gen_op_lldt_T0();
                   5517:             }
                   5518:             break;
                   5519:         case 1: /* str */
                   5520:             if (!s->pe || s->vm86)
                   5521:                 goto illegal_op;
                   5522:             gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
                   5523:             ot = OT_WORD;
                   5524:             if (mod == 3)
                   5525:                 ot += s->dflag;
                   5526:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
                   5527:             break;
                   5528:         case 3: /* ltr */
                   5529:             if (!s->pe || s->vm86)
                   5530:                 goto illegal_op;
                   5531:             if (s->cpl != 0) {
                   5532:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5533:             } else {
                   5534:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   5535:                 gen_jmp_im(pc_start - s->cs_base);
                   5536:                 gen_op_ltr_T0();
                   5537:             }
                   5538:             break;
                   5539:         case 4: /* verr */
                   5540:         case 5: /* verw */
                   5541:             if (!s->pe || s->vm86)
                   5542:                 goto illegal_op;
                   5543:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   5544:             if (s->cc_op != CC_OP_DYNAMIC)
                   5545:                 gen_op_set_cc_op(s->cc_op);
                   5546:             if (op == 4)
                   5547:                 gen_op_verr();
                   5548:             else
                   5549:                 gen_op_verw();
                   5550:             s->cc_op = CC_OP_EFLAGS;
                   5551:             break;
                   5552:         default:
                   5553:             goto illegal_op;
                   5554:         }
                   5555:         break;
                   5556:     case 0x101:
                   5557:         modrm = ldub_code(s->pc++);
                   5558:         mod = (modrm >> 6) & 3;
                   5559:         op = (modrm >> 3) & 7;
                   5560:         switch(op) {
                   5561:         case 0: /* sgdt */
                   5562:         case 1: /* sidt */
                   5563:             if (mod == 3)
                   5564:                 goto illegal_op;
                   5565:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5566:             if (op == 0)
                   5567:                 gen_op_movl_T0_env(offsetof(CPUX86State,gdt.limit));
                   5568:             else
                   5569:                 gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit));
                   5570:             gen_op_st_T0_A0[OT_WORD + s->mem_index]();
                   5571:             gen_add_A0_im(s, 2);
                   5572:             if (op == 0)
                   5573:                 gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base));
                   5574:             else
                   5575:                 gen_op_movtl_T0_env(offsetof(CPUX86State,idt.base));
                   5576:             if (!s->dflag)
                   5577:                 gen_op_andl_T0_im(0xffffff);
                   5578:             gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
                   5579:             break;
                   5580:         case 2: /* lgdt */
                   5581:         case 3: /* lidt */
                   5582:             if (mod == 3)
                   5583:                 goto illegal_op;
                   5584:             if (s->cpl != 0) {
                   5585:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5586:             } else {
                   5587:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5588:                 gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
                   5589:                 gen_add_A0_im(s, 2);
                   5590:                 gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
                   5591:                 if (!s->dflag)
                   5592:                     gen_op_andl_T0_im(0xffffff);
                   5593:                 if (op == 2) {
                   5594:                     gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
                   5595:                     gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
                   5596:                 } else {
                   5597:                     gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
                   5598:                     gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
                   5599:                 }
                   5600:             }
                   5601:             break;
                   5602:         case 4: /* smsw */
                   5603:             gen_op_movl_T0_env(offsetof(CPUX86State,cr[0]));
                   5604:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
                   5605:             break;
                   5606:         case 6: /* lmsw */
                   5607:             if (s->cpl != 0) {
                   5608:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5609:             } else {
                   5610:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
                   5611:                 gen_op_lmsw_T0();
                   5612:                 gen_jmp_im(s->pc - s->cs_base);
                   5613:                 gen_eob(s);
                   5614:             }
                   5615:             break;
                   5616:         case 7: /* invlpg */
                   5617:             if (s->cpl != 0) {
                   5618:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5619:             } else {
                   5620:                 if (mod == 3) {
                   5621: #ifdef TARGET_X86_64
                   5622:                     if (CODE64(s) && (modrm & 7) == 0) {
                   5623:                         /* swapgs */
                   5624:                         gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
                   5625:                         gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
                   5626:                         gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
                   5627:                         gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
                   5628:                     } else 
                   5629: #endif
                   5630:                     {
                   5631:                         goto illegal_op;
                   5632:                     }
                   5633:                 } else {
                   5634:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5635:                     gen_op_invlpg_A0();
                   5636:                     gen_jmp_im(s->pc - s->cs_base);
                   5637:                     gen_eob(s);
                   5638:                 }
                   5639:             }
                   5640:             break;
                   5641:         default:
                   5642:             goto illegal_op;
                   5643:         }
                   5644:         break;
                   5645:     case 0x108: /* invd */
                   5646:     case 0x109: /* wbinvd */
                   5647:         if (s->cpl != 0) {
                   5648:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5649:         } else {
                   5650:             /* nothing to do */
                   5651:         }
                   5652:         break;
                   5653:     case 0x63: /* arpl or movslS (x86_64) */
                   5654: #ifdef TARGET_X86_64
                   5655:         if (CODE64(s)) {
                   5656:             int d_ot;
                   5657:             /* d_ot is the size of destination */
                   5658:             d_ot = dflag + OT_WORD;
                   5659: 
                   5660:             modrm = ldub_code(s->pc++);
                   5661:             reg = ((modrm >> 3) & 7) | rex_r;
                   5662:             mod = (modrm >> 6) & 3;
                   5663:             rm = (modrm & 7) | REX_B(s);
                   5664:             
                   5665:             if (mod == 3) {
                   5666:                 gen_op_mov_TN_reg[OT_LONG][0][rm]();
                   5667:                 /* sign extend */
                   5668:                 if (d_ot == OT_QUAD)
                   5669:                     gen_op_movslq_T0_T0();
                   5670:                 gen_op_mov_reg_T0[d_ot][reg]();
                   5671:             } else {
                   5672:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5673:                 if (d_ot == OT_QUAD) {
                   5674:                     gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
                   5675:                 } else {
                   5676:                     gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
                   5677:                 }
                   5678:                 gen_op_mov_reg_T0[d_ot][reg]();
                   5679:             }
                   5680:         } else 
                   5681: #endif
                   5682:         {
                   5683:             if (!s->pe || s->vm86)
                   5684:                 goto illegal_op;
                   5685:             ot = dflag ? OT_LONG : OT_WORD;
                   5686:             modrm = ldub_code(s->pc++);
                   5687:             reg = (modrm >> 3) & 7;
                   5688:             mod = (modrm >> 6) & 3;
                   5689:             rm = modrm & 7;
                   5690:             if (mod != 3) {
                   5691:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5692:                 gen_op_ld_T0_A0[ot + s->mem_index]();
                   5693:             } else {
                   5694:                 gen_op_mov_TN_reg[ot][0][rm]();
                   5695:             }
                   5696:             if (s->cc_op != CC_OP_DYNAMIC)
                   5697:                 gen_op_set_cc_op(s->cc_op);
                   5698:             gen_op_arpl();
                   5699:             s->cc_op = CC_OP_EFLAGS;
                   5700:             if (mod != 3) {
                   5701:                 gen_op_st_T0_A0[ot + s->mem_index]();
                   5702:             } else {
                   5703:                 gen_op_mov_reg_T0[ot][rm]();
                   5704:             }
                   5705:             gen_op_arpl_update();
                   5706:         }
                   5707:         break;
                   5708:     case 0x102: /* lar */
                   5709:     case 0x103: /* lsl */
                   5710:         if (!s->pe || s->vm86)
                   5711:             goto illegal_op;
                   5712:         ot = dflag ? OT_LONG : OT_WORD;
                   5713:         modrm = ldub_code(s->pc++);
                   5714:         reg = ((modrm >> 3) & 7) | rex_r;
                   5715:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
                   5716:         gen_op_mov_TN_reg[ot][1][reg]();
                   5717:         if (s->cc_op != CC_OP_DYNAMIC)
                   5718:             gen_op_set_cc_op(s->cc_op);
                   5719:         if (b == 0x102)
                   5720:             gen_op_lar();
                   5721:         else
                   5722:             gen_op_lsl();
                   5723:         s->cc_op = CC_OP_EFLAGS;
                   5724:         gen_op_mov_reg_T1[ot][reg]();
                   5725:         break;
                   5726:     case 0x118:
                   5727:         modrm = ldub_code(s->pc++);
                   5728:         mod = (modrm >> 6) & 3;
                   5729:         op = (modrm >> 3) & 7;
                   5730:         switch(op) {
                   5731:         case 0: /* prefetchnta */
                   5732:         case 1: /* prefetchnt0 */
                   5733:         case 2: /* prefetchnt0 */
                   5734:         case 3: /* prefetchnt0 */
                   5735:             if (mod == 3)
                   5736:                 goto illegal_op;
                   5737:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5738:             /* nothing more to do */
                   5739:             break;
                   5740:         default:
                   5741:             goto illegal_op;
                   5742:         }
                   5743:         break;
                   5744:     case 0x120: /* mov reg, crN */
                   5745:     case 0x122: /* mov crN, reg */
                   5746:         if (s->cpl != 0) {
                   5747:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5748:         } else {
                   5749:             modrm = ldub_code(s->pc++);
                   5750:             if ((modrm & 0xc0) != 0xc0)
                   5751:                 goto illegal_op;
                   5752:             rm = (modrm & 7) | REX_B(s);
                   5753:             reg = ((modrm >> 3) & 7) | rex_r;
                   5754:             if (CODE64(s))
                   5755:                 ot = OT_QUAD;
                   5756:             else
                   5757:                 ot = OT_LONG;
                   5758:             switch(reg) {
                   5759:             case 0:
                   5760:             case 2:
                   5761:             case 3:
                   5762:             case 4:
                   5763:             case 8:
                   5764:                 if (b & 2) {
                   5765:                     gen_op_mov_TN_reg[ot][0][rm]();
                   5766:                     gen_op_movl_crN_T0(reg);
                   5767:                     gen_jmp_im(s->pc - s->cs_base);
                   5768:                     gen_eob(s);
                   5769:                 } else {
                   5770: #if !defined(CONFIG_USER_ONLY) 
                   5771:                     if (reg == 8)
                   5772:                         gen_op_movtl_T0_cr8();
                   5773:                     else
                   5774: #endif
                   5775:                         gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
                   5776:                     gen_op_mov_reg_T0[ot][rm]();
                   5777:                 }
                   5778:                 break;
                   5779:             default:
                   5780:                 goto illegal_op;
                   5781:             }
                   5782:         }
                   5783:         break;
                   5784:     case 0x121: /* mov reg, drN */
                   5785:     case 0x123: /* mov drN, reg */
                   5786:         if (s->cpl != 0) {
                   5787:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5788:         } else {
                   5789:             modrm = ldub_code(s->pc++);
                   5790:             if ((modrm & 0xc0) != 0xc0)
                   5791:                 goto illegal_op;
                   5792:             rm = (modrm & 7) | REX_B(s);
                   5793:             reg = ((modrm >> 3) & 7) | rex_r;
                   5794:             if (CODE64(s))
                   5795:                 ot = OT_QUAD;
                   5796:             else
                   5797:                 ot = OT_LONG;
                   5798:             /* XXX: do it dynamically with CR4.DE bit */
                   5799:             if (reg == 4 || reg == 5 || reg >= 8)
                   5800:                 goto illegal_op;
                   5801:             if (b & 2) {
                   5802:                 gen_op_mov_TN_reg[ot][0][rm]();
                   5803:                 gen_op_movl_drN_T0(reg);
                   5804:                 gen_jmp_im(s->pc - s->cs_base);
                   5805:                 gen_eob(s);
                   5806:             } else {
                   5807:                 gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
                   5808:                 gen_op_mov_reg_T0[ot][rm]();
                   5809:             }
                   5810:         }
                   5811:         break;
                   5812:     case 0x106: /* clts */
                   5813:         if (s->cpl != 0) {
                   5814:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                   5815:         } else {
                   5816:             gen_op_clts();
                   5817:             /* abort block because static cpu state changed */
                   5818:             gen_jmp_im(s->pc - s->cs_base);
                   5819:             gen_eob(s);
                   5820:         }
                   5821:         break;
                   5822:     /* MMX/SSE/SSE2/PNI support */
                   5823:     case 0x1c3: /* MOVNTI reg, mem */
                   5824:         if (!(s->cpuid_features & CPUID_SSE2))
                   5825:             goto illegal_op;
                   5826:         ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
                   5827:         modrm = ldub_code(s->pc++);
                   5828:         mod = (modrm >> 6) & 3;
                   5829:         if (mod == 3)
                   5830:             goto illegal_op;
                   5831:         reg = ((modrm >> 3) & 7) | rex_r;
                   5832:         /* generate a generic store */
                   5833:         gen_ldst_modrm(s, modrm, ot, reg, 1);
                   5834:         break;
                   5835:     case 0x1ae:
                   5836:         modrm = ldub_code(s->pc++);
                   5837:         mod = (modrm >> 6) & 3;
                   5838:         op = (modrm >> 3) & 7;
                   5839:         switch(op) {
                   5840:         case 0: /* fxsave */
1.1.1.3 ! root     5841:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 
        !          5842:                 (s->flags & HF_EM_MASK))
1.1       root     5843:                 goto illegal_op;
1.1.1.3 ! root     5844:             if (s->flags & HF_TS_MASK) {
        !          5845:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
        !          5846:                 break;
        !          5847:             }
1.1       root     5848:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5849:             gen_op_fxsave_A0((s->dflag == 2));
                   5850:             break;
                   5851:         case 1: /* fxrstor */
1.1.1.3 ! root     5852:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 
        !          5853:                 (s->flags & HF_EM_MASK))
1.1       root     5854:                 goto illegal_op;
1.1.1.3 ! root     5855:             if (s->flags & HF_TS_MASK) {
        !          5856:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
        !          5857:                 break;
        !          5858:             }
1.1       root     5859:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5860:             gen_op_fxrstor_A0((s->dflag == 2));
                   5861:             break;
                   5862:         case 2: /* ldmxcsr */
                   5863:         case 3: /* stmxcsr */
                   5864:             if (s->flags & HF_TS_MASK) {
                   5865:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
                   5866:                 break;
                   5867:             }
                   5868:             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
                   5869:                 mod == 3)
                   5870:                 goto illegal_op;
                   5871:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5872:             if (op == 2) {
                   5873:                 gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
                   5874:                 gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
                   5875:             } else {
                   5876:                 gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
                   5877:                 gen_op_st_T0_A0[OT_LONG + s->mem_index]();
                   5878:             }
                   5879:             break;
                   5880:         case 5: /* lfence */
                   5881:         case 6: /* mfence */
                   5882:             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
                   5883:                 goto illegal_op;
                   5884:             break;
                   5885:         case 7: /* sfence / clflush */
                   5886:             if ((modrm & 0xc7) == 0xc0) {
                   5887:                 /* sfence */
                   5888:                 if (!(s->cpuid_features & CPUID_SSE))
                   5889:                     goto illegal_op;
                   5890:             } else {
                   5891:                 /* clflush */
                   5892:                 if (!(s->cpuid_features & CPUID_CLFLUSH))
                   5893:                     goto illegal_op;
                   5894:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5895:             }
                   5896:             break;
                   5897:         default:
                   5898:             goto illegal_op;
                   5899:         }
                   5900:         break;
                   5901:     case 0x10d: /* prefetch */
                   5902:         modrm = ldub_code(s->pc++);
                   5903:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                   5904:         /* ignore for now */
                   5905:         break;
                   5906:     case 0x110 ... 0x117:
                   5907:     case 0x128 ... 0x12f:
                   5908:     case 0x150 ... 0x177:
                   5909:     case 0x17c ... 0x17f:
                   5910:     case 0x1c2:
                   5911:     case 0x1c4 ... 0x1c6:
                   5912:     case 0x1d0 ... 0x1fe:
                   5913:         gen_sse(s, b, pc_start, rex_r);
                   5914:         break;
                   5915:     default:
                   5916:         goto illegal_op;
                   5917:     }
                   5918:     /* lock generation */
                   5919:     if (s->prefix & PREFIX_LOCK)
                   5920:         gen_op_unlock();
                   5921:     return s->pc;
                   5922:  illegal_op:
                   5923:     if (s->prefix & PREFIX_LOCK)
                   5924:         gen_op_unlock();
                   5925:     /* XXX: ensure that no lock was generated */
                   5926:     gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
                   5927:     return s->pc;
                   5928: }
                   5929: 
                   5930: #define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
                   5931: #define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
                   5932: 
                   5933: /* flags read by an operation */
                   5934: static uint16_t opc_read_flags[NB_OPS] = { 
                   5935:     [INDEX_op_aas] = CC_A,
                   5936:     [INDEX_op_aaa] = CC_A,
                   5937:     [INDEX_op_das] = CC_A | CC_C,
                   5938:     [INDEX_op_daa] = CC_A | CC_C,
                   5939: 
                   5940:     /* subtle: due to the incl/decl implementation, C is used */
                   5941:     [INDEX_op_update_inc_cc] = CC_C, 
                   5942: 
                   5943:     [INDEX_op_into] = CC_O,
                   5944: 
                   5945:     [INDEX_op_jb_subb] = CC_C,
                   5946:     [INDEX_op_jb_subw] = CC_C,
                   5947:     [INDEX_op_jb_subl] = CC_C,
                   5948: 
                   5949:     [INDEX_op_jz_subb] = CC_Z,
                   5950:     [INDEX_op_jz_subw] = CC_Z,
                   5951:     [INDEX_op_jz_subl] = CC_Z,
                   5952: 
                   5953:     [INDEX_op_jbe_subb] = CC_Z | CC_C,
                   5954:     [INDEX_op_jbe_subw] = CC_Z | CC_C,
                   5955:     [INDEX_op_jbe_subl] = CC_Z | CC_C,
                   5956: 
                   5957:     [INDEX_op_js_subb] = CC_S,
                   5958:     [INDEX_op_js_subw] = CC_S,
                   5959:     [INDEX_op_js_subl] = CC_S,
                   5960: 
                   5961:     [INDEX_op_jl_subb] = CC_O | CC_S,
                   5962:     [INDEX_op_jl_subw] = CC_O | CC_S,
                   5963:     [INDEX_op_jl_subl] = CC_O | CC_S,
                   5964: 
                   5965:     [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
                   5966:     [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
                   5967:     [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
                   5968: 
                   5969:     [INDEX_op_loopnzw] = CC_Z,
                   5970:     [INDEX_op_loopnzl] = CC_Z,
                   5971:     [INDEX_op_loopzw] = CC_Z,
                   5972:     [INDEX_op_loopzl] = CC_Z,
                   5973: 
                   5974:     [INDEX_op_seto_T0_cc] = CC_O,
                   5975:     [INDEX_op_setb_T0_cc] = CC_C,
                   5976:     [INDEX_op_setz_T0_cc] = CC_Z,
                   5977:     [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
                   5978:     [INDEX_op_sets_T0_cc] = CC_S,
                   5979:     [INDEX_op_setp_T0_cc] = CC_P,
                   5980:     [INDEX_op_setl_T0_cc] = CC_O | CC_S,
                   5981:     [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
                   5982: 
                   5983:     [INDEX_op_setb_T0_subb] = CC_C,
                   5984:     [INDEX_op_setb_T0_subw] = CC_C,
                   5985:     [INDEX_op_setb_T0_subl] = CC_C,
                   5986: 
                   5987:     [INDEX_op_setz_T0_subb] = CC_Z,
                   5988:     [INDEX_op_setz_T0_subw] = CC_Z,
                   5989:     [INDEX_op_setz_T0_subl] = CC_Z,
                   5990: 
                   5991:     [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
                   5992:     [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
                   5993:     [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
                   5994: 
                   5995:     [INDEX_op_sets_T0_subb] = CC_S,
                   5996:     [INDEX_op_sets_T0_subw] = CC_S,
                   5997:     [INDEX_op_sets_T0_subl] = CC_S,
                   5998: 
                   5999:     [INDEX_op_setl_T0_subb] = CC_O | CC_S,
                   6000:     [INDEX_op_setl_T0_subw] = CC_O | CC_S,
                   6001:     [INDEX_op_setl_T0_subl] = CC_O | CC_S,
                   6002: 
                   6003:     [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
                   6004:     [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
                   6005:     [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
                   6006: 
                   6007:     [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
                   6008:     [INDEX_op_cmc] = CC_C,
                   6009:     [INDEX_op_salc] = CC_C,
                   6010: 
                   6011:     /* needed for correct flag optimisation before string ops */
                   6012:     [INDEX_op_jnz_ecxw] = CC_OSZAPC,
                   6013:     [INDEX_op_jnz_ecxl] = CC_OSZAPC,
                   6014:     [INDEX_op_jz_ecxw] = CC_OSZAPC,
                   6015:     [INDEX_op_jz_ecxl] = CC_OSZAPC,
                   6016: 
                   6017: #ifdef TARGET_X86_64
                   6018:     [INDEX_op_jb_subq] = CC_C,
                   6019:     [INDEX_op_jz_subq] = CC_Z,
                   6020:     [INDEX_op_jbe_subq] = CC_Z | CC_C,
                   6021:     [INDEX_op_js_subq] = CC_S,
                   6022:     [INDEX_op_jl_subq] = CC_O | CC_S,
                   6023:     [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
                   6024: 
                   6025:     [INDEX_op_loopnzq] = CC_Z,
                   6026:     [INDEX_op_loopzq] = CC_Z,
                   6027: 
                   6028:     [INDEX_op_setb_T0_subq] = CC_C,
                   6029:     [INDEX_op_setz_T0_subq] = CC_Z,
                   6030:     [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
                   6031:     [INDEX_op_sets_T0_subq] = CC_S,
                   6032:     [INDEX_op_setl_T0_subq] = CC_O | CC_S,
                   6033:     [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
                   6034: 
                   6035:     [INDEX_op_jnz_ecxq] = CC_OSZAPC,
                   6036:     [INDEX_op_jz_ecxq] = CC_OSZAPC,
                   6037: #endif
                   6038: 
                   6039: #define DEF_READF(SUFFIX)\
                   6040:     [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6041:     [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6042:     [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6043:     X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
                   6044:     [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6045:     [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6046:     [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6047:     X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
                   6048: \
                   6049:     [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6050:     [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6051:     [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6052:     X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
                   6053:     [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6054:     [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6055:     [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
                   6056:     X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
                   6057: 
                   6058:     DEF_READF( )
                   6059:     DEF_READF(_raw)
                   6060: #ifndef CONFIG_USER_ONLY
                   6061:     DEF_READF(_kernel)
                   6062:     DEF_READF(_user)
                   6063: #endif
                   6064: };
                   6065: 
                   6066: /* flags written by an operation */
                   6067: static uint16_t opc_write_flags[NB_OPS] = { 
                   6068:     [INDEX_op_update2_cc] = CC_OSZAPC,
                   6069:     [INDEX_op_update1_cc] = CC_OSZAPC,
                   6070:     [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
                   6071:     [INDEX_op_update_neg_cc] = CC_OSZAPC,
                   6072:     /* subtle: due to the incl/decl implementation, C is used */
                   6073:     [INDEX_op_update_inc_cc] = CC_OSZAPC, 
                   6074:     [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
                   6075: 
                   6076:     [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
                   6077:     [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
                   6078:     [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
                   6079:     X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
                   6080:     [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
                   6081:     [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
                   6082:     [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
                   6083:     X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
                   6084:     [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
                   6085:     [INDEX_op_imull_T0_T1] = CC_OSZAPC,
                   6086:     X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
                   6087: 
                   6088:     /* sse */
                   6089:     [INDEX_op_ucomiss] = CC_OSZAPC,
                   6090:     [INDEX_op_ucomisd] = CC_OSZAPC,
                   6091:     [INDEX_op_comiss] = CC_OSZAPC,
                   6092:     [INDEX_op_comisd] = CC_OSZAPC,
                   6093: 
                   6094:     /* bcd */
                   6095:     [INDEX_op_aam] = CC_OSZAPC,
                   6096:     [INDEX_op_aad] = CC_OSZAPC,
                   6097:     [INDEX_op_aas] = CC_OSZAPC,
                   6098:     [INDEX_op_aaa] = CC_OSZAPC,
                   6099:     [INDEX_op_das] = CC_OSZAPC,
                   6100:     [INDEX_op_daa] = CC_OSZAPC,
                   6101: 
                   6102:     [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
                   6103:     [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
                   6104:     [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
                   6105:     [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
                   6106:     [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
                   6107:     [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
                   6108:     [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
                   6109:     [INDEX_op_clc] = CC_C,
                   6110:     [INDEX_op_stc] = CC_C,
                   6111:     [INDEX_op_cmc] = CC_C,
                   6112: 
                   6113:     [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
                   6114:     [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
                   6115:     X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
                   6116:     [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
                   6117:     [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
                   6118:     X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
                   6119:     [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
                   6120:     [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
                   6121:     X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
                   6122:     [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
                   6123:     [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
                   6124:     X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
                   6125: 
                   6126:     [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
                   6127:     [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
                   6128:     X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
                   6129:     [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
                   6130:     [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
                   6131:     X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
                   6132: 
                   6133:     [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
                   6134:     [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
                   6135:     [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
                   6136:     X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
                   6137: 
                   6138:     [INDEX_op_cmpxchg8b] = CC_Z,
                   6139:     [INDEX_op_lar] = CC_Z,
                   6140:     [INDEX_op_lsl] = CC_Z,
                   6141:     [INDEX_op_verr] = CC_Z,
                   6142:     [INDEX_op_verw] = CC_Z,
                   6143:     [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
                   6144:     [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
                   6145: 
                   6146: #define DEF_WRITEF(SUFFIX)\
                   6147:     [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6148:     [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6149:     [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6150:     X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
                   6151:     [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6152:     [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6153:     [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6154:     X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
                   6155: \
                   6156:     [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6157:     [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6158:     [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6159:     X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
                   6160:     [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6161:     [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6162:     [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6163:     X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
                   6164: \
                   6165:     [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6166:     [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6167:     [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6168:     X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
                   6169:     [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6170:     [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6171:     [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
                   6172:     X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
                   6173: \
                   6174:     [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6175:     [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6176:     [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6177:     X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
                   6178: \
                   6179:     [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6180:     [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6181:     [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6182:     X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
                   6183: \
                   6184:     [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6185:     [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6186:     [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
                   6187:     X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
                   6188: \
                   6189:     [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
                   6190:     [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
                   6191:     X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
                   6192:     [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
                   6193:     [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
                   6194:     X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
                   6195: \
                   6196:     [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
                   6197:     [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
                   6198:     X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
                   6199:     [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
                   6200:     [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
                   6201:     X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
                   6202: \
                   6203:     [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
                   6204:     [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
                   6205:     [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
                   6206:     X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
                   6207: 
                   6208: 
                   6209:     DEF_WRITEF( )
                   6210:     DEF_WRITEF(_raw)
                   6211: #ifndef CONFIG_USER_ONLY
                   6212:     DEF_WRITEF(_kernel)
                   6213:     DEF_WRITEF(_user)
                   6214: #endif
                   6215: };
                   6216: 
                   6217: /* simpler form of an operation if no flags need to be generated */
                   6218: static uint16_t opc_simpler[NB_OPS] = { 
                   6219:     [INDEX_op_update2_cc] = INDEX_op_nop,
                   6220:     [INDEX_op_update1_cc] = INDEX_op_nop,
                   6221:     [INDEX_op_update_neg_cc] = INDEX_op_nop,
                   6222: #if 0
                   6223:     /* broken: CC_OP logic must be rewritten */
                   6224:     [INDEX_op_update_inc_cc] = INDEX_op_nop,
                   6225: #endif
                   6226: 
                   6227:     [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
                   6228:     [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
                   6229:     [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
                   6230:     X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
                   6231: 
                   6232:     [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
                   6233:     [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
                   6234:     [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
                   6235:     X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
                   6236: 
                   6237:     [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
                   6238:     [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
                   6239:     [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
                   6240:     X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
                   6241: 
                   6242: #define DEF_SIMPLER(SUFFIX)\
                   6243:     [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
                   6244:     [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
                   6245:     [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
                   6246:     X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
                   6247: \
                   6248:     [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
                   6249:     [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
                   6250:     [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
                   6251:     X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
                   6252: 
                   6253:     DEF_SIMPLER( )
                   6254:     DEF_SIMPLER(_raw)
                   6255: #ifndef CONFIG_USER_ONLY
                   6256:     DEF_SIMPLER(_kernel)
                   6257:     DEF_SIMPLER(_user)
                   6258: #endif
                   6259: };
                   6260: 
                   6261: void optimize_flags_init(void)
                   6262: {
                   6263:     int i;
                   6264:     /* put default values in arrays */
                   6265:     for(i = 0; i < NB_OPS; i++) {
                   6266:         if (opc_simpler[i] == 0)
                   6267:             opc_simpler[i] = i;
                   6268:     }
                   6269: }
                   6270: 
                   6271: /* CPU flags computation optimization: we move backward thru the
                   6272:    generated code to see which flags are needed. The operation is
                   6273:    modified if suitable */
                   6274: static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
                   6275: {
                   6276:     uint16_t *opc_ptr;
                   6277:     int live_flags, write_flags, op;
                   6278: 
                   6279:     opc_ptr = opc_buf + opc_buf_len;
                   6280:     /* live_flags contains the flags needed by the next instructions
                   6281:        in the code. At the end of the bloc, we consider that all the
                   6282:        flags are live. */
                   6283:     live_flags = CC_OSZAPC;
                   6284:     while (opc_ptr > opc_buf) {
                   6285:         op = *--opc_ptr;
                   6286:         /* if none of the flags written by the instruction is used,
                   6287:            then we can try to find a simpler instruction */
                   6288:         write_flags = opc_write_flags[op];
                   6289:         if ((live_flags & write_flags) == 0) {
                   6290:             *opc_ptr = opc_simpler[op];
                   6291:         }
                   6292:         /* compute the live flags before the instruction */
                   6293:         live_flags &= ~write_flags;
                   6294:         live_flags |= opc_read_flags[op];
                   6295:     }
                   6296: }
                   6297: 
                   6298: /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
                   6299:    basic block 'tb'. If search_pc is TRUE, also generate PC
                   6300:    information for each intermediate instruction. */
                   6301: static inline int gen_intermediate_code_internal(CPUState *env,
                   6302:                                                  TranslationBlock *tb, 
                   6303:                                                  int search_pc)
                   6304: {
                   6305:     DisasContext dc1, *dc = &dc1;
                   6306:     target_ulong pc_ptr;
                   6307:     uint16_t *gen_opc_end;
                   6308:     int flags, j, lj, cflags;
                   6309:     target_ulong pc_start;
                   6310:     target_ulong cs_base;
                   6311:     
                   6312:     /* generate intermediate code */
                   6313:     pc_start = tb->pc;
                   6314:     cs_base = tb->cs_base;
                   6315:     flags = tb->flags;
                   6316:     cflags = tb->cflags;
                   6317: 
                   6318:     dc->pe = (flags >> HF_PE_SHIFT) & 1;
                   6319:     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
                   6320:     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
                   6321:     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
                   6322:     dc->f_st = 0;
                   6323:     dc->vm86 = (flags >> VM_SHIFT) & 1;
                   6324:     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
                   6325:     dc->iopl = (flags >> IOPL_SHIFT) & 3;
                   6326:     dc->tf = (flags >> TF_SHIFT) & 1;
                   6327:     dc->singlestep_enabled = env->singlestep_enabled;
                   6328:     dc->cc_op = CC_OP_DYNAMIC;
                   6329:     dc->cs_base = cs_base;
                   6330:     dc->tb = tb;
                   6331:     dc->popl_esp_hack = 0;
                   6332:     /* select memory access functions */
                   6333:     dc->mem_index = 0;
                   6334:     if (flags & HF_SOFTMMU_MASK) {
                   6335:         if (dc->cpl == 3)
                   6336:             dc->mem_index = 2 * 4;
                   6337:         else
                   6338:             dc->mem_index = 1 * 4;
                   6339:     }
                   6340:     dc->cpuid_features = env->cpuid_features;
                   6341: #ifdef TARGET_X86_64
                   6342:     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
                   6343:     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
                   6344: #endif
                   6345:     dc->flags = flags;
                   6346:     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
                   6347:                     (flags & HF_INHIBIT_IRQ_MASK)
                   6348: #ifndef CONFIG_SOFTMMU
                   6349:                     || (flags & HF_SOFTMMU_MASK)
                   6350: #endif
                   6351:                     );
                   6352: #if 0
                   6353:     /* check addseg logic */
                   6354:     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
                   6355:         printf("ERROR addseg\n");
                   6356: #endif
                   6357: 
                   6358:     gen_opc_ptr = gen_opc_buf;
                   6359:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   6360:     gen_opparam_ptr = gen_opparam_buf;
                   6361:     nb_gen_labels = 0;
                   6362: 
                   6363:     dc->is_jmp = DISAS_NEXT;
                   6364:     pc_ptr = pc_start;
                   6365:     lj = -1;
                   6366: 
                   6367:     for(;;) {
                   6368:         if (env->nb_breakpoints > 0) {
                   6369:             for(j = 0; j < env->nb_breakpoints; j++) {
                   6370:                 if (env->breakpoints[j] == pc_ptr) {
                   6371:                     gen_debug(dc, pc_ptr - dc->cs_base);
                   6372:                     break;
                   6373:                 }
                   6374:             }
                   6375:         }
                   6376:         if (search_pc) {
                   6377:             j = gen_opc_ptr - gen_opc_buf;
                   6378:             if (lj < j) {
                   6379:                 lj++;
                   6380:                 while (lj < j)
                   6381:                     gen_opc_instr_start[lj++] = 0;
                   6382:             }
                   6383:             gen_opc_pc[lj] = pc_ptr;
                   6384:             gen_opc_cc_op[lj] = dc->cc_op;
                   6385:             gen_opc_instr_start[lj] = 1;
                   6386:         }
                   6387:         pc_ptr = disas_insn(dc, pc_ptr);
                   6388:         /* stop translation if indicated */
                   6389:         if (dc->is_jmp)
                   6390:             break;
                   6391:         /* if single step mode, we generate only one instruction and
                   6392:            generate an exception */
                   6393:         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
                   6394:            the flag and abort the translation to give the irqs a
                   6395:            change to be happen */
                   6396:         if (dc->tf || dc->singlestep_enabled || 
                   6397:             (flags & HF_INHIBIT_IRQ_MASK) ||
                   6398:             (cflags & CF_SINGLE_INSN)) {
                   6399:             gen_jmp_im(pc_ptr - dc->cs_base);
                   6400:             gen_eob(dc);
                   6401:             break;
                   6402:         }
                   6403:         /* if too long translation, stop generation too */
                   6404:         if (gen_opc_ptr >= gen_opc_end ||
                   6405:             (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
                   6406:             gen_jmp_im(pc_ptr - dc->cs_base);
                   6407:             gen_eob(dc);
                   6408:             break;
                   6409:         }
                   6410:     }
                   6411:     *gen_opc_ptr = INDEX_op_end;
                   6412:     /* we don't forget to fill the last values */
                   6413:     if (search_pc) {
                   6414:         j = gen_opc_ptr - gen_opc_buf;
                   6415:         lj++;
                   6416:         while (lj <= j)
                   6417:             gen_opc_instr_start[lj++] = 0;
                   6418:     }
                   6419:         
                   6420: #ifdef DEBUG_DISAS
                   6421:     if (loglevel & CPU_LOG_TB_CPU) {
                   6422:         cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
                   6423:     }
                   6424:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   6425:         int disas_flags;
                   6426:         fprintf(logfile, "----------------\n");
                   6427:         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
                   6428: #ifdef TARGET_X86_64
                   6429:         if (dc->code64)
                   6430:             disas_flags = 2;
                   6431:         else
                   6432: #endif
                   6433:             disas_flags = !dc->code32;
                   6434:        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
                   6435:         fprintf(logfile, "\n");
                   6436:         if (loglevel & CPU_LOG_TB_OP) {
                   6437:             fprintf(logfile, "OP:\n");
                   6438:             dump_ops(gen_opc_buf, gen_opparam_buf);
                   6439:             fprintf(logfile, "\n");
                   6440:         }
                   6441:     }
                   6442: #endif
                   6443: 
                   6444:     /* optimize flag computations */
                   6445:     optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
                   6446: 
                   6447: #ifdef DEBUG_DISAS
                   6448:     if (loglevel & CPU_LOG_TB_OP_OPT) {
                   6449:         fprintf(logfile, "AFTER FLAGS OPT:\n");
                   6450:         dump_ops(gen_opc_buf, gen_opparam_buf);
                   6451:         fprintf(logfile, "\n");
                   6452:     }
                   6453: #endif
                   6454:     if (!search_pc)
                   6455:         tb->size = pc_ptr - pc_start;
                   6456:     return 0;
                   6457: }
                   6458: 
                   6459: int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
                   6460: {
                   6461:     return gen_intermediate_code_internal(env, tb, 0);
                   6462: }
                   6463: 
                   6464: int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
                   6465: {
                   6466:     return gen_intermediate_code_internal(env, tb, 1);
                   6467: }
                   6468: 

unix.superglobalmegacorp.com

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