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