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