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

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

unix.superglobalmegacorp.com

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