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

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

unix.superglobalmegacorp.com

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