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

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

unix.superglobalmegacorp.com

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