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

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

unix.superglobalmegacorp.com

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