File:  [Qemu by Fabrice Bellard] / qemu / target-i386 / translate.c
Revision 1.1.1.16 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:31:11 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    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, see <http://www.gnu.org/licenses/>.
   18:  */
   19: #include <stdarg.h>
   20: #include <stdlib.h>
   21: #include <stdio.h>
   22: #include <string.h>
   23: #include <inttypes.h>
   24: #include <signal.h>
   25: 
   26: #include "cpu.h"
   27: #include "disas.h"
   28: #include "tcg-op.h"
   29: 
   30: #include "helper.h"
   31: #define GEN_HELPER 1
   32: #include "helper.h"
   33: 
   34: #define PREFIX_REPZ   0x01
   35: #define PREFIX_REPNZ  0x02
   36: #define PREFIX_LOCK   0x04
   37: #define PREFIX_DATA   0x08
   38: #define PREFIX_ADR    0x10
   39: 
   40: #ifdef TARGET_X86_64
   41: #define X86_64_ONLY(x) x
   42: #define X86_64_DEF(...)  __VA_ARGS__
   43: #define CODE64(s) ((s)->code64)
   44: #define REX_X(s) ((s)->rex_x)
   45: #define REX_B(s) ((s)->rex_b)
   46: /* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
   47: #if 1
   48: #define BUGGY_64(x) NULL
   49: #endif
   50: #else
   51: #define X86_64_ONLY(x) NULL
   52: #define X86_64_DEF(...)
   53: #define CODE64(s) 0
   54: #define REX_X(s) 0
   55: #define REX_B(s) 0
   56: #endif
   57: 
   58: //#define MACRO_TEST   1
   59: 
   60: /* global register indexes */
   61: static TCGv_ptr cpu_env;
   62: static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
   63: static TCGv_i32 cpu_cc_op;
   64: static TCGv cpu_regs[CPU_NB_REGS];
   65: /* local temps */
   66: static TCGv cpu_T[2], cpu_T3;
   67: /* local register indexes (only used inside old micro ops) */
   68: static TCGv cpu_tmp0, cpu_tmp4;
   69: static TCGv_ptr cpu_ptr0, cpu_ptr1;
   70: static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32;
   71: static TCGv_i64 cpu_tmp1_i64;
   72: static TCGv cpu_tmp5;
   73: 
   74: static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
   75: 
   76: #include "gen-icount.h"
   77: 
   78: #ifdef TARGET_X86_64
   79: static int x86_64_hregs;
   80: #endif
   81: 
   82: typedef struct DisasContext {
   83:     /* current insn context */
   84:     int override; /* -1 if no override */
   85:     int prefix;
   86:     int aflag, dflag;
   87:     target_ulong pc; /* pc = eip + cs_base */
   88:     int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
   89:                    static state change (stop translation) */
   90:     /* current block context */
   91:     target_ulong cs_base; /* base of CS segment */
   92:     int pe;     /* protected mode */
   93:     int code32; /* 32 bit code segment */
   94: #ifdef TARGET_X86_64
   95:     int lma;    /* long mode active */
   96:     int code64; /* 64 bit code segment */
   97:     int rex_x, rex_b;
   98: #endif
   99:     int ss32;   /* 32 bit stack segment */
  100:     int cc_op;  /* current CC operation */
  101:     int addseg; /* non zero if either DS/ES/SS have a non zero base */
  102:     int f_st;   /* currently unused */
  103:     int vm86;   /* vm86 mode */
  104:     int cpl;
  105:     int iopl;
  106:     int tf;     /* TF cpu flag */
  107:     int singlestep_enabled; /* "hardware" single step enabled */
  108:     int jmp_opt; /* use direct block chaining for direct jumps */
  109:     int mem_index; /* select memory access functions */
  110:     uint64_t flags; /* all execution flags */
  111:     struct TranslationBlock *tb;
  112:     int popl_esp_hack; /* for correct popl with esp base handling */
  113:     int rip_offset; /* only used in x86_64, but left for simplicity */
  114:     int cpuid_features;
  115:     int cpuid_ext_features;
  116:     int cpuid_ext2_features;
  117:     int cpuid_ext3_features;
  118: } DisasContext;
  119: 
  120: static void gen_eob(DisasContext *s);
  121: static void gen_jmp(DisasContext *s, target_ulong eip);
  122: static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
  123: 
  124: /* i386 arith/logic operations */
  125: enum {
  126:     OP_ADDL,
  127:     OP_ORL,
  128:     OP_ADCL,
  129:     OP_SBBL,
  130:     OP_ANDL,
  131:     OP_SUBL,
  132:     OP_XORL,
  133:     OP_CMPL,
  134: };
  135: 
  136: /* i386 shift ops */
  137: enum {
  138:     OP_ROL,
  139:     OP_ROR,
  140:     OP_RCL,
  141:     OP_RCR,
  142:     OP_SHL,
  143:     OP_SHR,
  144:     OP_SHL1, /* undocumented */
  145:     OP_SAR = 7,
  146: };
  147: 
  148: enum {
  149:     JCC_O,
  150:     JCC_B,
  151:     JCC_Z,
  152:     JCC_BE,
  153:     JCC_S,
  154:     JCC_P,
  155:     JCC_L,
  156:     JCC_LE,
  157: };
  158: 
  159: /* operand size */
  160: enum {
  161:     OT_BYTE = 0,
  162:     OT_WORD,
  163:     OT_LONG,
  164:     OT_QUAD,
  165: };
  166: 
  167: enum {
  168:     /* I386 int registers */
  169:     OR_EAX,   /* MUST be even numbered */
  170:     OR_ECX,
  171:     OR_EDX,
  172:     OR_EBX,
  173:     OR_ESP,
  174:     OR_EBP,
  175:     OR_ESI,
  176:     OR_EDI,
  177: 
  178:     OR_TMP0 = 16,    /* temporary operand register */
  179:     OR_TMP1,
  180:     OR_A0, /* temporary register used when doing address evaluation */
  181: };
  182: 
  183: static inline void gen_op_movl_T0_0(void)
  184: {
  185:     tcg_gen_movi_tl(cpu_T[0], 0);
  186: }
  187: 
  188: static inline void gen_op_movl_T0_im(int32_t val)
  189: {
  190:     tcg_gen_movi_tl(cpu_T[0], val);
  191: }
  192: 
  193: static inline void gen_op_movl_T0_imu(uint32_t val)
  194: {
  195:     tcg_gen_movi_tl(cpu_T[0], val);
  196: }
  197: 
  198: static inline void gen_op_movl_T1_im(int32_t val)
  199: {
  200:     tcg_gen_movi_tl(cpu_T[1], val);
  201: }
  202: 
  203: static inline void gen_op_movl_T1_imu(uint32_t val)
  204: {
  205:     tcg_gen_movi_tl(cpu_T[1], val);
  206: }
  207: 
  208: static inline void gen_op_movl_A0_im(uint32_t val)
  209: {
  210:     tcg_gen_movi_tl(cpu_A0, val);
  211: }
  212: 
  213: #ifdef TARGET_X86_64
  214: static inline void gen_op_movq_A0_im(int64_t val)
  215: {
  216:     tcg_gen_movi_tl(cpu_A0, val);
  217: }
  218: #endif
  219: 
  220: static inline void gen_movtl_T0_im(target_ulong val)
  221: {
  222:     tcg_gen_movi_tl(cpu_T[0], val);
  223: }
  224: 
  225: static inline void gen_movtl_T1_im(target_ulong val)
  226: {
  227:     tcg_gen_movi_tl(cpu_T[1], val);
  228: }
  229: 
  230: static inline void gen_op_andl_T0_ffff(void)
  231: {
  232:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
  233: }
  234: 
  235: static inline void gen_op_andl_T0_im(uint32_t val)
  236: {
  237:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
  238: }
  239: 
  240: static inline void gen_op_movl_T0_T1(void)
  241: {
  242:     tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
  243: }
  244: 
  245: static inline void gen_op_andl_A0_ffff(void)
  246: {
  247:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
  248: }
  249: 
  250: #ifdef TARGET_X86_64
  251: 
  252: #define NB_OP_SIZES 4
  253: 
  254: #else /* !TARGET_X86_64 */
  255: 
  256: #define NB_OP_SIZES 3
  257: 
  258: #endif /* !TARGET_X86_64 */
  259: 
  260: #if defined(HOST_WORDS_BIGENDIAN)
  261: #define REG_B_OFFSET (sizeof(target_ulong) - 1)
  262: #define REG_H_OFFSET (sizeof(target_ulong) - 2)
  263: #define REG_W_OFFSET (sizeof(target_ulong) - 2)
  264: #define REG_L_OFFSET (sizeof(target_ulong) - 4)
  265: #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
  266: #else
  267: #define REG_B_OFFSET 0
  268: #define REG_H_OFFSET 1
  269: #define REG_W_OFFSET 0
  270: #define REG_L_OFFSET 0
  271: #define REG_LH_OFFSET 4
  272: #endif
  273: 
  274: static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)
  275: {
  276:     switch(ot) {
  277:     case OT_BYTE:
  278:         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
  279:             tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
  280:         } else {
  281:             tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
  282:         }
  283:         break;
  284:     case OT_WORD:
  285:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
  286:         break;
  287:     default: /* XXX this shouldn't be reached;  abort? */
  288:     case OT_LONG:
  289:         /* For x86_64, this sets the higher half of register to zero.
  290:            For i386, this is equivalent to a mov. */
  291:         tcg_gen_ext32u_tl(cpu_regs[reg], t0);
  292:         break;
  293: #ifdef TARGET_X86_64
  294:     case OT_QUAD:
  295:         tcg_gen_mov_tl(cpu_regs[reg], t0);
  296:         break;
  297: #endif
  298:     }
  299: }
  300: 
  301: static inline void gen_op_mov_reg_T0(int ot, int reg)
  302: {
  303:     gen_op_mov_reg_v(ot, reg, cpu_T[0]);
  304: }
  305: 
  306: static inline void gen_op_mov_reg_T1(int ot, int reg)
  307: {
  308:     gen_op_mov_reg_v(ot, reg, cpu_T[1]);
  309: }
  310: 
  311: static inline void gen_op_mov_reg_A0(int size, int reg)
  312: {
  313:     switch(size) {
  314:     case 0:
  315:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16);
  316:         break;
  317:     default: /* XXX this shouldn't be reached;  abort? */
  318:     case 1:
  319:         /* For x86_64, this sets the higher half of register to zero.
  320:            For i386, this is equivalent to a mov. */
  321:         tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0);
  322:         break;
  323: #ifdef TARGET_X86_64
  324:     case 2:
  325:         tcg_gen_mov_tl(cpu_regs[reg], cpu_A0);
  326:         break;
  327: #endif
  328:     }
  329: }
  330: 
  331: static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg)
  332: {
  333:     switch(ot) {
  334:     case OT_BYTE:
  335:         if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
  336:             goto std_case;
  337:         } else {
  338:             tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8);
  339:             tcg_gen_ext8u_tl(t0, t0);
  340:         }
  341:         break;
  342:     default:
  343:     std_case:
  344:         tcg_gen_mov_tl(t0, cpu_regs[reg]);
  345:         break;
  346:     }
  347: }
  348: 
  349: static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
  350: {
  351:     gen_op_mov_v_reg(ot, cpu_T[t_index], reg);
  352: }
  353: 
  354: static inline void gen_op_movl_A0_reg(int reg)
  355: {
  356:     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
  357: }
  358: 
  359: static inline void gen_op_addl_A0_im(int32_t val)
  360: {
  361:     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
  362: #ifdef TARGET_X86_64
  363:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
  364: #endif
  365: }
  366: 
  367: #ifdef TARGET_X86_64
  368: static inline void gen_op_addq_A0_im(int64_t val)
  369: {
  370:     tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
  371: }
  372: #endif
  373:     
  374: static void gen_add_A0_im(DisasContext *s, int val)
  375: {
  376: #ifdef TARGET_X86_64
  377:     if (CODE64(s))
  378:         gen_op_addq_A0_im(val);
  379:     else
  380: #endif
  381:         gen_op_addl_A0_im(val);
  382: }
  383: 
  384: static inline void gen_op_addl_T0_T1(void)
  385: {
  386:     tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
  387: }
  388: 
  389: static inline void gen_op_jmp_T0(void)
  390: {
  391:     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
  392: }
  393: 
  394: static inline void gen_op_add_reg_im(int size, int reg, int32_t val)
  395: {
  396:     switch(size) {
  397:     case 0:
  398:         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
  399:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
  400:         break;
  401:     case 1:
  402:         tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val);
  403:         /* For x86_64, this sets the higher half of register to zero.
  404:            For i386, this is equivalent to a nop. */
  405:         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
  406:         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
  407:         break;
  408: #ifdef TARGET_X86_64
  409:     case 2:
  410:         tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val);
  411:         break;
  412: #endif
  413:     }
  414: }
  415: 
  416: static inline void gen_op_add_reg_T0(int size, int reg)
  417: {
  418:     switch(size) {
  419:     case 0:
  420:         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
  421:         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16);
  422:         break;
  423:     case 1:
  424:         tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
  425:         /* For x86_64, this sets the higher half of register to zero.
  426:            For i386, this is equivalent to a nop. */
  427:         tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0);
  428:         tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0);
  429:         break;
  430: #ifdef TARGET_X86_64
  431:     case 2:
  432:         tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]);
  433:         break;
  434: #endif
  435:     }
  436: }
  437: 
  438: static inline void gen_op_set_cc_op(int32_t val)
  439: {
  440:     tcg_gen_movi_i32(cpu_cc_op, val);
  441: }
  442: 
  443: static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
  444: {
  445:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
  446:     if (shift != 0)
  447:         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
  448:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
  449:     /* For x86_64, this sets the higher half of register to zero.
  450:        For i386, this is equivalent to a nop. */
  451:     tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
  452: }
  453: 
  454: static inline void gen_op_movl_A0_seg(int reg)
  455: {
  456:     tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
  457: }
  458: 
  459: static inline void gen_op_addl_A0_seg(int reg)
  460: {
  461:     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
  462:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
  463: #ifdef TARGET_X86_64
  464:     tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
  465: #endif
  466: }
  467: 
  468: #ifdef TARGET_X86_64
  469: static inline void gen_op_movq_A0_seg(int reg)
  470: {
  471:     tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
  472: }
  473: 
  474: static inline void gen_op_addq_A0_seg(int reg)
  475: {
  476:     tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
  477:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
  478: }
  479: 
  480: static inline void gen_op_movq_A0_reg(int reg)
  481: {
  482:     tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]);
  483: }
  484: 
  485: static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
  486: {
  487:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[reg]);
  488:     if (shift != 0)
  489:         tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
  490:     tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
  491: }
  492: #endif
  493: 
  494: static inline void gen_op_lds_T0_A0(int idx)
  495: {
  496:     int mem_index = (idx >> 2) - 1;
  497:     switch(idx & 3) {
  498:     case 0:
  499:         tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
  500:         break;
  501:     case 1:
  502:         tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
  503:         break;
  504:     default:
  505:     case 2:
  506:         tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
  507:         break;
  508:     }
  509: }
  510: 
  511: static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0)
  512: {
  513:     int mem_index = (idx >> 2) - 1;
  514:     switch(idx & 3) {
  515:     case 0:
  516:         tcg_gen_qemu_ld8u(t0, a0, mem_index);
  517:         break;
  518:     case 1:
  519:         tcg_gen_qemu_ld16u(t0, a0, mem_index);
  520:         break;
  521:     case 2:
  522:         tcg_gen_qemu_ld32u(t0, a0, mem_index);
  523:         break;
  524:     default:
  525:     case 3:
  526:         /* Should never happen on 32-bit targets.  */
  527: #ifdef TARGET_X86_64
  528:         tcg_gen_qemu_ld64(t0, a0, mem_index);
  529: #endif
  530:         break;
  531:     }
  532: }
  533: 
  534: /* XXX: always use ldu or lds */
  535: static inline void gen_op_ld_T0_A0(int idx)
  536: {
  537:     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
  538: }
  539: 
  540: static inline void gen_op_ldu_T0_A0(int idx)
  541: {
  542:     gen_op_ld_v(idx, cpu_T[0], cpu_A0);
  543: }
  544: 
  545: static inline void gen_op_ld_T1_A0(int idx)
  546: {
  547:     gen_op_ld_v(idx, cpu_T[1], cpu_A0);
  548: }
  549: 
  550: static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0)
  551: {
  552:     int mem_index = (idx >> 2) - 1;
  553:     switch(idx & 3) {
  554:     case 0:
  555:         tcg_gen_qemu_st8(t0, a0, mem_index);
  556:         break;
  557:     case 1:
  558:         tcg_gen_qemu_st16(t0, a0, mem_index);
  559:         break;
  560:     case 2:
  561:         tcg_gen_qemu_st32(t0, a0, mem_index);
  562:         break;
  563:     default:
  564:     case 3:
  565:         /* Should never happen on 32-bit targets.  */
  566: #ifdef TARGET_X86_64
  567:         tcg_gen_qemu_st64(t0, a0, mem_index);
  568: #endif
  569:         break;
  570:     }
  571: }
  572: 
  573: static inline void gen_op_st_T0_A0(int idx)
  574: {
  575:     gen_op_st_v(idx, cpu_T[0], cpu_A0);
  576: }
  577: 
  578: static inline void gen_op_st_T1_A0(int idx)
  579: {
  580:     gen_op_st_v(idx, cpu_T[1], cpu_A0);
  581: }
  582: 
  583: static inline void gen_jmp_im(target_ulong pc)
  584: {
  585:     tcg_gen_movi_tl(cpu_tmp0, pc);
  586:     tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
  587: }
  588: 
  589: static inline void gen_string_movl_A0_ESI(DisasContext *s)
  590: {
  591:     int override;
  592: 
  593:     override = s->override;
  594: #ifdef TARGET_X86_64
  595:     if (s->aflag == 2) {
  596:         if (override >= 0) {
  597:             gen_op_movq_A0_seg(override);
  598:             gen_op_addq_A0_reg_sN(0, R_ESI);
  599:         } else {
  600:             gen_op_movq_A0_reg(R_ESI);
  601:         }
  602:     } else
  603: #endif
  604:     if (s->aflag) {
  605:         /* 32 bit address */
  606:         if (s->addseg && override < 0)
  607:             override = R_DS;
  608:         if (override >= 0) {
  609:             gen_op_movl_A0_seg(override);
  610:             gen_op_addl_A0_reg_sN(0, R_ESI);
  611:         } else {
  612:             gen_op_movl_A0_reg(R_ESI);
  613:         }
  614:     } else {
  615:         /* 16 address, always override */
  616:         if (override < 0)
  617:             override = R_DS;
  618:         gen_op_movl_A0_reg(R_ESI);
  619:         gen_op_andl_A0_ffff();
  620:         gen_op_addl_A0_seg(override);
  621:     }
  622: }
  623: 
  624: static inline void gen_string_movl_A0_EDI(DisasContext *s)
  625: {
  626: #ifdef TARGET_X86_64
  627:     if (s->aflag == 2) {
  628:         gen_op_movq_A0_reg(R_EDI);
  629:     } else
  630: #endif
  631:     if (s->aflag) {
  632:         if (s->addseg) {
  633:             gen_op_movl_A0_seg(R_ES);
  634:             gen_op_addl_A0_reg_sN(0, R_EDI);
  635:         } else {
  636:             gen_op_movl_A0_reg(R_EDI);
  637:         }
  638:     } else {
  639:         gen_op_movl_A0_reg(R_EDI);
  640:         gen_op_andl_A0_ffff();
  641:         gen_op_addl_A0_seg(R_ES);
  642:     }
  643: }
  644: 
  645: static inline void gen_op_movl_T0_Dshift(int ot) 
  646: {
  647:     tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df));
  648:     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
  649: };
  650: 
  651: static void gen_extu(int ot, TCGv reg)
  652: {
  653:     switch(ot) {
  654:     case OT_BYTE:
  655:         tcg_gen_ext8u_tl(reg, reg);
  656:         break;
  657:     case OT_WORD:
  658:         tcg_gen_ext16u_tl(reg, reg);
  659:         break;
  660:     case OT_LONG:
  661:         tcg_gen_ext32u_tl(reg, reg);
  662:         break;
  663:     default:
  664:         break;
  665:     }
  666: }
  667: 
  668: static void gen_exts(int ot, TCGv reg)
  669: {
  670:     switch(ot) {
  671:     case OT_BYTE:
  672:         tcg_gen_ext8s_tl(reg, reg);
  673:         break;
  674:     case OT_WORD:
  675:         tcg_gen_ext16s_tl(reg, reg);
  676:         break;
  677:     case OT_LONG:
  678:         tcg_gen_ext32s_tl(reg, reg);
  679:         break;
  680:     default:
  681:         break;
  682:     }
  683: }
  684: 
  685: static inline void gen_op_jnz_ecx(int size, int label1)
  686: {
  687:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
  688:     gen_extu(size + 1, cpu_tmp0);
  689:     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1);
  690: }
  691: 
  692: static inline void gen_op_jz_ecx(int size, int label1)
  693: {
  694:     tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]);
  695:     gen_extu(size + 1, cpu_tmp0);
  696:     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
  697: }
  698: 
  699: static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n)
  700: {
  701:     switch (ot) {
  702:     case 0: gen_helper_inb(v, n); break;
  703:     case 1: gen_helper_inw(v, n); break;
  704:     case 2: gen_helper_inl(v, n); break;
  705:     }
  706: 
  707: }
  708: 
  709: static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n)
  710: {
  711:     switch (ot) {
  712:     case 0: gen_helper_outb(v, n); break;
  713:     case 1: gen_helper_outw(v, n); break;
  714:     case 2: gen_helper_outl(v, n); break;
  715:     }
  716: 
  717: }
  718: 
  719: static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip,
  720:                          uint32_t svm_flags)
  721: {
  722:     int state_saved;
  723:     target_ulong next_eip;
  724: 
  725:     state_saved = 0;
  726:     if (s->pe && (s->cpl > s->iopl || s->vm86)) {
  727:         if (s->cc_op != CC_OP_DYNAMIC)
  728:             gen_op_set_cc_op(s->cc_op);
  729:         gen_jmp_im(cur_eip);
  730:         state_saved = 1;
  731:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
  732:         switch (ot) {
  733:         case 0: gen_helper_check_iob(cpu_tmp2_i32); break;
  734:         case 1: gen_helper_check_iow(cpu_tmp2_i32); break;
  735:         case 2: gen_helper_check_iol(cpu_tmp2_i32); break;
  736:         }
  737:     }
  738:     if(s->flags & HF_SVMI_MASK) {
  739:         if (!state_saved) {
  740:             if (s->cc_op != CC_OP_DYNAMIC)
  741:                 gen_op_set_cc_op(s->cc_op);
  742:             gen_jmp_im(cur_eip);
  743:         }
  744:         svm_flags |= (1 << (4 + ot));
  745:         next_eip = s->pc - s->cs_base;
  746:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
  747:         gen_helper_svm_check_io(cpu_tmp2_i32, tcg_const_i32(svm_flags),
  748:                                 tcg_const_i32(next_eip - cur_eip));
  749:     }
  750: }
  751: 
  752: static inline void gen_movs(DisasContext *s, int ot)
  753: {
  754:     gen_string_movl_A0_ESI(s);
  755:     gen_op_ld_T0_A0(ot + s->mem_index);
  756:     gen_string_movl_A0_EDI(s);
  757:     gen_op_st_T0_A0(ot + s->mem_index);
  758:     gen_op_movl_T0_Dshift(ot);
  759:     gen_op_add_reg_T0(s->aflag, R_ESI);
  760:     gen_op_add_reg_T0(s->aflag, R_EDI);
  761: }
  762: 
  763: static inline void gen_update_cc_op(DisasContext *s)
  764: {
  765:     if (s->cc_op != CC_OP_DYNAMIC) {
  766:         gen_op_set_cc_op(s->cc_op);
  767:         s->cc_op = CC_OP_DYNAMIC;
  768:     }
  769: }
  770: 
  771: static void gen_op_update1_cc(void)
  772: {
  773:     tcg_gen_discard_tl(cpu_cc_src);
  774:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
  775: }
  776: 
  777: static void gen_op_update2_cc(void)
  778: {
  779:     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
  780:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
  781: }
  782: 
  783: static inline void gen_op_cmpl_T0_T1_cc(void)
  784: {
  785:     tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
  786:     tcg_gen_sub_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
  787: }
  788: 
  789: static inline void gen_op_testl_T0_T1_cc(void)
  790: {
  791:     tcg_gen_discard_tl(cpu_cc_src);
  792:     tcg_gen_and_tl(cpu_cc_dst, cpu_T[0], cpu_T[1]);
  793: }
  794: 
  795: static void gen_op_update_neg_cc(void)
  796: {
  797:     tcg_gen_neg_tl(cpu_cc_src, cpu_T[0]);
  798:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
  799: }
  800: 
  801: /* compute eflags.C to reg */
  802: static void gen_compute_eflags_c(TCGv reg)
  803: {
  804:     gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_cc_op);
  805:     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
  806: }
  807: 
  808: /* compute all eflags to cc_src */
  809: static void gen_compute_eflags(TCGv reg)
  810: {
  811:     gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_cc_op);
  812:     tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
  813: }
  814: 
  815: static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)
  816: {
  817:     if (s->cc_op != CC_OP_DYNAMIC)
  818:         gen_op_set_cc_op(s->cc_op);
  819:     switch(jcc_op) {
  820:     case JCC_O:
  821:         gen_compute_eflags(cpu_T[0]);
  822:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 11);
  823:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  824:         break;
  825:     case JCC_B:
  826:         gen_compute_eflags_c(cpu_T[0]);
  827:         break;
  828:     case JCC_Z:
  829:         gen_compute_eflags(cpu_T[0]);
  830:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 6);
  831:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  832:         break;
  833:     case JCC_BE:
  834:         gen_compute_eflags(cpu_tmp0);
  835:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 6);
  836:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
  837:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  838:         break;
  839:     case JCC_S:
  840:         gen_compute_eflags(cpu_T[0]);
  841:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 7);
  842:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  843:         break;
  844:     case JCC_P:
  845:         gen_compute_eflags(cpu_T[0]);
  846:         tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 2);
  847:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  848:         break;
  849:     case JCC_L:
  850:         gen_compute_eflags(cpu_tmp0);
  851:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
  852:         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 7); /* CC_S */
  853:         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
  854:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  855:         break;
  856:     default:
  857:     case JCC_LE:
  858:         gen_compute_eflags(cpu_tmp0);
  859:         tcg_gen_shri_tl(cpu_T[0], cpu_tmp0, 11); /* CC_O */
  860:         tcg_gen_shri_tl(cpu_tmp4, cpu_tmp0, 7); /* CC_S */
  861:         tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 6); /* CC_Z */
  862:         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
  863:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
  864:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 1);
  865:         break;
  866:     }
  867: }
  868: 
  869: /* return true if setcc_slow is not needed (WARNING: must be kept in
  870:    sync with gen_jcc1) */
  871: static int is_fast_jcc_case(DisasContext *s, int b)
  872: {
  873:     int jcc_op;
  874:     jcc_op = (b >> 1) & 7;
  875:     switch(s->cc_op) {
  876:         /* we optimize the cmp/jcc case */
  877:     case CC_OP_SUBB:
  878:     case CC_OP_SUBW:
  879:     case CC_OP_SUBL:
  880:     case CC_OP_SUBQ:
  881:         if (jcc_op == JCC_O || jcc_op == JCC_P)
  882:             goto slow_jcc;
  883:         break;
  884: 
  885:         /* some jumps are easy to compute */
  886:     case CC_OP_ADDB:
  887:     case CC_OP_ADDW:
  888:     case CC_OP_ADDL:
  889:     case CC_OP_ADDQ:
  890: 
  891:     case CC_OP_LOGICB:
  892:     case CC_OP_LOGICW:
  893:     case CC_OP_LOGICL:
  894:     case CC_OP_LOGICQ:
  895: 
  896:     case CC_OP_INCB:
  897:     case CC_OP_INCW:
  898:     case CC_OP_INCL:
  899:     case CC_OP_INCQ:
  900: 
  901:     case CC_OP_DECB:
  902:     case CC_OP_DECW:
  903:     case CC_OP_DECL:
  904:     case CC_OP_DECQ:
  905: 
  906:     case CC_OP_SHLB:
  907:     case CC_OP_SHLW:
  908:     case CC_OP_SHLL:
  909:     case CC_OP_SHLQ:
  910:         if (jcc_op != JCC_Z && jcc_op != JCC_S)
  911:             goto slow_jcc;
  912:         break;
  913:     default:
  914:     slow_jcc:
  915:         return 0;
  916:     }
  917:     return 1;
  918: }
  919: 
  920: /* generate a conditional jump to label 'l1' according to jump opcode
  921:    value 'b'. In the fast case, T0 is guaranted not to be used. */
  922: static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
  923: {
  924:     int inv, jcc_op, size, cond;
  925:     TCGv t0;
  926: 
  927:     inv = b & 1;
  928:     jcc_op = (b >> 1) & 7;
  929: 
  930:     switch(cc_op) {
  931:         /* we optimize the cmp/jcc case */
  932:     case CC_OP_SUBB:
  933:     case CC_OP_SUBW:
  934:     case CC_OP_SUBL:
  935:     case CC_OP_SUBQ:
  936:         
  937:         size = cc_op - CC_OP_SUBB;
  938:         switch(jcc_op) {
  939:         case JCC_Z:
  940:         fast_jcc_z:
  941:             switch(size) {
  942:             case 0:
  943:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
  944:                 t0 = cpu_tmp0;
  945:                 break;
  946:             case 1:
  947:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
  948:                 t0 = cpu_tmp0;
  949:                 break;
  950: #ifdef TARGET_X86_64
  951:             case 2:
  952:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
  953:                 t0 = cpu_tmp0;
  954:                 break;
  955: #endif
  956:             default:
  957:                 t0 = cpu_cc_dst;
  958:                 break;
  959:             }
  960:             tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
  961:             break;
  962:         case JCC_S:
  963:         fast_jcc_s:
  964:             switch(size) {
  965:             case 0:
  966:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
  967:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
  968:                                    0, l1);
  969:                 break;
  970:             case 1:
  971:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
  972:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
  973:                                    0, l1);
  974:                 break;
  975: #ifdef TARGET_X86_64
  976:             case 2:
  977:                 tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
  978:                 tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
  979:                                    0, l1);
  980:                 break;
  981: #endif
  982:             default:
  983:                 tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, 
  984:                                    0, l1);
  985:                 break;
  986:             }
  987:             break;
  988:             
  989:         case JCC_B:
  990:             cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
  991:             goto fast_jcc_b;
  992:         case JCC_BE:
  993:             cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
  994:         fast_jcc_b:
  995:             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
  996:             switch(size) {
  997:             case 0:
  998:                 t0 = cpu_tmp0;
  999:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
 1000:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
 1001:                 break;
 1002:             case 1:
 1003:                 t0 = cpu_tmp0;
 1004:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
 1005:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
 1006:                 break;
 1007: #ifdef TARGET_X86_64
 1008:             case 2:
 1009:                 t0 = cpu_tmp0;
 1010:                 tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
 1011:                 tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
 1012:                 break;
 1013: #endif
 1014:             default:
 1015:                 t0 = cpu_cc_src;
 1016:                 break;
 1017:             }
 1018:             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
 1019:             break;
 1020:             
 1021:         case JCC_L:
 1022:             cond = inv ? TCG_COND_GE : TCG_COND_LT;
 1023:             goto fast_jcc_l;
 1024:         case JCC_LE:
 1025:             cond = inv ? TCG_COND_GT : TCG_COND_LE;
 1026:         fast_jcc_l:
 1027:             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
 1028:             switch(size) {
 1029:             case 0:
 1030:                 t0 = cpu_tmp0;
 1031:                 tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
 1032:                 tcg_gen_ext8s_tl(t0, cpu_cc_src);
 1033:                 break;
 1034:             case 1:
 1035:                 t0 = cpu_tmp0;
 1036:                 tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
 1037:                 tcg_gen_ext16s_tl(t0, cpu_cc_src);
 1038:                 break;
 1039: #ifdef TARGET_X86_64
 1040:             case 2:
 1041:                 t0 = cpu_tmp0;
 1042:                 tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
 1043:                 tcg_gen_ext32s_tl(t0, cpu_cc_src);
 1044:                 break;
 1045: #endif
 1046:             default:
 1047:                 t0 = cpu_cc_src;
 1048:                 break;
 1049:             }
 1050:             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
 1051:             break;
 1052:             
 1053:         default:
 1054:             goto slow_jcc;
 1055:         }
 1056:         break;
 1057:         
 1058:         /* some jumps are easy to compute */
 1059:     case CC_OP_ADDB:
 1060:     case CC_OP_ADDW:
 1061:     case CC_OP_ADDL:
 1062:     case CC_OP_ADDQ:
 1063:         
 1064:     case CC_OP_ADCB:
 1065:     case CC_OP_ADCW:
 1066:     case CC_OP_ADCL:
 1067:     case CC_OP_ADCQ:
 1068:         
 1069:     case CC_OP_SBBB:
 1070:     case CC_OP_SBBW:
 1071:     case CC_OP_SBBL:
 1072:     case CC_OP_SBBQ:
 1073:         
 1074:     case CC_OP_LOGICB:
 1075:     case CC_OP_LOGICW:
 1076:     case CC_OP_LOGICL:
 1077:     case CC_OP_LOGICQ:
 1078:         
 1079:     case CC_OP_INCB:
 1080:     case CC_OP_INCW:
 1081:     case CC_OP_INCL:
 1082:     case CC_OP_INCQ:
 1083:         
 1084:     case CC_OP_DECB:
 1085:     case CC_OP_DECW:
 1086:     case CC_OP_DECL:
 1087:     case CC_OP_DECQ:
 1088:         
 1089:     case CC_OP_SHLB:
 1090:     case CC_OP_SHLW:
 1091:     case CC_OP_SHLL:
 1092:     case CC_OP_SHLQ:
 1093:         
 1094:     case CC_OP_SARB:
 1095:     case CC_OP_SARW:
 1096:     case CC_OP_SARL:
 1097:     case CC_OP_SARQ:
 1098:         switch(jcc_op) {
 1099:         case JCC_Z:
 1100:             size = (cc_op - CC_OP_ADDB) & 3;
 1101:             goto fast_jcc_z;
 1102:         case JCC_S:
 1103:             size = (cc_op - CC_OP_ADDB) & 3;
 1104:             goto fast_jcc_s;
 1105:         default:
 1106:             goto slow_jcc;
 1107:         }
 1108:         break;
 1109:     default:
 1110:     slow_jcc:
 1111:         gen_setcc_slow_T0(s, jcc_op);
 1112:         tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, 
 1113:                            cpu_T[0], 0, l1);
 1114:         break;
 1115:     }
 1116: }
 1117: 
 1118: /* XXX: does not work with gdbstub "ice" single step - not a
 1119:    serious problem */
 1120: static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
 1121: {
 1122:     int l1, l2;
 1123: 
 1124:     l1 = gen_new_label();
 1125:     l2 = gen_new_label();
 1126:     gen_op_jnz_ecx(s->aflag, l1);
 1127:     gen_set_label(l2);
 1128:     gen_jmp_tb(s, next_eip, 1);
 1129:     gen_set_label(l1);
 1130:     return l2;
 1131: }
 1132: 
 1133: static inline void gen_stos(DisasContext *s, int ot)
 1134: {
 1135:     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
 1136:     gen_string_movl_A0_EDI(s);
 1137:     gen_op_st_T0_A0(ot + s->mem_index);
 1138:     gen_op_movl_T0_Dshift(ot);
 1139:     gen_op_add_reg_T0(s->aflag, R_EDI);
 1140: }
 1141: 
 1142: static inline void gen_lods(DisasContext *s, int ot)
 1143: {
 1144:     gen_string_movl_A0_ESI(s);
 1145:     gen_op_ld_T0_A0(ot + s->mem_index);
 1146:     gen_op_mov_reg_T0(ot, R_EAX);
 1147:     gen_op_movl_T0_Dshift(ot);
 1148:     gen_op_add_reg_T0(s->aflag, R_ESI);
 1149: }
 1150: 
 1151: static inline void gen_scas(DisasContext *s, int ot)
 1152: {
 1153:     gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
 1154:     gen_string_movl_A0_EDI(s);
 1155:     gen_op_ld_T1_A0(ot + s->mem_index);
 1156:     gen_op_cmpl_T0_T1_cc();
 1157:     gen_op_movl_T0_Dshift(ot);
 1158:     gen_op_add_reg_T0(s->aflag, R_EDI);
 1159: }
 1160: 
 1161: static inline void gen_cmps(DisasContext *s, int ot)
 1162: {
 1163:     gen_string_movl_A0_ESI(s);
 1164:     gen_op_ld_T0_A0(ot + s->mem_index);
 1165:     gen_string_movl_A0_EDI(s);
 1166:     gen_op_ld_T1_A0(ot + s->mem_index);
 1167:     gen_op_cmpl_T0_T1_cc();
 1168:     gen_op_movl_T0_Dshift(ot);
 1169:     gen_op_add_reg_T0(s->aflag, R_ESI);
 1170:     gen_op_add_reg_T0(s->aflag, R_EDI);
 1171: }
 1172: 
 1173: static inline void gen_ins(DisasContext *s, int ot)
 1174: {
 1175:     if (use_icount)
 1176:         gen_io_start();
 1177:     gen_string_movl_A0_EDI(s);
 1178:     /* Note: we must do this dummy write first to be restartable in
 1179:        case of page fault. */
 1180:     gen_op_movl_T0_0();
 1181:     gen_op_st_T0_A0(ot + s->mem_index);
 1182:     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
 1183:     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
 1184:     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
 1185:     gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);
 1186:     gen_op_st_T0_A0(ot + s->mem_index);
 1187:     gen_op_movl_T0_Dshift(ot);
 1188:     gen_op_add_reg_T0(s->aflag, R_EDI);
 1189:     if (use_icount)
 1190:         gen_io_end();
 1191: }
 1192: 
 1193: static inline void gen_outs(DisasContext *s, int ot)
 1194: {
 1195:     if (use_icount)
 1196:         gen_io_start();
 1197:     gen_string_movl_A0_ESI(s);
 1198:     gen_op_ld_T0_A0(ot + s->mem_index);
 1199: 
 1200:     gen_op_mov_TN_reg(OT_WORD, 1, R_EDX);
 1201:     tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]);
 1202:     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
 1203:     tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
 1204:     gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
 1205: 
 1206:     gen_op_movl_T0_Dshift(ot);
 1207:     gen_op_add_reg_T0(s->aflag, R_ESI);
 1208:     if (use_icount)
 1209:         gen_io_end();
 1210: }
 1211: 
 1212: /* same method as Valgrind : we generate jumps to current or next
 1213:    instruction */
 1214: #define GEN_REPZ(op)                                                          \
 1215: static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
 1216:                                  target_ulong cur_eip, target_ulong next_eip) \
 1217: {                                                                             \
 1218:     int l2;\
 1219:     gen_update_cc_op(s);                                                      \
 1220:     l2 = gen_jz_ecx_string(s, next_eip);                                      \
 1221:     gen_ ## op(s, ot);                                                        \
 1222:     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
 1223:     /* a loop would cause two single step exceptions if ECX = 1               \
 1224:        before rep string_insn */                                              \
 1225:     if (!s->jmp_opt)                                                          \
 1226:         gen_op_jz_ecx(s->aflag, l2);                                          \
 1227:     gen_jmp(s, cur_eip);                                                      \
 1228: }
 1229: 
 1230: #define GEN_REPZ2(op)                                                         \
 1231: static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
 1232:                                    target_ulong cur_eip,                      \
 1233:                                    target_ulong next_eip,                     \
 1234:                                    int nz)                                    \
 1235: {                                                                             \
 1236:     int l2;\
 1237:     gen_update_cc_op(s);                                                      \
 1238:     l2 = gen_jz_ecx_string(s, next_eip);                                      \
 1239:     gen_ ## op(s, ot);                                                        \
 1240:     gen_op_add_reg_im(s->aflag, R_ECX, -1);                                   \
 1241:     gen_op_set_cc_op(CC_OP_SUBB + ot);                                        \
 1242:     gen_jcc1(s, CC_OP_SUBB + ot, (JCC_Z << 1) | (nz ^ 1), l2);                \
 1243:     if (!s->jmp_opt)                                                          \
 1244:         gen_op_jz_ecx(s->aflag, l2);                                          \
 1245:     gen_jmp(s, cur_eip);                                                      \
 1246: }
 1247: 
 1248: GEN_REPZ(movs)
 1249: GEN_REPZ(stos)
 1250: GEN_REPZ(lods)
 1251: GEN_REPZ(ins)
 1252: GEN_REPZ(outs)
 1253: GEN_REPZ2(scas)
 1254: GEN_REPZ2(cmps)
 1255: 
 1256: static void gen_helper_fp_arith_ST0_FT0(int op)
 1257: {
 1258:     switch (op) {
 1259:     case 0: gen_helper_fadd_ST0_FT0(); break;
 1260:     case 1: gen_helper_fmul_ST0_FT0(); break;
 1261:     case 2: gen_helper_fcom_ST0_FT0(); break;
 1262:     case 3: gen_helper_fcom_ST0_FT0(); break;
 1263:     case 4: gen_helper_fsub_ST0_FT0(); break;
 1264:     case 5: gen_helper_fsubr_ST0_FT0(); break;
 1265:     case 6: gen_helper_fdiv_ST0_FT0(); break;
 1266:     case 7: gen_helper_fdivr_ST0_FT0(); break;
 1267:     }
 1268: }
 1269: 
 1270: /* NOTE the exception in "r" op ordering */
 1271: static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
 1272: {
 1273:     TCGv_i32 tmp = tcg_const_i32(opreg);
 1274:     switch (op) {
 1275:     case 0: gen_helper_fadd_STN_ST0(tmp); break;
 1276:     case 1: gen_helper_fmul_STN_ST0(tmp); break;
 1277:     case 4: gen_helper_fsubr_STN_ST0(tmp); break;
 1278:     case 5: gen_helper_fsub_STN_ST0(tmp); break;
 1279:     case 6: gen_helper_fdivr_STN_ST0(tmp); break;
 1280:     case 7: gen_helper_fdiv_STN_ST0(tmp); break;
 1281:     }
 1282: }
 1283: 
 1284: /* if d == OR_TMP0, it means memory operand (address in A0) */
 1285: static void gen_op(DisasContext *s1, int op, int ot, int d)
 1286: {
 1287:     if (d != OR_TMP0) {
 1288:         gen_op_mov_TN_reg(ot, 0, d);
 1289:     } else {
 1290:         gen_op_ld_T0_A0(ot + s1->mem_index);
 1291:     }
 1292:     switch(op) {
 1293:     case OP_ADCL:
 1294:         if (s1->cc_op != CC_OP_DYNAMIC)
 1295:             gen_op_set_cc_op(s1->cc_op);
 1296:         gen_compute_eflags_c(cpu_tmp4);
 1297:         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1298:         tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
 1299:         if (d != OR_TMP0)
 1300:             gen_op_mov_reg_T0(ot, d);
 1301:         else
 1302:             gen_op_st_T0_A0(ot + s1->mem_index);
 1303:         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
 1304:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 1305:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
 1306:         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
 1307:         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot);
 1308:         s1->cc_op = CC_OP_DYNAMIC;
 1309:         break;
 1310:     case OP_SBBL:
 1311:         if (s1->cc_op != CC_OP_DYNAMIC)
 1312:             gen_op_set_cc_op(s1->cc_op);
 1313:         gen_compute_eflags_c(cpu_tmp4);
 1314:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1315:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4);
 1316:         if (d != OR_TMP0)
 1317:             gen_op_mov_reg_T0(ot, d);
 1318:         else
 1319:             gen_op_st_T0_A0(ot + s1->mem_index);
 1320:         tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]);
 1321:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 1322:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4);
 1323:         tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2);
 1324:         tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot);
 1325:         s1->cc_op = CC_OP_DYNAMIC;
 1326:         break;
 1327:     case OP_ADDL:
 1328:         gen_op_addl_T0_T1();
 1329:         if (d != OR_TMP0)
 1330:             gen_op_mov_reg_T0(ot, d);
 1331:         else
 1332:             gen_op_st_T0_A0(ot + s1->mem_index);
 1333:         gen_op_update2_cc();
 1334:         s1->cc_op = CC_OP_ADDB + ot;
 1335:         break;
 1336:     case OP_SUBL:
 1337:         tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1338:         if (d != OR_TMP0)
 1339:             gen_op_mov_reg_T0(ot, d);
 1340:         else
 1341:             gen_op_st_T0_A0(ot + s1->mem_index);
 1342:         gen_op_update2_cc();
 1343:         s1->cc_op = CC_OP_SUBB + ot;
 1344:         break;
 1345:     default:
 1346:     case OP_ANDL:
 1347:         tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1348:         if (d != OR_TMP0)
 1349:             gen_op_mov_reg_T0(ot, d);
 1350:         else
 1351:             gen_op_st_T0_A0(ot + s1->mem_index);
 1352:         gen_op_update1_cc();
 1353:         s1->cc_op = CC_OP_LOGICB + ot;
 1354:         break;
 1355:     case OP_ORL:
 1356:         tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1357:         if (d != OR_TMP0)
 1358:             gen_op_mov_reg_T0(ot, d);
 1359:         else
 1360:             gen_op_st_T0_A0(ot + s1->mem_index);
 1361:         gen_op_update1_cc();
 1362:         s1->cc_op = CC_OP_LOGICB + ot;
 1363:         break;
 1364:     case OP_XORL:
 1365:         tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 1366:         if (d != OR_TMP0)
 1367:             gen_op_mov_reg_T0(ot, d);
 1368:         else
 1369:             gen_op_st_T0_A0(ot + s1->mem_index);
 1370:         gen_op_update1_cc();
 1371:         s1->cc_op = CC_OP_LOGICB + ot;
 1372:         break;
 1373:     case OP_CMPL:
 1374:         gen_op_cmpl_T0_T1_cc();
 1375:         s1->cc_op = CC_OP_SUBB + ot;
 1376:         break;
 1377:     }
 1378: }
 1379: 
 1380: /* if d == OR_TMP0, it means memory operand (address in A0) */
 1381: static void gen_inc(DisasContext *s1, int ot, int d, int c)
 1382: {
 1383:     if (d != OR_TMP0)
 1384:         gen_op_mov_TN_reg(ot, 0, d);
 1385:     else
 1386:         gen_op_ld_T0_A0(ot + s1->mem_index);
 1387:     if (s1->cc_op != CC_OP_DYNAMIC)
 1388:         gen_op_set_cc_op(s1->cc_op);
 1389:     if (c > 0) {
 1390:         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1);
 1391:         s1->cc_op = CC_OP_INCB + ot;
 1392:     } else {
 1393:         tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1);
 1394:         s1->cc_op = CC_OP_DECB + ot;
 1395:     }
 1396:     if (d != OR_TMP0)
 1397:         gen_op_mov_reg_T0(ot, d);
 1398:     else
 1399:         gen_op_st_T0_A0(ot + s1->mem_index);
 1400:     gen_compute_eflags_c(cpu_cc_src);
 1401:     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 1402: }
 1403: 
 1404: static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
 1405:                             int is_right, int is_arith)
 1406: {
 1407:     target_ulong mask;
 1408:     int shift_label;
 1409:     TCGv t0, t1, t2;
 1410: 
 1411:     if (ot == OT_QUAD) {
 1412:         mask = 0x3f;
 1413:     } else {
 1414:         mask = 0x1f;
 1415:     }
 1416: 
 1417:     /* load */
 1418:     if (op1 == OR_TMP0) {
 1419:         gen_op_ld_T0_A0(ot + s->mem_index);
 1420:     } else {
 1421:         gen_op_mov_TN_reg(ot, 0, op1);
 1422:     }
 1423: 
 1424:     t0 = tcg_temp_local_new();
 1425:     t1 = tcg_temp_local_new();
 1426:     t2 = tcg_temp_local_new();
 1427: 
 1428:     tcg_gen_andi_tl(t2, cpu_T[1], mask);
 1429: 
 1430:     if (is_right) {
 1431:         if (is_arith) {
 1432:             gen_exts(ot, cpu_T[0]);
 1433:             tcg_gen_mov_tl(t0, cpu_T[0]);
 1434:             tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2);
 1435:         } else {
 1436:             gen_extu(ot, cpu_T[0]);
 1437:             tcg_gen_mov_tl(t0, cpu_T[0]);
 1438:             tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2);
 1439:         }
 1440:     } else {
 1441:         tcg_gen_mov_tl(t0, cpu_T[0]);
 1442:         tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2);
 1443:     }
 1444: 
 1445:     /* store */
 1446:     if (op1 == OR_TMP0) {
 1447:         gen_op_st_T0_A0(ot + s->mem_index);
 1448:     } else {
 1449:         gen_op_mov_reg_T0(ot, op1);
 1450:     }
 1451: 
 1452:     /* update eflags if non zero shift */
 1453:     if (s->cc_op != CC_OP_DYNAMIC) {
 1454:         gen_op_set_cc_op(s->cc_op);
 1455:     }
 1456: 
 1457:     tcg_gen_mov_tl(t1, cpu_T[0]);
 1458: 
 1459:     shift_label = gen_new_label();
 1460:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label);
 1461: 
 1462:     tcg_gen_addi_tl(t2, t2, -1);
 1463:     tcg_gen_mov_tl(cpu_cc_dst, t1);
 1464: 
 1465:     if (is_right) {
 1466:         if (is_arith) {
 1467:             tcg_gen_sar_tl(cpu_cc_src, t0, t2);
 1468:         } else {
 1469:             tcg_gen_shr_tl(cpu_cc_src, t0, t2);
 1470:         }
 1471:     } else {
 1472:         tcg_gen_shl_tl(cpu_cc_src, t0, t2);
 1473:     }
 1474: 
 1475:     if (is_right) {
 1476:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
 1477:     } else {
 1478:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
 1479:     }
 1480: 
 1481:     gen_set_label(shift_label);
 1482:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 1483: 
 1484:     tcg_temp_free(t0);
 1485:     tcg_temp_free(t1);
 1486:     tcg_temp_free(t2);
 1487: }
 1488: 
 1489: static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2,
 1490:                             int is_right, int is_arith)
 1491: {
 1492:     int mask;
 1493:     
 1494:     if (ot == OT_QUAD)
 1495:         mask = 0x3f;
 1496:     else
 1497:         mask = 0x1f;
 1498: 
 1499:     /* load */
 1500:     if (op1 == OR_TMP0)
 1501:         gen_op_ld_T0_A0(ot + s->mem_index);
 1502:     else
 1503:         gen_op_mov_TN_reg(ot, 0, op1);
 1504: 
 1505:     op2 &= mask;
 1506:     if (op2 != 0) {
 1507:         if (is_right) {
 1508:             if (is_arith) {
 1509:                 gen_exts(ot, cpu_T[0]);
 1510:                 tcg_gen_sari_tl(cpu_tmp4, cpu_T[0], op2 - 1);
 1511:                 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], op2);
 1512:             } else {
 1513:                 gen_extu(ot, cpu_T[0]);
 1514:                 tcg_gen_shri_tl(cpu_tmp4, cpu_T[0], op2 - 1);
 1515:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], op2);
 1516:             }
 1517:         } else {
 1518:             tcg_gen_shli_tl(cpu_tmp4, cpu_T[0], op2 - 1);
 1519:             tcg_gen_shli_tl(cpu_T[0], cpu_T[0], op2);
 1520:         }
 1521:     }
 1522: 
 1523:     /* store */
 1524:     if (op1 == OR_TMP0)
 1525:         gen_op_st_T0_A0(ot + s->mem_index);
 1526:     else
 1527:         gen_op_mov_reg_T0(ot, op1);
 1528:         
 1529:     /* update eflags if non zero shift */
 1530:     if (op2 != 0) {
 1531:         tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
 1532:         tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 1533:         if (is_right)
 1534:             s->cc_op = CC_OP_SARB + ot;
 1535:         else
 1536:             s->cc_op = CC_OP_SHLB + ot;
 1537:     }
 1538: }
 1539: 
 1540: static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2)
 1541: {
 1542:     if (arg2 >= 0)
 1543:         tcg_gen_shli_tl(ret, arg1, arg2);
 1544:     else
 1545:         tcg_gen_shri_tl(ret, arg1, -arg2);
 1546: }
 1547: 
 1548: static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, 
 1549:                           int is_right)
 1550: {
 1551:     target_ulong mask;
 1552:     int label1, label2, data_bits;
 1553:     TCGv t0, t1, t2, a0;
 1554: 
 1555:     /* XXX: inefficient, but we must use local temps */
 1556:     t0 = tcg_temp_local_new();
 1557:     t1 = tcg_temp_local_new();
 1558:     t2 = tcg_temp_local_new();
 1559:     a0 = tcg_temp_local_new();
 1560: 
 1561:     if (ot == OT_QUAD)
 1562:         mask = 0x3f;
 1563:     else
 1564:         mask = 0x1f;
 1565: 
 1566:     /* load */
 1567:     if (op1 == OR_TMP0) {
 1568:         tcg_gen_mov_tl(a0, cpu_A0);
 1569:         gen_op_ld_v(ot + s->mem_index, t0, a0);
 1570:     } else {
 1571:         gen_op_mov_v_reg(ot, t0, op1);
 1572:     }
 1573: 
 1574:     tcg_gen_mov_tl(t1, cpu_T[1]);
 1575: 
 1576:     tcg_gen_andi_tl(t1, t1, mask);
 1577: 
 1578:     /* Must test zero case to avoid using undefined behaviour in TCG
 1579:        shifts. */
 1580:     label1 = gen_new_label();
 1581:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1);
 1582:     
 1583:     if (ot <= OT_WORD)
 1584:         tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1);
 1585:     else
 1586:         tcg_gen_mov_tl(cpu_tmp0, t1);
 1587:     
 1588:     gen_extu(ot, t0);
 1589:     tcg_gen_mov_tl(t2, t0);
 1590: 
 1591:     data_bits = 8 << ot;
 1592:     /* XXX: rely on behaviour of shifts when operand 2 overflows (XXX:
 1593:        fix TCG definition) */
 1594:     if (is_right) {
 1595:         tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp0);
 1596:         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
 1597:         tcg_gen_shl_tl(t0, t0, cpu_tmp0);
 1598:     } else {
 1599:         tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp0);
 1600:         tcg_gen_subfi_tl(cpu_tmp0, data_bits, cpu_tmp0);
 1601:         tcg_gen_shr_tl(t0, t0, cpu_tmp0);
 1602:     }
 1603:     tcg_gen_or_tl(t0, t0, cpu_tmp4);
 1604: 
 1605:     gen_set_label(label1);
 1606:     /* store */
 1607:     if (op1 == OR_TMP0) {
 1608:         gen_op_st_v(ot + s->mem_index, t0, a0);
 1609:     } else {
 1610:         gen_op_mov_reg_v(ot, op1, t0);
 1611:     }
 1612:     
 1613:     /* update eflags */
 1614:     if (s->cc_op != CC_OP_DYNAMIC)
 1615:         gen_op_set_cc_op(s->cc_op);
 1616: 
 1617:     label2 = gen_new_label();
 1618:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label2);
 1619: 
 1620:     gen_compute_eflags(cpu_cc_src);
 1621:     tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
 1622:     tcg_gen_xor_tl(cpu_tmp0, t2, t0);
 1623:     tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
 1624:     tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
 1625:     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
 1626:     if (is_right) {
 1627:         tcg_gen_shri_tl(t0, t0, data_bits - 1);
 1628:     }
 1629:     tcg_gen_andi_tl(t0, t0, CC_C);
 1630:     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
 1631:     
 1632:     tcg_gen_discard_tl(cpu_cc_dst);
 1633:     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
 1634:         
 1635:     gen_set_label(label2);
 1636:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 1637: 
 1638:     tcg_temp_free(t0);
 1639:     tcg_temp_free(t1);
 1640:     tcg_temp_free(t2);
 1641:     tcg_temp_free(a0);
 1642: }
 1643: 
 1644: static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
 1645:                           int is_right)
 1646: {
 1647:     int mask;
 1648:     int data_bits;
 1649:     TCGv t0, t1, a0;
 1650: 
 1651:     /* XXX: inefficient, but we must use local temps */
 1652:     t0 = tcg_temp_local_new();
 1653:     t1 = tcg_temp_local_new();
 1654:     a0 = tcg_temp_local_new();
 1655: 
 1656:     if (ot == OT_QUAD)
 1657:         mask = 0x3f;
 1658:     else
 1659:         mask = 0x1f;
 1660: 
 1661:     /* load */
 1662:     if (op1 == OR_TMP0) {
 1663:         tcg_gen_mov_tl(a0, cpu_A0);
 1664:         gen_op_ld_v(ot + s->mem_index, t0, a0);
 1665:     } else {
 1666:         gen_op_mov_v_reg(ot, t0, op1);
 1667:     }
 1668: 
 1669:     gen_extu(ot, t0);
 1670:     tcg_gen_mov_tl(t1, t0);
 1671: 
 1672:     op2 &= mask;
 1673:     data_bits = 8 << ot;
 1674:     if (op2 != 0) {
 1675:         int shift = op2 & ((1 << (3 + ot)) - 1);
 1676:         if (is_right) {
 1677:             tcg_gen_shri_tl(cpu_tmp4, t0, shift);
 1678:             tcg_gen_shli_tl(t0, t0, data_bits - shift);
 1679:         }
 1680:         else {
 1681:             tcg_gen_shli_tl(cpu_tmp4, t0, shift);
 1682:             tcg_gen_shri_tl(t0, t0, data_bits - shift);
 1683:         }
 1684:         tcg_gen_or_tl(t0, t0, cpu_tmp4);
 1685:     }
 1686: 
 1687:     /* store */
 1688:     if (op1 == OR_TMP0) {
 1689:         gen_op_st_v(ot + s->mem_index, t0, a0);
 1690:     } else {
 1691:         gen_op_mov_reg_v(ot, op1, t0);
 1692:     }
 1693: 
 1694:     if (op2 != 0) {
 1695:         /* update eflags */
 1696:         if (s->cc_op != CC_OP_DYNAMIC)
 1697:             gen_op_set_cc_op(s->cc_op);
 1698: 
 1699:         gen_compute_eflags(cpu_cc_src);
 1700:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~(CC_O | CC_C));
 1701:         tcg_gen_xor_tl(cpu_tmp0, t1, t0);
 1702:         tcg_gen_lshift(cpu_tmp0, cpu_tmp0, 11 - (data_bits - 1));
 1703:         tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_O);
 1704:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
 1705:         if (is_right) {
 1706:             tcg_gen_shri_tl(t0, t0, data_bits - 1);
 1707:         }
 1708:         tcg_gen_andi_tl(t0, t0, CC_C);
 1709:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
 1710: 
 1711:         tcg_gen_discard_tl(cpu_cc_dst);
 1712:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
 1713:         s->cc_op = CC_OP_EFLAGS;
 1714:     }
 1715: 
 1716:     tcg_temp_free(t0);
 1717:     tcg_temp_free(t1);
 1718:     tcg_temp_free(a0);
 1719: }
 1720: 
 1721: /* XXX: add faster immediate = 1 case */
 1722: static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
 1723:                            int is_right)
 1724: {
 1725:     int label1;
 1726: 
 1727:     if (s->cc_op != CC_OP_DYNAMIC)
 1728:         gen_op_set_cc_op(s->cc_op);
 1729: 
 1730:     /* load */
 1731:     if (op1 == OR_TMP0)
 1732:         gen_op_ld_T0_A0(ot + s->mem_index);
 1733:     else
 1734:         gen_op_mov_TN_reg(ot, 0, op1);
 1735:     
 1736:     if (is_right) {
 1737:         switch (ot) {
 1738:         case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1739:         case 1: gen_helper_rcrw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1740:         case 2: gen_helper_rcrl(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1741: #ifdef TARGET_X86_64
 1742:         case 3: gen_helper_rcrq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1743: #endif
 1744:         }
 1745:     } else {
 1746:         switch (ot) {
 1747:         case 0: gen_helper_rclb(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1748:         case 1: gen_helper_rclw(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1749:         case 2: gen_helper_rcll(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1750: #ifdef TARGET_X86_64
 1751:         case 3: gen_helper_rclq(cpu_T[0], cpu_T[0], cpu_T[1]); break;
 1752: #endif
 1753:         }
 1754:     }
 1755:     /* store */
 1756:     if (op1 == OR_TMP0)
 1757:         gen_op_st_T0_A0(ot + s->mem_index);
 1758:     else
 1759:         gen_op_mov_reg_T0(ot, op1);
 1760: 
 1761:     /* update eflags */
 1762:     label1 = gen_new_label();
 1763:     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
 1764: 
 1765:     tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
 1766:     tcg_gen_discard_tl(cpu_cc_dst);
 1767:     tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
 1768:         
 1769:     gen_set_label(label1);
 1770:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 1771: }
 1772: 
 1773: /* XXX: add faster immediate case */
 1774: static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, 
 1775:                                 int is_right)
 1776: {
 1777:     int label1, label2, data_bits;
 1778:     target_ulong mask;
 1779:     TCGv t0, t1, t2, a0;
 1780: 
 1781:     t0 = tcg_temp_local_new();
 1782:     t1 = tcg_temp_local_new();
 1783:     t2 = tcg_temp_local_new();
 1784:     a0 = tcg_temp_local_new();
 1785: 
 1786:     if (ot == OT_QUAD)
 1787:         mask = 0x3f;
 1788:     else
 1789:         mask = 0x1f;
 1790: 
 1791:     /* load */
 1792:     if (op1 == OR_TMP0) {
 1793:         tcg_gen_mov_tl(a0, cpu_A0);
 1794:         gen_op_ld_v(ot + s->mem_index, t0, a0);
 1795:     } else {
 1796:         gen_op_mov_v_reg(ot, t0, op1);
 1797:     }
 1798: 
 1799:     tcg_gen_andi_tl(cpu_T3, cpu_T3, mask);
 1800: 
 1801:     tcg_gen_mov_tl(t1, cpu_T[1]);
 1802:     tcg_gen_mov_tl(t2, cpu_T3);
 1803: 
 1804:     /* Must test zero case to avoid using undefined behaviour in TCG
 1805:        shifts. */
 1806:     label1 = gen_new_label();
 1807:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
 1808:     
 1809:     tcg_gen_addi_tl(cpu_tmp5, t2, -1);
 1810:     if (ot == OT_WORD) {
 1811:         /* Note: we implement the Intel behaviour for shift count > 16 */
 1812:         if (is_right) {
 1813:             tcg_gen_andi_tl(t0, t0, 0xffff);
 1814:             tcg_gen_shli_tl(cpu_tmp0, t1, 16);
 1815:             tcg_gen_or_tl(t0, t0, cpu_tmp0);
 1816:             tcg_gen_ext32u_tl(t0, t0);
 1817: 
 1818:             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
 1819:             
 1820:             /* only needed if count > 16, but a test would complicate */
 1821:             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
 1822:             tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5);
 1823: 
 1824:             tcg_gen_shr_tl(t0, t0, t2);
 1825: 
 1826:             tcg_gen_or_tl(t0, t0, cpu_tmp0);
 1827:         } else {
 1828:             /* XXX: not optimal */
 1829:             tcg_gen_andi_tl(t0, t0, 0xffff);
 1830:             tcg_gen_shli_tl(t1, t1, 16);
 1831:             tcg_gen_or_tl(t1, t1, t0);
 1832:             tcg_gen_ext32u_tl(t1, t1);
 1833:             
 1834:             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
 1835:             tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5);
 1836:             tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0);
 1837:             tcg_gen_or_tl(cpu_tmp4, cpu_tmp4, cpu_tmp5);
 1838: 
 1839:             tcg_gen_shl_tl(t0, t0, t2);
 1840:             tcg_gen_subfi_tl(cpu_tmp5, 32, t2);
 1841:             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
 1842:             tcg_gen_or_tl(t0, t0, t1);
 1843:         }
 1844:     } else {
 1845:         data_bits = 8 << ot;
 1846:         if (is_right) {
 1847:             if (ot == OT_LONG)
 1848:                 tcg_gen_ext32u_tl(t0, t0);
 1849: 
 1850:             tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5);
 1851: 
 1852:             tcg_gen_shr_tl(t0, t0, t2);
 1853:             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
 1854:             tcg_gen_shl_tl(t1, t1, cpu_tmp5);
 1855:             tcg_gen_or_tl(t0, t0, t1);
 1856:             
 1857:         } else {
 1858:             if (ot == OT_LONG)
 1859:                 tcg_gen_ext32u_tl(t1, t1);
 1860: 
 1861:             tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5);
 1862:             
 1863:             tcg_gen_shl_tl(t0, t0, t2);
 1864:             tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2);
 1865:             tcg_gen_shr_tl(t1, t1, cpu_tmp5);
 1866:             tcg_gen_or_tl(t0, t0, t1);
 1867:         }
 1868:     }
 1869:     tcg_gen_mov_tl(t1, cpu_tmp4);
 1870: 
 1871:     gen_set_label(label1);
 1872:     /* store */
 1873:     if (op1 == OR_TMP0) {
 1874:         gen_op_st_v(ot + s->mem_index, t0, a0);
 1875:     } else {
 1876:         gen_op_mov_reg_v(ot, op1, t0);
 1877:     }
 1878:     
 1879:     /* update eflags */
 1880:     if (s->cc_op != CC_OP_DYNAMIC)
 1881:         gen_op_set_cc_op(s->cc_op);
 1882: 
 1883:     label2 = gen_new_label();
 1884:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label2);
 1885: 
 1886:     tcg_gen_mov_tl(cpu_cc_src, t1);
 1887:     tcg_gen_mov_tl(cpu_cc_dst, t0);
 1888:     if (is_right) {
 1889:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot);
 1890:     } else {
 1891:         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot);
 1892:     }
 1893:     gen_set_label(label2);
 1894:     s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 1895: 
 1896:     tcg_temp_free(t0);
 1897:     tcg_temp_free(t1);
 1898:     tcg_temp_free(t2);
 1899:     tcg_temp_free(a0);
 1900: }
 1901: 
 1902: static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
 1903: {
 1904:     if (s != OR_TMP1)
 1905:         gen_op_mov_TN_reg(ot, 1, s);
 1906:     switch(op) {
 1907:     case OP_ROL:
 1908:         gen_rot_rm_T1(s1, ot, d, 0);
 1909:         break;
 1910:     case OP_ROR:
 1911:         gen_rot_rm_T1(s1, ot, d, 1);
 1912:         break;
 1913:     case OP_SHL:
 1914:     case OP_SHL1:
 1915:         gen_shift_rm_T1(s1, ot, d, 0, 0);
 1916:         break;
 1917:     case OP_SHR:
 1918:         gen_shift_rm_T1(s1, ot, d, 1, 0);
 1919:         break;
 1920:     case OP_SAR:
 1921:         gen_shift_rm_T1(s1, ot, d, 1, 1);
 1922:         break;
 1923:     case OP_RCL:
 1924:         gen_rotc_rm_T1(s1, ot, d, 0);
 1925:         break;
 1926:     case OP_RCR:
 1927:         gen_rotc_rm_T1(s1, ot, d, 1);
 1928:         break;
 1929:     }
 1930: }
 1931: 
 1932: static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
 1933: {
 1934:     switch(op) {
 1935:     case OP_ROL:
 1936:         gen_rot_rm_im(s1, ot, d, c, 0);
 1937:         break;
 1938:     case OP_ROR:
 1939:         gen_rot_rm_im(s1, ot, d, c, 1);
 1940:         break;
 1941:     case OP_SHL:
 1942:     case OP_SHL1:
 1943:         gen_shift_rm_im(s1, ot, d, c, 0, 0);
 1944:         break;
 1945:     case OP_SHR:
 1946:         gen_shift_rm_im(s1, ot, d, c, 1, 0);
 1947:         break;
 1948:     case OP_SAR:
 1949:         gen_shift_rm_im(s1, ot, d, c, 1, 1);
 1950:         break;
 1951:     default:
 1952:         /* currently not optimized */
 1953:         gen_op_movl_T1_im(c);
 1954:         gen_shift(s1, op, ot, d, OR_TMP1);
 1955:         break;
 1956:     }
 1957: }
 1958: 
 1959: static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
 1960: {
 1961:     target_long disp;
 1962:     int havesib;
 1963:     int base;
 1964:     int index;
 1965:     int scale;
 1966:     int opreg;
 1967:     int mod, rm, code, override, must_add_seg;
 1968: 
 1969:     override = s->override;
 1970:     must_add_seg = s->addseg;
 1971:     if (override >= 0)
 1972:         must_add_seg = 1;
 1973:     mod = (modrm >> 6) & 3;
 1974:     rm = modrm & 7;
 1975: 
 1976:     if (s->aflag) {
 1977: 
 1978:         havesib = 0;
 1979:         base = rm;
 1980:         index = 0;
 1981:         scale = 0;
 1982: 
 1983:         if (base == 4) {
 1984:             havesib = 1;
 1985:             code = ldub_code(s->pc++);
 1986:             scale = (code >> 6) & 3;
 1987:             index = ((code >> 3) & 7) | REX_X(s);
 1988:             base = (code & 7);
 1989:         }
 1990:         base |= REX_B(s);
 1991: 
 1992:         switch (mod) {
 1993:         case 0:
 1994:             if ((base & 7) == 5) {
 1995:                 base = -1;
 1996:                 disp = (int32_t)ldl_code(s->pc);
 1997:                 s->pc += 4;
 1998:                 if (CODE64(s) && !havesib) {
 1999:                     disp += s->pc + s->rip_offset;
 2000:                 }
 2001:             } else {
 2002:                 disp = 0;
 2003:             }
 2004:             break;
 2005:         case 1:
 2006:             disp = (int8_t)ldub_code(s->pc++);
 2007:             break;
 2008:         default:
 2009:         case 2:
 2010:             disp = (int32_t)ldl_code(s->pc);
 2011:             s->pc += 4;
 2012:             break;
 2013:         }
 2014: 
 2015:         if (base >= 0) {
 2016:             /* for correct popl handling with esp */
 2017:             if (base == 4 && s->popl_esp_hack)
 2018:                 disp += s->popl_esp_hack;
 2019: #ifdef TARGET_X86_64
 2020:             if (s->aflag == 2) {
 2021:                 gen_op_movq_A0_reg(base);
 2022:                 if (disp != 0) {
 2023:                     gen_op_addq_A0_im(disp);
 2024:                 }
 2025:             } else
 2026: #endif
 2027:             {
 2028:                 gen_op_movl_A0_reg(base);
 2029:                 if (disp != 0)
 2030:                     gen_op_addl_A0_im(disp);
 2031:             }
 2032:         } else {
 2033: #ifdef TARGET_X86_64
 2034:             if (s->aflag == 2) {
 2035:                 gen_op_movq_A0_im(disp);
 2036:             } else
 2037: #endif
 2038:             {
 2039:                 gen_op_movl_A0_im(disp);
 2040:             }
 2041:         }
 2042:         /* index == 4 means no index */
 2043:         if (havesib && (index != 4)) {
 2044: #ifdef TARGET_X86_64
 2045:             if (s->aflag == 2) {
 2046:                 gen_op_addq_A0_reg_sN(scale, index);
 2047:             } else
 2048: #endif
 2049:             {
 2050:                 gen_op_addl_A0_reg_sN(scale, index);
 2051:             }
 2052:         }
 2053:         if (must_add_seg) {
 2054:             if (override < 0) {
 2055:                 if (base == R_EBP || base == R_ESP)
 2056:                     override = R_SS;
 2057:                 else
 2058:                     override = R_DS;
 2059:             }
 2060: #ifdef TARGET_X86_64
 2061:             if (s->aflag == 2) {
 2062:                 gen_op_addq_A0_seg(override);
 2063:             } else
 2064: #endif
 2065:             {
 2066:                 gen_op_addl_A0_seg(override);
 2067:             }
 2068:         }
 2069:     } else {
 2070:         switch (mod) {
 2071:         case 0:
 2072:             if (rm == 6) {
 2073:                 disp = lduw_code(s->pc);
 2074:                 s->pc += 2;
 2075:                 gen_op_movl_A0_im(disp);
 2076:                 rm = 0; /* avoid SS override */
 2077:                 goto no_rm;
 2078:             } else {
 2079:                 disp = 0;
 2080:             }
 2081:             break;
 2082:         case 1:
 2083:             disp = (int8_t)ldub_code(s->pc++);
 2084:             break;
 2085:         default:
 2086:         case 2:
 2087:             disp = lduw_code(s->pc);
 2088:             s->pc += 2;
 2089:             break;
 2090:         }
 2091:         switch(rm) {
 2092:         case 0:
 2093:             gen_op_movl_A0_reg(R_EBX);
 2094:             gen_op_addl_A0_reg_sN(0, R_ESI);
 2095:             break;
 2096:         case 1:
 2097:             gen_op_movl_A0_reg(R_EBX);
 2098:             gen_op_addl_A0_reg_sN(0, R_EDI);
 2099:             break;
 2100:         case 2:
 2101:             gen_op_movl_A0_reg(R_EBP);
 2102:             gen_op_addl_A0_reg_sN(0, R_ESI);
 2103:             break;
 2104:         case 3:
 2105:             gen_op_movl_A0_reg(R_EBP);
 2106:             gen_op_addl_A0_reg_sN(0, R_EDI);
 2107:             break;
 2108:         case 4:
 2109:             gen_op_movl_A0_reg(R_ESI);
 2110:             break;
 2111:         case 5:
 2112:             gen_op_movl_A0_reg(R_EDI);
 2113:             break;
 2114:         case 6:
 2115:             gen_op_movl_A0_reg(R_EBP);
 2116:             break;
 2117:         default:
 2118:         case 7:
 2119:             gen_op_movl_A0_reg(R_EBX);
 2120:             break;
 2121:         }
 2122:         if (disp != 0)
 2123:             gen_op_addl_A0_im(disp);
 2124:         gen_op_andl_A0_ffff();
 2125:     no_rm:
 2126:         if (must_add_seg) {
 2127:             if (override < 0) {
 2128:                 if (rm == 2 || rm == 3 || rm == 6)
 2129:                     override = R_SS;
 2130:                 else
 2131:                     override = R_DS;
 2132:             }
 2133:             gen_op_addl_A0_seg(override);
 2134:         }
 2135:     }
 2136: 
 2137:     opreg = OR_A0;
 2138:     disp = 0;
 2139:     *reg_ptr = opreg;
 2140:     *offset_ptr = disp;
 2141: }
 2142: 
 2143: static void gen_nop_modrm(DisasContext *s, int modrm)
 2144: {
 2145:     int mod, rm, base, code;
 2146: 
 2147:     mod = (modrm >> 6) & 3;
 2148:     if (mod == 3)
 2149:         return;
 2150:     rm = modrm & 7;
 2151: 
 2152:     if (s->aflag) {
 2153: 
 2154:         base = rm;
 2155: 
 2156:         if (base == 4) {
 2157:             code = ldub_code(s->pc++);
 2158:             base = (code & 7);
 2159:         }
 2160: 
 2161:         switch (mod) {
 2162:         case 0:
 2163:             if (base == 5) {
 2164:                 s->pc += 4;
 2165:             }
 2166:             break;
 2167:         case 1:
 2168:             s->pc++;
 2169:             break;
 2170:         default:
 2171:         case 2:
 2172:             s->pc += 4;
 2173:             break;
 2174:         }
 2175:     } else {
 2176:         switch (mod) {
 2177:         case 0:
 2178:             if (rm == 6) {
 2179:                 s->pc += 2;
 2180:             }
 2181:             break;
 2182:         case 1:
 2183:             s->pc++;
 2184:             break;
 2185:         default:
 2186:         case 2:
 2187:             s->pc += 2;
 2188:             break;
 2189:         }
 2190:     }
 2191: }
 2192: 
 2193: /* used for LEA and MOV AX, mem */
 2194: static void gen_add_A0_ds_seg(DisasContext *s)
 2195: {
 2196:     int override, must_add_seg;
 2197:     must_add_seg = s->addseg;
 2198:     override = R_DS;
 2199:     if (s->override >= 0) {
 2200:         override = s->override;
 2201:         must_add_seg = 1;
 2202:     }
 2203:     if (must_add_seg) {
 2204: #ifdef TARGET_X86_64
 2205:         if (CODE64(s)) {
 2206:             gen_op_addq_A0_seg(override);
 2207:         } else
 2208: #endif
 2209:         {
 2210:             gen_op_addl_A0_seg(override);
 2211:         }
 2212:     }
 2213: }
 2214: 
 2215: /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
 2216:    OR_TMP0 */
 2217: static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
 2218: {
 2219:     int mod, rm, opreg, disp;
 2220: 
 2221:     mod = (modrm >> 6) & 3;
 2222:     rm = (modrm & 7) | REX_B(s);
 2223:     if (mod == 3) {
 2224:         if (is_store) {
 2225:             if (reg != OR_TMP0)
 2226:                 gen_op_mov_TN_reg(ot, 0, reg);
 2227:             gen_op_mov_reg_T0(ot, rm);
 2228:         } else {
 2229:             gen_op_mov_TN_reg(ot, 0, rm);
 2230:             if (reg != OR_TMP0)
 2231:                 gen_op_mov_reg_T0(ot, reg);
 2232:         }
 2233:     } else {
 2234:         gen_lea_modrm(s, modrm, &opreg, &disp);
 2235:         if (is_store) {
 2236:             if (reg != OR_TMP0)
 2237:                 gen_op_mov_TN_reg(ot, 0, reg);
 2238:             gen_op_st_T0_A0(ot + s->mem_index);
 2239:         } else {
 2240:             gen_op_ld_T0_A0(ot + s->mem_index);
 2241:             if (reg != OR_TMP0)
 2242:                 gen_op_mov_reg_T0(ot, reg);
 2243:         }
 2244:     }
 2245: }
 2246: 
 2247: static inline uint32_t insn_get(DisasContext *s, int ot)
 2248: {
 2249:     uint32_t ret;
 2250: 
 2251:     switch(ot) {
 2252:     case OT_BYTE:
 2253:         ret = ldub_code(s->pc);
 2254:         s->pc++;
 2255:         break;
 2256:     case OT_WORD:
 2257:         ret = lduw_code(s->pc);
 2258:         s->pc += 2;
 2259:         break;
 2260:     default:
 2261:     case OT_LONG:
 2262:         ret = ldl_code(s->pc);
 2263:         s->pc += 4;
 2264:         break;
 2265:     }
 2266:     return ret;
 2267: }
 2268: 
 2269: static inline int insn_const_size(unsigned int ot)
 2270: {
 2271:     if (ot <= OT_LONG)
 2272:         return 1 << ot;
 2273:     else
 2274:         return 4;
 2275: }
 2276: 
 2277: static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
 2278: {
 2279:     TranslationBlock *tb;
 2280:     target_ulong pc;
 2281: 
 2282:     pc = s->cs_base + eip;
 2283:     tb = s->tb;
 2284:     /* NOTE: we handle the case where the TB spans two pages here */
 2285:     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
 2286:         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
 2287:         /* jump to same page: we can use a direct jump */
 2288:         tcg_gen_goto_tb(tb_num);
 2289:         gen_jmp_im(eip);
 2290:         tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
 2291:     } else {
 2292:         /* jump to another page: currently not optimized */
 2293:         gen_jmp_im(eip);
 2294:         gen_eob(s);
 2295:     }
 2296: }
 2297: 
 2298: static inline void gen_jcc(DisasContext *s, int b,
 2299:                            target_ulong val, target_ulong next_eip)
 2300: {
 2301:     int l1, l2, cc_op;
 2302: 
 2303:     cc_op = s->cc_op;
 2304:     gen_update_cc_op(s);
 2305:     if (s->jmp_opt) {
 2306:         l1 = gen_new_label();
 2307:         gen_jcc1(s, cc_op, b, l1);
 2308:         
 2309:         gen_goto_tb(s, 0, next_eip);
 2310: 
 2311:         gen_set_label(l1);
 2312:         gen_goto_tb(s, 1, val);
 2313:         s->is_jmp = DISAS_TB_JUMP;
 2314:     } else {
 2315: 
 2316:         l1 = gen_new_label();
 2317:         l2 = gen_new_label();
 2318:         gen_jcc1(s, cc_op, b, l1);
 2319: 
 2320:         gen_jmp_im(next_eip);
 2321:         tcg_gen_br(l2);
 2322: 
 2323:         gen_set_label(l1);
 2324:         gen_jmp_im(val);
 2325:         gen_set_label(l2);
 2326:         gen_eob(s);
 2327:     }
 2328: }
 2329: 
 2330: static void gen_setcc(DisasContext *s, int b)
 2331: {
 2332:     int inv, jcc_op, l1;
 2333:     TCGv t0;
 2334: 
 2335:     if (is_fast_jcc_case(s, b)) {
 2336:         /* nominal case: we use a jump */
 2337:         /* XXX: make it faster by adding new instructions in TCG */
 2338:         t0 = tcg_temp_local_new();
 2339:         tcg_gen_movi_tl(t0, 0);
 2340:         l1 = gen_new_label();
 2341:         gen_jcc1(s, s->cc_op, b ^ 1, l1);
 2342:         tcg_gen_movi_tl(t0, 1);
 2343:         gen_set_label(l1);
 2344:         tcg_gen_mov_tl(cpu_T[0], t0);
 2345:         tcg_temp_free(t0);
 2346:     } else {
 2347:         /* slow case: it is more efficient not to generate a jump,
 2348:            although it is questionnable whether this optimization is
 2349:            worth to */
 2350:         inv = b & 1;
 2351:         jcc_op = (b >> 1) & 7;
 2352:         gen_setcc_slow_T0(s, jcc_op);
 2353:         if (inv) {
 2354:             tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1);
 2355:         }
 2356:     }
 2357: }
 2358: 
 2359: static inline void gen_op_movl_T0_seg(int seg_reg)
 2360: {
 2361:     tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
 2362:                      offsetof(CPUX86State,segs[seg_reg].selector));
 2363: }
 2364: 
 2365: static inline void gen_op_movl_seg_T0_vm(int seg_reg)
 2366: {
 2367:     tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
 2368:     tcg_gen_st32_tl(cpu_T[0], cpu_env, 
 2369:                     offsetof(CPUX86State,segs[seg_reg].selector));
 2370:     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
 2371:     tcg_gen_st_tl(cpu_T[0], cpu_env, 
 2372:                   offsetof(CPUX86State,segs[seg_reg].base));
 2373: }
 2374: 
 2375: /* move T0 to seg_reg and compute if the CPU state may change. Never
 2376:    call this function with seg_reg == R_CS */
 2377: static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
 2378: {
 2379:     if (s->pe && !s->vm86) {
 2380:         /* XXX: optimize by finding processor state dynamically */
 2381:         if (s->cc_op != CC_OP_DYNAMIC)
 2382:             gen_op_set_cc_op(s->cc_op);
 2383:         gen_jmp_im(cur_eip);
 2384:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 2385:         gen_helper_load_seg(tcg_const_i32(seg_reg), cpu_tmp2_i32);
 2386:         /* abort translation because the addseg value may change or
 2387:            because ss32 may change. For R_SS, translation must always
 2388:            stop as a special handling must be done to disable hardware
 2389:            interrupts for the next instruction */
 2390:         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
 2391:             s->is_jmp = DISAS_TB_JUMP;
 2392:     } else {
 2393:         gen_op_movl_seg_T0_vm(seg_reg);
 2394:         if (seg_reg == R_SS)
 2395:             s->is_jmp = DISAS_TB_JUMP;
 2396:     }
 2397: }
 2398: 
 2399: static inline int svm_is_rep(int prefixes)
 2400: {
 2401:     return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
 2402: }
 2403: 
 2404: static inline void
 2405: gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
 2406:                               uint32_t type, uint64_t param)
 2407: {
 2408:     /* no SVM activated; fast case */
 2409:     if (likely(!(s->flags & HF_SVMI_MASK)))
 2410:         return;
 2411:     if (s->cc_op != CC_OP_DYNAMIC)
 2412:         gen_op_set_cc_op(s->cc_op);
 2413:     gen_jmp_im(pc_start - s->cs_base);
 2414:     gen_helper_svm_check_intercept_param(tcg_const_i32(type),
 2415:                                          tcg_const_i64(param));
 2416: }
 2417: 
 2418: static inline void
 2419: gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
 2420: {
 2421:     gen_svm_check_intercept_param(s, pc_start, type, 0);
 2422: }
 2423: 
 2424: static inline void gen_stack_update(DisasContext *s, int addend)
 2425: {
 2426: #ifdef TARGET_X86_64
 2427:     if (CODE64(s)) {
 2428:         gen_op_add_reg_im(2, R_ESP, addend);
 2429:     } else
 2430: #endif
 2431:     if (s->ss32) {
 2432:         gen_op_add_reg_im(1, R_ESP, addend);
 2433:     } else {
 2434:         gen_op_add_reg_im(0, R_ESP, addend);
 2435:     }
 2436: }
 2437: 
 2438: /* generate a push. It depends on ss32, addseg and dflag */
 2439: static void gen_push_T0(DisasContext *s)
 2440: {
 2441: #ifdef TARGET_X86_64
 2442:     if (CODE64(s)) {
 2443:         gen_op_movq_A0_reg(R_ESP);
 2444:         if (s->dflag) {
 2445:             gen_op_addq_A0_im(-8);
 2446:             gen_op_st_T0_A0(OT_QUAD + s->mem_index);
 2447:         } else {
 2448:             gen_op_addq_A0_im(-2);
 2449:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
 2450:         }
 2451:         gen_op_mov_reg_A0(2, R_ESP);
 2452:     } else
 2453: #endif
 2454:     {
 2455:         gen_op_movl_A0_reg(R_ESP);
 2456:         if (!s->dflag)
 2457:             gen_op_addl_A0_im(-2);
 2458:         else
 2459:             gen_op_addl_A0_im(-4);
 2460:         if (s->ss32) {
 2461:             if (s->addseg) {
 2462:                 tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2463:                 gen_op_addl_A0_seg(R_SS);
 2464:             }
 2465:         } else {
 2466:             gen_op_andl_A0_ffff();
 2467:             tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2468:             gen_op_addl_A0_seg(R_SS);
 2469:         }
 2470:         gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
 2471:         if (s->ss32 && !s->addseg)
 2472:             gen_op_mov_reg_A0(1, R_ESP);
 2473:         else
 2474:             gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
 2475:     }
 2476: }
 2477: 
 2478: /* generate a push. It depends on ss32, addseg and dflag */
 2479: /* slower version for T1, only used for call Ev */
 2480: static void gen_push_T1(DisasContext *s)
 2481: {
 2482: #ifdef TARGET_X86_64
 2483:     if (CODE64(s)) {
 2484:         gen_op_movq_A0_reg(R_ESP);
 2485:         if (s->dflag) {
 2486:             gen_op_addq_A0_im(-8);
 2487:             gen_op_st_T1_A0(OT_QUAD + s->mem_index);
 2488:         } else {
 2489:             gen_op_addq_A0_im(-2);
 2490:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
 2491:         }
 2492:         gen_op_mov_reg_A0(2, R_ESP);
 2493:     } else
 2494: #endif
 2495:     {
 2496:         gen_op_movl_A0_reg(R_ESP);
 2497:         if (!s->dflag)
 2498:             gen_op_addl_A0_im(-2);
 2499:         else
 2500:             gen_op_addl_A0_im(-4);
 2501:         if (s->ss32) {
 2502:             if (s->addseg) {
 2503:                 gen_op_addl_A0_seg(R_SS);
 2504:             }
 2505:         } else {
 2506:             gen_op_andl_A0_ffff();
 2507:             gen_op_addl_A0_seg(R_SS);
 2508:         }
 2509:         gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
 2510: 
 2511:         if (s->ss32 && !s->addseg)
 2512:             gen_op_mov_reg_A0(1, R_ESP);
 2513:         else
 2514:             gen_stack_update(s, (-2) << s->dflag);
 2515:     }
 2516: }
 2517: 
 2518: /* two step pop is necessary for precise exceptions */
 2519: static void gen_pop_T0(DisasContext *s)
 2520: {
 2521: #ifdef TARGET_X86_64
 2522:     if (CODE64(s)) {
 2523:         gen_op_movq_A0_reg(R_ESP);
 2524:         gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
 2525:     } else
 2526: #endif
 2527:     {
 2528:         gen_op_movl_A0_reg(R_ESP);
 2529:         if (s->ss32) {
 2530:             if (s->addseg)
 2531:                 gen_op_addl_A0_seg(R_SS);
 2532:         } else {
 2533:             gen_op_andl_A0_ffff();
 2534:             gen_op_addl_A0_seg(R_SS);
 2535:         }
 2536:         gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
 2537:     }
 2538: }
 2539: 
 2540: static void gen_pop_update(DisasContext *s)
 2541: {
 2542: #ifdef TARGET_X86_64
 2543:     if (CODE64(s) && s->dflag) {
 2544:         gen_stack_update(s, 8);
 2545:     } else
 2546: #endif
 2547:     {
 2548:         gen_stack_update(s, 2 << s->dflag);
 2549:     }
 2550: }
 2551: 
 2552: static void gen_stack_A0(DisasContext *s)
 2553: {
 2554:     gen_op_movl_A0_reg(R_ESP);
 2555:     if (!s->ss32)
 2556:         gen_op_andl_A0_ffff();
 2557:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2558:     if (s->addseg)
 2559:         gen_op_addl_A0_seg(R_SS);
 2560: }
 2561: 
 2562: /* NOTE: wrap around in 16 bit not fully handled */
 2563: static void gen_pusha(DisasContext *s)
 2564: {
 2565:     int i;
 2566:     gen_op_movl_A0_reg(R_ESP);
 2567:     gen_op_addl_A0_im(-16 <<  s->dflag);
 2568:     if (!s->ss32)
 2569:         gen_op_andl_A0_ffff();
 2570:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2571:     if (s->addseg)
 2572:         gen_op_addl_A0_seg(R_SS);
 2573:     for(i = 0;i < 8; i++) {
 2574:         gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
 2575:         gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
 2576:         gen_op_addl_A0_im(2 <<  s->dflag);
 2577:     }
 2578:     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
 2579: }
 2580: 
 2581: /* NOTE: wrap around in 16 bit not fully handled */
 2582: static void gen_popa(DisasContext *s)
 2583: {
 2584:     int i;
 2585:     gen_op_movl_A0_reg(R_ESP);
 2586:     if (!s->ss32)
 2587:         gen_op_andl_A0_ffff();
 2588:     tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2589:     tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 <<  s->dflag);
 2590:     if (s->addseg)
 2591:         gen_op_addl_A0_seg(R_SS);
 2592:     for(i = 0;i < 8; i++) {
 2593:         /* ESP is not reloaded */
 2594:         if (i != 3) {
 2595:             gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
 2596:             gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
 2597:         }
 2598:         gen_op_addl_A0_im(2 <<  s->dflag);
 2599:     }
 2600:     gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
 2601: }
 2602: 
 2603: static void gen_enter(DisasContext *s, int esp_addend, int level)
 2604: {
 2605:     int ot, opsize;
 2606: 
 2607:     level &= 0x1f;
 2608: #ifdef TARGET_X86_64
 2609:     if (CODE64(s)) {
 2610:         ot = s->dflag ? OT_QUAD : OT_WORD;
 2611:         opsize = 1 << ot;
 2612: 
 2613:         gen_op_movl_A0_reg(R_ESP);
 2614:         gen_op_addq_A0_im(-opsize);
 2615:         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2616: 
 2617:         /* push bp */
 2618:         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
 2619:         gen_op_st_T0_A0(ot + s->mem_index);
 2620:         if (level) {
 2621:             /* XXX: must save state */
 2622:             gen_helper_enter64_level(tcg_const_i32(level),
 2623:                                      tcg_const_i32((ot == OT_QUAD)),
 2624:                                      cpu_T[1]);
 2625:         }
 2626:         gen_op_mov_reg_T1(ot, R_EBP);
 2627:         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
 2628:         gen_op_mov_reg_T1(OT_QUAD, R_ESP);
 2629:     } else
 2630: #endif
 2631:     {
 2632:         ot = s->dflag + OT_WORD;
 2633:         opsize = 2 << s->dflag;
 2634: 
 2635:         gen_op_movl_A0_reg(R_ESP);
 2636:         gen_op_addl_A0_im(-opsize);
 2637:         if (!s->ss32)
 2638:             gen_op_andl_A0_ffff();
 2639:         tcg_gen_mov_tl(cpu_T[1], cpu_A0);
 2640:         if (s->addseg)
 2641:             gen_op_addl_A0_seg(R_SS);
 2642:         /* push bp */
 2643:         gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
 2644:         gen_op_st_T0_A0(ot + s->mem_index);
 2645:         if (level) {
 2646:             /* XXX: must save state */
 2647:             gen_helper_enter_level(tcg_const_i32(level),
 2648:                                    tcg_const_i32(s->dflag),
 2649:                                    cpu_T[1]);
 2650:         }
 2651:         gen_op_mov_reg_T1(ot, R_EBP);
 2652:         tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level));
 2653:         gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
 2654:     }
 2655: }
 2656: 
 2657: static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
 2658: {
 2659:     if (s->cc_op != CC_OP_DYNAMIC)
 2660:         gen_op_set_cc_op(s->cc_op);
 2661:     gen_jmp_im(cur_eip);
 2662:     gen_helper_raise_exception(tcg_const_i32(trapno));
 2663:     s->is_jmp = DISAS_TB_JUMP;
 2664: }
 2665: 
 2666: /* an interrupt is different from an exception because of the
 2667:    privilege checks */
 2668: static void gen_interrupt(DisasContext *s, int intno,
 2669:                           target_ulong cur_eip, target_ulong next_eip)
 2670: {
 2671:     if (s->cc_op != CC_OP_DYNAMIC)
 2672:         gen_op_set_cc_op(s->cc_op);
 2673:     gen_jmp_im(cur_eip);
 2674:     gen_helper_raise_interrupt(tcg_const_i32(intno), 
 2675:                                tcg_const_i32(next_eip - cur_eip));
 2676:     s->is_jmp = DISAS_TB_JUMP;
 2677: }
 2678: 
 2679: static void gen_debug(DisasContext *s, target_ulong cur_eip)
 2680: {
 2681:     if (s->cc_op != CC_OP_DYNAMIC)
 2682:         gen_op_set_cc_op(s->cc_op);
 2683:     gen_jmp_im(cur_eip);
 2684:     gen_helper_debug();
 2685:     s->is_jmp = DISAS_TB_JUMP;
 2686: }
 2687: 
 2688: /* generate a generic end of block. Trace exception is also generated
 2689:    if needed */
 2690: static void gen_eob(DisasContext *s)
 2691: {
 2692:     if (s->cc_op != CC_OP_DYNAMIC)
 2693:         gen_op_set_cc_op(s->cc_op);
 2694:     if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
 2695:         gen_helper_reset_inhibit_irq();
 2696:     }
 2697:     if (s->tb->flags & HF_RF_MASK) {
 2698:         gen_helper_reset_rf();
 2699:     }
 2700:     if (s->singlestep_enabled) {
 2701:         gen_helper_debug();
 2702:     } else if (s->tf) {
 2703: 	gen_helper_single_step();
 2704:     } else {
 2705:         tcg_gen_exit_tb(0);
 2706:     }
 2707:     s->is_jmp = DISAS_TB_JUMP;
 2708: }
 2709: 
 2710: /* generate a jump to eip. No segment change must happen before as a
 2711:    direct call to the next block may occur */
 2712: static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
 2713: {
 2714:     if (s->jmp_opt) {
 2715:         gen_update_cc_op(s);
 2716:         gen_goto_tb(s, tb_num, eip);
 2717:         s->is_jmp = DISAS_TB_JUMP;
 2718:     } else {
 2719:         gen_jmp_im(eip);
 2720:         gen_eob(s);
 2721:     }
 2722: }
 2723: 
 2724: static void gen_jmp(DisasContext *s, target_ulong eip)
 2725: {
 2726:     gen_jmp_tb(s, eip, 0);
 2727: }
 2728: 
 2729: static inline void gen_ldq_env_A0(int idx, int offset)
 2730: {
 2731:     int mem_index = (idx >> 2) - 1;
 2732:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
 2733:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
 2734: }
 2735: 
 2736: static inline void gen_stq_env_A0(int idx, int offset)
 2737: {
 2738:     int mem_index = (idx >> 2) - 1;
 2739:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
 2740:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
 2741: }
 2742: 
 2743: static inline void gen_ldo_env_A0(int idx, int offset)
 2744: {
 2745:     int mem_index = (idx >> 2) - 1;
 2746:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index);
 2747:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
 2748:     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
 2749:     tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index);
 2750:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
 2751: }
 2752: 
 2753: static inline void gen_sto_env_A0(int idx, int offset)
 2754: {
 2755:     int mem_index = (idx >> 2) - 1;
 2756:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
 2757:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index);
 2758:     tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
 2759:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
 2760:     tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index);
 2761: }
 2762: 
 2763: static inline void gen_op_movo(int d_offset, int s_offset)
 2764: {
 2765:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
 2766:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
 2767:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset + 8);
 2768:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset + 8);
 2769: }
 2770: 
 2771: static inline void gen_op_movq(int d_offset, int s_offset)
 2772: {
 2773:     tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, s_offset);
 2774:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
 2775: }
 2776: 
 2777: static inline void gen_op_movl(int d_offset, int s_offset)
 2778: {
 2779:     tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, s_offset);
 2780:     tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, d_offset);
 2781: }
 2782: 
 2783: static inline void gen_op_movq_env_0(int d_offset)
 2784: {
 2785:     tcg_gen_movi_i64(cpu_tmp1_i64, 0);
 2786:     tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, d_offset);
 2787: }
 2788: 
 2789: #define SSE_SPECIAL ((void *)1)
 2790: #define SSE_DUMMY ((void *)2)
 2791: 
 2792: #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
 2793: #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
 2794:                      gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
 2795: 
 2796: static void *sse_op_table1[256][4] = {
 2797:     /* 3DNow! extensions */
 2798:     [0x0e] = { SSE_DUMMY }, /* femms */
 2799:     [0x0f] = { SSE_DUMMY }, /* pf... */
 2800:     /* pure SSE operations */
 2801:     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
 2802:     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
 2803:     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
 2804:     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
 2805:     [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
 2806:     [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
 2807:     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
 2808:     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
 2809: 
 2810:     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
 2811:     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
 2812:     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
 2813:     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
 2814:     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
 2815:     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
 2816:     [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
 2817:     [0x2f] = { gen_helper_comiss, gen_helper_comisd },
 2818:     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
 2819:     [0x51] = SSE_FOP(sqrt),
 2820:     [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
 2821:     [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
 2822:     [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
 2823:     [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
 2824:     [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
 2825:     [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
 2826:     [0x58] = SSE_FOP(add),
 2827:     [0x59] = SSE_FOP(mul),
 2828:     [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
 2829:                gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
 2830:     [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
 2831:     [0x5c] = SSE_FOP(sub),
 2832:     [0x5d] = SSE_FOP(min),
 2833:     [0x5e] = SSE_FOP(div),
 2834:     [0x5f] = SSE_FOP(max),
 2835: 
 2836:     [0xc2] = SSE_FOP(cmpeq),
 2837:     [0xc6] = { gen_helper_shufps, gen_helper_shufpd },
 2838: 
 2839:     [0x38] = { SSE_SPECIAL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* SSSE3/SSE4 */
 2840:     [0x3a] = { SSE_SPECIAL, SSE_SPECIAL }, /* SSSE3/SSE4 */
 2841: 
 2842:     /* MMX ops and their SSE extensions */
 2843:     [0x60] = MMX_OP2(punpcklbw),
 2844:     [0x61] = MMX_OP2(punpcklwd),
 2845:     [0x62] = MMX_OP2(punpckldq),
 2846:     [0x63] = MMX_OP2(packsswb),
 2847:     [0x64] = MMX_OP2(pcmpgtb),
 2848:     [0x65] = MMX_OP2(pcmpgtw),
 2849:     [0x66] = MMX_OP2(pcmpgtl),
 2850:     [0x67] = MMX_OP2(packuswb),
 2851:     [0x68] = MMX_OP2(punpckhbw),
 2852:     [0x69] = MMX_OP2(punpckhwd),
 2853:     [0x6a] = MMX_OP2(punpckhdq),
 2854:     [0x6b] = MMX_OP2(packssdw),
 2855:     [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
 2856:     [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
 2857:     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
 2858:     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
 2859:     [0x70] = { gen_helper_pshufw_mmx,
 2860:                gen_helper_pshufd_xmm,
 2861:                gen_helper_pshufhw_xmm,
 2862:                gen_helper_pshuflw_xmm },
 2863:     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
 2864:     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
 2865:     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
 2866:     [0x74] = MMX_OP2(pcmpeqb),
 2867:     [0x75] = MMX_OP2(pcmpeqw),
 2868:     [0x76] = MMX_OP2(pcmpeql),
 2869:     [0x77] = { SSE_DUMMY }, /* emms */
 2870:     [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
 2871:     [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
 2872:     [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
 2873:     [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
 2874:     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
 2875:     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
 2876:     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
 2877:     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
 2878:     [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
 2879:     [0xd1] = MMX_OP2(psrlw),
 2880:     [0xd2] = MMX_OP2(psrld),
 2881:     [0xd3] = MMX_OP2(psrlq),
 2882:     [0xd4] = MMX_OP2(paddq),
 2883:     [0xd5] = MMX_OP2(pmullw),
 2884:     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
 2885:     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
 2886:     [0xd8] = MMX_OP2(psubusb),
 2887:     [0xd9] = MMX_OP2(psubusw),
 2888:     [0xda] = MMX_OP2(pminub),
 2889:     [0xdb] = MMX_OP2(pand),
 2890:     [0xdc] = MMX_OP2(paddusb),
 2891:     [0xdd] = MMX_OP2(paddusw),
 2892:     [0xde] = MMX_OP2(pmaxub),
 2893:     [0xdf] = MMX_OP2(pandn),
 2894:     [0xe0] = MMX_OP2(pavgb),
 2895:     [0xe1] = MMX_OP2(psraw),
 2896:     [0xe2] = MMX_OP2(psrad),
 2897:     [0xe3] = MMX_OP2(pavgw),
 2898:     [0xe4] = MMX_OP2(pmulhuw),
 2899:     [0xe5] = MMX_OP2(pmulhw),
 2900:     [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
 2901:     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
 2902:     [0xe8] = MMX_OP2(psubsb),
 2903:     [0xe9] = MMX_OP2(psubsw),
 2904:     [0xea] = MMX_OP2(pminsw),
 2905:     [0xeb] = MMX_OP2(por),
 2906:     [0xec] = MMX_OP2(paddsb),
 2907:     [0xed] = MMX_OP2(paddsw),
 2908:     [0xee] = MMX_OP2(pmaxsw),
 2909:     [0xef] = MMX_OP2(pxor),
 2910:     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
 2911:     [0xf1] = MMX_OP2(psllw),
 2912:     [0xf2] = MMX_OP2(pslld),
 2913:     [0xf3] = MMX_OP2(psllq),
 2914:     [0xf4] = MMX_OP2(pmuludq),
 2915:     [0xf5] = MMX_OP2(pmaddwd),
 2916:     [0xf6] = MMX_OP2(psadbw),
 2917:     [0xf7] = MMX_OP2(maskmov),
 2918:     [0xf8] = MMX_OP2(psubb),
 2919:     [0xf9] = MMX_OP2(psubw),
 2920:     [0xfa] = MMX_OP2(psubl),
 2921:     [0xfb] = MMX_OP2(psubq),
 2922:     [0xfc] = MMX_OP2(paddb),
 2923:     [0xfd] = MMX_OP2(paddw),
 2924:     [0xfe] = MMX_OP2(paddl),
 2925: };
 2926: 
 2927: static void *sse_op_table2[3 * 8][2] = {
 2928:     [0 + 2] = MMX_OP2(psrlw),
 2929:     [0 + 4] = MMX_OP2(psraw),
 2930:     [0 + 6] = MMX_OP2(psllw),
 2931:     [8 + 2] = MMX_OP2(psrld),
 2932:     [8 + 4] = MMX_OP2(psrad),
 2933:     [8 + 6] = MMX_OP2(pslld),
 2934:     [16 + 2] = MMX_OP2(psrlq),
 2935:     [16 + 3] = { NULL, gen_helper_psrldq_xmm },
 2936:     [16 + 6] = MMX_OP2(psllq),
 2937:     [16 + 7] = { NULL, gen_helper_pslldq_xmm },
 2938: };
 2939: 
 2940: static void *sse_op_table3[4 * 3] = {
 2941:     gen_helper_cvtsi2ss,
 2942:     gen_helper_cvtsi2sd,
 2943:     X86_64_ONLY(gen_helper_cvtsq2ss),
 2944:     X86_64_ONLY(gen_helper_cvtsq2sd),
 2945: 
 2946:     gen_helper_cvttss2si,
 2947:     gen_helper_cvttsd2si,
 2948:     X86_64_ONLY(gen_helper_cvttss2sq),
 2949:     X86_64_ONLY(gen_helper_cvttsd2sq),
 2950: 
 2951:     gen_helper_cvtss2si,
 2952:     gen_helper_cvtsd2si,
 2953:     X86_64_ONLY(gen_helper_cvtss2sq),
 2954:     X86_64_ONLY(gen_helper_cvtsd2sq),
 2955: };
 2956: 
 2957: static void *sse_op_table4[8][4] = {
 2958:     SSE_FOP(cmpeq),
 2959:     SSE_FOP(cmplt),
 2960:     SSE_FOP(cmple),
 2961:     SSE_FOP(cmpunord),
 2962:     SSE_FOP(cmpneq),
 2963:     SSE_FOP(cmpnlt),
 2964:     SSE_FOP(cmpnle),
 2965:     SSE_FOP(cmpord),
 2966: };
 2967: 
 2968: static void *sse_op_table5[256] = {
 2969:     [0x0c] = gen_helper_pi2fw,
 2970:     [0x0d] = gen_helper_pi2fd,
 2971:     [0x1c] = gen_helper_pf2iw,
 2972:     [0x1d] = gen_helper_pf2id,
 2973:     [0x8a] = gen_helper_pfnacc,
 2974:     [0x8e] = gen_helper_pfpnacc,
 2975:     [0x90] = gen_helper_pfcmpge,
 2976:     [0x94] = gen_helper_pfmin,
 2977:     [0x96] = gen_helper_pfrcp,
 2978:     [0x97] = gen_helper_pfrsqrt,
 2979:     [0x9a] = gen_helper_pfsub,
 2980:     [0x9e] = gen_helper_pfadd,
 2981:     [0xa0] = gen_helper_pfcmpgt,
 2982:     [0xa4] = gen_helper_pfmax,
 2983:     [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
 2984:     [0xa7] = gen_helper_movq, /* pfrsqit1 */
 2985:     [0xaa] = gen_helper_pfsubr,
 2986:     [0xae] = gen_helper_pfacc,
 2987:     [0xb0] = gen_helper_pfcmpeq,
 2988:     [0xb4] = gen_helper_pfmul,
 2989:     [0xb6] = gen_helper_movq, /* pfrcpit2 */
 2990:     [0xb7] = gen_helper_pmulhrw_mmx,
 2991:     [0xbb] = gen_helper_pswapd,
 2992:     [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
 2993: };
 2994: 
 2995: struct sse_op_helper_s {
 2996:     void *op[2]; uint32_t ext_mask;
 2997: };
 2998: #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
 2999: #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
 3000: #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
 3001: #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
 3002: static struct sse_op_helper_s sse_op_table6[256] = {
 3003:     [0x00] = SSSE3_OP(pshufb),
 3004:     [0x01] = SSSE3_OP(phaddw),
 3005:     [0x02] = SSSE3_OP(phaddd),
 3006:     [0x03] = SSSE3_OP(phaddsw),
 3007:     [0x04] = SSSE3_OP(pmaddubsw),
 3008:     [0x05] = SSSE3_OP(phsubw),
 3009:     [0x06] = SSSE3_OP(phsubd),
 3010:     [0x07] = SSSE3_OP(phsubsw),
 3011:     [0x08] = SSSE3_OP(psignb),
 3012:     [0x09] = SSSE3_OP(psignw),
 3013:     [0x0a] = SSSE3_OP(psignd),
 3014:     [0x0b] = SSSE3_OP(pmulhrsw),
 3015:     [0x10] = SSE41_OP(pblendvb),
 3016:     [0x14] = SSE41_OP(blendvps),
 3017:     [0x15] = SSE41_OP(blendvpd),
 3018:     [0x17] = SSE41_OP(ptest),
 3019:     [0x1c] = SSSE3_OP(pabsb),
 3020:     [0x1d] = SSSE3_OP(pabsw),
 3021:     [0x1e] = SSSE3_OP(pabsd),
 3022:     [0x20] = SSE41_OP(pmovsxbw),
 3023:     [0x21] = SSE41_OP(pmovsxbd),
 3024:     [0x22] = SSE41_OP(pmovsxbq),
 3025:     [0x23] = SSE41_OP(pmovsxwd),
 3026:     [0x24] = SSE41_OP(pmovsxwq),
 3027:     [0x25] = SSE41_OP(pmovsxdq),
 3028:     [0x28] = SSE41_OP(pmuldq),
 3029:     [0x29] = SSE41_OP(pcmpeqq),
 3030:     [0x2a] = SSE41_SPECIAL, /* movntqda */
 3031:     [0x2b] = SSE41_OP(packusdw),
 3032:     [0x30] = SSE41_OP(pmovzxbw),
 3033:     [0x31] = SSE41_OP(pmovzxbd),
 3034:     [0x32] = SSE41_OP(pmovzxbq),
 3035:     [0x33] = SSE41_OP(pmovzxwd),
 3036:     [0x34] = SSE41_OP(pmovzxwq),
 3037:     [0x35] = SSE41_OP(pmovzxdq),
 3038:     [0x37] = SSE42_OP(pcmpgtq),
 3039:     [0x38] = SSE41_OP(pminsb),
 3040:     [0x39] = SSE41_OP(pminsd),
 3041:     [0x3a] = SSE41_OP(pminuw),
 3042:     [0x3b] = SSE41_OP(pminud),
 3043:     [0x3c] = SSE41_OP(pmaxsb),
 3044:     [0x3d] = SSE41_OP(pmaxsd),
 3045:     [0x3e] = SSE41_OP(pmaxuw),
 3046:     [0x3f] = SSE41_OP(pmaxud),
 3047:     [0x40] = SSE41_OP(pmulld),
 3048:     [0x41] = SSE41_OP(phminposuw),
 3049: };
 3050: 
 3051: static struct sse_op_helper_s sse_op_table7[256] = {
 3052:     [0x08] = SSE41_OP(roundps),
 3053:     [0x09] = SSE41_OP(roundpd),
 3054:     [0x0a] = SSE41_OP(roundss),
 3055:     [0x0b] = SSE41_OP(roundsd),
 3056:     [0x0c] = SSE41_OP(blendps),
 3057:     [0x0d] = SSE41_OP(blendpd),
 3058:     [0x0e] = SSE41_OP(pblendw),
 3059:     [0x0f] = SSSE3_OP(palignr),
 3060:     [0x14] = SSE41_SPECIAL, /* pextrb */
 3061:     [0x15] = SSE41_SPECIAL, /* pextrw */
 3062:     [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
 3063:     [0x17] = SSE41_SPECIAL, /* extractps */
 3064:     [0x20] = SSE41_SPECIAL, /* pinsrb */
 3065:     [0x21] = SSE41_SPECIAL, /* insertps */
 3066:     [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
 3067:     [0x40] = SSE41_OP(dpps),
 3068:     [0x41] = SSE41_OP(dppd),
 3069:     [0x42] = SSE41_OP(mpsadbw),
 3070:     [0x60] = SSE42_OP(pcmpestrm),
 3071:     [0x61] = SSE42_OP(pcmpestri),
 3072:     [0x62] = SSE42_OP(pcmpistrm),
 3073:     [0x63] = SSE42_OP(pcmpistri),
 3074: };
 3075: 
 3076: static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
 3077: {
 3078:     int b1, op1_offset, op2_offset, is_xmm, val, ot;
 3079:     int modrm, mod, rm, reg, reg_addr, offset_addr;
 3080:     void *sse_op2;
 3081: 
 3082:     b &= 0xff;
 3083:     if (s->prefix & PREFIX_DATA)
 3084:         b1 = 1;
 3085:     else if (s->prefix & PREFIX_REPZ)
 3086:         b1 = 2;
 3087:     else if (s->prefix & PREFIX_REPNZ)
 3088:         b1 = 3;
 3089:     else
 3090:         b1 = 0;
 3091:     sse_op2 = sse_op_table1[b][b1];
 3092:     if (!sse_op2)
 3093:         goto illegal_op;
 3094:     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
 3095:         is_xmm = 1;
 3096:     } else {
 3097:         if (b1 == 0) {
 3098:             /* MMX case */
 3099:             is_xmm = 0;
 3100:         } else {
 3101:             is_xmm = 1;
 3102:         }
 3103:     }
 3104:     /* simple MMX/SSE operation */
 3105:     if (s->flags & HF_TS_MASK) {
 3106:         gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 3107:         return;
 3108:     }
 3109:     if (s->flags & HF_EM_MASK) {
 3110:     illegal_op:
 3111:         gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
 3112:         return;
 3113:     }
 3114:     if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
 3115:         if ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))
 3116:             goto illegal_op;
 3117:     if (b == 0x0e) {
 3118:         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
 3119:             goto illegal_op;
 3120:         /* femms */
 3121:         gen_helper_emms();
 3122:         return;
 3123:     }
 3124:     if (b == 0x77) {
 3125:         /* emms */
 3126:         gen_helper_emms();
 3127:         return;
 3128:     }
 3129:     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
 3130:        the static cpu state) */
 3131:     if (!is_xmm) {
 3132:         gen_helper_enter_mmx();
 3133:     }
 3134: 
 3135:     modrm = ldub_code(s->pc++);
 3136:     reg = ((modrm >> 3) & 7);
 3137:     if (is_xmm)
 3138:         reg |= rex_r;
 3139:     mod = (modrm >> 6) & 3;
 3140:     if (sse_op2 == SSE_SPECIAL) {
 3141:         b |= (b1 << 8);
 3142:         switch(b) {
 3143:         case 0x0e7: /* movntq */
 3144:             if (mod == 3)
 3145:                 goto illegal_op;
 3146:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3147:             gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
 3148:             break;
 3149:         case 0x1e7: /* movntdq */
 3150:         case 0x02b: /* movntps */
 3151:         case 0x12b: /* movntps */
 3152:             if (mod == 3)
 3153:                 goto illegal_op;
 3154:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3155:             gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3156:             break;
 3157:         case 0x3f0: /* lddqu */
 3158:             if (mod == 3)
 3159:                 goto illegal_op;
 3160:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3161:             gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3162:             break;
 3163:         case 0x22b: /* movntss */
 3164:         case 0x32b: /* movntsd */
 3165:             if (mod == 3)
 3166:                 goto illegal_op;
 3167:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3168:             if (b1 & 1) {
 3169:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,
 3170:                     xmm_regs[reg]));
 3171:             } else {
 3172:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
 3173:                     xmm_regs[reg].XMM_L(0)));
 3174:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
 3175:             }
 3176:             break;
 3177:         case 0x6e: /* movd mm, ea */
 3178: #ifdef TARGET_X86_64
 3179:             if (s->dflag == 2) {
 3180:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
 3181:                 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));
 3182:             } else
 3183: #endif
 3184:             {
 3185:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
 3186:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
 3187:                                  offsetof(CPUX86State,fpregs[reg].mmx));
 3188:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 3189:                 gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);
 3190:             }
 3191:             break;
 3192:         case 0x16e: /* movd xmm, ea */
 3193: #ifdef TARGET_X86_64
 3194:             if (s->dflag == 2) {
 3195:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
 3196:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
 3197:                                  offsetof(CPUX86State,xmm_regs[reg]));
 3198:                 gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]);
 3199:             } else
 3200: #endif
 3201:             {
 3202:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
 3203:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
 3204:                                  offsetof(CPUX86State,xmm_regs[reg]));
 3205:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 3206:                 gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);
 3207:             }
 3208:             break;
 3209:         case 0x6f: /* movq mm, ea */
 3210:             if (mod != 3) {
 3211:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3212:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
 3213:             } else {
 3214:                 rm = (modrm & 7);
 3215:                 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
 3216:                                offsetof(CPUX86State,fpregs[rm].mmx));
 3217:                 tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
 3218:                                offsetof(CPUX86State,fpregs[reg].mmx));
 3219:             }
 3220:             break;
 3221:         case 0x010: /* movups */
 3222:         case 0x110: /* movupd */
 3223:         case 0x028: /* movaps */
 3224:         case 0x128: /* movapd */
 3225:         case 0x16f: /* movdqa xmm, ea */
 3226:         case 0x26f: /* movdqu xmm, ea */
 3227:             if (mod != 3) {
 3228:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3229:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3230:             } else {
 3231:                 rm = (modrm & 7) | REX_B(s);
 3232:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
 3233:                             offsetof(CPUX86State,xmm_regs[rm]));
 3234:             }
 3235:             break;
 3236:         case 0x210: /* movss xmm, ea */
 3237:             if (mod != 3) {
 3238:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3239:                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 3240:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
 3241:                 gen_op_movl_T0_0();
 3242:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
 3243:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
 3244:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
 3245:             } else {
 3246:                 rm = (modrm & 7) | REX_B(s);
 3247:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
 3248:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
 3249:             }
 3250:             break;
 3251:         case 0x310: /* movsd xmm, ea */
 3252:             if (mod != 3) {
 3253:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3254:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3255:                 gen_op_movl_T0_0();
 3256:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
 3257:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
 3258:             } else {
 3259:                 rm = (modrm & 7) | REX_B(s);
 3260:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
 3261:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
 3262:             }
 3263:             break;
 3264:         case 0x012: /* movlps */
 3265:         case 0x112: /* movlpd */
 3266:             if (mod != 3) {
 3267:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3268:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3269:             } else {
 3270:                 /* movhlps */
 3271:                 rm = (modrm & 7) | REX_B(s);
 3272:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
 3273:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
 3274:             }
 3275:             break;
 3276:         case 0x212: /* movsldup */
 3277:             if (mod != 3) {
 3278:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3279:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3280:             } else {
 3281:                 rm = (modrm & 7) | REX_B(s);
 3282:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
 3283:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
 3284:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
 3285:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
 3286:             }
 3287:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
 3288:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
 3289:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
 3290:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
 3291:             break;
 3292:         case 0x312: /* movddup */
 3293:             if (mod != 3) {
 3294:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3295:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3296:             } else {
 3297:                 rm = (modrm & 7) | REX_B(s);
 3298:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
 3299:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
 3300:             }
 3301:             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
 3302:                         offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3303:             break;
 3304:         case 0x016: /* movhps */
 3305:         case 0x116: /* movhpd */
 3306:             if (mod != 3) {
 3307:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3308:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
 3309:             } else {
 3310:                 /* movlhps */
 3311:                 rm = (modrm & 7) | REX_B(s);
 3312:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
 3313:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
 3314:             }
 3315:             break;
 3316:         case 0x216: /* movshdup */
 3317:             if (mod != 3) {
 3318:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3319:                 gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3320:             } else {
 3321:                 rm = (modrm & 7) | REX_B(s);
 3322:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
 3323:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
 3324:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
 3325:                             offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
 3326:             }
 3327:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
 3328:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
 3329:             gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
 3330:                         offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
 3331:             break;
 3332:         case 0x178:
 3333:         case 0x378:
 3334:             {
 3335:                 int bit_index, field_length;
 3336: 
 3337:                 if (b1 == 1 && reg != 0)
 3338:                     goto illegal_op;
 3339:                 field_length = ldub_code(s->pc++) & 0x3F;
 3340:                 bit_index = ldub_code(s->pc++) & 0x3F;
 3341:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
 3342:                     offsetof(CPUX86State,xmm_regs[reg]));
 3343:                 if (b1 == 1)
 3344:                     gen_helper_extrq_i(cpu_ptr0, tcg_const_i32(bit_index),
 3345:                         tcg_const_i32(field_length));
 3346:                 else
 3347:                     gen_helper_insertq_i(cpu_ptr0, tcg_const_i32(bit_index),
 3348:                         tcg_const_i32(field_length));
 3349:             }
 3350:             break;
 3351:         case 0x7e: /* movd ea, mm */
 3352: #ifdef TARGET_X86_64
 3353:             if (s->dflag == 2) {
 3354:                 tcg_gen_ld_i64(cpu_T[0], cpu_env, 
 3355:                                offsetof(CPUX86State,fpregs[reg].mmx));
 3356:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
 3357:             } else
 3358: #endif
 3359:             {
 3360:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
 3361:                                  offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
 3362:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
 3363:             }
 3364:             break;
 3365:         case 0x17e: /* movd ea, xmm */
 3366: #ifdef TARGET_X86_64
 3367:             if (s->dflag == 2) {
 3368:                 tcg_gen_ld_i64(cpu_T[0], cpu_env, 
 3369:                                offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3370:                 gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
 3371:             } else
 3372: #endif
 3373:             {
 3374:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
 3375:                                  offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
 3376:                 gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
 3377:             }
 3378:             break;
 3379:         case 0x27e: /* movq xmm, ea */
 3380:             if (mod != 3) {
 3381:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3382:                 gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3383:             } else {
 3384:                 rm = (modrm & 7) | REX_B(s);
 3385:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
 3386:                             offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
 3387:             }
 3388:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
 3389:             break;
 3390:         case 0x7f: /* movq ea, mm */
 3391:             if (mod != 3) {
 3392:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3393:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx));
 3394:             } else {
 3395:                 rm = (modrm & 7);
 3396:                 gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
 3397:                             offsetof(CPUX86State,fpregs[reg].mmx));
 3398:             }
 3399:             break;
 3400:         case 0x011: /* movups */
 3401:         case 0x111: /* movupd */
 3402:         case 0x029: /* movaps */
 3403:         case 0x129: /* movapd */
 3404:         case 0x17f: /* movdqa ea, xmm */
 3405:         case 0x27f: /* movdqu ea, xmm */
 3406:             if (mod != 3) {
 3407:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3408:                 gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg]));
 3409:             } else {
 3410:                 rm = (modrm & 7) | REX_B(s);
 3411:                 gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
 3412:                             offsetof(CPUX86State,xmm_regs[reg]));
 3413:             }
 3414:             break;
 3415:         case 0x211: /* movss ea, xmm */
 3416:             if (mod != 3) {
 3417:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3418:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
 3419:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
 3420:             } else {
 3421:                 rm = (modrm & 7) | REX_B(s);
 3422:                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
 3423:                             offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
 3424:             }
 3425:             break;
 3426:         case 0x311: /* movsd ea, xmm */
 3427:             if (mod != 3) {
 3428:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3429:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3430:             } else {
 3431:                 rm = (modrm & 7) | REX_B(s);
 3432:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
 3433:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3434:             }
 3435:             break;
 3436:         case 0x013: /* movlps */
 3437:         case 0x113: /* movlpd */
 3438:             if (mod != 3) {
 3439:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3440:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3441:             } else {
 3442:                 goto illegal_op;
 3443:             }
 3444:             break;
 3445:         case 0x017: /* movhps */
 3446:         case 0x117: /* movhpd */
 3447:             if (mod != 3) {
 3448:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3449:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
 3450:             } else {
 3451:                 goto illegal_op;
 3452:             }
 3453:             break;
 3454:         case 0x71: /* shift mm, im */
 3455:         case 0x72:
 3456:         case 0x73:
 3457:         case 0x171: /* shift xmm, im */
 3458:         case 0x172:
 3459:         case 0x173:
 3460:             if (b1 >= 2) {
 3461: 	        goto illegal_op;
 3462:             }
 3463:             val = ldub_code(s->pc++);
 3464:             if (is_xmm) {
 3465:                 gen_op_movl_T0_im(val);
 3466:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
 3467:                 gen_op_movl_T0_0();
 3468:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));
 3469:                 op1_offset = offsetof(CPUX86State,xmm_t0);
 3470:             } else {
 3471:                 gen_op_movl_T0_im(val);
 3472:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));
 3473:                 gen_op_movl_T0_0();
 3474:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));
 3475:                 op1_offset = offsetof(CPUX86State,mmx_t0);
 3476:             }
 3477:             sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
 3478:             if (!sse_op2)
 3479:                 goto illegal_op;
 3480:             if (is_xmm) {
 3481:                 rm = (modrm & 7) | REX_B(s);
 3482:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
 3483:             } else {
 3484:                 rm = (modrm & 7);
 3485:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
 3486:             }
 3487:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
 3488:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);
 3489:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
 3490:             break;
 3491:         case 0x050: /* movmskps */
 3492:             rm = (modrm & 7) | REX_B(s);
 3493:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
 3494:                              offsetof(CPUX86State,xmm_regs[rm]));
 3495:             gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0);
 3496:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 3497:             gen_op_mov_reg_T0(OT_LONG, reg);
 3498:             break;
 3499:         case 0x150: /* movmskpd */
 3500:             rm = (modrm & 7) | REX_B(s);
 3501:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, 
 3502:                              offsetof(CPUX86State,xmm_regs[rm]));
 3503:             gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0);
 3504:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 3505:             gen_op_mov_reg_T0(OT_LONG, reg);
 3506:             break;
 3507:         case 0x02a: /* cvtpi2ps */
 3508:         case 0x12a: /* cvtpi2pd */
 3509:             gen_helper_enter_mmx();
 3510:             if (mod != 3) {
 3511:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3512:                 op2_offset = offsetof(CPUX86State,mmx_t0);
 3513:                 gen_ldq_env_A0(s->mem_index, op2_offset);
 3514:             } else {
 3515:                 rm = (modrm & 7);
 3516:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
 3517:             }
 3518:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
 3519:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 3520:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 3521:             switch(b >> 8) {
 3522:             case 0x0:
 3523:                 gen_helper_cvtpi2ps(cpu_ptr0, cpu_ptr1);
 3524:                 break;
 3525:             default:
 3526:             case 0x1:
 3527:                 gen_helper_cvtpi2pd(cpu_ptr0, cpu_ptr1);
 3528:                 break;
 3529:             }
 3530:             break;
 3531:         case 0x22a: /* cvtsi2ss */
 3532:         case 0x32a: /* cvtsi2sd */
 3533:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
 3534:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 3535:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
 3536:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 3537:             sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)];
 3538:             if (ot == OT_LONG) {
 3539:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 3540:                 ((void (*)(TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_tmp2_i32);
 3541:             } else {
 3542:                 ((void (*)(TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_T[0]);
 3543:             }
 3544:             break;
 3545:         case 0x02c: /* cvttps2pi */
 3546:         case 0x12c: /* cvttpd2pi */
 3547:         case 0x02d: /* cvtps2pi */
 3548:         case 0x12d: /* cvtpd2pi */
 3549:             gen_helper_enter_mmx();
 3550:             if (mod != 3) {
 3551:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3552:                 op2_offset = offsetof(CPUX86State,xmm_t0);
 3553:                 gen_ldo_env_A0(s->mem_index, op2_offset);
 3554:             } else {
 3555:                 rm = (modrm & 7) | REX_B(s);
 3556:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
 3557:             }
 3558:             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
 3559:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 3560:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 3561:             switch(b) {
 3562:             case 0x02c:
 3563:                 gen_helper_cvttps2pi(cpu_ptr0, cpu_ptr1);
 3564:                 break;
 3565:             case 0x12c:
 3566:                 gen_helper_cvttpd2pi(cpu_ptr0, cpu_ptr1);
 3567:                 break;
 3568:             case 0x02d:
 3569:                 gen_helper_cvtps2pi(cpu_ptr0, cpu_ptr1);
 3570:                 break;
 3571:             case 0x12d:
 3572:                 gen_helper_cvtpd2pi(cpu_ptr0, cpu_ptr1);
 3573:                 break;
 3574:             }
 3575:             break;
 3576:         case 0x22c: /* cvttss2si */
 3577:         case 0x32c: /* cvttsd2si */
 3578:         case 0x22d: /* cvtss2si */
 3579:         case 0x32d: /* cvtsd2si */
 3580:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
 3581:             if (mod != 3) {
 3582:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3583:                 if ((b >> 8) & 1) {
 3584:                     gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
 3585:                 } else {
 3586:                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 3587:                     tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
 3588:                 }
 3589:                 op2_offset = offsetof(CPUX86State,xmm_t0);
 3590:             } else {
 3591:                 rm = (modrm & 7) | REX_B(s);
 3592:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
 3593:             }
 3594:             sse_op2 = sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
 3595:                                     (b & 1) * 4];
 3596:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);
 3597:             if (ot == OT_LONG) {
 3598:                 ((void (*)(TCGv_i32, TCGv_ptr))sse_op2)(cpu_tmp2_i32, cpu_ptr0);
 3599:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 3600:             } else {
 3601:                 ((void (*)(TCGv, TCGv_ptr))sse_op2)(cpu_T[0], cpu_ptr0);
 3602:             }
 3603:             gen_op_mov_reg_T0(ot, reg);
 3604:             break;
 3605:         case 0xc4: /* pinsrw */
 3606:         case 0x1c4:
 3607:             s->rip_offset = 1;
 3608:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 3609:             val = ldub_code(s->pc++);
 3610:             if (b1) {
 3611:                 val &= 7;
 3612:                 tcg_gen_st16_tl(cpu_T[0], cpu_env,
 3613:                                 offsetof(CPUX86State,xmm_regs[reg].XMM_W(val)));
 3614:             } else {
 3615:                 val &= 3;
 3616:                 tcg_gen_st16_tl(cpu_T[0], cpu_env,
 3617:                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
 3618:             }
 3619:             break;
 3620:         case 0xc5: /* pextrw */
 3621:         case 0x1c5:
 3622:             if (mod != 3)
 3623:                 goto illegal_op;
 3624:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
 3625:             val = ldub_code(s->pc++);
 3626:             if (b1) {
 3627:                 val &= 7;
 3628:                 rm = (modrm & 7) | REX_B(s);
 3629:                 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
 3630:                                  offsetof(CPUX86State,xmm_regs[rm].XMM_W(val)));
 3631:             } else {
 3632:                 val &= 3;
 3633:                 rm = (modrm & 7);
 3634:                 tcg_gen_ld16u_tl(cpu_T[0], cpu_env,
 3635:                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
 3636:             }
 3637:             reg = ((modrm >> 3) & 7) | rex_r;
 3638:             gen_op_mov_reg_T0(ot, reg);
 3639:             break;
 3640:         case 0x1d6: /* movq ea, xmm */
 3641:             if (mod != 3) {
 3642:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3643:                 gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3644:             } else {
 3645:                 rm = (modrm & 7) | REX_B(s);
 3646:                 gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
 3647:                             offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
 3648:                 gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
 3649:             }
 3650:             break;
 3651:         case 0x2d6: /* movq2dq */
 3652:             gen_helper_enter_mmx();
 3653:             rm = (modrm & 7);
 3654:             gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
 3655:                         offsetof(CPUX86State,fpregs[rm].mmx));
 3656:             gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
 3657:             break;
 3658:         case 0x3d6: /* movdq2q */
 3659:             gen_helper_enter_mmx();
 3660:             rm = (modrm & 7) | REX_B(s);
 3661:             gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
 3662:                         offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
 3663:             break;
 3664:         case 0xd7: /* pmovmskb */
 3665:         case 0x1d7:
 3666:             if (mod != 3)
 3667:                 goto illegal_op;
 3668:             if (b1) {
 3669:                 rm = (modrm & 7) | REX_B(s);
 3670:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));
 3671:                 gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_ptr0);
 3672:             } else {
 3673:                 rm = (modrm & 7);
 3674:                 tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));
 3675:                 gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_ptr0);
 3676:             }
 3677:             tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 3678:             reg = ((modrm >> 3) & 7) | rex_r;
 3679:             gen_op_mov_reg_T0(OT_LONG, reg);
 3680:             break;
 3681:         case 0x138:
 3682:             if (s->prefix & PREFIX_REPNZ)
 3683:                 goto crc32;
 3684:         case 0x038:
 3685:             b = modrm;
 3686:             modrm = ldub_code(s->pc++);
 3687:             rm = modrm & 7;
 3688:             reg = ((modrm >> 3) & 7) | rex_r;
 3689:             mod = (modrm >> 6) & 3;
 3690:             if (b1 >= 2) {
 3691:                 goto illegal_op;
 3692:             }
 3693: 
 3694:             sse_op2 = sse_op_table6[b].op[b1];
 3695:             if (!sse_op2)
 3696:                 goto illegal_op;
 3697:             if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
 3698:                 goto illegal_op;
 3699: 
 3700:             if (b1) {
 3701:                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
 3702:                 if (mod == 3) {
 3703:                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
 3704:                 } else {
 3705:                     op2_offset = offsetof(CPUX86State,xmm_t0);
 3706:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3707:                     switch (b) {
 3708:                     case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
 3709:                     case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
 3710:                     case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
 3711:                         gen_ldq_env_A0(s->mem_index, op2_offset +
 3712:                                         offsetof(XMMReg, XMM_Q(0)));
 3713:                         break;
 3714:                     case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
 3715:                     case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
 3716:                         tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
 3717:                                           (s->mem_index >> 2) - 1);
 3718:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
 3719:                         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
 3720:                                         offsetof(XMMReg, XMM_L(0)));
 3721:                         break;
 3722:                     case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
 3723:                         tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0,
 3724:                                           (s->mem_index >> 2) - 1);
 3725:                         tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
 3726:                                         offsetof(XMMReg, XMM_W(0)));
 3727:                         break;
 3728:                     case 0x2a:            /* movntqda */
 3729:                         gen_ldo_env_A0(s->mem_index, op1_offset);
 3730:                         return;
 3731:                     default:
 3732:                         gen_ldo_env_A0(s->mem_index, op2_offset);
 3733:                     }
 3734:                 }
 3735:             } else {
 3736:                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
 3737:                 if (mod == 3) {
 3738:                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
 3739:                 } else {
 3740:                     op2_offset = offsetof(CPUX86State,mmx_t0);
 3741:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3742:                     gen_ldq_env_A0(s->mem_index, op2_offset);
 3743:                 }
 3744:             }
 3745:             if (sse_op2 == SSE_SPECIAL)
 3746:                 goto illegal_op;
 3747: 
 3748:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 3749:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 3750:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
 3751: 
 3752:             if (b == 0x17)
 3753:                 s->cc_op = CC_OP_EFLAGS;
 3754:             break;
 3755:         case 0x338: /* crc32 */
 3756:         crc32:
 3757:             b = modrm;
 3758:             modrm = ldub_code(s->pc++);
 3759:             reg = ((modrm >> 3) & 7) | rex_r;
 3760: 
 3761:             if (b != 0xf0 && b != 0xf1)
 3762:                 goto illegal_op;
 3763:             if (!(s->cpuid_ext_features & CPUID_EXT_SSE42))
 3764:                 goto illegal_op;
 3765: 
 3766:             if (b == 0xf0)
 3767:                 ot = OT_BYTE;
 3768:             else if (b == 0xf1 && s->dflag != 2)
 3769:                 if (s->prefix & PREFIX_DATA)
 3770:                     ot = OT_WORD;
 3771:                 else
 3772:                     ot = OT_LONG;
 3773:             else
 3774:                 ot = OT_QUAD;
 3775: 
 3776:             gen_op_mov_TN_reg(OT_LONG, 0, reg);
 3777:             tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 3778:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 3779:             gen_helper_crc32(cpu_T[0], cpu_tmp2_i32,
 3780:                              cpu_T[0], tcg_const_i32(8 << ot));
 3781: 
 3782:             ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
 3783:             gen_op_mov_reg_T0(ot, reg);
 3784:             break;
 3785:         case 0x03a:
 3786:         case 0x13a:
 3787:             b = modrm;
 3788:             modrm = ldub_code(s->pc++);
 3789:             rm = modrm & 7;
 3790:             reg = ((modrm >> 3) & 7) | rex_r;
 3791:             mod = (modrm >> 6) & 3;
 3792:             if (b1 >= 2) {
 3793:                 goto illegal_op;
 3794:             }
 3795: 
 3796:             sse_op2 = sse_op_table7[b].op[b1];
 3797:             if (!sse_op2)
 3798:                 goto illegal_op;
 3799:             if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
 3800:                 goto illegal_op;
 3801: 
 3802:             if (sse_op2 == SSE_SPECIAL) {
 3803:                 ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
 3804:                 rm = (modrm & 7) | REX_B(s);
 3805:                 if (mod != 3)
 3806:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3807:                 reg = ((modrm >> 3) & 7) | rex_r;
 3808:                 val = ldub_code(s->pc++);
 3809:                 switch (b) {
 3810:                 case 0x14: /* pextrb */
 3811:                     tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
 3812:                                             xmm_regs[reg].XMM_B(val & 15)));
 3813:                     if (mod == 3)
 3814:                         gen_op_mov_reg_T0(ot, rm);
 3815:                     else
 3816:                         tcg_gen_qemu_st8(cpu_T[0], cpu_A0,
 3817:                                         (s->mem_index >> 2) - 1);
 3818:                     break;
 3819:                 case 0x15: /* pextrw */
 3820:                     tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
 3821:                                             xmm_regs[reg].XMM_W(val & 7)));
 3822:                     if (mod == 3)
 3823:                         gen_op_mov_reg_T0(ot, rm);
 3824:                     else
 3825:                         tcg_gen_qemu_st16(cpu_T[0], cpu_A0,
 3826:                                         (s->mem_index >> 2) - 1);
 3827:                     break;
 3828:                 case 0x16:
 3829:                     if (ot == OT_LONG) { /* pextrd */
 3830:                         tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
 3831:                                         offsetof(CPUX86State,
 3832:                                                 xmm_regs[reg].XMM_L(val & 3)));
 3833:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 3834:                         if (mod == 3)
 3835:                             gen_op_mov_reg_v(ot, rm, cpu_T[0]);
 3836:                         else
 3837:                             tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
 3838:                                             (s->mem_index >> 2) - 1);
 3839:                     } else { /* pextrq */
 3840: #ifdef TARGET_X86_64
 3841:                         tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,
 3842:                                         offsetof(CPUX86State,
 3843:                                                 xmm_regs[reg].XMM_Q(val & 1)));
 3844:                         if (mod == 3)
 3845:                             gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64);
 3846:                         else
 3847:                             tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0,
 3848:                                             (s->mem_index >> 2) - 1);
 3849: #else
 3850:                         goto illegal_op;
 3851: #endif
 3852:                     }
 3853:                     break;
 3854:                 case 0x17: /* extractps */
 3855:                     tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
 3856:                                             xmm_regs[reg].XMM_L(val & 3)));
 3857:                     if (mod == 3)
 3858:                         gen_op_mov_reg_T0(ot, rm);
 3859:                     else
 3860:                         tcg_gen_qemu_st32(cpu_T[0], cpu_A0,
 3861:                                         (s->mem_index >> 2) - 1);
 3862:                     break;
 3863:                 case 0x20: /* pinsrb */
 3864:                     if (mod == 3)
 3865:                         gen_op_mov_TN_reg(OT_LONG, 0, rm);
 3866:                     else
 3867:                         tcg_gen_qemu_ld8u(cpu_tmp0, cpu_A0,
 3868:                                         (s->mem_index >> 2) - 1);
 3869:                     tcg_gen_st8_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State,
 3870:                                             xmm_regs[reg].XMM_B(val & 15)));
 3871:                     break;
 3872:                 case 0x21: /* insertps */
 3873:                     if (mod == 3) {
 3874:                         tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,
 3875:                                         offsetof(CPUX86State,xmm_regs[rm]
 3876:                                                 .XMM_L((val >> 6) & 3)));
 3877:                     } else {
 3878:                         tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
 3879:                                         (s->mem_index >> 2) - 1);
 3880:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
 3881:                     }
 3882:                     tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
 3883:                                     offsetof(CPUX86State,xmm_regs[reg]
 3884:                                             .XMM_L((val >> 4) & 3)));
 3885:                     if ((val >> 0) & 1)
 3886:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
 3887:                                         cpu_env, offsetof(CPUX86State,
 3888:                                                 xmm_regs[reg].XMM_L(0)));
 3889:                     if ((val >> 1) & 1)
 3890:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
 3891:                                         cpu_env, offsetof(CPUX86State,
 3892:                                                 xmm_regs[reg].XMM_L(1)));
 3893:                     if ((val >> 2) & 1)
 3894:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
 3895:                                         cpu_env, offsetof(CPUX86State,
 3896:                                                 xmm_regs[reg].XMM_L(2)));
 3897:                     if ((val >> 3) & 1)
 3898:                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
 3899:                                         cpu_env, offsetof(CPUX86State,
 3900:                                                 xmm_regs[reg].XMM_L(3)));
 3901:                     break;
 3902:                 case 0x22:
 3903:                     if (ot == OT_LONG) { /* pinsrd */
 3904:                         if (mod == 3)
 3905:                             gen_op_mov_v_reg(ot, cpu_tmp0, rm);
 3906:                         else
 3907:                             tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0,
 3908:                                             (s->mem_index >> 2) - 1);
 3909:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0);
 3910:                         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
 3911:                                         offsetof(CPUX86State,
 3912:                                                 xmm_regs[reg].XMM_L(val & 3)));
 3913:                     } else { /* pinsrq */
 3914: #ifdef TARGET_X86_64
 3915:                         if (mod == 3)
 3916:                             gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
 3917:                         else
 3918:                             tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0,
 3919:                                             (s->mem_index >> 2) - 1);
 3920:                         tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
 3921:                                         offsetof(CPUX86State,
 3922:                                                 xmm_regs[reg].XMM_Q(val & 1)));
 3923: #else
 3924:                         goto illegal_op;
 3925: #endif
 3926:                     }
 3927:                     break;
 3928:                 }
 3929:                 return;
 3930:             }
 3931: 
 3932:             if (b1) {
 3933:                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
 3934:                 if (mod == 3) {
 3935:                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
 3936:                 } else {
 3937:                     op2_offset = offsetof(CPUX86State,xmm_t0);
 3938:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3939:                     gen_ldo_env_A0(s->mem_index, op2_offset);
 3940:                 }
 3941:             } else {
 3942:                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
 3943:                 if (mod == 3) {
 3944:                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
 3945:                 } else {
 3946:                     op2_offset = offsetof(CPUX86State,mmx_t0);
 3947:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3948:                     gen_ldq_env_A0(s->mem_index, op2_offset);
 3949:                 }
 3950:             }
 3951:             val = ldub_code(s->pc++);
 3952: 
 3953:             if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
 3954:                 s->cc_op = CC_OP_EFLAGS;
 3955: 
 3956:                 if (s->dflag == 2)
 3957:                     /* The helper must use entire 64-bit gp registers */
 3958:                     val |= 1 << 8;
 3959:             }
 3960: 
 3961:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 3962:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 3963:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
 3964:             break;
 3965:         default:
 3966:             goto illegal_op;
 3967:         }
 3968:     } else {
 3969:         /* generic MMX or SSE operation */
 3970:         switch(b) {
 3971:         case 0x70: /* pshufx insn */
 3972:         case 0xc6: /* pshufx insn */
 3973:         case 0xc2: /* compare insns */
 3974:             s->rip_offset = 1;
 3975:             break;
 3976:         default:
 3977:             break;
 3978:         }
 3979:         if (is_xmm) {
 3980:             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
 3981:             if (mod != 3) {
 3982:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 3983:                 op2_offset = offsetof(CPUX86State,xmm_t0);
 3984:                 if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
 3985:                                 b == 0xc2)) {
 3986:                     /* specific case for SSE single instructions */
 3987:                     if (b1 == 2) {
 3988:                         /* 32 bit access */
 3989:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 3990:                         tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));
 3991:                     } else {
 3992:                         /* 64 bit access */
 3993:                         gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0)));
 3994:                     }
 3995:                 } else {
 3996:                     gen_ldo_env_A0(s->mem_index, op2_offset);
 3997:                 }
 3998:             } else {
 3999:                 rm = (modrm & 7) | REX_B(s);
 4000:                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
 4001:             }
 4002:         } else {
 4003:             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
 4004:             if (mod != 3) {
 4005:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4006:                 op2_offset = offsetof(CPUX86State,mmx_t0);
 4007:                 gen_ldq_env_A0(s->mem_index, op2_offset);
 4008:             } else {
 4009:                 rm = (modrm & 7);
 4010:                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
 4011:             }
 4012:         }
 4013:         switch(b) {
 4014:         case 0x0f: /* 3DNow! data insns */
 4015:             if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW))
 4016:                 goto illegal_op;
 4017:             val = ldub_code(s->pc++);
 4018:             sse_op2 = sse_op_table5[val];
 4019:             if (!sse_op2)
 4020:                 goto illegal_op;
 4021:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 4022:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 4023:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
 4024:             break;
 4025:         case 0x70: /* pshufx insn */
 4026:         case 0xc6: /* pshufx insn */
 4027:             val = ldub_code(s->pc++);
 4028:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 4029:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 4030:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv_i32))sse_op2)(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));
 4031:             break;
 4032:         case 0xc2:
 4033:             /* compare insns */
 4034:             val = ldub_code(s->pc++);
 4035:             if (val >= 8)
 4036:                 goto illegal_op;
 4037:             sse_op2 = sse_op_table4[val][b1];
 4038:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 4039:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 4040:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
 4041:             break;
 4042:         case 0xf7:
 4043:             /* maskmov : we must prepare A0 */
 4044:             if (mod != 3)
 4045:                 goto illegal_op;
 4046: #ifdef TARGET_X86_64
 4047:             if (s->aflag == 2) {
 4048:                 gen_op_movq_A0_reg(R_EDI);
 4049:             } else
 4050: #endif
 4051:             {
 4052:                 gen_op_movl_A0_reg(R_EDI);
 4053:                 if (s->aflag == 0)
 4054:                     gen_op_andl_A0_ffff();
 4055:             }
 4056:             gen_add_A0_ds_seg(s);
 4057: 
 4058:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 4059:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 4060:             ((void (*)(TCGv_ptr, TCGv_ptr, TCGv))sse_op2)(cpu_ptr0, cpu_ptr1, cpu_A0);
 4061:             break;
 4062:         default:
 4063:             tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
 4064:             tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
 4065:             ((void (*)(TCGv_ptr, TCGv_ptr))sse_op2)(cpu_ptr0, cpu_ptr1);
 4066:             break;
 4067:         }
 4068:         if (b == 0x2e || b == 0x2f) {
 4069:             s->cc_op = CC_OP_EFLAGS;
 4070:         }
 4071:     }
 4072: }
 4073: 
 4074: /* convert one instruction. s->is_jmp is set if the translation must
 4075:    be stopped. Return the next pc value */
 4076: static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 4077: {
 4078:     int b, prefixes, aflag, dflag;
 4079:     int shift, ot;
 4080:     int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
 4081:     target_ulong next_eip, tval;
 4082:     int rex_w, rex_r;
 4083: 
 4084:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
 4085:         tcg_gen_debug_insn_start(pc_start);
 4086:     s->pc = pc_start;
 4087:     prefixes = 0;
 4088:     aflag = s->code32;
 4089:     dflag = s->code32;
 4090:     s->override = -1;
 4091:     rex_w = -1;
 4092:     rex_r = 0;
 4093: #ifdef TARGET_X86_64
 4094:     s->rex_x = 0;
 4095:     s->rex_b = 0;
 4096:     x86_64_hregs = 0;
 4097: #endif
 4098:     s->rip_offset = 0; /* for relative ip address */
 4099:  next_byte:
 4100:     b = ldub_code(s->pc);
 4101:     s->pc++;
 4102:     /* check prefixes */
 4103: #ifdef TARGET_X86_64
 4104:     if (CODE64(s)) {
 4105:         switch (b) {
 4106:         case 0xf3:
 4107:             prefixes |= PREFIX_REPZ;
 4108:             goto next_byte;
 4109:         case 0xf2:
 4110:             prefixes |= PREFIX_REPNZ;
 4111:             goto next_byte;
 4112:         case 0xf0:
 4113:             prefixes |= PREFIX_LOCK;
 4114:             goto next_byte;
 4115:         case 0x2e:
 4116:             s->override = R_CS;
 4117:             goto next_byte;
 4118:         case 0x36:
 4119:             s->override = R_SS;
 4120:             goto next_byte;
 4121:         case 0x3e:
 4122:             s->override = R_DS;
 4123:             goto next_byte;
 4124:         case 0x26:
 4125:             s->override = R_ES;
 4126:             goto next_byte;
 4127:         case 0x64:
 4128:             s->override = R_FS;
 4129:             goto next_byte;
 4130:         case 0x65:
 4131:             s->override = R_GS;
 4132:             goto next_byte;
 4133:         case 0x66:
 4134:             prefixes |= PREFIX_DATA;
 4135:             goto next_byte;
 4136:         case 0x67:
 4137:             prefixes |= PREFIX_ADR;
 4138:             goto next_byte;
 4139:         case 0x40 ... 0x4f:
 4140:             /* REX prefix */
 4141:             rex_w = (b >> 3) & 1;
 4142:             rex_r = (b & 0x4) << 1;
 4143:             s->rex_x = (b & 0x2) << 2;
 4144:             REX_B(s) = (b & 0x1) << 3;
 4145:             x86_64_hregs = 1; /* select uniform byte register addressing */
 4146:             goto next_byte;
 4147:         }
 4148:         if (rex_w == 1) {
 4149:             /* 0x66 is ignored if rex.w is set */
 4150:             dflag = 2;
 4151:         } else {
 4152:             if (prefixes & PREFIX_DATA)
 4153:                 dflag ^= 1;
 4154:         }
 4155:         if (!(prefixes & PREFIX_ADR))
 4156:             aflag = 2;
 4157:     } else
 4158: #endif
 4159:     {
 4160:         switch (b) {
 4161:         case 0xf3:
 4162:             prefixes |= PREFIX_REPZ;
 4163:             goto next_byte;
 4164:         case 0xf2:
 4165:             prefixes |= PREFIX_REPNZ;
 4166:             goto next_byte;
 4167:         case 0xf0:
 4168:             prefixes |= PREFIX_LOCK;
 4169:             goto next_byte;
 4170:         case 0x2e:
 4171:             s->override = R_CS;
 4172:             goto next_byte;
 4173:         case 0x36:
 4174:             s->override = R_SS;
 4175:             goto next_byte;
 4176:         case 0x3e:
 4177:             s->override = R_DS;
 4178:             goto next_byte;
 4179:         case 0x26:
 4180:             s->override = R_ES;
 4181:             goto next_byte;
 4182:         case 0x64:
 4183:             s->override = R_FS;
 4184:             goto next_byte;
 4185:         case 0x65:
 4186:             s->override = R_GS;
 4187:             goto next_byte;
 4188:         case 0x66:
 4189:             prefixes |= PREFIX_DATA;
 4190:             goto next_byte;
 4191:         case 0x67:
 4192:             prefixes |= PREFIX_ADR;
 4193:             goto next_byte;
 4194:         }
 4195:         if (prefixes & PREFIX_DATA)
 4196:             dflag ^= 1;
 4197:         if (prefixes & PREFIX_ADR)
 4198:             aflag ^= 1;
 4199:     }
 4200: 
 4201:     s->prefix = prefixes;
 4202:     s->aflag = aflag;
 4203:     s->dflag = dflag;
 4204: 
 4205:     /* lock generation */
 4206:     if (prefixes & PREFIX_LOCK)
 4207:         gen_helper_lock();
 4208: 
 4209:     /* now check op code */
 4210:  reswitch:
 4211:     switch(b) {
 4212:     case 0x0f:
 4213:         /**************************/
 4214:         /* extended op code */
 4215:         b = ldub_code(s->pc++) | 0x100;
 4216:         goto reswitch;
 4217: 
 4218:         /**************************/
 4219:         /* arith & logic */
 4220:     case 0x00 ... 0x05:
 4221:     case 0x08 ... 0x0d:
 4222:     case 0x10 ... 0x15:
 4223:     case 0x18 ... 0x1d:
 4224:     case 0x20 ... 0x25:
 4225:     case 0x28 ... 0x2d:
 4226:     case 0x30 ... 0x35:
 4227:     case 0x38 ... 0x3d:
 4228:         {
 4229:             int op, f, val;
 4230:             op = (b >> 3) & 7;
 4231:             f = (b >> 1) & 3;
 4232: 
 4233:             if ((b & 1) == 0)
 4234:                 ot = OT_BYTE;
 4235:             else
 4236:                 ot = dflag + OT_WORD;
 4237: 
 4238:             switch(f) {
 4239:             case 0: /* OP Ev, Gv */
 4240:                 modrm = ldub_code(s->pc++);
 4241:                 reg = ((modrm >> 3) & 7) | rex_r;
 4242:                 mod = (modrm >> 6) & 3;
 4243:                 rm = (modrm & 7) | REX_B(s);
 4244:                 if (mod != 3) {
 4245:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4246:                     opreg = OR_TMP0;
 4247:                 } else if (op == OP_XORL && rm == reg) {
 4248:                 xor_zero:
 4249:                     /* xor reg, reg optimisation */
 4250:                     gen_op_movl_T0_0();
 4251:                     s->cc_op = CC_OP_LOGICB + ot;
 4252:                     gen_op_mov_reg_T0(ot, reg);
 4253:                     gen_op_update1_cc();
 4254:                     break;
 4255:                 } else {
 4256:                     opreg = rm;
 4257:                 }
 4258:                 gen_op_mov_TN_reg(ot, 1, reg);
 4259:                 gen_op(s, op, ot, opreg);
 4260:                 break;
 4261:             case 1: /* OP Gv, Ev */
 4262:                 modrm = ldub_code(s->pc++);
 4263:                 mod = (modrm >> 6) & 3;
 4264:                 reg = ((modrm >> 3) & 7) | rex_r;
 4265:                 rm = (modrm & 7) | REX_B(s);
 4266:                 if (mod != 3) {
 4267:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4268:                     gen_op_ld_T1_A0(ot + s->mem_index);
 4269:                 } else if (op == OP_XORL && rm == reg) {
 4270:                     goto xor_zero;
 4271:                 } else {
 4272:                     gen_op_mov_TN_reg(ot, 1, rm);
 4273:                 }
 4274:                 gen_op(s, op, ot, reg);
 4275:                 break;
 4276:             case 2: /* OP A, Iv */
 4277:                 val = insn_get(s, ot);
 4278:                 gen_op_movl_T1_im(val);
 4279:                 gen_op(s, op, ot, OR_EAX);
 4280:                 break;
 4281:             }
 4282:         }
 4283:         break;
 4284: 
 4285:     case 0x82:
 4286:         if (CODE64(s))
 4287:             goto illegal_op;
 4288:     case 0x80: /* GRP1 */
 4289:     case 0x81:
 4290:     case 0x83:
 4291:         {
 4292:             int val;
 4293: 
 4294:             if ((b & 1) == 0)
 4295:                 ot = OT_BYTE;
 4296:             else
 4297:                 ot = dflag + OT_WORD;
 4298: 
 4299:             modrm = ldub_code(s->pc++);
 4300:             mod = (modrm >> 6) & 3;
 4301:             rm = (modrm & 7) | REX_B(s);
 4302:             op = (modrm >> 3) & 7;
 4303: 
 4304:             if (mod != 3) {
 4305:                 if (b == 0x83)
 4306:                     s->rip_offset = 1;
 4307:                 else
 4308:                     s->rip_offset = insn_const_size(ot);
 4309:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4310:                 opreg = OR_TMP0;
 4311:             } else {
 4312:                 opreg = rm;
 4313:             }
 4314: 
 4315:             switch(b) {
 4316:             default:
 4317:             case 0x80:
 4318:             case 0x81:
 4319:             case 0x82:
 4320:                 val = insn_get(s, ot);
 4321:                 break;
 4322:             case 0x83:
 4323:                 val = (int8_t)insn_get(s, OT_BYTE);
 4324:                 break;
 4325:             }
 4326:             gen_op_movl_T1_im(val);
 4327:             gen_op(s, op, ot, opreg);
 4328:         }
 4329:         break;
 4330: 
 4331:         /**************************/
 4332:         /* inc, dec, and other misc arith */
 4333:     case 0x40 ... 0x47: /* inc Gv */
 4334:         ot = dflag ? OT_LONG : OT_WORD;
 4335:         gen_inc(s, ot, OR_EAX + (b & 7), 1);
 4336:         break;
 4337:     case 0x48 ... 0x4f: /* dec Gv */
 4338:         ot = dflag ? OT_LONG : OT_WORD;
 4339:         gen_inc(s, ot, OR_EAX + (b & 7), -1);
 4340:         break;
 4341:     case 0xf6: /* GRP3 */
 4342:     case 0xf7:
 4343:         if ((b & 1) == 0)
 4344:             ot = OT_BYTE;
 4345:         else
 4346:             ot = dflag + OT_WORD;
 4347: 
 4348:         modrm = ldub_code(s->pc++);
 4349:         mod = (modrm >> 6) & 3;
 4350:         rm = (modrm & 7) | REX_B(s);
 4351:         op = (modrm >> 3) & 7;
 4352:         if (mod != 3) {
 4353:             if (op == 0)
 4354:                 s->rip_offset = insn_const_size(ot);
 4355:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4356:             gen_op_ld_T0_A0(ot + s->mem_index);
 4357:         } else {
 4358:             gen_op_mov_TN_reg(ot, 0, rm);
 4359:         }
 4360: 
 4361:         switch(op) {
 4362:         case 0: /* test */
 4363:             val = insn_get(s, ot);
 4364:             gen_op_movl_T1_im(val);
 4365:             gen_op_testl_T0_T1_cc();
 4366:             s->cc_op = CC_OP_LOGICB + ot;
 4367:             break;
 4368:         case 2: /* not */
 4369:             tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
 4370:             if (mod != 3) {
 4371:                 gen_op_st_T0_A0(ot + s->mem_index);
 4372:             } else {
 4373:                 gen_op_mov_reg_T0(ot, rm);
 4374:             }
 4375:             break;
 4376:         case 3: /* neg */
 4377:             tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
 4378:             if (mod != 3) {
 4379:                 gen_op_st_T0_A0(ot + s->mem_index);
 4380:             } else {
 4381:                 gen_op_mov_reg_T0(ot, rm);
 4382:             }
 4383:             gen_op_update_neg_cc();
 4384:             s->cc_op = CC_OP_SUBB + ot;
 4385:             break;
 4386:         case 4: /* mul */
 4387:             switch(ot) {
 4388:             case OT_BYTE:
 4389:                 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
 4390:                 tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
 4391:                 tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]);
 4392:                 /* XXX: use 32 bit mul which could be faster */
 4393:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4394:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
 4395:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4396:                 tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00);
 4397:                 s->cc_op = CC_OP_MULB;
 4398:                 break;
 4399:             case OT_WORD:
 4400:                 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
 4401:                 tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
 4402:                 tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]);
 4403:                 /* XXX: use 32 bit mul which could be faster */
 4404:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4405:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
 4406:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4407:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
 4408:                 gen_op_mov_reg_T0(OT_WORD, R_EDX);
 4409:                 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
 4410:                 s->cc_op = CC_OP_MULW;
 4411:                 break;
 4412:             default:
 4413:             case OT_LONG:
 4414: #ifdef TARGET_X86_64
 4415:                 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
 4416:                 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
 4417:                 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
 4418:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4419:                 gen_op_mov_reg_T0(OT_LONG, R_EAX);
 4420:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4421:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
 4422:                 gen_op_mov_reg_T0(OT_LONG, R_EDX);
 4423:                 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
 4424: #else
 4425:                 {
 4426:                     TCGv_i64 t0, t1;
 4427:                     t0 = tcg_temp_new_i64();
 4428:                     t1 = tcg_temp_new_i64();
 4429:                     gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
 4430:                     tcg_gen_extu_i32_i64(t0, cpu_T[0]);
 4431:                     tcg_gen_extu_i32_i64(t1, cpu_T[1]);
 4432:                     tcg_gen_mul_i64(t0, t0, t1);
 4433:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
 4434:                     gen_op_mov_reg_T0(OT_LONG, R_EAX);
 4435:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4436:                     tcg_gen_shri_i64(t0, t0, 32);
 4437:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
 4438:                     gen_op_mov_reg_T0(OT_LONG, R_EDX);
 4439:                     tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
 4440:                 }
 4441: #endif
 4442:                 s->cc_op = CC_OP_MULL;
 4443:                 break;
 4444: #ifdef TARGET_X86_64
 4445:             case OT_QUAD:
 4446:                 gen_helper_mulq_EAX_T0(cpu_T[0]);
 4447:                 s->cc_op = CC_OP_MULQ;
 4448:                 break;
 4449: #endif
 4450:             }
 4451:             break;
 4452:         case 5: /* imul */
 4453:             switch(ot) {
 4454:             case OT_BYTE:
 4455:                 gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX);
 4456:                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
 4457:                 tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]);
 4458:                 /* XXX: use 32 bit mul which could be faster */
 4459:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4460:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
 4461:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4462:                 tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]);
 4463:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4464:                 s->cc_op = CC_OP_MULB;
 4465:                 break;
 4466:             case OT_WORD:
 4467:                 gen_op_mov_TN_reg(OT_WORD, 1, R_EAX);
 4468:                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
 4469:                 tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
 4470:                 /* XXX: use 32 bit mul which could be faster */
 4471:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4472:                 gen_op_mov_reg_T0(OT_WORD, R_EAX);
 4473:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4474:                 tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
 4475:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4476:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16);
 4477:                 gen_op_mov_reg_T0(OT_WORD, R_EDX);
 4478:                 s->cc_op = CC_OP_MULW;
 4479:                 break;
 4480:             default:
 4481:             case OT_LONG:
 4482: #ifdef TARGET_X86_64
 4483:                 gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
 4484:                 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
 4485:                 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
 4486:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4487:                 gen_op_mov_reg_T0(OT_LONG, R_EAX);
 4488:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4489:                 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
 4490:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4491:                 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
 4492:                 gen_op_mov_reg_T0(OT_LONG, R_EDX);
 4493: #else
 4494:                 {
 4495:                     TCGv_i64 t0, t1;
 4496:                     t0 = tcg_temp_new_i64();
 4497:                     t1 = tcg_temp_new_i64();
 4498:                     gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
 4499:                     tcg_gen_ext_i32_i64(t0, cpu_T[0]);
 4500:                     tcg_gen_ext_i32_i64(t1, cpu_T[1]);
 4501:                     tcg_gen_mul_i64(t0, t0, t1);
 4502:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
 4503:                     gen_op_mov_reg_T0(OT_LONG, R_EAX);
 4504:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4505:                     tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
 4506:                     tcg_gen_shri_i64(t0, t0, 32);
 4507:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
 4508:                     gen_op_mov_reg_T0(OT_LONG, R_EDX);
 4509:                     tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4510:                 }
 4511: #endif
 4512:                 s->cc_op = CC_OP_MULL;
 4513:                 break;
 4514: #ifdef TARGET_X86_64
 4515:             case OT_QUAD:
 4516:                 gen_helper_imulq_EAX_T0(cpu_T[0]);
 4517:                 s->cc_op = CC_OP_MULQ;
 4518:                 break;
 4519: #endif
 4520:             }
 4521:             break;
 4522:         case 6: /* div */
 4523:             switch(ot) {
 4524:             case OT_BYTE:
 4525:                 gen_jmp_im(pc_start - s->cs_base);
 4526:                 gen_helper_divb_AL(cpu_T[0]);
 4527:                 break;
 4528:             case OT_WORD:
 4529:                 gen_jmp_im(pc_start - s->cs_base);
 4530:                 gen_helper_divw_AX(cpu_T[0]);
 4531:                 break;
 4532:             default:
 4533:             case OT_LONG:
 4534:                 gen_jmp_im(pc_start - s->cs_base);
 4535:                 gen_helper_divl_EAX(cpu_T[0]);
 4536:                 break;
 4537: #ifdef TARGET_X86_64
 4538:             case OT_QUAD:
 4539:                 gen_jmp_im(pc_start - s->cs_base);
 4540:                 gen_helper_divq_EAX(cpu_T[0]);
 4541:                 break;
 4542: #endif
 4543:             }
 4544:             break;
 4545:         case 7: /* idiv */
 4546:             switch(ot) {
 4547:             case OT_BYTE:
 4548:                 gen_jmp_im(pc_start - s->cs_base);
 4549:                 gen_helper_idivb_AL(cpu_T[0]);
 4550:                 break;
 4551:             case OT_WORD:
 4552:                 gen_jmp_im(pc_start - s->cs_base);
 4553:                 gen_helper_idivw_AX(cpu_T[0]);
 4554:                 break;
 4555:             default:
 4556:             case OT_LONG:
 4557:                 gen_jmp_im(pc_start - s->cs_base);
 4558:                 gen_helper_idivl_EAX(cpu_T[0]);
 4559:                 break;
 4560: #ifdef TARGET_X86_64
 4561:             case OT_QUAD:
 4562:                 gen_jmp_im(pc_start - s->cs_base);
 4563:                 gen_helper_idivq_EAX(cpu_T[0]);
 4564:                 break;
 4565: #endif
 4566:             }
 4567:             break;
 4568:         default:
 4569:             goto illegal_op;
 4570:         }
 4571:         break;
 4572: 
 4573:     case 0xfe: /* GRP4 */
 4574:     case 0xff: /* GRP5 */
 4575:         if ((b & 1) == 0)
 4576:             ot = OT_BYTE;
 4577:         else
 4578:             ot = dflag + OT_WORD;
 4579: 
 4580:         modrm = ldub_code(s->pc++);
 4581:         mod = (modrm >> 6) & 3;
 4582:         rm = (modrm & 7) | REX_B(s);
 4583:         op = (modrm >> 3) & 7;
 4584:         if (op >= 2 && b == 0xfe) {
 4585:             goto illegal_op;
 4586:         }
 4587:         if (CODE64(s)) {
 4588:             if (op == 2 || op == 4) {
 4589:                 /* operand size for jumps is 64 bit */
 4590:                 ot = OT_QUAD;
 4591:             } else if (op == 3 || op == 5) {
 4592:                 ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD;
 4593:             } else if (op == 6) {
 4594:                 /* default push size is 64 bit */
 4595:                 ot = dflag ? OT_QUAD : OT_WORD;
 4596:             }
 4597:         }
 4598:         if (mod != 3) {
 4599:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4600:             if (op >= 2 && op != 3 && op != 5)
 4601:                 gen_op_ld_T0_A0(ot + s->mem_index);
 4602:         } else {
 4603:             gen_op_mov_TN_reg(ot, 0, rm);
 4604:         }
 4605: 
 4606:         switch(op) {
 4607:         case 0: /* inc Ev */
 4608:             if (mod != 3)
 4609:                 opreg = OR_TMP0;
 4610:             else
 4611:                 opreg = rm;
 4612:             gen_inc(s, ot, opreg, 1);
 4613:             break;
 4614:         case 1: /* dec Ev */
 4615:             if (mod != 3)
 4616:                 opreg = OR_TMP0;
 4617:             else
 4618:                 opreg = rm;
 4619:             gen_inc(s, ot, opreg, -1);
 4620:             break;
 4621:         case 2: /* call Ev */
 4622:             /* XXX: optimize if memory (no 'and' is necessary) */
 4623:             if (s->dflag == 0)
 4624:                 gen_op_andl_T0_ffff();
 4625:             next_eip = s->pc - s->cs_base;
 4626:             gen_movtl_T1_im(next_eip);
 4627:             gen_push_T1(s);
 4628:             gen_op_jmp_T0();
 4629:             gen_eob(s);
 4630:             break;
 4631:         case 3: /* lcall Ev */
 4632:             gen_op_ld_T1_A0(ot + s->mem_index);
 4633:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
 4634:             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
 4635:         do_lcall:
 4636:             if (s->pe && !s->vm86) {
 4637:                 if (s->cc_op != CC_OP_DYNAMIC)
 4638:                     gen_op_set_cc_op(s->cc_op);
 4639:                 gen_jmp_im(pc_start - s->cs_base);
 4640:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 4641:                 gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1],
 4642:                                            tcg_const_i32(dflag), 
 4643:                                            tcg_const_i32(s->pc - pc_start));
 4644:             } else {
 4645:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 4646:                 gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1],
 4647:                                       tcg_const_i32(dflag), 
 4648:                                       tcg_const_i32(s->pc - s->cs_base));
 4649:             }
 4650:             gen_eob(s);
 4651:             break;
 4652:         case 4: /* jmp Ev */
 4653:             if (s->dflag == 0)
 4654:                 gen_op_andl_T0_ffff();
 4655:             gen_op_jmp_T0();
 4656:             gen_eob(s);
 4657:             break;
 4658:         case 5: /* ljmp Ev */
 4659:             gen_op_ld_T1_A0(ot + s->mem_index);
 4660:             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
 4661:             gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
 4662:         do_ljmp:
 4663:             if (s->pe && !s->vm86) {
 4664:                 if (s->cc_op != CC_OP_DYNAMIC)
 4665:                     gen_op_set_cc_op(s->cc_op);
 4666:                 gen_jmp_im(pc_start - s->cs_base);
 4667:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 4668:                 gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1],
 4669:                                           tcg_const_i32(s->pc - pc_start));
 4670:             } else {
 4671:                 gen_op_movl_seg_T0_vm(R_CS);
 4672:                 gen_op_movl_T0_T1();
 4673:                 gen_op_jmp_T0();
 4674:             }
 4675:             gen_eob(s);
 4676:             break;
 4677:         case 6: /* push Ev */
 4678:             gen_push_T0(s);
 4679:             break;
 4680:         default:
 4681:             goto illegal_op;
 4682:         }
 4683:         break;
 4684: 
 4685:     case 0x84: /* test Ev, Gv */
 4686:     case 0x85:
 4687:         if ((b & 1) == 0)
 4688:             ot = OT_BYTE;
 4689:         else
 4690:             ot = dflag + OT_WORD;
 4691: 
 4692:         modrm = ldub_code(s->pc++);
 4693:         reg = ((modrm >> 3) & 7) | rex_r;
 4694: 
 4695:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 4696:         gen_op_mov_TN_reg(ot, 1, reg);
 4697:         gen_op_testl_T0_T1_cc();
 4698:         s->cc_op = CC_OP_LOGICB + ot;
 4699:         break;
 4700: 
 4701:     case 0xa8: /* test eAX, Iv */
 4702:     case 0xa9:
 4703:         if ((b & 1) == 0)
 4704:             ot = OT_BYTE;
 4705:         else
 4706:             ot = dflag + OT_WORD;
 4707:         val = insn_get(s, ot);
 4708: 
 4709:         gen_op_mov_TN_reg(ot, 0, OR_EAX);
 4710:         gen_op_movl_T1_im(val);
 4711:         gen_op_testl_T0_T1_cc();
 4712:         s->cc_op = CC_OP_LOGICB + ot;
 4713:         break;
 4714: 
 4715:     case 0x98: /* CWDE/CBW */
 4716: #ifdef TARGET_X86_64
 4717:         if (dflag == 2) {
 4718:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
 4719:             tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
 4720:             gen_op_mov_reg_T0(OT_QUAD, R_EAX);
 4721:         } else
 4722: #endif
 4723:         if (dflag == 1) {
 4724:             gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
 4725:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
 4726:             gen_op_mov_reg_T0(OT_LONG, R_EAX);
 4727:         } else {
 4728:             gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX);
 4729:             tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
 4730:             gen_op_mov_reg_T0(OT_WORD, R_EAX);
 4731:         }
 4732:         break;
 4733:     case 0x99: /* CDQ/CWD */
 4734: #ifdef TARGET_X86_64
 4735:         if (dflag == 2) {
 4736:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
 4737:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63);
 4738:             gen_op_mov_reg_T0(OT_QUAD, R_EDX);
 4739:         } else
 4740: #endif
 4741:         if (dflag == 1) {
 4742:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
 4743:             tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
 4744:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31);
 4745:             gen_op_mov_reg_T0(OT_LONG, R_EDX);
 4746:         } else {
 4747:             gen_op_mov_TN_reg(OT_WORD, 0, R_EAX);
 4748:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
 4749:             tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15);
 4750:             gen_op_mov_reg_T0(OT_WORD, R_EDX);
 4751:         }
 4752:         break;
 4753:     case 0x1af: /* imul Gv, Ev */
 4754:     case 0x69: /* imul Gv, Ev, I */
 4755:     case 0x6b:
 4756:         ot = dflag + OT_WORD;
 4757:         modrm = ldub_code(s->pc++);
 4758:         reg = ((modrm >> 3) & 7) | rex_r;
 4759:         if (b == 0x69)
 4760:             s->rip_offset = insn_const_size(ot);
 4761:         else if (b == 0x6b)
 4762:             s->rip_offset = 1;
 4763:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 4764:         if (b == 0x69) {
 4765:             val = insn_get(s, ot);
 4766:             gen_op_movl_T1_im(val);
 4767:         } else if (b == 0x6b) {
 4768:             val = (int8_t)insn_get(s, OT_BYTE);
 4769:             gen_op_movl_T1_im(val);
 4770:         } else {
 4771:             gen_op_mov_TN_reg(ot, 1, reg);
 4772:         }
 4773: 
 4774: #ifdef TARGET_X86_64
 4775:         if (ot == OT_QUAD) {
 4776:             gen_helper_imulq_T0_T1(cpu_T[0], cpu_T[0], cpu_T[1]);
 4777:         } else
 4778: #endif
 4779:         if (ot == OT_LONG) {
 4780: #ifdef TARGET_X86_64
 4781:                 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
 4782:                 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
 4783:                 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4784:                 tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4785:                 tcg_gen_ext32s_tl(cpu_tmp0, cpu_T[0]);
 4786:                 tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4787: #else
 4788:                 {
 4789:                     TCGv_i64 t0, t1;
 4790:                     t0 = tcg_temp_new_i64();
 4791:                     t1 = tcg_temp_new_i64();
 4792:                     tcg_gen_ext_i32_i64(t0, cpu_T[0]);
 4793:                     tcg_gen_ext_i32_i64(t1, cpu_T[1]);
 4794:                     tcg_gen_mul_i64(t0, t0, t1);
 4795:                     tcg_gen_trunc_i64_i32(cpu_T[0], t0);
 4796:                     tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4797:                     tcg_gen_sari_tl(cpu_tmp0, cpu_T[0], 31);
 4798:                     tcg_gen_shri_i64(t0, t0, 32);
 4799:                     tcg_gen_trunc_i64_i32(cpu_T[1], t0);
 4800:                     tcg_gen_sub_tl(cpu_cc_src, cpu_T[1], cpu_tmp0);
 4801:                 }
 4802: #endif
 4803:         } else {
 4804:             tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
 4805:             tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]);
 4806:             /* XXX: use 32 bit mul which could be faster */
 4807:             tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
 4808:             tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
 4809:             tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]);
 4810:             tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0);
 4811:         }
 4812:         gen_op_mov_reg_T0(ot, reg);
 4813:         s->cc_op = CC_OP_MULB + ot;
 4814:         break;
 4815:     case 0x1c0:
 4816:     case 0x1c1: /* xadd Ev, Gv */
 4817:         if ((b & 1) == 0)
 4818:             ot = OT_BYTE;
 4819:         else
 4820:             ot = dflag + OT_WORD;
 4821:         modrm = ldub_code(s->pc++);
 4822:         reg = ((modrm >> 3) & 7) | rex_r;
 4823:         mod = (modrm >> 6) & 3;
 4824:         if (mod == 3) {
 4825:             rm = (modrm & 7) | REX_B(s);
 4826:             gen_op_mov_TN_reg(ot, 0, reg);
 4827:             gen_op_mov_TN_reg(ot, 1, rm);
 4828:             gen_op_addl_T0_T1();
 4829:             gen_op_mov_reg_T1(ot, reg);
 4830:             gen_op_mov_reg_T0(ot, rm);
 4831:         } else {
 4832:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4833:             gen_op_mov_TN_reg(ot, 0, reg);
 4834:             gen_op_ld_T1_A0(ot + s->mem_index);
 4835:             gen_op_addl_T0_T1();
 4836:             gen_op_st_T0_A0(ot + s->mem_index);
 4837:             gen_op_mov_reg_T1(ot, reg);
 4838:         }
 4839:         gen_op_update2_cc();
 4840:         s->cc_op = CC_OP_ADDB + ot;
 4841:         break;
 4842:     case 0x1b0:
 4843:     case 0x1b1: /* cmpxchg Ev, Gv */
 4844:         {
 4845:             int label1, label2;
 4846:             TCGv t0, t1, t2, a0;
 4847: 
 4848:             if ((b & 1) == 0)
 4849:                 ot = OT_BYTE;
 4850:             else
 4851:                 ot = dflag + OT_WORD;
 4852:             modrm = ldub_code(s->pc++);
 4853:             reg = ((modrm >> 3) & 7) | rex_r;
 4854:             mod = (modrm >> 6) & 3;
 4855:             t0 = tcg_temp_local_new();
 4856:             t1 = tcg_temp_local_new();
 4857:             t2 = tcg_temp_local_new();
 4858:             a0 = tcg_temp_local_new();
 4859:             gen_op_mov_v_reg(ot, t1, reg);
 4860:             if (mod == 3) {
 4861:                 rm = (modrm & 7) | REX_B(s);
 4862:                 gen_op_mov_v_reg(ot, t0, rm);
 4863:             } else {
 4864:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4865:                 tcg_gen_mov_tl(a0, cpu_A0);
 4866:                 gen_op_ld_v(ot + s->mem_index, t0, a0);
 4867:                 rm = 0; /* avoid warning */
 4868:             }
 4869:             label1 = gen_new_label();
 4870:             tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
 4871:             gen_extu(ot, t2);
 4872:             tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
 4873:             label2 = gen_new_label();
 4874:             if (mod == 3) {
 4875:                 gen_op_mov_reg_v(ot, R_EAX, t0);
 4876:                 tcg_gen_br(label2);
 4877:                 gen_set_label(label1);
 4878:                 gen_op_mov_reg_v(ot, rm, t1);
 4879:             } else {
 4880:                 /* perform no-op store cycle like physical cpu; must be
 4881:                    before changing accumulator to ensure idempotency if
 4882:                    the store faults and the instruction is restarted */
 4883:                 gen_op_st_v(ot + s->mem_index, t0, a0);
 4884:                 gen_op_mov_reg_v(ot, R_EAX, t0);
 4885:                 tcg_gen_br(label2);
 4886:                 gen_set_label(label1);
 4887:                 gen_op_st_v(ot + s->mem_index, t1, a0);
 4888:             }
 4889:             gen_set_label(label2);
 4890:             tcg_gen_mov_tl(cpu_cc_src, t0);
 4891:             tcg_gen_mov_tl(cpu_cc_dst, t2);
 4892:             s->cc_op = CC_OP_SUBB + ot;
 4893:             tcg_temp_free(t0);
 4894:             tcg_temp_free(t1);
 4895:             tcg_temp_free(t2);
 4896:             tcg_temp_free(a0);
 4897:         }
 4898:         break;
 4899:     case 0x1c7: /* cmpxchg8b */
 4900:         modrm = ldub_code(s->pc++);
 4901:         mod = (modrm >> 6) & 3;
 4902:         if ((mod == 3) || ((modrm & 0x38) != 0x8))
 4903:             goto illegal_op;
 4904: #ifdef TARGET_X86_64
 4905:         if (dflag == 2) {
 4906:             if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
 4907:                 goto illegal_op;
 4908:             gen_jmp_im(pc_start - s->cs_base);
 4909:             if (s->cc_op != CC_OP_DYNAMIC)
 4910:                 gen_op_set_cc_op(s->cc_op);
 4911:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4912:             gen_helper_cmpxchg16b(cpu_A0);
 4913:         } else
 4914: #endif        
 4915:         {
 4916:             if (!(s->cpuid_features & CPUID_CX8))
 4917:                 goto illegal_op;
 4918:             gen_jmp_im(pc_start - s->cs_base);
 4919:             if (s->cc_op != CC_OP_DYNAMIC)
 4920:                 gen_op_set_cc_op(s->cc_op);
 4921:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 4922:             gen_helper_cmpxchg8b(cpu_A0);
 4923:         }
 4924:         s->cc_op = CC_OP_EFLAGS;
 4925:         break;
 4926: 
 4927:         /**************************/
 4928:         /* push/pop */
 4929:     case 0x50 ... 0x57: /* push */
 4930:         gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
 4931:         gen_push_T0(s);
 4932:         break;
 4933:     case 0x58 ... 0x5f: /* pop */
 4934:         if (CODE64(s)) {
 4935:             ot = dflag ? OT_QUAD : OT_WORD;
 4936:         } else {
 4937:             ot = dflag + OT_WORD;
 4938:         }
 4939:         gen_pop_T0(s);
 4940:         /* NOTE: order is important for pop %sp */
 4941:         gen_pop_update(s);
 4942:         gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
 4943:         break;
 4944:     case 0x60: /* pusha */
 4945:         if (CODE64(s))
 4946:             goto illegal_op;
 4947:         gen_pusha(s);
 4948:         break;
 4949:     case 0x61: /* popa */
 4950:         if (CODE64(s))
 4951:             goto illegal_op;
 4952:         gen_popa(s);
 4953:         break;
 4954:     case 0x68: /* push Iv */
 4955:     case 0x6a:
 4956:         if (CODE64(s)) {
 4957:             ot = dflag ? OT_QUAD : OT_WORD;
 4958:         } else {
 4959:             ot = dflag + OT_WORD;
 4960:         }
 4961:         if (b == 0x68)
 4962:             val = insn_get(s, ot);
 4963:         else
 4964:             val = (int8_t)insn_get(s, OT_BYTE);
 4965:         gen_op_movl_T0_im(val);
 4966:         gen_push_T0(s);
 4967:         break;
 4968:     case 0x8f: /* pop Ev */
 4969:         if (CODE64(s)) {
 4970:             ot = dflag ? OT_QUAD : OT_WORD;
 4971:         } else {
 4972:             ot = dflag + OT_WORD;
 4973:         }
 4974:         modrm = ldub_code(s->pc++);
 4975:         mod = (modrm >> 6) & 3;
 4976:         gen_pop_T0(s);
 4977:         if (mod == 3) {
 4978:             /* NOTE: order is important for pop %sp */
 4979:             gen_pop_update(s);
 4980:             rm = (modrm & 7) | REX_B(s);
 4981:             gen_op_mov_reg_T0(ot, rm);
 4982:         } else {
 4983:             /* NOTE: order is important too for MMU exceptions */
 4984:             s->popl_esp_hack = 1 << ot;
 4985:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
 4986:             s->popl_esp_hack = 0;
 4987:             gen_pop_update(s);
 4988:         }
 4989:         break;
 4990:     case 0xc8: /* enter */
 4991:         {
 4992:             int level;
 4993:             val = lduw_code(s->pc);
 4994:             s->pc += 2;
 4995:             level = ldub_code(s->pc++);
 4996:             gen_enter(s, val, level);
 4997:         }
 4998:         break;
 4999:     case 0xc9: /* leave */
 5000:         /* XXX: exception not precise (ESP is updated before potential exception) */
 5001:         if (CODE64(s)) {
 5002:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
 5003:             gen_op_mov_reg_T0(OT_QUAD, R_ESP);
 5004:         } else if (s->ss32) {
 5005:             gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
 5006:             gen_op_mov_reg_T0(OT_LONG, R_ESP);
 5007:         } else {
 5008:             gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
 5009:             gen_op_mov_reg_T0(OT_WORD, R_ESP);
 5010:         }
 5011:         gen_pop_T0(s);
 5012:         if (CODE64(s)) {
 5013:             ot = dflag ? OT_QUAD : OT_WORD;
 5014:         } else {
 5015:             ot = dflag + OT_WORD;
 5016:         }
 5017:         gen_op_mov_reg_T0(ot, R_EBP);
 5018:         gen_pop_update(s);
 5019:         break;
 5020:     case 0x06: /* push es */
 5021:     case 0x0e: /* push cs */
 5022:     case 0x16: /* push ss */
 5023:     case 0x1e: /* push ds */
 5024:         if (CODE64(s))
 5025:             goto illegal_op;
 5026:         gen_op_movl_T0_seg(b >> 3);
 5027:         gen_push_T0(s);
 5028:         break;
 5029:     case 0x1a0: /* push fs */
 5030:     case 0x1a8: /* push gs */
 5031:         gen_op_movl_T0_seg((b >> 3) & 7);
 5032:         gen_push_T0(s);
 5033:         break;
 5034:     case 0x07: /* pop es */
 5035:     case 0x17: /* pop ss */
 5036:     case 0x1f: /* pop ds */
 5037:         if (CODE64(s))
 5038:             goto illegal_op;
 5039:         reg = b >> 3;
 5040:         gen_pop_T0(s);
 5041:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
 5042:         gen_pop_update(s);
 5043:         if (reg == R_SS) {
 5044:             /* if reg == SS, inhibit interrupts/trace. */
 5045:             /* If several instructions disable interrupts, only the
 5046:                _first_ does it */
 5047:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
 5048:                 gen_helper_set_inhibit_irq();
 5049:             s->tf = 0;
 5050:         }
 5051:         if (s->is_jmp) {
 5052:             gen_jmp_im(s->pc - s->cs_base);
 5053:             gen_eob(s);
 5054:         }
 5055:         break;
 5056:     case 0x1a1: /* pop fs */
 5057:     case 0x1a9: /* pop gs */
 5058:         gen_pop_T0(s);
 5059:         gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
 5060:         gen_pop_update(s);
 5061:         if (s->is_jmp) {
 5062:             gen_jmp_im(s->pc - s->cs_base);
 5063:             gen_eob(s);
 5064:         }
 5065:         break;
 5066: 
 5067:         /**************************/
 5068:         /* mov */
 5069:     case 0x88:
 5070:     case 0x89: /* mov Gv, Ev */
 5071:         if ((b & 1) == 0)
 5072:             ot = OT_BYTE;
 5073:         else
 5074:             ot = dflag + OT_WORD;
 5075:         modrm = ldub_code(s->pc++);
 5076:         reg = ((modrm >> 3) & 7) | rex_r;
 5077: 
 5078:         /* generate a generic store */
 5079:         gen_ldst_modrm(s, modrm, ot, reg, 1);
 5080:         break;
 5081:     case 0xc6:
 5082:     case 0xc7: /* mov Ev, Iv */
 5083:         if ((b & 1) == 0)
 5084:             ot = OT_BYTE;
 5085:         else
 5086:             ot = dflag + OT_WORD;
 5087:         modrm = ldub_code(s->pc++);
 5088:         mod = (modrm >> 6) & 3;
 5089:         if (mod != 3) {
 5090:             s->rip_offset = insn_const_size(ot);
 5091:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5092:         }
 5093:         val = insn_get(s, ot);
 5094:         gen_op_movl_T0_im(val);
 5095:         if (mod != 3)
 5096:             gen_op_st_T0_A0(ot + s->mem_index);
 5097:         else
 5098:             gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
 5099:         break;
 5100:     case 0x8a:
 5101:     case 0x8b: /* mov Ev, Gv */
 5102:         if ((b & 1) == 0)
 5103:             ot = OT_BYTE;
 5104:         else
 5105:             ot = OT_WORD + dflag;
 5106:         modrm = ldub_code(s->pc++);
 5107:         reg = ((modrm >> 3) & 7) | rex_r;
 5108: 
 5109:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 5110:         gen_op_mov_reg_T0(ot, reg);
 5111:         break;
 5112:     case 0x8e: /* mov seg, Gv */
 5113:         modrm = ldub_code(s->pc++);
 5114:         reg = (modrm >> 3) & 7;
 5115:         if (reg >= 6 || reg == R_CS)
 5116:             goto illegal_op;
 5117:         gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 5118:         gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
 5119:         if (reg == R_SS) {
 5120:             /* if reg == SS, inhibit interrupts/trace */
 5121:             /* If several instructions disable interrupts, only the
 5122:                _first_ does it */
 5123:             if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
 5124:                 gen_helper_set_inhibit_irq();
 5125:             s->tf = 0;
 5126:         }
 5127:         if (s->is_jmp) {
 5128:             gen_jmp_im(s->pc - s->cs_base);
 5129:             gen_eob(s);
 5130:         }
 5131:         break;
 5132:     case 0x8c: /* mov Gv, seg */
 5133:         modrm = ldub_code(s->pc++);
 5134:         reg = (modrm >> 3) & 7;
 5135:         mod = (modrm >> 6) & 3;
 5136:         if (reg >= 6)
 5137:             goto illegal_op;
 5138:         gen_op_movl_T0_seg(reg);
 5139:         if (mod == 3)
 5140:             ot = OT_WORD + dflag;
 5141:         else
 5142:             ot = OT_WORD;
 5143:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
 5144:         break;
 5145: 
 5146:     case 0x1b6: /* movzbS Gv, Eb */
 5147:     case 0x1b7: /* movzwS Gv, Eb */
 5148:     case 0x1be: /* movsbS Gv, Eb */
 5149:     case 0x1bf: /* movswS Gv, Eb */
 5150:         {
 5151:             int d_ot;
 5152:             /* d_ot is the size of destination */
 5153:             d_ot = dflag + OT_WORD;
 5154:             /* ot is the size of source */
 5155:             ot = (b & 1) + OT_BYTE;
 5156:             modrm = ldub_code(s->pc++);
 5157:             reg = ((modrm >> 3) & 7) | rex_r;
 5158:             mod = (modrm >> 6) & 3;
 5159:             rm = (modrm & 7) | REX_B(s);
 5160: 
 5161:             if (mod == 3) {
 5162:                 gen_op_mov_TN_reg(ot, 0, rm);
 5163:                 switch(ot | (b & 8)) {
 5164:                 case OT_BYTE:
 5165:                     tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]);
 5166:                     break;
 5167:                 case OT_BYTE | 8:
 5168:                     tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
 5169:                     break;
 5170:                 case OT_WORD:
 5171:                     tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
 5172:                     break;
 5173:                 default:
 5174:                 case OT_WORD | 8:
 5175:                     tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
 5176:                     break;
 5177:                 }
 5178:                 gen_op_mov_reg_T0(d_ot, reg);
 5179:             } else {
 5180:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5181:                 if (b & 8) {
 5182:                     gen_op_lds_T0_A0(ot + s->mem_index);
 5183:                 } else {
 5184:                     gen_op_ldu_T0_A0(ot + s->mem_index);
 5185:                 }
 5186:                 gen_op_mov_reg_T0(d_ot, reg);
 5187:             }
 5188:         }
 5189:         break;
 5190: 
 5191:     case 0x8d: /* lea */
 5192:         ot = dflag + OT_WORD;
 5193:         modrm = ldub_code(s->pc++);
 5194:         mod = (modrm >> 6) & 3;
 5195:         if (mod == 3)
 5196:             goto illegal_op;
 5197:         reg = ((modrm >> 3) & 7) | rex_r;
 5198:         /* we must ensure that no segment is added */
 5199:         s->override = -1;
 5200:         val = s->addseg;
 5201:         s->addseg = 0;
 5202:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5203:         s->addseg = val;
 5204:         gen_op_mov_reg_A0(ot - OT_WORD, reg);
 5205:         break;
 5206: 
 5207:     case 0xa0: /* mov EAX, Ov */
 5208:     case 0xa1:
 5209:     case 0xa2: /* mov Ov, EAX */
 5210:     case 0xa3:
 5211:         {
 5212:             target_ulong offset_addr;
 5213: 
 5214:             if ((b & 1) == 0)
 5215:                 ot = OT_BYTE;
 5216:             else
 5217:                 ot = dflag + OT_WORD;
 5218: #ifdef TARGET_X86_64
 5219:             if (s->aflag == 2) {
 5220:                 offset_addr = ldq_code(s->pc);
 5221:                 s->pc += 8;
 5222:                 gen_op_movq_A0_im(offset_addr);
 5223:             } else
 5224: #endif
 5225:             {
 5226:                 if (s->aflag) {
 5227:                     offset_addr = insn_get(s, OT_LONG);
 5228:                 } else {
 5229:                     offset_addr = insn_get(s, OT_WORD);
 5230:                 }
 5231:                 gen_op_movl_A0_im(offset_addr);
 5232:             }
 5233:             gen_add_A0_ds_seg(s);
 5234:             if ((b & 2) == 0) {
 5235:                 gen_op_ld_T0_A0(ot + s->mem_index);
 5236:                 gen_op_mov_reg_T0(ot, R_EAX);
 5237:             } else {
 5238:                 gen_op_mov_TN_reg(ot, 0, R_EAX);
 5239:                 gen_op_st_T0_A0(ot + s->mem_index);
 5240:             }
 5241:         }
 5242:         break;
 5243:     case 0xd7: /* xlat */
 5244: #ifdef TARGET_X86_64
 5245:         if (s->aflag == 2) {
 5246:             gen_op_movq_A0_reg(R_EBX);
 5247:             gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX);
 5248:             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
 5249:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
 5250:         } else
 5251: #endif
 5252:         {
 5253:             gen_op_movl_A0_reg(R_EBX);
 5254:             gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
 5255:             tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff);
 5256:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]);
 5257:             if (s->aflag == 0)
 5258:                 gen_op_andl_A0_ffff();
 5259:             else
 5260:                 tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
 5261:         }
 5262:         gen_add_A0_ds_seg(s);
 5263:         gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
 5264:         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
 5265:         break;
 5266:     case 0xb0 ... 0xb7: /* mov R, Ib */
 5267:         val = insn_get(s, OT_BYTE);
 5268:         gen_op_movl_T0_im(val);
 5269:         gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
 5270:         break;
 5271:     case 0xb8 ... 0xbf: /* mov R, Iv */
 5272: #ifdef TARGET_X86_64
 5273:         if (dflag == 2) {
 5274:             uint64_t tmp;
 5275:             /* 64 bit case */
 5276:             tmp = ldq_code(s->pc);
 5277:             s->pc += 8;
 5278:             reg = (b & 7) | REX_B(s);
 5279:             gen_movtl_T0_im(tmp);
 5280:             gen_op_mov_reg_T0(OT_QUAD, reg);
 5281:         } else
 5282: #endif
 5283:         {
 5284:             ot = dflag ? OT_LONG : OT_WORD;
 5285:             val = insn_get(s, ot);
 5286:             reg = (b & 7) | REX_B(s);
 5287:             gen_op_movl_T0_im(val);
 5288:             gen_op_mov_reg_T0(ot, reg);
 5289:         }
 5290:         break;
 5291: 
 5292:     case 0x91 ... 0x97: /* xchg R, EAX */
 5293:     do_xchg_reg_eax:
 5294:         ot = dflag + OT_WORD;
 5295:         reg = (b & 7) | REX_B(s);
 5296:         rm = R_EAX;
 5297:         goto do_xchg_reg;
 5298:     case 0x86:
 5299:     case 0x87: /* xchg Ev, Gv */
 5300:         if ((b & 1) == 0)
 5301:             ot = OT_BYTE;
 5302:         else
 5303:             ot = dflag + OT_WORD;
 5304:         modrm = ldub_code(s->pc++);
 5305:         reg = ((modrm >> 3) & 7) | rex_r;
 5306:         mod = (modrm >> 6) & 3;
 5307:         if (mod == 3) {
 5308:             rm = (modrm & 7) | REX_B(s);
 5309:         do_xchg_reg:
 5310:             gen_op_mov_TN_reg(ot, 0, reg);
 5311:             gen_op_mov_TN_reg(ot, 1, rm);
 5312:             gen_op_mov_reg_T0(ot, rm);
 5313:             gen_op_mov_reg_T1(ot, reg);
 5314:         } else {
 5315:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5316:             gen_op_mov_TN_reg(ot, 0, reg);
 5317:             /* for xchg, lock is implicit */
 5318:             if (!(prefixes & PREFIX_LOCK))
 5319:                 gen_helper_lock();
 5320:             gen_op_ld_T1_A0(ot + s->mem_index);
 5321:             gen_op_st_T0_A0(ot + s->mem_index);
 5322:             if (!(prefixes & PREFIX_LOCK))
 5323:                 gen_helper_unlock();
 5324:             gen_op_mov_reg_T1(ot, reg);
 5325:         }
 5326:         break;
 5327:     case 0xc4: /* les Gv */
 5328:         if (CODE64(s))
 5329:             goto illegal_op;
 5330:         op = R_ES;
 5331:         goto do_lxx;
 5332:     case 0xc5: /* lds Gv */
 5333:         if (CODE64(s))
 5334:             goto illegal_op;
 5335:         op = R_DS;
 5336:         goto do_lxx;
 5337:     case 0x1b2: /* lss Gv */
 5338:         op = R_SS;
 5339:         goto do_lxx;
 5340:     case 0x1b4: /* lfs Gv */
 5341:         op = R_FS;
 5342:         goto do_lxx;
 5343:     case 0x1b5: /* lgs Gv */
 5344:         op = R_GS;
 5345:     do_lxx:
 5346:         ot = dflag ? OT_LONG : OT_WORD;
 5347:         modrm = ldub_code(s->pc++);
 5348:         reg = ((modrm >> 3) & 7) | rex_r;
 5349:         mod = (modrm >> 6) & 3;
 5350:         if (mod == 3)
 5351:             goto illegal_op;
 5352:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5353:         gen_op_ld_T1_A0(ot + s->mem_index);
 5354:         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
 5355:         /* load the segment first to handle exceptions properly */
 5356:         gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
 5357:         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
 5358:         /* then put the data */
 5359:         gen_op_mov_reg_T1(ot, reg);
 5360:         if (s->is_jmp) {
 5361:             gen_jmp_im(s->pc - s->cs_base);
 5362:             gen_eob(s);
 5363:         }
 5364:         break;
 5365: 
 5366:         /************************/
 5367:         /* shifts */
 5368:     case 0xc0:
 5369:     case 0xc1:
 5370:         /* shift Ev,Ib */
 5371:         shift = 2;
 5372:     grp2:
 5373:         {
 5374:             if ((b & 1) == 0)
 5375:                 ot = OT_BYTE;
 5376:             else
 5377:                 ot = dflag + OT_WORD;
 5378: 
 5379:             modrm = ldub_code(s->pc++);
 5380:             mod = (modrm >> 6) & 3;
 5381:             op = (modrm >> 3) & 7;
 5382: 
 5383:             if (mod != 3) {
 5384:                 if (shift == 2) {
 5385:                     s->rip_offset = 1;
 5386:                 }
 5387:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5388:                 opreg = OR_TMP0;
 5389:             } else {
 5390:                 opreg = (modrm & 7) | REX_B(s);
 5391:             }
 5392: 
 5393:             /* simpler op */
 5394:             if (shift == 0) {
 5395:                 gen_shift(s, op, ot, opreg, OR_ECX);
 5396:             } else {
 5397:                 if (shift == 2) {
 5398:                     shift = ldub_code(s->pc++);
 5399:                 }
 5400:                 gen_shifti(s, op, ot, opreg, shift);
 5401:             }
 5402:         }
 5403:         break;
 5404:     case 0xd0:
 5405:     case 0xd1:
 5406:         /* shift Ev,1 */
 5407:         shift = 1;
 5408:         goto grp2;
 5409:     case 0xd2:
 5410:     case 0xd3:
 5411:         /* shift Ev,cl */
 5412:         shift = 0;
 5413:         goto grp2;
 5414: 
 5415:     case 0x1a4: /* shld imm */
 5416:         op = 0;
 5417:         shift = 1;
 5418:         goto do_shiftd;
 5419:     case 0x1a5: /* shld cl */
 5420:         op = 0;
 5421:         shift = 0;
 5422:         goto do_shiftd;
 5423:     case 0x1ac: /* shrd imm */
 5424:         op = 1;
 5425:         shift = 1;
 5426:         goto do_shiftd;
 5427:     case 0x1ad: /* shrd cl */
 5428:         op = 1;
 5429:         shift = 0;
 5430:     do_shiftd:
 5431:         ot = dflag + OT_WORD;
 5432:         modrm = ldub_code(s->pc++);
 5433:         mod = (modrm >> 6) & 3;
 5434:         rm = (modrm & 7) | REX_B(s);
 5435:         reg = ((modrm >> 3) & 7) | rex_r;
 5436:         if (mod != 3) {
 5437:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5438:             opreg = OR_TMP0;
 5439:         } else {
 5440:             opreg = rm;
 5441:         }
 5442:         gen_op_mov_TN_reg(ot, 1, reg);
 5443: 
 5444:         if (shift) {
 5445:             val = ldub_code(s->pc++);
 5446:             tcg_gen_movi_tl(cpu_T3, val);
 5447:         } else {
 5448:             tcg_gen_mov_tl(cpu_T3, cpu_regs[R_ECX]);
 5449:         }
 5450:         gen_shiftd_rm_T1_T3(s, ot, opreg, op);
 5451:         break;
 5452: 
 5453:         /************************/
 5454:         /* floats */
 5455:     case 0xd8 ... 0xdf:
 5456:         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
 5457:             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
 5458:             /* XXX: what to do if illegal op ? */
 5459:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 5460:             break;
 5461:         }
 5462:         modrm = ldub_code(s->pc++);
 5463:         mod = (modrm >> 6) & 3;
 5464:         rm = modrm & 7;
 5465:         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
 5466:         if (mod != 3) {
 5467:             /* memory op */
 5468:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 5469:             switch(op) {
 5470:             case 0x00 ... 0x07: /* fxxxs */
 5471:             case 0x10 ... 0x17: /* fixxxl */
 5472:             case 0x20 ... 0x27: /* fxxxl */
 5473:             case 0x30 ... 0x37: /* fixxx */
 5474:                 {
 5475:                     int op1;
 5476:                     op1 = op & 7;
 5477: 
 5478:                     switch(op >> 4) {
 5479:                     case 0:
 5480:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 5481:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5482:                         gen_helper_flds_FT0(cpu_tmp2_i32);
 5483:                         break;
 5484:                     case 1:
 5485:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 5486:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5487:                         gen_helper_fildl_FT0(cpu_tmp2_i32);
 5488:                         break;
 5489:                     case 2:
 5490:                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
 5491:                                           (s->mem_index >> 2) - 1);
 5492:                         gen_helper_fldl_FT0(cpu_tmp1_i64);
 5493:                         break;
 5494:                     case 3:
 5495:                     default:
 5496:                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
 5497:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5498:                         gen_helper_fildl_FT0(cpu_tmp2_i32);
 5499:                         break;
 5500:                     }
 5501: 
 5502:                     gen_helper_fp_arith_ST0_FT0(op1);
 5503:                     if (op1 == 3) {
 5504:                         /* fcomp needs pop */
 5505:                         gen_helper_fpop();
 5506:                     }
 5507:                 }
 5508:                 break;
 5509:             case 0x08: /* flds */
 5510:             case 0x0a: /* fsts */
 5511:             case 0x0b: /* fstps */
 5512:             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
 5513:             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
 5514:             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
 5515:                 switch(op & 7) {
 5516:                 case 0:
 5517:                     switch(op >> 4) {
 5518:                     case 0:
 5519:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 5520:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5521:                         gen_helper_flds_ST0(cpu_tmp2_i32);
 5522:                         break;
 5523:                     case 1:
 5524:                         gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 5525:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5526:                         gen_helper_fildl_ST0(cpu_tmp2_i32);
 5527:                         break;
 5528:                     case 2:
 5529:                         tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
 5530:                                           (s->mem_index >> 2) - 1);
 5531:                         gen_helper_fldl_ST0(cpu_tmp1_i64);
 5532:                         break;
 5533:                     case 3:
 5534:                     default:
 5535:                         gen_op_lds_T0_A0(OT_WORD + s->mem_index);
 5536:                         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5537:                         gen_helper_fildl_ST0(cpu_tmp2_i32);
 5538:                         break;
 5539:                     }
 5540:                     break;
 5541:                 case 1:
 5542:                     /* XXX: the corresponding CPUID bit must be tested ! */
 5543:                     switch(op >> 4) {
 5544:                     case 1:
 5545:                         gen_helper_fisttl_ST0(cpu_tmp2_i32);
 5546:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5547:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
 5548:                         break;
 5549:                     case 2:
 5550:                         gen_helper_fisttll_ST0(cpu_tmp1_i64);
 5551:                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
 5552:                                           (s->mem_index >> 2) - 1);
 5553:                         break;
 5554:                     case 3:
 5555:                     default:
 5556:                         gen_helper_fistt_ST0(cpu_tmp2_i32);
 5557:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5558:                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
 5559:                         break;
 5560:                     }
 5561:                     gen_helper_fpop();
 5562:                     break;
 5563:                 default:
 5564:                     switch(op >> 4) {
 5565:                     case 0:
 5566:                         gen_helper_fsts_ST0(cpu_tmp2_i32);
 5567:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5568:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
 5569:                         break;
 5570:                     case 1:
 5571:                         gen_helper_fistl_ST0(cpu_tmp2_i32);
 5572:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5573:                         gen_op_st_T0_A0(OT_LONG + s->mem_index);
 5574:                         break;
 5575:                     case 2:
 5576:                         gen_helper_fstl_ST0(cpu_tmp1_i64);
 5577:                         tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
 5578:                                           (s->mem_index >> 2) - 1);
 5579:                         break;
 5580:                     case 3:
 5581:                     default:
 5582:                         gen_helper_fist_ST0(cpu_tmp2_i32);
 5583:                         tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5584:                         gen_op_st_T0_A0(OT_WORD + s->mem_index);
 5585:                         break;
 5586:                     }
 5587:                     if ((op & 7) == 3)
 5588:                         gen_helper_fpop();
 5589:                     break;
 5590:                 }
 5591:                 break;
 5592:             case 0x0c: /* fldenv mem */
 5593:                 if (s->cc_op != CC_OP_DYNAMIC)
 5594:                     gen_op_set_cc_op(s->cc_op);
 5595:                 gen_jmp_im(pc_start - s->cs_base);
 5596:                 gen_helper_fldenv(
 5597:                                    cpu_A0, tcg_const_i32(s->dflag));
 5598:                 break;
 5599:             case 0x0d: /* fldcw mem */
 5600:                 gen_op_ld_T0_A0(OT_WORD + s->mem_index);
 5601:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 5602:                 gen_helper_fldcw(cpu_tmp2_i32);
 5603:                 break;
 5604:             case 0x0e: /* fnstenv mem */
 5605:                 if (s->cc_op != CC_OP_DYNAMIC)
 5606:                     gen_op_set_cc_op(s->cc_op);
 5607:                 gen_jmp_im(pc_start - s->cs_base);
 5608:                 gen_helper_fstenv(cpu_A0, tcg_const_i32(s->dflag));
 5609:                 break;
 5610:             case 0x0f: /* fnstcw mem */
 5611:                 gen_helper_fnstcw(cpu_tmp2_i32);
 5612:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5613:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
 5614:                 break;
 5615:             case 0x1d: /* fldt mem */
 5616:                 if (s->cc_op != CC_OP_DYNAMIC)
 5617:                     gen_op_set_cc_op(s->cc_op);
 5618:                 gen_jmp_im(pc_start - s->cs_base);
 5619:                 gen_helper_fldt_ST0(cpu_A0);
 5620:                 break;
 5621:             case 0x1f: /* fstpt mem */
 5622:                 if (s->cc_op != CC_OP_DYNAMIC)
 5623:                     gen_op_set_cc_op(s->cc_op);
 5624:                 gen_jmp_im(pc_start - s->cs_base);
 5625:                 gen_helper_fstt_ST0(cpu_A0);
 5626:                 gen_helper_fpop();
 5627:                 break;
 5628:             case 0x2c: /* frstor mem */
 5629:                 if (s->cc_op != CC_OP_DYNAMIC)
 5630:                     gen_op_set_cc_op(s->cc_op);
 5631:                 gen_jmp_im(pc_start - s->cs_base);
 5632:                 gen_helper_frstor(cpu_A0, tcg_const_i32(s->dflag));
 5633:                 break;
 5634:             case 0x2e: /* fnsave mem */
 5635:                 if (s->cc_op != CC_OP_DYNAMIC)
 5636:                     gen_op_set_cc_op(s->cc_op);
 5637:                 gen_jmp_im(pc_start - s->cs_base);
 5638:                 gen_helper_fsave(cpu_A0, tcg_const_i32(s->dflag));
 5639:                 break;
 5640:             case 0x2f: /* fnstsw mem */
 5641:                 gen_helper_fnstsw(cpu_tmp2_i32);
 5642:                 tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5643:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
 5644:                 break;
 5645:             case 0x3c: /* fbld */
 5646:                 if (s->cc_op != CC_OP_DYNAMIC)
 5647:                     gen_op_set_cc_op(s->cc_op);
 5648:                 gen_jmp_im(pc_start - s->cs_base);
 5649:                 gen_helper_fbld_ST0(cpu_A0);
 5650:                 break;
 5651:             case 0x3e: /* fbstp */
 5652:                 if (s->cc_op != CC_OP_DYNAMIC)
 5653:                     gen_op_set_cc_op(s->cc_op);
 5654:                 gen_jmp_im(pc_start - s->cs_base);
 5655:                 gen_helper_fbst_ST0(cpu_A0);
 5656:                 gen_helper_fpop();
 5657:                 break;
 5658:             case 0x3d: /* fildll */
 5659:                 tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, 
 5660:                                   (s->mem_index >> 2) - 1);
 5661:                 gen_helper_fildll_ST0(cpu_tmp1_i64);
 5662:                 break;
 5663:             case 0x3f: /* fistpll */
 5664:                 gen_helper_fistll_ST0(cpu_tmp1_i64);
 5665:                 tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, 
 5666:                                   (s->mem_index >> 2) - 1);
 5667:                 gen_helper_fpop();
 5668:                 break;
 5669:             default:
 5670:                 goto illegal_op;
 5671:             }
 5672:         } else {
 5673:             /* register float ops */
 5674:             opreg = rm;
 5675: 
 5676:             switch(op) {
 5677:             case 0x08: /* fld sti */
 5678:                 gen_helper_fpush();
 5679:                 gen_helper_fmov_ST0_STN(tcg_const_i32((opreg + 1) & 7));
 5680:                 break;
 5681:             case 0x09: /* fxchg sti */
 5682:             case 0x29: /* fxchg4 sti, undocumented op */
 5683:             case 0x39: /* fxchg7 sti, undocumented op */
 5684:                 gen_helper_fxchg_ST0_STN(tcg_const_i32(opreg));
 5685:                 break;
 5686:             case 0x0a: /* grp d9/2 */
 5687:                 switch(rm) {
 5688:                 case 0: /* fnop */
 5689:                     /* check exceptions (FreeBSD FPU probe) */
 5690:                     if (s->cc_op != CC_OP_DYNAMIC)
 5691:                         gen_op_set_cc_op(s->cc_op);
 5692:                     gen_jmp_im(pc_start - s->cs_base);
 5693:                     gen_helper_fwait();
 5694:                     break;
 5695:                 default:
 5696:                     goto illegal_op;
 5697:                 }
 5698:                 break;
 5699:             case 0x0c: /* grp d9/4 */
 5700:                 switch(rm) {
 5701:                 case 0: /* fchs */
 5702:                     gen_helper_fchs_ST0();
 5703:                     break;
 5704:                 case 1: /* fabs */
 5705:                     gen_helper_fabs_ST0();
 5706:                     break;
 5707:                 case 4: /* ftst */
 5708:                     gen_helper_fldz_FT0();
 5709:                     gen_helper_fcom_ST0_FT0();
 5710:                     break;
 5711:                 case 5: /* fxam */
 5712:                     gen_helper_fxam_ST0();
 5713:                     break;
 5714:                 default:
 5715:                     goto illegal_op;
 5716:                 }
 5717:                 break;
 5718:             case 0x0d: /* grp d9/5 */
 5719:                 {
 5720:                     switch(rm) {
 5721:                     case 0:
 5722:                         gen_helper_fpush();
 5723:                         gen_helper_fld1_ST0();
 5724:                         break;
 5725:                     case 1:
 5726:                         gen_helper_fpush();
 5727:                         gen_helper_fldl2t_ST0();
 5728:                         break;
 5729:                     case 2:
 5730:                         gen_helper_fpush();
 5731:                         gen_helper_fldl2e_ST0();
 5732:                         break;
 5733:                     case 3:
 5734:                         gen_helper_fpush();
 5735:                         gen_helper_fldpi_ST0();
 5736:                         break;
 5737:                     case 4:
 5738:                         gen_helper_fpush();
 5739:                         gen_helper_fldlg2_ST0();
 5740:                         break;
 5741:                     case 5:
 5742:                         gen_helper_fpush();
 5743:                         gen_helper_fldln2_ST0();
 5744:                         break;
 5745:                     case 6:
 5746:                         gen_helper_fpush();
 5747:                         gen_helper_fldz_ST0();
 5748:                         break;
 5749:                     default:
 5750:                         goto illegal_op;
 5751:                     }
 5752:                 }
 5753:                 break;
 5754:             case 0x0e: /* grp d9/6 */
 5755:                 switch(rm) {
 5756:                 case 0: /* f2xm1 */
 5757:                     gen_helper_f2xm1();
 5758:                     break;
 5759:                 case 1: /* fyl2x */
 5760:                     gen_helper_fyl2x();
 5761:                     break;
 5762:                 case 2: /* fptan */
 5763:                     gen_helper_fptan();
 5764:                     break;
 5765:                 case 3: /* fpatan */
 5766:                     gen_helper_fpatan();
 5767:                     break;
 5768:                 case 4: /* fxtract */
 5769:                     gen_helper_fxtract();
 5770:                     break;
 5771:                 case 5: /* fprem1 */
 5772:                     gen_helper_fprem1();
 5773:                     break;
 5774:                 case 6: /* fdecstp */
 5775:                     gen_helper_fdecstp();
 5776:                     break;
 5777:                 default:
 5778:                 case 7: /* fincstp */
 5779:                     gen_helper_fincstp();
 5780:                     break;
 5781:                 }
 5782:                 break;
 5783:             case 0x0f: /* grp d9/7 */
 5784:                 switch(rm) {
 5785:                 case 0: /* fprem */
 5786:                     gen_helper_fprem();
 5787:                     break;
 5788:                 case 1: /* fyl2xp1 */
 5789:                     gen_helper_fyl2xp1();
 5790:                     break;
 5791:                 case 2: /* fsqrt */
 5792:                     gen_helper_fsqrt();
 5793:                     break;
 5794:                 case 3: /* fsincos */
 5795:                     gen_helper_fsincos();
 5796:                     break;
 5797:                 case 5: /* fscale */
 5798:                     gen_helper_fscale();
 5799:                     break;
 5800:                 case 4: /* frndint */
 5801:                     gen_helper_frndint();
 5802:                     break;
 5803:                 case 6: /* fsin */
 5804:                     gen_helper_fsin();
 5805:                     break;
 5806:                 default:
 5807:                 case 7: /* fcos */
 5808:                     gen_helper_fcos();
 5809:                     break;
 5810:                 }
 5811:                 break;
 5812:             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
 5813:             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
 5814:             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
 5815:                 {
 5816:                     int op1;
 5817: 
 5818:                     op1 = op & 7;
 5819:                     if (op >= 0x20) {
 5820:                         gen_helper_fp_arith_STN_ST0(op1, opreg);
 5821:                         if (op >= 0x30)
 5822:                             gen_helper_fpop();
 5823:                     } else {
 5824:                         gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5825:                         gen_helper_fp_arith_ST0_FT0(op1);
 5826:                     }
 5827:                 }
 5828:                 break;
 5829:             case 0x02: /* fcom */
 5830:             case 0x22: /* fcom2, undocumented op */
 5831:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5832:                 gen_helper_fcom_ST0_FT0();
 5833:                 break;
 5834:             case 0x03: /* fcomp */
 5835:             case 0x23: /* fcomp3, undocumented op */
 5836:             case 0x32: /* fcomp5, undocumented op */
 5837:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5838:                 gen_helper_fcom_ST0_FT0();
 5839:                 gen_helper_fpop();
 5840:                 break;
 5841:             case 0x15: /* da/5 */
 5842:                 switch(rm) {
 5843:                 case 1: /* fucompp */
 5844:                     gen_helper_fmov_FT0_STN(tcg_const_i32(1));
 5845:                     gen_helper_fucom_ST0_FT0();
 5846:                     gen_helper_fpop();
 5847:                     gen_helper_fpop();
 5848:                     break;
 5849:                 default:
 5850:                     goto illegal_op;
 5851:                 }
 5852:                 break;
 5853:             case 0x1c:
 5854:                 switch(rm) {
 5855:                 case 0: /* feni (287 only, just do nop here) */
 5856:                     break;
 5857:                 case 1: /* fdisi (287 only, just do nop here) */
 5858:                     break;
 5859:                 case 2: /* fclex */
 5860:                     gen_helper_fclex();
 5861:                     break;
 5862:                 case 3: /* fninit */
 5863:                     gen_helper_fninit();
 5864:                     break;
 5865:                 case 4: /* fsetpm (287 only, just do nop here) */
 5866:                     break;
 5867:                 default:
 5868:                     goto illegal_op;
 5869:                 }
 5870:                 break;
 5871:             case 0x1d: /* fucomi */
 5872:                 if (s->cc_op != CC_OP_DYNAMIC)
 5873:                     gen_op_set_cc_op(s->cc_op);
 5874:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5875:                 gen_helper_fucomi_ST0_FT0();
 5876:                 s->cc_op = CC_OP_EFLAGS;
 5877:                 break;
 5878:             case 0x1e: /* fcomi */
 5879:                 if (s->cc_op != CC_OP_DYNAMIC)
 5880:                     gen_op_set_cc_op(s->cc_op);
 5881:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5882:                 gen_helper_fcomi_ST0_FT0();
 5883:                 s->cc_op = CC_OP_EFLAGS;
 5884:                 break;
 5885:             case 0x28: /* ffree sti */
 5886:                 gen_helper_ffree_STN(tcg_const_i32(opreg));
 5887:                 break;
 5888:             case 0x2a: /* fst sti */
 5889:                 gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
 5890:                 break;
 5891:             case 0x2b: /* fstp sti */
 5892:             case 0x0b: /* fstp1 sti, undocumented op */
 5893:             case 0x3a: /* fstp8 sti, undocumented op */
 5894:             case 0x3b: /* fstp9 sti, undocumented op */
 5895:                 gen_helper_fmov_STN_ST0(tcg_const_i32(opreg));
 5896:                 gen_helper_fpop();
 5897:                 break;
 5898:             case 0x2c: /* fucom st(i) */
 5899:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5900:                 gen_helper_fucom_ST0_FT0();
 5901:                 break;
 5902:             case 0x2d: /* fucomp st(i) */
 5903:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5904:                 gen_helper_fucom_ST0_FT0();
 5905:                 gen_helper_fpop();
 5906:                 break;
 5907:             case 0x33: /* de/3 */
 5908:                 switch(rm) {
 5909:                 case 1: /* fcompp */
 5910:                     gen_helper_fmov_FT0_STN(tcg_const_i32(1));
 5911:                     gen_helper_fcom_ST0_FT0();
 5912:                     gen_helper_fpop();
 5913:                     gen_helper_fpop();
 5914:                     break;
 5915:                 default:
 5916:                     goto illegal_op;
 5917:                 }
 5918:                 break;
 5919:             case 0x38: /* ffreep sti, undocumented op */
 5920:                 gen_helper_ffree_STN(tcg_const_i32(opreg));
 5921:                 gen_helper_fpop();
 5922:                 break;
 5923:             case 0x3c: /* df/4 */
 5924:                 switch(rm) {
 5925:                 case 0:
 5926:                     gen_helper_fnstsw(cpu_tmp2_i32);
 5927:                     tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);
 5928:                     gen_op_mov_reg_T0(OT_WORD, R_EAX);
 5929:                     break;
 5930:                 default:
 5931:                     goto illegal_op;
 5932:                 }
 5933:                 break;
 5934:             case 0x3d: /* fucomip */
 5935:                 if (s->cc_op != CC_OP_DYNAMIC)
 5936:                     gen_op_set_cc_op(s->cc_op);
 5937:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5938:                 gen_helper_fucomi_ST0_FT0();
 5939:                 gen_helper_fpop();
 5940:                 s->cc_op = CC_OP_EFLAGS;
 5941:                 break;
 5942:             case 0x3e: /* fcomip */
 5943:                 if (s->cc_op != CC_OP_DYNAMIC)
 5944:                     gen_op_set_cc_op(s->cc_op);
 5945:                 gen_helper_fmov_FT0_STN(tcg_const_i32(opreg));
 5946:                 gen_helper_fcomi_ST0_FT0();
 5947:                 gen_helper_fpop();
 5948:                 s->cc_op = CC_OP_EFLAGS;
 5949:                 break;
 5950:             case 0x10 ... 0x13: /* fcmovxx */
 5951:             case 0x18 ... 0x1b:
 5952:                 {
 5953:                     int op1, l1;
 5954:                     static const uint8_t fcmov_cc[8] = {
 5955:                         (JCC_B << 1),
 5956:                         (JCC_Z << 1),
 5957:                         (JCC_BE << 1),
 5958:                         (JCC_P << 1),
 5959:                     };
 5960:                     op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
 5961:                     l1 = gen_new_label();
 5962:                     gen_jcc1(s, s->cc_op, op1, l1);
 5963:                     gen_helper_fmov_ST0_STN(tcg_const_i32(opreg));
 5964:                     gen_set_label(l1);
 5965:                 }
 5966:                 break;
 5967:             default:
 5968:                 goto illegal_op;
 5969:             }
 5970:         }
 5971:         break;
 5972:         /************************/
 5973:         /* string ops */
 5974: 
 5975:     case 0xa4: /* movsS */
 5976:     case 0xa5:
 5977:         if ((b & 1) == 0)
 5978:             ot = OT_BYTE;
 5979:         else
 5980:             ot = dflag + OT_WORD;
 5981: 
 5982:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 5983:             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 5984:         } else {
 5985:             gen_movs(s, ot);
 5986:         }
 5987:         break;
 5988: 
 5989:     case 0xaa: /* stosS */
 5990:     case 0xab:
 5991:         if ((b & 1) == 0)
 5992:             ot = OT_BYTE;
 5993:         else
 5994:             ot = dflag + OT_WORD;
 5995: 
 5996:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 5997:             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 5998:         } else {
 5999:             gen_stos(s, ot);
 6000:         }
 6001:         break;
 6002:     case 0xac: /* lodsS */
 6003:     case 0xad:
 6004:         if ((b & 1) == 0)
 6005:             ot = OT_BYTE;
 6006:         else
 6007:             ot = dflag + OT_WORD;
 6008:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 6009:             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 6010:         } else {
 6011:             gen_lods(s, ot);
 6012:         }
 6013:         break;
 6014:     case 0xae: /* scasS */
 6015:     case 0xaf:
 6016:         if ((b & 1) == 0)
 6017:             ot = OT_BYTE;
 6018:         else
 6019:             ot = dflag + OT_WORD;
 6020:         if (prefixes & PREFIX_REPNZ) {
 6021:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
 6022:         } else if (prefixes & PREFIX_REPZ) {
 6023:             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
 6024:         } else {
 6025:             gen_scas(s, ot);
 6026:             s->cc_op = CC_OP_SUBB + ot;
 6027:         }
 6028:         break;
 6029: 
 6030:     case 0xa6: /* cmpsS */
 6031:     case 0xa7:
 6032:         if ((b & 1) == 0)
 6033:             ot = OT_BYTE;
 6034:         else
 6035:             ot = dflag + OT_WORD;
 6036:         if (prefixes & PREFIX_REPNZ) {
 6037:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
 6038:         } else if (prefixes & PREFIX_REPZ) {
 6039:             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
 6040:         } else {
 6041:             gen_cmps(s, ot);
 6042:             s->cc_op = CC_OP_SUBB + ot;
 6043:         }
 6044:         break;
 6045:     case 0x6c: /* insS */
 6046:     case 0x6d:
 6047:         if ((b & 1) == 0)
 6048:             ot = OT_BYTE;
 6049:         else
 6050:             ot = dflag ? OT_LONG : OT_WORD;
 6051:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 6052:         gen_op_andl_T0_ffff();
 6053:         gen_check_io(s, ot, pc_start - s->cs_base, 
 6054:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
 6055:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 6056:             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 6057:         } else {
 6058:             gen_ins(s, ot);
 6059:             if (use_icount) {
 6060:                 gen_jmp(s, s->pc - s->cs_base);
 6061:             }
 6062:         }
 6063:         break;
 6064:     case 0x6e: /* outsS */
 6065:     case 0x6f:
 6066:         if ((b & 1) == 0)
 6067:             ot = OT_BYTE;
 6068:         else
 6069:             ot = dflag ? OT_LONG : OT_WORD;
 6070:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 6071:         gen_op_andl_T0_ffff();
 6072:         gen_check_io(s, ot, pc_start - s->cs_base,
 6073:                      svm_is_rep(prefixes) | 4);
 6074:         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
 6075:             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
 6076:         } else {
 6077:             gen_outs(s, ot);
 6078:             if (use_icount) {
 6079:                 gen_jmp(s, s->pc - s->cs_base);
 6080:             }
 6081:         }
 6082:         break;
 6083: 
 6084:         /************************/
 6085:         /* port I/O */
 6086: 
 6087:     case 0xe4:
 6088:     case 0xe5:
 6089:         if ((b & 1) == 0)
 6090:             ot = OT_BYTE;
 6091:         else
 6092:             ot = dflag ? OT_LONG : OT_WORD;
 6093:         val = ldub_code(s->pc++);
 6094:         gen_op_movl_T0_im(val);
 6095:         gen_check_io(s, ot, pc_start - s->cs_base,
 6096:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
 6097:         if (use_icount)
 6098:             gen_io_start();
 6099:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6100:         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
 6101:         gen_op_mov_reg_T1(ot, R_EAX);
 6102:         if (use_icount) {
 6103:             gen_io_end();
 6104:             gen_jmp(s, s->pc - s->cs_base);
 6105:         }
 6106:         break;
 6107:     case 0xe6:
 6108:     case 0xe7:
 6109:         if ((b & 1) == 0)
 6110:             ot = OT_BYTE;
 6111:         else
 6112:             ot = dflag ? OT_LONG : OT_WORD;
 6113:         val = ldub_code(s->pc++);
 6114:         gen_op_movl_T0_im(val);
 6115:         gen_check_io(s, ot, pc_start - s->cs_base,
 6116:                      svm_is_rep(prefixes));
 6117:         gen_op_mov_TN_reg(ot, 1, R_EAX);
 6118: 
 6119:         if (use_icount)
 6120:             gen_io_start();
 6121:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6122:         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
 6123:         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
 6124:         if (use_icount) {
 6125:             gen_io_end();
 6126:             gen_jmp(s, s->pc - s->cs_base);
 6127:         }
 6128:         break;
 6129:     case 0xec:
 6130:     case 0xed:
 6131:         if ((b & 1) == 0)
 6132:             ot = OT_BYTE;
 6133:         else
 6134:             ot = dflag ? OT_LONG : OT_WORD;
 6135:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 6136:         gen_op_andl_T0_ffff();
 6137:         gen_check_io(s, ot, pc_start - s->cs_base,
 6138:                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
 6139:         if (use_icount)
 6140:             gen_io_start();
 6141:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6142:         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
 6143:         gen_op_mov_reg_T1(ot, R_EAX);
 6144:         if (use_icount) {
 6145:             gen_io_end();
 6146:             gen_jmp(s, s->pc - s->cs_base);
 6147:         }
 6148:         break;
 6149:     case 0xee:
 6150:     case 0xef:
 6151:         if ((b & 1) == 0)
 6152:             ot = OT_BYTE;
 6153:         else
 6154:             ot = dflag ? OT_LONG : OT_WORD;
 6155:         gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
 6156:         gen_op_andl_T0_ffff();
 6157:         gen_check_io(s, ot, pc_start - s->cs_base,
 6158:                      svm_is_rep(prefixes));
 6159:         gen_op_mov_TN_reg(ot, 1, R_EAX);
 6160: 
 6161:         if (use_icount)
 6162:             gen_io_start();
 6163:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6164:         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
 6165:         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
 6166:         if (use_icount) {
 6167:             gen_io_end();
 6168:             gen_jmp(s, s->pc - s->cs_base);
 6169:         }
 6170:         break;
 6171: 
 6172:         /************************/
 6173:         /* control */
 6174:     case 0xc2: /* ret im */
 6175:         val = ldsw_code(s->pc);
 6176:         s->pc += 2;
 6177:         gen_pop_T0(s);
 6178:         if (CODE64(s) && s->dflag)
 6179:             s->dflag = 2;
 6180:         gen_stack_update(s, val + (2 << s->dflag));
 6181:         if (s->dflag == 0)
 6182:             gen_op_andl_T0_ffff();
 6183:         gen_op_jmp_T0();
 6184:         gen_eob(s);
 6185:         break;
 6186:     case 0xc3: /* ret */
 6187:         gen_pop_T0(s);
 6188:         gen_pop_update(s);
 6189:         if (s->dflag == 0)
 6190:             gen_op_andl_T0_ffff();
 6191:         gen_op_jmp_T0();
 6192:         gen_eob(s);
 6193:         break;
 6194:     case 0xca: /* lret im */
 6195:         val = ldsw_code(s->pc);
 6196:         s->pc += 2;
 6197:     do_lret:
 6198:         if (s->pe && !s->vm86) {
 6199:             if (s->cc_op != CC_OP_DYNAMIC)
 6200:                 gen_op_set_cc_op(s->cc_op);
 6201:             gen_jmp_im(pc_start - s->cs_base);
 6202:             gen_helper_lret_protected(tcg_const_i32(s->dflag),
 6203:                                       tcg_const_i32(val));
 6204:         } else {
 6205:             gen_stack_A0(s);
 6206:             /* pop offset */
 6207:             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
 6208:             if (s->dflag == 0)
 6209:                 gen_op_andl_T0_ffff();
 6210:             /* NOTE: keeping EIP updated is not a problem in case of
 6211:                exception */
 6212:             gen_op_jmp_T0();
 6213:             /* pop selector */
 6214:             gen_op_addl_A0_im(2 << s->dflag);
 6215:             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
 6216:             gen_op_movl_seg_T0_vm(R_CS);
 6217:             /* add stack offset */
 6218:             gen_stack_update(s, val + (4 << s->dflag));
 6219:         }
 6220:         gen_eob(s);
 6221:         break;
 6222:     case 0xcb: /* lret */
 6223:         val = 0;
 6224:         goto do_lret;
 6225:     case 0xcf: /* iret */
 6226:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
 6227:         if (!s->pe) {
 6228:             /* real mode */
 6229:             gen_helper_iret_real(tcg_const_i32(s->dflag));
 6230:             s->cc_op = CC_OP_EFLAGS;
 6231:         } else if (s->vm86) {
 6232:             if (s->iopl != 3) {
 6233:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6234:             } else {
 6235:                 gen_helper_iret_real(tcg_const_i32(s->dflag));
 6236:                 s->cc_op = CC_OP_EFLAGS;
 6237:             }
 6238:         } else {
 6239:             if (s->cc_op != CC_OP_DYNAMIC)
 6240:                 gen_op_set_cc_op(s->cc_op);
 6241:             gen_jmp_im(pc_start - s->cs_base);
 6242:             gen_helper_iret_protected(tcg_const_i32(s->dflag), 
 6243:                                       tcg_const_i32(s->pc - s->cs_base));
 6244:             s->cc_op = CC_OP_EFLAGS;
 6245:         }
 6246:         gen_eob(s);
 6247:         break;
 6248:     case 0xe8: /* call im */
 6249:         {
 6250:             if (dflag)
 6251:                 tval = (int32_t)insn_get(s, OT_LONG);
 6252:             else
 6253:                 tval = (int16_t)insn_get(s, OT_WORD);
 6254:             next_eip = s->pc - s->cs_base;
 6255:             tval += next_eip;
 6256:             if (s->dflag == 0)
 6257:                 tval &= 0xffff;
 6258:             else if(!CODE64(s))
 6259:                 tval &= 0xffffffff;
 6260:             gen_movtl_T0_im(next_eip);
 6261:             gen_push_T0(s);
 6262:             gen_jmp(s, tval);
 6263:         }
 6264:         break;
 6265:     case 0x9a: /* lcall im */
 6266:         {
 6267:             unsigned int selector, offset;
 6268: 
 6269:             if (CODE64(s))
 6270:                 goto illegal_op;
 6271:             ot = dflag ? OT_LONG : OT_WORD;
 6272:             offset = insn_get(s, ot);
 6273:             selector = insn_get(s, OT_WORD);
 6274: 
 6275:             gen_op_movl_T0_im(selector);
 6276:             gen_op_movl_T1_imu(offset);
 6277:         }
 6278:         goto do_lcall;
 6279:     case 0xe9: /* jmp im */
 6280:         if (dflag)
 6281:             tval = (int32_t)insn_get(s, OT_LONG);
 6282:         else
 6283:             tval = (int16_t)insn_get(s, OT_WORD);
 6284:         tval += s->pc - s->cs_base;
 6285:         if (s->dflag == 0)
 6286:             tval &= 0xffff;
 6287:         else if(!CODE64(s))
 6288:             tval &= 0xffffffff;
 6289:         gen_jmp(s, tval);
 6290:         break;
 6291:     case 0xea: /* ljmp im */
 6292:         {
 6293:             unsigned int selector, offset;
 6294: 
 6295:             if (CODE64(s))
 6296:                 goto illegal_op;
 6297:             ot = dflag ? OT_LONG : OT_WORD;
 6298:             offset = insn_get(s, ot);
 6299:             selector = insn_get(s, OT_WORD);
 6300: 
 6301:             gen_op_movl_T0_im(selector);
 6302:             gen_op_movl_T1_imu(offset);
 6303:         }
 6304:         goto do_ljmp;
 6305:     case 0xeb: /* jmp Jb */
 6306:         tval = (int8_t)insn_get(s, OT_BYTE);
 6307:         tval += s->pc - s->cs_base;
 6308:         if (s->dflag == 0)
 6309:             tval &= 0xffff;
 6310:         gen_jmp(s, tval);
 6311:         break;
 6312:     case 0x70 ... 0x7f: /* jcc Jb */
 6313:         tval = (int8_t)insn_get(s, OT_BYTE);
 6314:         goto do_jcc;
 6315:     case 0x180 ... 0x18f: /* jcc Jv */
 6316:         if (dflag) {
 6317:             tval = (int32_t)insn_get(s, OT_LONG);
 6318:         } else {
 6319:             tval = (int16_t)insn_get(s, OT_WORD);
 6320:         }
 6321:     do_jcc:
 6322:         next_eip = s->pc - s->cs_base;
 6323:         tval += next_eip;
 6324:         if (s->dflag == 0)
 6325:             tval &= 0xffff;
 6326:         gen_jcc(s, b, tval, next_eip);
 6327:         break;
 6328: 
 6329:     case 0x190 ... 0x19f: /* setcc Gv */
 6330:         modrm = ldub_code(s->pc++);
 6331:         gen_setcc(s, b);
 6332:         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
 6333:         break;
 6334:     case 0x140 ... 0x14f: /* cmov Gv, Ev */
 6335:         {
 6336:             int l1;
 6337:             TCGv t0;
 6338: 
 6339:             ot = dflag + OT_WORD;
 6340:             modrm = ldub_code(s->pc++);
 6341:             reg = ((modrm >> 3) & 7) | rex_r;
 6342:             mod = (modrm >> 6) & 3;
 6343:             t0 = tcg_temp_local_new();
 6344:             if (mod != 3) {
 6345:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 6346:                 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
 6347:             } else {
 6348:                 rm = (modrm & 7) | REX_B(s);
 6349:                 gen_op_mov_v_reg(ot, t0, rm);
 6350:             }
 6351: #ifdef TARGET_X86_64
 6352:             if (ot == OT_LONG) {
 6353:                 /* XXX: specific Intel behaviour ? */
 6354:                 l1 = gen_new_label();
 6355:                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
 6356:                 tcg_gen_mov_tl(cpu_regs[reg], t0);
 6357:                 gen_set_label(l1);
 6358:                 tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]);
 6359:             } else
 6360: #endif
 6361:             {
 6362:                 l1 = gen_new_label();
 6363:                 gen_jcc1(s, s->cc_op, b ^ 1, l1);
 6364:                 gen_op_mov_reg_v(ot, reg, t0);
 6365:                 gen_set_label(l1);
 6366:             }
 6367:             tcg_temp_free(t0);
 6368:         }
 6369:         break;
 6370: 
 6371:         /************************/
 6372:         /* flags */
 6373:     case 0x9c: /* pushf */
 6374:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
 6375:         if (s->vm86 && s->iopl != 3) {
 6376:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6377:         } else {
 6378:             if (s->cc_op != CC_OP_DYNAMIC)
 6379:                 gen_op_set_cc_op(s->cc_op);
 6380:             gen_helper_read_eflags(cpu_T[0]);
 6381:             gen_push_T0(s);
 6382:         }
 6383:         break;
 6384:     case 0x9d: /* popf */
 6385:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
 6386:         if (s->vm86 && s->iopl != 3) {
 6387:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6388:         } else {
 6389:             gen_pop_T0(s);
 6390:             if (s->cpl == 0) {
 6391:                 if (s->dflag) {
 6392:                     gen_helper_write_eflags(cpu_T[0],
 6393:                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
 6394:                 } else {
 6395:                     gen_helper_write_eflags(cpu_T[0],
 6396:                                        tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
 6397:                 }
 6398:             } else {
 6399:                 if (s->cpl <= s->iopl) {
 6400:                     if (s->dflag) {
 6401:                         gen_helper_write_eflags(cpu_T[0],
 6402:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
 6403:                     } else {
 6404:                         gen_helper_write_eflags(cpu_T[0],
 6405:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
 6406:                     }
 6407:                 } else {
 6408:                     if (s->dflag) {
 6409:                         gen_helper_write_eflags(cpu_T[0],
 6410:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
 6411:                     } else {
 6412:                         gen_helper_write_eflags(cpu_T[0],
 6413:                                            tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
 6414:                     }
 6415:                 }
 6416:             }
 6417:             gen_pop_update(s);
 6418:             s->cc_op = CC_OP_EFLAGS;
 6419:             /* abort translation because TF flag may change */
 6420:             gen_jmp_im(s->pc - s->cs_base);
 6421:             gen_eob(s);
 6422:         }
 6423:         break;
 6424:     case 0x9e: /* sahf */
 6425:         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
 6426:             goto illegal_op;
 6427:         gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
 6428:         if (s->cc_op != CC_OP_DYNAMIC)
 6429:             gen_op_set_cc_op(s->cc_op);
 6430:         gen_compute_eflags(cpu_cc_src);
 6431:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
 6432:         tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
 6433:         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
 6434:         s->cc_op = CC_OP_EFLAGS;
 6435:         break;
 6436:     case 0x9f: /* lahf */
 6437:         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
 6438:             goto illegal_op;
 6439:         if (s->cc_op != CC_OP_DYNAMIC)
 6440:             gen_op_set_cc_op(s->cc_op);
 6441:         gen_compute_eflags(cpu_T[0]);
 6442:         /* Note: gen_compute_eflags() only gives the condition codes */
 6443:         tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
 6444:         gen_op_mov_reg_T0(OT_BYTE, R_AH);
 6445:         break;
 6446:     case 0xf5: /* cmc */
 6447:         if (s->cc_op != CC_OP_DYNAMIC)
 6448:             gen_op_set_cc_op(s->cc_op);
 6449:         gen_compute_eflags(cpu_cc_src);
 6450:         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
 6451:         s->cc_op = CC_OP_EFLAGS;
 6452:         break;
 6453:     case 0xf8: /* clc */
 6454:         if (s->cc_op != CC_OP_DYNAMIC)
 6455:             gen_op_set_cc_op(s->cc_op);
 6456:         gen_compute_eflags(cpu_cc_src);
 6457:         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
 6458:         s->cc_op = CC_OP_EFLAGS;
 6459:         break;
 6460:     case 0xf9: /* stc */
 6461:         if (s->cc_op != CC_OP_DYNAMIC)
 6462:             gen_op_set_cc_op(s->cc_op);
 6463:         gen_compute_eflags(cpu_cc_src);
 6464:         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
 6465:         s->cc_op = CC_OP_EFLAGS;
 6466:         break;
 6467:     case 0xfc: /* cld */
 6468:         tcg_gen_movi_i32(cpu_tmp2_i32, 1);
 6469:         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
 6470:         break;
 6471:     case 0xfd: /* std */
 6472:         tcg_gen_movi_i32(cpu_tmp2_i32, -1);
 6473:         tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUState, df));
 6474:         break;
 6475: 
 6476:         /************************/
 6477:         /* bit operations */
 6478:     case 0x1ba: /* bt/bts/btr/btc Gv, im */
 6479:         ot = dflag + OT_WORD;
 6480:         modrm = ldub_code(s->pc++);
 6481:         op = (modrm >> 3) & 7;
 6482:         mod = (modrm >> 6) & 3;
 6483:         rm = (modrm & 7) | REX_B(s);
 6484:         if (mod != 3) {
 6485:             s->rip_offset = 1;
 6486:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 6487:             gen_op_ld_T0_A0(ot + s->mem_index);
 6488:         } else {
 6489:             gen_op_mov_TN_reg(ot, 0, rm);
 6490:         }
 6491:         /* load shift */
 6492:         val = ldub_code(s->pc++);
 6493:         gen_op_movl_T1_im(val);
 6494:         if (op < 4)
 6495:             goto illegal_op;
 6496:         op -= 4;
 6497:         goto bt_op;
 6498:     case 0x1a3: /* bt Gv, Ev */
 6499:         op = 0;
 6500:         goto do_btx;
 6501:     case 0x1ab: /* bts */
 6502:         op = 1;
 6503:         goto do_btx;
 6504:     case 0x1b3: /* btr */
 6505:         op = 2;
 6506:         goto do_btx;
 6507:     case 0x1bb: /* btc */
 6508:         op = 3;
 6509:     do_btx:
 6510:         ot = dflag + OT_WORD;
 6511:         modrm = ldub_code(s->pc++);
 6512:         reg = ((modrm >> 3) & 7) | rex_r;
 6513:         mod = (modrm >> 6) & 3;
 6514:         rm = (modrm & 7) | REX_B(s);
 6515:         gen_op_mov_TN_reg(OT_LONG, 1, reg);
 6516:         if (mod != 3) {
 6517:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 6518:             /* specific case: we need to add a displacement */
 6519:             gen_exts(ot, cpu_T[1]);
 6520:             tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
 6521:             tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
 6522:             tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
 6523:             gen_op_ld_T0_A0(ot + s->mem_index);
 6524:         } else {
 6525:             gen_op_mov_TN_reg(ot, 0, rm);
 6526:         }
 6527:     bt_op:
 6528:         tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
 6529:         switch(op) {
 6530:         case 0:
 6531:             tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
 6532:             tcg_gen_movi_tl(cpu_cc_dst, 0);
 6533:             break;
 6534:         case 1:
 6535:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
 6536:             tcg_gen_movi_tl(cpu_tmp0, 1);
 6537:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
 6538:             tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
 6539:             break;
 6540:         case 2:
 6541:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
 6542:             tcg_gen_movi_tl(cpu_tmp0, 1);
 6543:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
 6544:             tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
 6545:             tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
 6546:             break;
 6547:         default:
 6548:         case 3:
 6549:             tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
 6550:             tcg_gen_movi_tl(cpu_tmp0, 1);
 6551:             tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
 6552:             tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
 6553:             break;
 6554:         }
 6555:         s->cc_op = CC_OP_SARB + ot;
 6556:         if (op != 0) {
 6557:             if (mod != 3)
 6558:                 gen_op_st_T0_A0(ot + s->mem_index);
 6559:             else
 6560:                 gen_op_mov_reg_T0(ot, rm);
 6561:             tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
 6562:             tcg_gen_movi_tl(cpu_cc_dst, 0);
 6563:         }
 6564:         break;
 6565:     case 0x1bc: /* bsf */
 6566:     case 0x1bd: /* bsr */
 6567:         {
 6568:             int label1;
 6569:             TCGv t0;
 6570: 
 6571:             ot = dflag + OT_WORD;
 6572:             modrm = ldub_code(s->pc++);
 6573:             reg = ((modrm >> 3) & 7) | rex_r;
 6574:             gen_ldst_modrm(s,modrm, ot, OR_TMP0, 0);
 6575:             gen_extu(ot, cpu_T[0]);
 6576:             t0 = tcg_temp_local_new();
 6577:             tcg_gen_mov_tl(t0, cpu_T[0]);
 6578:             if ((b & 1) && (prefixes & PREFIX_REPZ) &&
 6579:                 (s->cpuid_ext3_features & CPUID_EXT3_ABM)) {
 6580:                 switch(ot) {
 6581:                 case OT_WORD: gen_helper_lzcnt(cpu_T[0], t0,
 6582:                     tcg_const_i32(16)); break;
 6583:                 case OT_LONG: gen_helper_lzcnt(cpu_T[0], t0,
 6584:                     tcg_const_i32(32)); break;
 6585:                 case OT_QUAD: gen_helper_lzcnt(cpu_T[0], t0,
 6586:                     tcg_const_i32(64)); break;
 6587:                 }
 6588:                 gen_op_mov_reg_T0(ot, reg);
 6589:             } else {
 6590:                 label1 = gen_new_label();
 6591:                 tcg_gen_movi_tl(cpu_cc_dst, 0);
 6592:                 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, label1);
 6593:                 if (b & 1) {
 6594:                     gen_helper_bsr(cpu_T[0], t0);
 6595:                 } else {
 6596:                     gen_helper_bsf(cpu_T[0], t0);
 6597:                 }
 6598:                 gen_op_mov_reg_T0(ot, reg);
 6599:                 tcg_gen_movi_tl(cpu_cc_dst, 1);
 6600:                 gen_set_label(label1);
 6601:                 tcg_gen_discard_tl(cpu_cc_src);
 6602:                 s->cc_op = CC_OP_LOGICB + ot;
 6603:             }
 6604:             tcg_temp_free(t0);
 6605:         }
 6606:         break;
 6607:         /************************/
 6608:         /* bcd */
 6609:     case 0x27: /* daa */
 6610:         if (CODE64(s))
 6611:             goto illegal_op;
 6612:         if (s->cc_op != CC_OP_DYNAMIC)
 6613:             gen_op_set_cc_op(s->cc_op);
 6614:         gen_helper_daa();
 6615:         s->cc_op = CC_OP_EFLAGS;
 6616:         break;
 6617:     case 0x2f: /* das */
 6618:         if (CODE64(s))
 6619:             goto illegal_op;
 6620:         if (s->cc_op != CC_OP_DYNAMIC)
 6621:             gen_op_set_cc_op(s->cc_op);
 6622:         gen_helper_das();
 6623:         s->cc_op = CC_OP_EFLAGS;
 6624:         break;
 6625:     case 0x37: /* aaa */
 6626:         if (CODE64(s))
 6627:             goto illegal_op;
 6628:         if (s->cc_op != CC_OP_DYNAMIC)
 6629:             gen_op_set_cc_op(s->cc_op);
 6630:         gen_helper_aaa();
 6631:         s->cc_op = CC_OP_EFLAGS;
 6632:         break;
 6633:     case 0x3f: /* aas */
 6634:         if (CODE64(s))
 6635:             goto illegal_op;
 6636:         if (s->cc_op != CC_OP_DYNAMIC)
 6637:             gen_op_set_cc_op(s->cc_op);
 6638:         gen_helper_aas();
 6639:         s->cc_op = CC_OP_EFLAGS;
 6640:         break;
 6641:     case 0xd4: /* aam */
 6642:         if (CODE64(s))
 6643:             goto illegal_op;
 6644:         val = ldub_code(s->pc++);
 6645:         if (val == 0) {
 6646:             gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
 6647:         } else {
 6648:             gen_helper_aam(tcg_const_i32(val));
 6649:             s->cc_op = CC_OP_LOGICB;
 6650:         }
 6651:         break;
 6652:     case 0xd5: /* aad */
 6653:         if (CODE64(s))
 6654:             goto illegal_op;
 6655:         val = ldub_code(s->pc++);
 6656:         gen_helper_aad(tcg_const_i32(val));
 6657:         s->cc_op = CC_OP_LOGICB;
 6658:         break;
 6659:         /************************/
 6660:         /* misc */
 6661:     case 0x90: /* nop */
 6662:         /* XXX: correct lock test for all insn */
 6663:         if (prefixes & PREFIX_LOCK) {
 6664:             goto illegal_op;
 6665:         }
 6666:         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
 6667:         if (REX_B(s)) {
 6668:             goto do_xchg_reg_eax;
 6669:         }
 6670:         if (prefixes & PREFIX_REPZ) {
 6671:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_PAUSE);
 6672:         }
 6673:         break;
 6674:     case 0x9b: /* fwait */
 6675:         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
 6676:             (HF_MP_MASK | HF_TS_MASK)) {
 6677:             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 6678:         } else {
 6679:             if (s->cc_op != CC_OP_DYNAMIC)
 6680:                 gen_op_set_cc_op(s->cc_op);
 6681:             gen_jmp_im(pc_start - s->cs_base);
 6682:             gen_helper_fwait();
 6683:         }
 6684:         break;
 6685:     case 0xcc: /* int3 */
 6686:         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
 6687:         break;
 6688:     case 0xcd: /* int N */
 6689:         val = ldub_code(s->pc++);
 6690:         if (s->vm86 && s->iopl != 3) {
 6691:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6692:         } else {
 6693:             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
 6694:         }
 6695:         break;
 6696:     case 0xce: /* into */
 6697:         if (CODE64(s))
 6698:             goto illegal_op;
 6699:         if (s->cc_op != CC_OP_DYNAMIC)
 6700:             gen_op_set_cc_op(s->cc_op);
 6701:         gen_jmp_im(pc_start - s->cs_base);
 6702:         gen_helper_into(tcg_const_i32(s->pc - pc_start));
 6703:         break;
 6704: #ifdef WANT_ICEBP
 6705:     case 0xf1: /* icebp (undocumented, exits to external debugger) */
 6706:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
 6707: #if 1
 6708:         gen_debug(s, pc_start - s->cs_base);
 6709: #else
 6710:         /* start debug */
 6711:         tb_flush(cpu_single_env);
 6712:         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
 6713: #endif
 6714:         break;
 6715: #endif
 6716:     case 0xfa: /* cli */
 6717:         if (!s->vm86) {
 6718:             if (s->cpl <= s->iopl) {
 6719:                 gen_helper_cli();
 6720:             } else {
 6721:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6722:             }
 6723:         } else {
 6724:             if (s->iopl == 3) {
 6725:                 gen_helper_cli();
 6726:             } else {
 6727:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6728:             }
 6729:         }
 6730:         break;
 6731:     case 0xfb: /* sti */
 6732:         if (!s->vm86) {
 6733:             if (s->cpl <= s->iopl) {
 6734:             gen_sti:
 6735:                 gen_helper_sti();
 6736:                 /* interruptions are enabled only the first insn after sti */
 6737:                 /* If several instructions disable interrupts, only the
 6738:                    _first_ does it */
 6739:                 if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
 6740:                     gen_helper_set_inhibit_irq();
 6741:                 /* give a chance to handle pending irqs */
 6742:                 gen_jmp_im(s->pc - s->cs_base);
 6743:                 gen_eob(s);
 6744:             } else {
 6745:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6746:             }
 6747:         } else {
 6748:             if (s->iopl == 3) {
 6749:                 goto gen_sti;
 6750:             } else {
 6751:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6752:             }
 6753:         }
 6754:         break;
 6755:     case 0x62: /* bound */
 6756:         if (CODE64(s))
 6757:             goto illegal_op;
 6758:         ot = dflag ? OT_LONG : OT_WORD;
 6759:         modrm = ldub_code(s->pc++);
 6760:         reg = (modrm >> 3) & 7;
 6761:         mod = (modrm >> 6) & 3;
 6762:         if (mod == 3)
 6763:             goto illegal_op;
 6764:         gen_op_mov_TN_reg(ot, 0, reg);
 6765:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 6766:         gen_jmp_im(pc_start - s->cs_base);
 6767:         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6768:         if (ot == OT_WORD)
 6769:             gen_helper_boundw(cpu_A0, cpu_tmp2_i32);
 6770:         else
 6771:             gen_helper_boundl(cpu_A0, cpu_tmp2_i32);
 6772:         break;
 6773:     case 0x1c8 ... 0x1cf: /* bswap reg */
 6774:         reg = (b & 7) | REX_B(s);
 6775: #ifdef TARGET_X86_64
 6776:         if (dflag == 2) {
 6777:             gen_op_mov_TN_reg(OT_QUAD, 0, reg);
 6778:             tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]);
 6779:             gen_op_mov_reg_T0(OT_QUAD, reg);
 6780:         } else
 6781: #endif
 6782:         {
 6783:             gen_op_mov_TN_reg(OT_LONG, 0, reg);
 6784:             tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
 6785:             tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]);
 6786:             gen_op_mov_reg_T0(OT_LONG, reg);
 6787:         }
 6788:         break;
 6789:     case 0xd6: /* salc */
 6790:         if (CODE64(s))
 6791:             goto illegal_op;
 6792:         if (s->cc_op != CC_OP_DYNAMIC)
 6793:             gen_op_set_cc_op(s->cc_op);
 6794:         gen_compute_eflags_c(cpu_T[0]);
 6795:         tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
 6796:         gen_op_mov_reg_T0(OT_BYTE, R_EAX);
 6797:         break;
 6798:     case 0xe0: /* loopnz */
 6799:     case 0xe1: /* loopz */
 6800:     case 0xe2: /* loop */
 6801:     case 0xe3: /* jecxz */
 6802:         {
 6803:             int l1, l2, l3;
 6804: 
 6805:             tval = (int8_t)insn_get(s, OT_BYTE);
 6806:             next_eip = s->pc - s->cs_base;
 6807:             tval += next_eip;
 6808:             if (s->dflag == 0)
 6809:                 tval &= 0xffff;
 6810: 
 6811:             l1 = gen_new_label();
 6812:             l2 = gen_new_label();
 6813:             l3 = gen_new_label();
 6814:             b &= 3;
 6815:             switch(b) {
 6816:             case 0: /* loopnz */
 6817:             case 1: /* loopz */
 6818:                 if (s->cc_op != CC_OP_DYNAMIC)
 6819:                     gen_op_set_cc_op(s->cc_op);
 6820:                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
 6821:                 gen_op_jz_ecx(s->aflag, l3);
 6822:                 gen_compute_eflags(cpu_tmp0);
 6823:                 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, CC_Z);
 6824:                 if (b == 0) {
 6825:                     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
 6826:                 } else {
 6827:                     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, l1);
 6828:                 }
 6829:                 break;
 6830:             case 2: /* loop */
 6831:                 gen_op_add_reg_im(s->aflag, R_ECX, -1);
 6832:                 gen_op_jnz_ecx(s->aflag, l1);
 6833:                 break;
 6834:             default:
 6835:             case 3: /* jcxz */
 6836:                 gen_op_jz_ecx(s->aflag, l1);
 6837:                 break;
 6838:             }
 6839: 
 6840:             gen_set_label(l3);
 6841:             gen_jmp_im(next_eip);
 6842:             tcg_gen_br(l2);
 6843: 
 6844:             gen_set_label(l1);
 6845:             gen_jmp_im(tval);
 6846:             gen_set_label(l2);
 6847:             gen_eob(s);
 6848:         }
 6849:         break;
 6850:     case 0x130: /* wrmsr */
 6851:     case 0x132: /* rdmsr */
 6852:         if (s->cpl != 0) {
 6853:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6854:         } else {
 6855:             if (s->cc_op != CC_OP_DYNAMIC)
 6856:                 gen_op_set_cc_op(s->cc_op);
 6857:             gen_jmp_im(pc_start - s->cs_base);
 6858:             if (b & 2) {
 6859:                 gen_helper_rdmsr();
 6860:             } else {
 6861:                 gen_helper_wrmsr();
 6862:             }
 6863:         }
 6864:         break;
 6865:     case 0x131: /* rdtsc */
 6866:         if (s->cc_op != CC_OP_DYNAMIC)
 6867:             gen_op_set_cc_op(s->cc_op);
 6868:         gen_jmp_im(pc_start - s->cs_base);
 6869:         if (use_icount)
 6870:             gen_io_start();
 6871:         gen_helper_rdtsc();
 6872:         if (use_icount) {
 6873:             gen_io_end();
 6874:             gen_jmp(s, s->pc - s->cs_base);
 6875:         }
 6876:         break;
 6877:     case 0x133: /* rdpmc */
 6878:         if (s->cc_op != CC_OP_DYNAMIC)
 6879:             gen_op_set_cc_op(s->cc_op);
 6880:         gen_jmp_im(pc_start - s->cs_base);
 6881:         gen_helper_rdpmc();
 6882:         break;
 6883:     case 0x134: /* sysenter */
 6884:         /* For Intel SYSENTER is valid on 64-bit */
 6885:         if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
 6886:             goto illegal_op;
 6887:         if (!s->pe) {
 6888:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6889:         } else {
 6890:             gen_update_cc_op(s);
 6891:             gen_jmp_im(pc_start - s->cs_base);
 6892:             gen_helper_sysenter();
 6893:             gen_eob(s);
 6894:         }
 6895:         break;
 6896:     case 0x135: /* sysexit */
 6897:         /* For Intel SYSEXIT is valid on 64-bit */
 6898:         if (CODE64(s) && cpu_single_env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
 6899:             goto illegal_op;
 6900:         if (!s->pe) {
 6901:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6902:         } else {
 6903:             gen_update_cc_op(s);
 6904:             gen_jmp_im(pc_start - s->cs_base);
 6905:             gen_helper_sysexit(tcg_const_i32(dflag));
 6906:             gen_eob(s);
 6907:         }
 6908:         break;
 6909: #ifdef TARGET_X86_64
 6910:     case 0x105: /* syscall */
 6911:         /* XXX: is it usable in real mode ? */
 6912:         gen_update_cc_op(s);
 6913:         gen_jmp_im(pc_start - s->cs_base);
 6914:         gen_helper_syscall(tcg_const_i32(s->pc - pc_start));
 6915:         gen_eob(s);
 6916:         break;
 6917:     case 0x107: /* sysret */
 6918:         if (!s->pe) {
 6919:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6920:         } else {
 6921:             gen_update_cc_op(s);
 6922:             gen_jmp_im(pc_start - s->cs_base);
 6923:             gen_helper_sysret(tcg_const_i32(s->dflag));
 6924:             /* condition codes are modified only in long mode */
 6925:             if (s->lma)
 6926:                 s->cc_op = CC_OP_EFLAGS;
 6927:             gen_eob(s);
 6928:         }
 6929:         break;
 6930: #endif
 6931:     case 0x1a2: /* cpuid */
 6932:         if (s->cc_op != CC_OP_DYNAMIC)
 6933:             gen_op_set_cc_op(s->cc_op);
 6934:         gen_jmp_im(pc_start - s->cs_base);
 6935:         gen_helper_cpuid();
 6936:         break;
 6937:     case 0xf4: /* hlt */
 6938:         if (s->cpl != 0) {
 6939:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6940:         } else {
 6941:             if (s->cc_op != CC_OP_DYNAMIC)
 6942:                 gen_op_set_cc_op(s->cc_op);
 6943:             gen_jmp_im(pc_start - s->cs_base);
 6944:             gen_helper_hlt(tcg_const_i32(s->pc - pc_start));
 6945:             s->is_jmp = DISAS_TB_JUMP;
 6946:         }
 6947:         break;
 6948:     case 0x100:
 6949:         modrm = ldub_code(s->pc++);
 6950:         mod = (modrm >> 6) & 3;
 6951:         op = (modrm >> 3) & 7;
 6952:         switch(op) {
 6953:         case 0: /* sldt */
 6954:             if (!s->pe || s->vm86)
 6955:                 goto illegal_op;
 6956:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
 6957:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector));
 6958:             ot = OT_WORD;
 6959:             if (mod == 3)
 6960:                 ot += s->dflag;
 6961:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
 6962:             break;
 6963:         case 2: /* lldt */
 6964:             if (!s->pe || s->vm86)
 6965:                 goto illegal_op;
 6966:             if (s->cpl != 0) {
 6967:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6968:             } else {
 6969:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
 6970:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 6971:                 gen_jmp_im(pc_start - s->cs_base);
 6972:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6973:                 gen_helper_lldt(cpu_tmp2_i32);
 6974:             }
 6975:             break;
 6976:         case 1: /* str */
 6977:             if (!s->pe || s->vm86)
 6978:                 goto illegal_op;
 6979:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
 6980:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector));
 6981:             ot = OT_WORD;
 6982:             if (mod == 3)
 6983:                 ot += s->dflag;
 6984:             gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
 6985:             break;
 6986:         case 3: /* ltr */
 6987:             if (!s->pe || s->vm86)
 6988:                 goto illegal_op;
 6989:             if (s->cpl != 0) {
 6990:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 6991:             } else {
 6992:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
 6993:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 6994:                 gen_jmp_im(pc_start - s->cs_base);
 6995:                 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
 6996:                 gen_helper_ltr(cpu_tmp2_i32);
 6997:             }
 6998:             break;
 6999:         case 4: /* verr */
 7000:         case 5: /* verw */
 7001:             if (!s->pe || s->vm86)
 7002:                 goto illegal_op;
 7003:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 7004:             if (s->cc_op != CC_OP_DYNAMIC)
 7005:                 gen_op_set_cc_op(s->cc_op);
 7006:             if (op == 4)
 7007:                 gen_helper_verr(cpu_T[0]);
 7008:             else
 7009:                 gen_helper_verw(cpu_T[0]);
 7010:             s->cc_op = CC_OP_EFLAGS;
 7011:             break;
 7012:         default:
 7013:             goto illegal_op;
 7014:         }
 7015:         break;
 7016:     case 0x101:
 7017:         modrm = ldub_code(s->pc++);
 7018:         mod = (modrm >> 6) & 3;
 7019:         op = (modrm >> 3) & 7;
 7020:         rm = modrm & 7;
 7021:         switch(op) {
 7022:         case 0: /* sgdt */
 7023:             if (mod == 3)
 7024:                 goto illegal_op;
 7025:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
 7026:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7027:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit));
 7028:             gen_op_st_T0_A0(OT_WORD + s->mem_index);
 7029:             gen_add_A0_im(s, 2);
 7030:             tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base));
 7031:             if (!s->dflag)
 7032:                 gen_op_andl_T0_im(0xffffff);
 7033:             gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
 7034:             break;
 7035:         case 1:
 7036:             if (mod == 3) {
 7037:                 switch (rm) {
 7038:                 case 0: /* monitor */
 7039:                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
 7040:                         s->cpl != 0)
 7041:                         goto illegal_op;
 7042:                     if (s->cc_op != CC_OP_DYNAMIC)
 7043:                         gen_op_set_cc_op(s->cc_op);
 7044:                     gen_jmp_im(pc_start - s->cs_base);
 7045: #ifdef TARGET_X86_64
 7046:                     if (s->aflag == 2) {
 7047:                         gen_op_movq_A0_reg(R_EAX);
 7048:                     } else
 7049: #endif
 7050:                     {
 7051:                         gen_op_movl_A0_reg(R_EAX);
 7052:                         if (s->aflag == 0)
 7053:                             gen_op_andl_A0_ffff();
 7054:                     }
 7055:                     gen_add_A0_ds_seg(s);
 7056:                     gen_helper_monitor(cpu_A0);
 7057:                     break;
 7058:                 case 1: /* mwait */
 7059:                     if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
 7060:                         s->cpl != 0)
 7061:                         goto illegal_op;
 7062:                     gen_update_cc_op(s);
 7063:                     gen_jmp_im(pc_start - s->cs_base);
 7064:                     gen_helper_mwait(tcg_const_i32(s->pc - pc_start));
 7065:                     gen_eob(s);
 7066:                     break;
 7067:                 default:
 7068:                     goto illegal_op;
 7069:                 }
 7070:             } else { /* sidt */
 7071:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
 7072:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7073:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit));
 7074:                 gen_op_st_T0_A0(OT_WORD + s->mem_index);
 7075:                 gen_add_A0_im(s, 2);
 7076:                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base));
 7077:                 if (!s->dflag)
 7078:                     gen_op_andl_T0_im(0xffffff);
 7079:                 gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
 7080:             }
 7081:             break;
 7082:         case 2: /* lgdt */
 7083:         case 3: /* lidt */
 7084:             if (mod == 3) {
 7085:                 if (s->cc_op != CC_OP_DYNAMIC)
 7086:                     gen_op_set_cc_op(s->cc_op);
 7087:                 gen_jmp_im(pc_start - s->cs_base);
 7088:                 switch(rm) {
 7089:                 case 0: /* VMRUN */
 7090:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
 7091:                         goto illegal_op;
 7092:                     if (s->cpl != 0) {
 7093:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7094:                         break;
 7095:                     } else {
 7096:                         gen_helper_vmrun(tcg_const_i32(s->aflag),
 7097:                                          tcg_const_i32(s->pc - pc_start));
 7098:                         tcg_gen_exit_tb(0);
 7099:                         s->is_jmp = DISAS_TB_JUMP;
 7100:                     }
 7101:                     break;
 7102:                 case 1: /* VMMCALL */
 7103:                     if (!(s->flags & HF_SVME_MASK))
 7104:                         goto illegal_op;
 7105:                     gen_helper_vmmcall();
 7106:                     break;
 7107:                 case 2: /* VMLOAD */
 7108:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
 7109:                         goto illegal_op;
 7110:                     if (s->cpl != 0) {
 7111:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7112:                         break;
 7113:                     } else {
 7114:                         gen_helper_vmload(tcg_const_i32(s->aflag));
 7115:                     }
 7116:                     break;
 7117:                 case 3: /* VMSAVE */
 7118:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
 7119:                         goto illegal_op;
 7120:                     if (s->cpl != 0) {
 7121:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7122:                         break;
 7123:                     } else {
 7124:                         gen_helper_vmsave(tcg_const_i32(s->aflag));
 7125:                     }
 7126:                     break;
 7127:                 case 4: /* STGI */
 7128:                     if ((!(s->flags & HF_SVME_MASK) &&
 7129:                          !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
 7130:                         !s->pe)
 7131:                         goto illegal_op;
 7132:                     if (s->cpl != 0) {
 7133:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7134:                         break;
 7135:                     } else {
 7136:                         gen_helper_stgi();
 7137:                     }
 7138:                     break;
 7139:                 case 5: /* CLGI */
 7140:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
 7141:                         goto illegal_op;
 7142:                     if (s->cpl != 0) {
 7143:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7144:                         break;
 7145:                     } else {
 7146:                         gen_helper_clgi();
 7147:                     }
 7148:                     break;
 7149:                 case 6: /* SKINIT */
 7150:                     if ((!(s->flags & HF_SVME_MASK) && 
 7151:                          !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || 
 7152:                         !s->pe)
 7153:                         goto illegal_op;
 7154:                     gen_helper_skinit();
 7155:                     break;
 7156:                 case 7: /* INVLPGA */
 7157:                     if (!(s->flags & HF_SVME_MASK) || !s->pe)
 7158:                         goto illegal_op;
 7159:                     if (s->cpl != 0) {
 7160:                         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7161:                         break;
 7162:                     } else {
 7163:                         gen_helper_invlpga(tcg_const_i32(s->aflag));
 7164:                     }
 7165:                     break;
 7166:                 default:
 7167:                     goto illegal_op;
 7168:                 }
 7169:             } else if (s->cpl != 0) {
 7170:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7171:             } else {
 7172:                 gen_svm_check_intercept(s, pc_start,
 7173:                                         op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE);
 7174:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7175:                 gen_op_ld_T1_A0(OT_WORD + s->mem_index);
 7176:                 gen_add_A0_im(s, 2);
 7177:                 gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
 7178:                 if (!s->dflag)
 7179:                     gen_op_andl_T0_im(0xffffff);
 7180:                 if (op == 2) {
 7181:                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base));
 7182:                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit));
 7183:                 } else {
 7184:                     tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,idt.base));
 7185:                     tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,idt.limit));
 7186:                 }
 7187:             }
 7188:             break;
 7189:         case 4: /* smsw */
 7190:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
 7191: #if defined TARGET_X86_64 && defined HOST_WORDS_BIGENDIAN
 7192:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]) + 4);
 7193: #else
 7194:             tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0]));
 7195: #endif
 7196:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
 7197:             break;
 7198:         case 6: /* lmsw */
 7199:             if (s->cpl != 0) {
 7200:                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7201:             } else {
 7202:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
 7203:                 gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 7204:                 gen_helper_lmsw(cpu_T[0]);
 7205:                 gen_jmp_im(s->pc - s->cs_base);
 7206:                 gen_eob(s);
 7207:             }
 7208:             break;
 7209:         case 7:
 7210:             if (mod != 3) { /* invlpg */
 7211:                 if (s->cpl != 0) {
 7212:                     gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7213:                 } else {
 7214:                     if (s->cc_op != CC_OP_DYNAMIC)
 7215:                         gen_op_set_cc_op(s->cc_op);
 7216:                     gen_jmp_im(pc_start - s->cs_base);
 7217:                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7218:                     gen_helper_invlpg(cpu_A0);
 7219:                     gen_jmp_im(s->pc - s->cs_base);
 7220:                     gen_eob(s);
 7221:                 }
 7222:             } else {
 7223:                 switch (rm) {
 7224:                 case 0: /* swapgs */
 7225: #ifdef TARGET_X86_64
 7226:                     if (CODE64(s)) {
 7227:                         if (s->cpl != 0) {
 7228:                             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7229:                         } else {
 7230:                             tcg_gen_ld_tl(cpu_T[0], cpu_env,
 7231:                                 offsetof(CPUX86State,segs[R_GS].base));
 7232:                             tcg_gen_ld_tl(cpu_T[1], cpu_env,
 7233:                                 offsetof(CPUX86State,kernelgsbase));
 7234:                             tcg_gen_st_tl(cpu_T[1], cpu_env,
 7235:                                 offsetof(CPUX86State,segs[R_GS].base));
 7236:                             tcg_gen_st_tl(cpu_T[0], cpu_env,
 7237:                                 offsetof(CPUX86State,kernelgsbase));
 7238:                         }
 7239:                     } else
 7240: #endif
 7241:                     {
 7242:                         goto illegal_op;
 7243:                     }
 7244:                     break;
 7245:                 case 1: /* rdtscp */
 7246:                     if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
 7247:                         goto illegal_op;
 7248:                     if (s->cc_op != CC_OP_DYNAMIC)
 7249:                         gen_op_set_cc_op(s->cc_op);
 7250:                     gen_jmp_im(pc_start - s->cs_base);
 7251:                     if (use_icount)
 7252:                         gen_io_start();
 7253:                     gen_helper_rdtscp();
 7254:                     if (use_icount) {
 7255:                         gen_io_end();
 7256:                         gen_jmp(s, s->pc - s->cs_base);
 7257:                     }
 7258:                     break;
 7259:                 default:
 7260:                     goto illegal_op;
 7261:                 }
 7262:             }
 7263:             break;
 7264:         default:
 7265:             goto illegal_op;
 7266:         }
 7267:         break;
 7268:     case 0x108: /* invd */
 7269:     case 0x109: /* wbinvd */
 7270:         if (s->cpl != 0) {
 7271:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7272:         } else {
 7273:             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
 7274:             /* nothing to do */
 7275:         }
 7276:         break;
 7277:     case 0x63: /* arpl or movslS (x86_64) */
 7278: #ifdef TARGET_X86_64
 7279:         if (CODE64(s)) {
 7280:             int d_ot;
 7281:             /* d_ot is the size of destination */
 7282:             d_ot = dflag + OT_WORD;
 7283: 
 7284:             modrm = ldub_code(s->pc++);
 7285:             reg = ((modrm >> 3) & 7) | rex_r;
 7286:             mod = (modrm >> 6) & 3;
 7287:             rm = (modrm & 7) | REX_B(s);
 7288: 
 7289:             if (mod == 3) {
 7290:                 gen_op_mov_TN_reg(OT_LONG, 0, rm);
 7291:                 /* sign extend */
 7292:                 if (d_ot == OT_QUAD)
 7293:                     tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
 7294:                 gen_op_mov_reg_T0(d_ot, reg);
 7295:             } else {
 7296:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7297:                 if (d_ot == OT_QUAD) {
 7298:                     gen_op_lds_T0_A0(OT_LONG + s->mem_index);
 7299:                 } else {
 7300:                     gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 7301:                 }
 7302:                 gen_op_mov_reg_T0(d_ot, reg);
 7303:             }
 7304:         } else
 7305: #endif
 7306:         {
 7307:             int label1;
 7308:             TCGv t0, t1, t2, a0;
 7309: 
 7310:             if (!s->pe || s->vm86)
 7311:                 goto illegal_op;
 7312:             t0 = tcg_temp_local_new();
 7313:             t1 = tcg_temp_local_new();
 7314:             t2 = tcg_temp_local_new();
 7315:             ot = OT_WORD;
 7316:             modrm = ldub_code(s->pc++);
 7317:             reg = (modrm >> 3) & 7;
 7318:             mod = (modrm >> 6) & 3;
 7319:             rm = modrm & 7;
 7320:             if (mod != 3) {
 7321:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7322:                 gen_op_ld_v(ot + s->mem_index, t0, cpu_A0);
 7323:                 a0 = tcg_temp_local_new();
 7324:                 tcg_gen_mov_tl(a0, cpu_A0);
 7325:             } else {
 7326:                 gen_op_mov_v_reg(ot, t0, rm);
 7327:                 TCGV_UNUSED(a0);
 7328:             }
 7329:             gen_op_mov_v_reg(ot, t1, reg);
 7330:             tcg_gen_andi_tl(cpu_tmp0, t0, 3);
 7331:             tcg_gen_andi_tl(t1, t1, 3);
 7332:             tcg_gen_movi_tl(t2, 0);
 7333:             label1 = gen_new_label();
 7334:             tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, t1, label1);
 7335:             tcg_gen_andi_tl(t0, t0, ~3);
 7336:             tcg_gen_or_tl(t0, t0, t1);
 7337:             tcg_gen_movi_tl(t2, CC_Z);
 7338:             gen_set_label(label1);
 7339:             if (mod != 3) {
 7340:                 gen_op_st_v(ot + s->mem_index, t0, a0);
 7341:                 tcg_temp_free(a0);
 7342:            } else {
 7343:                 gen_op_mov_reg_v(ot, rm, t0);
 7344:             }
 7345:             if (s->cc_op != CC_OP_DYNAMIC)
 7346:                 gen_op_set_cc_op(s->cc_op);
 7347:             gen_compute_eflags(cpu_cc_src);
 7348:             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
 7349:             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
 7350:             s->cc_op = CC_OP_EFLAGS;
 7351:             tcg_temp_free(t0);
 7352:             tcg_temp_free(t1);
 7353:             tcg_temp_free(t2);
 7354:         }
 7355:         break;
 7356:     case 0x102: /* lar */
 7357:     case 0x103: /* lsl */
 7358:         {
 7359:             int label1;
 7360:             TCGv t0;
 7361:             if (!s->pe || s->vm86)
 7362:                 goto illegal_op;
 7363:             ot = dflag ? OT_LONG : OT_WORD;
 7364:             modrm = ldub_code(s->pc++);
 7365:             reg = ((modrm >> 3) & 7) | rex_r;
 7366:             gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
 7367:             t0 = tcg_temp_local_new();
 7368:             if (s->cc_op != CC_OP_DYNAMIC)
 7369:                 gen_op_set_cc_op(s->cc_op);
 7370:             if (b == 0x102)
 7371:                 gen_helper_lar(t0, cpu_T[0]);
 7372:             else
 7373:                 gen_helper_lsl(t0, cpu_T[0]);
 7374:             tcg_gen_andi_tl(cpu_tmp0, cpu_cc_src, CC_Z);
 7375:             label1 = gen_new_label();
 7376:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1);
 7377:             gen_op_mov_reg_v(ot, reg, t0);
 7378:             gen_set_label(label1);
 7379:             s->cc_op = CC_OP_EFLAGS;
 7380:             tcg_temp_free(t0);
 7381:         }
 7382:         break;
 7383:     case 0x118:
 7384:         modrm = ldub_code(s->pc++);
 7385:         mod = (modrm >> 6) & 3;
 7386:         op = (modrm >> 3) & 7;
 7387:         switch(op) {
 7388:         case 0: /* prefetchnta */
 7389:         case 1: /* prefetchnt0 */
 7390:         case 2: /* prefetchnt0 */
 7391:         case 3: /* prefetchnt0 */
 7392:             if (mod == 3)
 7393:                 goto illegal_op;
 7394:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7395:             /* nothing more to do */
 7396:             break;
 7397:         default: /* nop (multi byte) */
 7398:             gen_nop_modrm(s, modrm);
 7399:             break;
 7400:         }
 7401:         break;
 7402:     case 0x119 ... 0x11f: /* nop (multi byte) */
 7403:         modrm = ldub_code(s->pc++);
 7404:         gen_nop_modrm(s, modrm);
 7405:         break;
 7406:     case 0x120: /* mov reg, crN */
 7407:     case 0x122: /* mov crN, reg */
 7408:         if (s->cpl != 0) {
 7409:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7410:         } else {
 7411:             modrm = ldub_code(s->pc++);
 7412:             if ((modrm & 0xc0) != 0xc0)
 7413:                 goto illegal_op;
 7414:             rm = (modrm & 7) | REX_B(s);
 7415:             reg = ((modrm >> 3) & 7) | rex_r;
 7416:             if (CODE64(s))
 7417:                 ot = OT_QUAD;
 7418:             else
 7419:                 ot = OT_LONG;
 7420:             if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
 7421:                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
 7422:                 reg = 8;
 7423:             }
 7424:             switch(reg) {
 7425:             case 0:
 7426:             case 2:
 7427:             case 3:
 7428:             case 4:
 7429:             case 8:
 7430:                 if (s->cc_op != CC_OP_DYNAMIC)
 7431:                     gen_op_set_cc_op(s->cc_op);
 7432:                 gen_jmp_im(pc_start - s->cs_base);
 7433:                 if (b & 2) {
 7434:                     gen_op_mov_TN_reg(ot, 0, rm);
 7435:                     gen_helper_write_crN(tcg_const_i32(reg), cpu_T[0]);
 7436:                     gen_jmp_im(s->pc - s->cs_base);
 7437:                     gen_eob(s);
 7438:                 } else {
 7439:                     gen_helper_read_crN(cpu_T[0], tcg_const_i32(reg));
 7440:                     gen_op_mov_reg_T0(ot, rm);
 7441:                 }
 7442:                 break;
 7443:             default:
 7444:                 goto illegal_op;
 7445:             }
 7446:         }
 7447:         break;
 7448:     case 0x121: /* mov reg, drN */
 7449:     case 0x123: /* mov drN, reg */
 7450:         if (s->cpl != 0) {
 7451:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7452:         } else {
 7453:             modrm = ldub_code(s->pc++);
 7454:             if ((modrm & 0xc0) != 0xc0)
 7455:                 goto illegal_op;
 7456:             rm = (modrm & 7) | REX_B(s);
 7457:             reg = ((modrm >> 3) & 7) | rex_r;
 7458:             if (CODE64(s))
 7459:                 ot = OT_QUAD;
 7460:             else
 7461:                 ot = OT_LONG;
 7462:             /* XXX: do it dynamically with CR4.DE bit */
 7463:             if (reg == 4 || reg == 5 || reg >= 8)
 7464:                 goto illegal_op;
 7465:             if (b & 2) {
 7466:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
 7467:                 gen_op_mov_TN_reg(ot, 0, rm);
 7468:                 gen_helper_movl_drN_T0(tcg_const_i32(reg), cpu_T[0]);
 7469:                 gen_jmp_im(s->pc - s->cs_base);
 7470:                 gen_eob(s);
 7471:             } else {
 7472:                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
 7473:                 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
 7474:                 gen_op_mov_reg_T0(ot, rm);
 7475:             }
 7476:         }
 7477:         break;
 7478:     case 0x106: /* clts */
 7479:         if (s->cpl != 0) {
 7480:             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
 7481:         } else {
 7482:             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
 7483:             gen_helper_clts();
 7484:             /* abort block because static cpu state changed */
 7485:             gen_jmp_im(s->pc - s->cs_base);
 7486:             gen_eob(s);
 7487:         }
 7488:         break;
 7489:     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
 7490:     case 0x1c3: /* MOVNTI reg, mem */
 7491:         if (!(s->cpuid_features & CPUID_SSE2))
 7492:             goto illegal_op;
 7493:         ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
 7494:         modrm = ldub_code(s->pc++);
 7495:         mod = (modrm >> 6) & 3;
 7496:         if (mod == 3)
 7497:             goto illegal_op;
 7498:         reg = ((modrm >> 3) & 7) | rex_r;
 7499:         /* generate a generic store */
 7500:         gen_ldst_modrm(s, modrm, ot, reg, 1);
 7501:         break;
 7502:     case 0x1ae:
 7503:         modrm = ldub_code(s->pc++);
 7504:         mod = (modrm >> 6) & 3;
 7505:         op = (modrm >> 3) & 7;
 7506:         switch(op) {
 7507:         case 0: /* fxsave */
 7508:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
 7509:                 (s->prefix & PREFIX_LOCK))
 7510:                 goto illegal_op;
 7511:             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
 7512:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 7513:                 break;
 7514:             }
 7515:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7516:             if (s->cc_op != CC_OP_DYNAMIC)
 7517:                 gen_op_set_cc_op(s->cc_op);
 7518:             gen_jmp_im(pc_start - s->cs_base);
 7519:             gen_helper_fxsave(cpu_A0, tcg_const_i32((s->dflag == 2)));
 7520:             break;
 7521:         case 1: /* fxrstor */
 7522:             if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) ||
 7523:                 (s->prefix & PREFIX_LOCK))
 7524:                 goto illegal_op;
 7525:             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
 7526:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 7527:                 break;
 7528:             }
 7529:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7530:             if (s->cc_op != CC_OP_DYNAMIC)
 7531:                 gen_op_set_cc_op(s->cc_op);
 7532:             gen_jmp_im(pc_start - s->cs_base);
 7533:             gen_helper_fxrstor(cpu_A0, tcg_const_i32((s->dflag == 2)));
 7534:             break;
 7535:         case 2: /* ldmxcsr */
 7536:         case 3: /* stmxcsr */
 7537:             if (s->flags & HF_TS_MASK) {
 7538:                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
 7539:                 break;
 7540:             }
 7541:             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
 7542:                 mod == 3)
 7543:                 goto illegal_op;
 7544:             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7545:             if (op == 2) {
 7546:                 gen_op_ld_T0_A0(OT_LONG + s->mem_index);
 7547:                 tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
 7548:             } else {
 7549:                 tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr));
 7550:                 gen_op_st_T0_A0(OT_LONG + s->mem_index);
 7551:             }
 7552:             break;
 7553:         case 5: /* lfence */
 7554:         case 6: /* mfence */
 7555:             if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
 7556:                 goto illegal_op;
 7557:             break;
 7558:         case 7: /* sfence / clflush */
 7559:             if ((modrm & 0xc7) == 0xc0) {
 7560:                 /* sfence */
 7561:                 /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
 7562:                 if (!(s->cpuid_features & CPUID_SSE))
 7563:                     goto illegal_op;
 7564:             } else {
 7565:                 /* clflush */
 7566:                 if (!(s->cpuid_features & CPUID_CLFLUSH))
 7567:                     goto illegal_op;
 7568:                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7569:             }
 7570:             break;
 7571:         default:
 7572:             goto illegal_op;
 7573:         }
 7574:         break;
 7575:     case 0x10d: /* 3DNow! prefetch(w) */
 7576:         modrm = ldub_code(s->pc++);
 7577:         mod = (modrm >> 6) & 3;
 7578:         if (mod == 3)
 7579:             goto illegal_op;
 7580:         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 7581:         /* ignore for now */
 7582:         break;
 7583:     case 0x1aa: /* rsm */
 7584:         gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
 7585:         if (!(s->flags & HF_SMM_MASK))
 7586:             goto illegal_op;
 7587:         gen_update_cc_op(s);
 7588:         gen_jmp_im(s->pc - s->cs_base);
 7589:         gen_helper_rsm();
 7590:         gen_eob(s);
 7591:         break;
 7592:     case 0x1b8: /* SSE4.2 popcnt */
 7593:         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
 7594:              PREFIX_REPZ)
 7595:             goto illegal_op;
 7596:         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
 7597:             goto illegal_op;
 7598: 
 7599:         modrm = ldub_code(s->pc++);
 7600:         reg = ((modrm >> 3) & 7);
 7601: 
 7602:         if (s->prefix & PREFIX_DATA)
 7603:             ot = OT_WORD;
 7604:         else if (s->dflag != 2)
 7605:             ot = OT_LONG;
 7606:         else
 7607:             ot = OT_QUAD;
 7608: 
 7609:         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
 7610:         gen_helper_popcnt(cpu_T[0], cpu_T[0], tcg_const_i32(ot));
 7611:         gen_op_mov_reg_T0(ot, reg);
 7612: 
 7613:         s->cc_op = CC_OP_EFLAGS;
 7614:         break;
 7615:     case 0x10e ... 0x10f:
 7616:         /* 3DNow! instructions, ignore prefixes */
 7617:         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
 7618:     case 0x110 ... 0x117:
 7619:     case 0x128 ... 0x12f:
 7620:     case 0x138 ... 0x13a:
 7621:     case 0x150 ... 0x179:
 7622:     case 0x17c ... 0x17f:
 7623:     case 0x1c2:
 7624:     case 0x1c4 ... 0x1c6:
 7625:     case 0x1d0 ... 0x1fe:
 7626:         gen_sse(s, b, pc_start, rex_r);
 7627:         break;
 7628:     default:
 7629:         goto illegal_op;
 7630:     }
 7631:     /* lock generation */
 7632:     if (s->prefix & PREFIX_LOCK)
 7633:         gen_helper_unlock();
 7634:     return s->pc;
 7635:  illegal_op:
 7636:     if (s->prefix & PREFIX_LOCK)
 7637:         gen_helper_unlock();
 7638:     /* XXX: ensure that no lock was generated */
 7639:     gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
 7640:     return s->pc;
 7641: }
 7642: 
 7643: void optimize_flags_init(void)
 7644: {
 7645:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 7646:     cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,
 7647:                                        offsetof(CPUState, cc_op), "cc_op");
 7648:     cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
 7649:                                     "cc_src");
 7650:     cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
 7651:                                     "cc_dst");
 7652:     cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_tmp),
 7653:                                     "cc_tmp");
 7654: 
 7655: #ifdef TARGET_X86_64
 7656:     cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
 7657:                                              offsetof(CPUState, regs[R_EAX]), "rax");
 7658:     cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,
 7659:                                              offsetof(CPUState, regs[R_ECX]), "rcx");
 7660:     cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,
 7661:                                              offsetof(CPUState, regs[R_EDX]), "rdx");
 7662:     cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,
 7663:                                              offsetof(CPUState, regs[R_EBX]), "rbx");
 7664:     cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,
 7665:                                              offsetof(CPUState, regs[R_ESP]), "rsp");
 7666:     cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,
 7667:                                              offsetof(CPUState, regs[R_EBP]), "rbp");
 7668:     cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,
 7669:                                              offsetof(CPUState, regs[R_ESI]), "rsi");
 7670:     cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,
 7671:                                              offsetof(CPUState, regs[R_EDI]), "rdi");
 7672:     cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,
 7673:                                          offsetof(CPUState, regs[8]), "r8");
 7674:     cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,
 7675:                                           offsetof(CPUState, regs[9]), "r9");
 7676:     cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,
 7677:                                           offsetof(CPUState, regs[10]), "r10");
 7678:     cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,
 7679:                                           offsetof(CPUState, regs[11]), "r11");
 7680:     cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,
 7681:                                           offsetof(CPUState, regs[12]), "r12");
 7682:     cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,
 7683:                                           offsetof(CPUState, regs[13]), "r13");
 7684:     cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,
 7685:                                           offsetof(CPUState, regs[14]), "r14");
 7686:     cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
 7687:                                           offsetof(CPUState, regs[15]), "r15");
 7688: #else
 7689:     cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,
 7690:                                              offsetof(CPUState, regs[R_EAX]), "eax");
 7691:     cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,
 7692:                                              offsetof(CPUState, regs[R_ECX]), "ecx");
 7693:     cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,
 7694:                                              offsetof(CPUState, regs[R_EDX]), "edx");
 7695:     cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,
 7696:                                              offsetof(CPUState, regs[R_EBX]), "ebx");
 7697:     cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,
 7698:                                              offsetof(CPUState, regs[R_ESP]), "esp");
 7699:     cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,
 7700:                                              offsetof(CPUState, regs[R_EBP]), "ebp");
 7701:     cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,
 7702:                                              offsetof(CPUState, regs[R_ESI]), "esi");
 7703:     cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,
 7704:                                              offsetof(CPUState, regs[R_EDI]), "edi");
 7705: #endif
 7706: 
 7707:     /* register helpers */
 7708: #define GEN_HELPER 2
 7709: #include "helper.h"
 7710: }
 7711: 
 7712: /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
 7713:    basic block 'tb'. If search_pc is TRUE, also generate PC
 7714:    information for each intermediate instruction. */
 7715: static inline void gen_intermediate_code_internal(CPUState *env,
 7716:                                                   TranslationBlock *tb,
 7717:                                                   int search_pc)
 7718: {
 7719:     DisasContext dc1, *dc = &dc1;
 7720:     target_ulong pc_ptr;
 7721:     uint16_t *gen_opc_end;
 7722:     CPUBreakpoint *bp;
 7723:     int j, lj;
 7724:     uint64_t flags;
 7725:     target_ulong pc_start;
 7726:     target_ulong cs_base;
 7727:     int num_insns;
 7728:     int max_insns;
 7729: 
 7730:     /* generate intermediate code */
 7731:     pc_start = tb->pc;
 7732:     cs_base = tb->cs_base;
 7733:     flags = tb->flags;
 7734: 
 7735:     dc->pe = (flags >> HF_PE_SHIFT) & 1;
 7736:     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
 7737:     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
 7738:     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
 7739:     dc->f_st = 0;
 7740:     dc->vm86 = (flags >> VM_SHIFT) & 1;
 7741:     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
 7742:     dc->iopl = (flags >> IOPL_SHIFT) & 3;
 7743:     dc->tf = (flags >> TF_SHIFT) & 1;
 7744:     dc->singlestep_enabled = env->singlestep_enabled;
 7745:     dc->cc_op = CC_OP_DYNAMIC;
 7746:     dc->cs_base = cs_base;
 7747:     dc->tb = tb;
 7748:     dc->popl_esp_hack = 0;
 7749:     /* select memory access functions */
 7750:     dc->mem_index = 0;
 7751:     if (flags & HF_SOFTMMU_MASK) {
 7752:         if (dc->cpl == 3)
 7753:             dc->mem_index = 2 * 4;
 7754:         else
 7755:             dc->mem_index = 1 * 4;
 7756:     }
 7757:     dc->cpuid_features = env->cpuid_features;
 7758:     dc->cpuid_ext_features = env->cpuid_ext_features;
 7759:     dc->cpuid_ext2_features = env->cpuid_ext2_features;
 7760:     dc->cpuid_ext3_features = env->cpuid_ext3_features;
 7761: #ifdef TARGET_X86_64
 7762:     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
 7763:     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 7764: #endif
 7765:     dc->flags = flags;
 7766:     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
 7767:                     (flags & HF_INHIBIT_IRQ_MASK)
 7768: #ifndef CONFIG_SOFTMMU
 7769:                     || (flags & HF_SOFTMMU_MASK)
 7770: #endif
 7771:                     );
 7772: #if 0
 7773:     /* check addseg logic */
 7774:     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
 7775:         printf("ERROR addseg\n");
 7776: #endif
 7777: 
 7778:     cpu_T[0] = tcg_temp_new();
 7779:     cpu_T[1] = tcg_temp_new();
 7780:     cpu_A0 = tcg_temp_new();
 7781:     cpu_T3 = tcg_temp_new();
 7782: 
 7783:     cpu_tmp0 = tcg_temp_new();
 7784:     cpu_tmp1_i64 = tcg_temp_new_i64();
 7785:     cpu_tmp2_i32 = tcg_temp_new_i32();
 7786:     cpu_tmp3_i32 = tcg_temp_new_i32();
 7787:     cpu_tmp4 = tcg_temp_new();
 7788:     cpu_tmp5 = tcg_temp_new();
 7789:     cpu_ptr0 = tcg_temp_new_ptr();
 7790:     cpu_ptr1 = tcg_temp_new_ptr();
 7791: 
 7792:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 7793: 
 7794:     dc->is_jmp = DISAS_NEXT;
 7795:     pc_ptr = pc_start;
 7796:     lj = -1;
 7797:     num_insns = 0;
 7798:     max_insns = tb->cflags & CF_COUNT_MASK;
 7799:     if (max_insns == 0)
 7800:         max_insns = CF_COUNT_MASK;
 7801: 
 7802:     gen_icount_start();
 7803:     for(;;) {
 7804:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
 7805:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
 7806:                 if (bp->pc == pc_ptr &&
 7807:                     !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
 7808:                     gen_debug(dc, pc_ptr - dc->cs_base);
 7809:                     break;
 7810:                 }
 7811:             }
 7812:         }
 7813:         if (search_pc) {
 7814:             j = gen_opc_ptr - gen_opc_buf;
 7815:             if (lj < j) {
 7816:                 lj++;
 7817:                 while (lj < j)
 7818:                     gen_opc_instr_start[lj++] = 0;
 7819:             }
 7820:             gen_opc_pc[lj] = pc_ptr;
 7821:             gen_opc_cc_op[lj] = dc->cc_op;
 7822:             gen_opc_instr_start[lj] = 1;
 7823:             gen_opc_icount[lj] = num_insns;
 7824:         }
 7825:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
 7826:             gen_io_start();
 7827: 
 7828:         pc_ptr = disas_insn(dc, pc_ptr);
 7829:         num_insns++;
 7830:         /* stop translation if indicated */
 7831:         if (dc->is_jmp)
 7832:             break;
 7833:         /* if single step mode, we generate only one instruction and
 7834:            generate an exception */
 7835:         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
 7836:            the flag and abort the translation to give the irqs a
 7837:            change to be happen */
 7838:         if (dc->tf || dc->singlestep_enabled ||
 7839:             (flags & HF_INHIBIT_IRQ_MASK)) {
 7840:             gen_jmp_im(pc_ptr - dc->cs_base);
 7841:             gen_eob(dc);
 7842:             break;
 7843:         }
 7844:         /* if too long translation, stop generation too */
 7845:         if (gen_opc_ptr >= gen_opc_end ||
 7846:             (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
 7847:             num_insns >= max_insns) {
 7848:             gen_jmp_im(pc_ptr - dc->cs_base);
 7849:             gen_eob(dc);
 7850:             break;
 7851:         }
 7852:         if (singlestep) {
 7853:             gen_jmp_im(pc_ptr - dc->cs_base);
 7854:             gen_eob(dc);
 7855:             break;
 7856:         }
 7857:     }
 7858:     if (tb->cflags & CF_LAST_IO)
 7859:         gen_io_end();
 7860:     gen_icount_end(tb, num_insns);
 7861:     *gen_opc_ptr = INDEX_op_end;
 7862:     /* we don't forget to fill the last values */
 7863:     if (search_pc) {
 7864:         j = gen_opc_ptr - gen_opc_buf;
 7865:         lj++;
 7866:         while (lj <= j)
 7867:             gen_opc_instr_start[lj++] = 0;
 7868:     }
 7869: 
 7870: #ifdef DEBUG_DISAS
 7871:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 7872:         int disas_flags;
 7873:         qemu_log("----------------\n");
 7874:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
 7875: #ifdef TARGET_X86_64
 7876:         if (dc->code64)
 7877:             disas_flags = 2;
 7878:         else
 7879: #endif
 7880:             disas_flags = !dc->code32;
 7881:         log_target_disas(pc_start, pc_ptr - pc_start, disas_flags);
 7882:         qemu_log("\n");
 7883:     }
 7884: #endif
 7885: 
 7886:     if (!search_pc) {
 7887:         tb->size = pc_ptr - pc_start;
 7888:         tb->icount = num_insns;
 7889:     }
 7890: }
 7891: 
 7892: void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
 7893: {
 7894:     gen_intermediate_code_internal(env, tb, 0);
 7895: }
 7896: 
 7897: void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
 7898: {
 7899:     gen_intermediate_code_internal(env, tb, 1);
 7900: }
 7901: 
 7902: void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 7903: {
 7904:     int cc_op;
 7905: #ifdef DEBUG_DISAS
 7906:     if (qemu_loglevel_mask(CPU_LOG_TB_OP)) {
 7907:         int i;
 7908:         qemu_log("RESTORE:\n");
 7909:         for(i = 0;i <= pc_pos; i++) {
 7910:             if (gen_opc_instr_start[i]) {
 7911:                 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
 7912:             }
 7913:         }
 7914:         qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
 7915:                 pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
 7916:                 (uint32_t)tb->cs_base);
 7917:     }
 7918: #endif
 7919:     env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
 7920:     cc_op = gen_opc_cc_op[pc_pos];
 7921:     if (cc_op != CC_OP_DYNAMIC)
 7922:         env->cc_op = cc_op;
 7923: }

unix.superglobalmegacorp.com