qemu/target/i386/tcg/translate.c
<<
>>
Prefs
   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.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19#include "qemu/osdep.h"
  20
  21#include "qemu/host-utils.h"
  22#include "cpu.h"
  23#include "disas/disas.h"
  24#include "exec/exec-all.h"
  25#include "tcg/tcg-op.h"
  26#include "tcg/tcg-op-gvec.h"
  27#include "exec/cpu_ldst.h"
  28#include "exec/translator.h"
  29#include "fpu/softfloat.h"
  30
  31#include "exec/helper-proto.h"
  32#include "exec/helper-gen.h"
  33#include "helper-tcg.h"
  34
  35#include "exec/log.h"
  36
  37#define PREFIX_REPZ   0x01
  38#define PREFIX_REPNZ  0x02
  39#define PREFIX_LOCK   0x04
  40#define PREFIX_DATA   0x08
  41#define PREFIX_ADR    0x10
  42#define PREFIX_VEX    0x20
  43#define PREFIX_REX    0x40
  44
  45#ifdef TARGET_X86_64
  46# define ctztl  ctz64
  47# define clztl  clz64
  48#else
  49# define ctztl  ctz32
  50# define clztl  clz32
  51#endif
  52
  53/* For a switch indexed by MODRM, match all memory operands for a given OP.  */
  54#define CASE_MODRM_MEM_OP(OP) \
  55    case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
  56    case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
  57    case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
  58
  59#define CASE_MODRM_OP(OP) \
  60    case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
  61    case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
  62    case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
  63    case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
  64
  65//#define MACRO_TEST   1
  66
  67/* global register indexes */
  68static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
  69static TCGv cpu_eip;
  70static TCGv_i32 cpu_cc_op;
  71static TCGv cpu_regs[CPU_NB_REGS];
  72static TCGv cpu_seg_base[6];
  73static TCGv_i64 cpu_bndl[4];
  74static TCGv_i64 cpu_bndu[4];
  75
  76#include "exec/gen-icount.h"
  77
  78typedef struct DisasContext {
  79    DisasContextBase base;
  80
  81    target_ulong pc;       /* pc = eip + cs_base */
  82    target_ulong cs_base;  /* base of CS segment */
  83    target_ulong pc_save;
  84
  85    MemOp aflag;
  86    MemOp dflag;
  87
  88    int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
  89    uint8_t prefix;
  90
  91    bool has_modrm;
  92    uint8_t modrm;
  93
  94#ifndef CONFIG_USER_ONLY
  95    uint8_t cpl;   /* code priv level */
  96    uint8_t iopl;  /* i/o priv level */
  97#endif
  98    uint8_t vex_l;  /* vex vector length */
  99    uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
 100    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
 101    uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
 102
 103#ifdef TARGET_X86_64
 104    uint8_t rex_r;
 105    uint8_t rex_x;
 106    uint8_t rex_b;
 107#endif
 108    bool vex_w; /* used by AVX even on 32-bit processors */
 109    bool jmp_opt; /* use direct block chaining for direct jumps */
 110    bool repz_opt; /* optimize jumps within repz instructions */
 111    bool cc_op_dirty;
 112
 113    CCOp cc_op;  /* current CC operation */
 114    int mem_index; /* select memory access functions */
 115    uint32_t flags; /* all execution flags */
 116    int cpuid_features;
 117    int cpuid_ext_features;
 118    int cpuid_ext2_features;
 119    int cpuid_ext3_features;
 120    int cpuid_7_0_ebx_features;
 121    int cpuid_7_0_ecx_features;
 122    int cpuid_xsave_features;
 123
 124    /* TCG local temps */
 125    TCGv cc_srcT;
 126    TCGv A0;
 127    TCGv T0;
 128    TCGv T1;
 129
 130    /* TCG local register indexes (only used inside old micro ops) */
 131    TCGv tmp0;
 132    TCGv tmp4;
 133    TCGv_i32 tmp2_i32;
 134    TCGv_i32 tmp3_i32;
 135    TCGv_i64 tmp1_i64;
 136
 137    sigjmp_buf jmpbuf;
 138    TCGOp *prev_insn_end;
 139} DisasContext;
 140
 141#define DISAS_EOB_ONLY         DISAS_TARGET_0
 142#define DISAS_EOB_NEXT         DISAS_TARGET_1
 143#define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_2
 144#define DISAS_JUMP             DISAS_TARGET_3
 145
 146/* The environment in which user-only runs is constrained. */
 147#ifdef CONFIG_USER_ONLY
 148#define PE(S)     true
 149#define CPL(S)    3
 150#define IOPL(S)   0
 151#define SVME(S)   false
 152#define GUEST(S)  false
 153#else
 154#define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
 155#define CPL(S)    ((S)->cpl)
 156#define IOPL(S)   ((S)->iopl)
 157#define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
 158#define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
 159#endif
 160#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
 161#define VM86(S)   false
 162#define CODE32(S) true
 163#define SS32(S)   true
 164#define ADDSEG(S) false
 165#else
 166#define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
 167#define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
 168#define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
 169#define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
 170#endif
 171#if !defined(TARGET_X86_64)
 172#define CODE64(S) false
 173#define LMA(S)    false
 174#elif defined(CONFIG_USER_ONLY)
 175#define CODE64(S) true
 176#define LMA(S)    true
 177#else
 178#define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
 179#define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
 180#endif
 181
 182#ifdef TARGET_X86_64
 183#define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
 184#define REX_W(S)       ((S)->vex_w)
 185#define REX_R(S)       ((S)->rex_r + 0)
 186#define REX_X(S)       ((S)->rex_x + 0)
 187#define REX_B(S)       ((S)->rex_b + 0)
 188#else
 189#define REX_PREFIX(S)  false
 190#define REX_W(S)       false
 191#define REX_R(S)       0
 192#define REX_X(S)       0
 193#define REX_B(S)       0
 194#endif
 195
 196/*
 197 * Many sysemu-only helpers are not reachable for user-only.
 198 * Define stub generators here, so that we need not either sprinkle
 199 * ifdefs through the translator, nor provide the helper function.
 200 */
 201#define STUB_HELPER(NAME, ...) \
 202    static inline void gen_helper_##NAME(__VA_ARGS__) \
 203    { qemu_build_not_reached(); }
 204
 205#ifdef CONFIG_USER_ONLY
 206STUB_HELPER(clgi, TCGv_env env)
 207STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
 208STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
 209STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
 210STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
 211STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
 212STUB_HELPER(monitor, TCGv_env env, TCGv addr)
 213STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
 214STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
 215STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
 216STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
 217STUB_HELPER(rdmsr, TCGv_env env)
 218STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
 219STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg)
 220STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
 221STUB_HELPER(stgi, TCGv_env env)
 222STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
 223STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
 224STUB_HELPER(vmmcall, TCGv_env env)
 225STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
 226STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
 227STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
 228STUB_HELPER(wrmsr, TCGv_env env)
 229#endif
 230
 231static void gen_eob(DisasContext *s);
 232static void gen_jr(DisasContext *s);
 233static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
 234static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num);
 235static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
 236static void gen_exception_gpf(DisasContext *s);
 237
 238/* i386 arith/logic operations */
 239enum {
 240    OP_ADDL,
 241    OP_ORL,
 242    OP_ADCL,
 243    OP_SBBL,
 244    OP_ANDL,
 245    OP_SUBL,
 246    OP_XORL,
 247    OP_CMPL,
 248};
 249
 250/* i386 shift ops */
 251enum {
 252    OP_ROL,
 253    OP_ROR,
 254    OP_RCL,
 255    OP_RCR,
 256    OP_SHL,
 257    OP_SHR,
 258    OP_SHL1, /* undocumented */
 259    OP_SAR = 7,
 260};
 261
 262enum {
 263    JCC_O,
 264    JCC_B,
 265    JCC_Z,
 266    JCC_BE,
 267    JCC_S,
 268    JCC_P,
 269    JCC_L,
 270    JCC_LE,
 271};
 272
 273enum {
 274    /* I386 int registers */
 275    OR_EAX,   /* MUST be even numbered */
 276    OR_ECX,
 277    OR_EDX,
 278    OR_EBX,
 279    OR_ESP,
 280    OR_EBP,
 281    OR_ESI,
 282    OR_EDI,
 283
 284    OR_TMP0 = 16,    /* temporary operand register */
 285    OR_TMP1,
 286    OR_A0, /* temporary register used when doing address evaluation */
 287};
 288
 289enum {
 290    USES_CC_DST  = 1,
 291    USES_CC_SRC  = 2,
 292    USES_CC_SRC2 = 4,
 293    USES_CC_SRCT = 8,
 294};
 295
 296/* Bit set if the global variable is live after setting CC_OP to X.  */
 297static const uint8_t cc_op_live[CC_OP_NB] = {
 298    [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 299    [CC_OP_EFLAGS] = USES_CC_SRC,
 300    [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
 301    [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
 302    [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 303    [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
 304    [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 305    [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
 306    [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
 307    [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
 308    [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
 309    [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
 310    [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
 311    [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
 312    [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
 313    [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
 314    [CC_OP_CLR] = 0,
 315    [CC_OP_POPCNT] = USES_CC_SRC,
 316};
 317
 318static void set_cc_op(DisasContext *s, CCOp op)
 319{
 320    int dead;
 321
 322    if (s->cc_op == op) {
 323        return;
 324    }
 325
 326    /* Discard CC computation that will no longer be used.  */
 327    dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
 328    if (dead & USES_CC_DST) {
 329        tcg_gen_discard_tl(cpu_cc_dst);
 330    }
 331    if (dead & USES_CC_SRC) {
 332        tcg_gen_discard_tl(cpu_cc_src);
 333    }
 334    if (dead & USES_CC_SRC2) {
 335        tcg_gen_discard_tl(cpu_cc_src2);
 336    }
 337    if (dead & USES_CC_SRCT) {
 338        tcg_gen_discard_tl(s->cc_srcT);
 339    }
 340
 341    if (op == CC_OP_DYNAMIC) {
 342        /* The DYNAMIC setting is translator only, and should never be
 343           stored.  Thus we always consider it clean.  */
 344        s->cc_op_dirty = false;
 345    } else {
 346        /* Discard any computed CC_OP value (see shifts).  */
 347        if (s->cc_op == CC_OP_DYNAMIC) {
 348            tcg_gen_discard_i32(cpu_cc_op);
 349        }
 350        s->cc_op_dirty = true;
 351    }
 352    s->cc_op = op;
 353}
 354
 355static void gen_update_cc_op(DisasContext *s)
 356{
 357    if (s->cc_op_dirty) {
 358        tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
 359        s->cc_op_dirty = false;
 360    }
 361}
 362
 363#ifdef TARGET_X86_64
 364
 365#define NB_OP_SIZES 4
 366
 367#else /* !TARGET_X86_64 */
 368
 369#define NB_OP_SIZES 3
 370
 371#endif /* !TARGET_X86_64 */
 372
 373#if HOST_BIG_ENDIAN
 374#define REG_B_OFFSET (sizeof(target_ulong) - 1)
 375#define REG_H_OFFSET (sizeof(target_ulong) - 2)
 376#define REG_W_OFFSET (sizeof(target_ulong) - 2)
 377#define REG_L_OFFSET (sizeof(target_ulong) - 4)
 378#define REG_LH_OFFSET (sizeof(target_ulong) - 8)
 379#else
 380#define REG_B_OFFSET 0
 381#define REG_H_OFFSET 1
 382#define REG_W_OFFSET 0
 383#define REG_L_OFFSET 0
 384#define REG_LH_OFFSET 4
 385#endif
 386
 387/* In instruction encodings for byte register accesses the
 388 * register number usually indicates "low 8 bits of register N";
 389 * however there are some special cases where N 4..7 indicates
 390 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
 391 * true for this special case, false otherwise.
 392 */
 393static inline bool byte_reg_is_xH(DisasContext *s, int reg)
 394{
 395    /* Any time the REX prefix is present, byte registers are uniform */
 396    if (reg < 4 || REX_PREFIX(s)) {
 397        return false;
 398    }
 399    return true;
 400}
 401
 402/* Select the size of a push/pop operation.  */
 403static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
 404{
 405    if (CODE64(s)) {
 406        return ot == MO_16 ? MO_16 : MO_64;
 407    } else {
 408        return ot;
 409    }
 410}
 411
 412/* Select the size of the stack pointer.  */
 413static inline MemOp mo_stacksize(DisasContext *s)
 414{
 415    return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
 416}
 417
 418/* Select only size 64 else 32.  Used for SSE operand sizes.  */
 419static inline MemOp mo_64_32(MemOp ot)
 420{
 421#ifdef TARGET_X86_64
 422    return ot == MO_64 ? MO_64 : MO_32;
 423#else
 424    return MO_32;
 425#endif
 426}
 427
 428/* Select size 8 if lsb of B is clear, else OT.  Used for decoding
 429   byte vs word opcodes.  */
 430static inline MemOp mo_b_d(int b, MemOp ot)
 431{
 432    return b & 1 ? ot : MO_8;
 433}
 434
 435/* Select size 8 if lsb of B is clear, else OT capped at 32.
 436   Used for decoding operand size of port opcodes.  */
 437static inline MemOp mo_b_d32(int b, MemOp ot)
 438{
 439    return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
 440}
 441
 442/* Compute the result of writing t0 to the OT-sized register REG.
 443 *
 444 * If DEST is NULL, store the result into the register and return the
 445 * register's TCGv.
 446 *
 447 * If DEST is not NULL, store the result into DEST and return the
 448 * register's TCGv.
 449 */
 450static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0)
 451{
 452    switch(ot) {
 453    case MO_8:
 454        if (byte_reg_is_xH(s, reg)) {
 455            dest = dest ? dest : cpu_regs[reg - 4];
 456            tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8);
 457            return cpu_regs[reg - 4];
 458        }
 459        dest = dest ? dest : cpu_regs[reg];
 460        tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8);
 461        break;
 462    case MO_16:
 463        dest = dest ? dest : cpu_regs[reg];
 464        tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16);
 465        break;
 466    case MO_32:
 467        /* For x86_64, this sets the higher half of register to zero.
 468           For i386, this is equivalent to a mov. */
 469        dest = dest ? dest : cpu_regs[reg];
 470        tcg_gen_ext32u_tl(dest, t0);
 471        break;
 472#ifdef TARGET_X86_64
 473    case MO_64:
 474        dest = dest ? dest : cpu_regs[reg];
 475        tcg_gen_mov_tl(dest, t0);
 476        break;
 477#endif
 478    default:
 479        tcg_abort();
 480    }
 481    return cpu_regs[reg];
 482}
 483
 484static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0)
 485{
 486    gen_op_deposit_reg_v(s, ot, reg, NULL, t0);
 487}
 488
 489static inline
 490void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
 491{
 492    if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
 493        tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
 494    } else {
 495        tcg_gen_mov_tl(t0, cpu_regs[reg]);
 496    }
 497}
 498
 499static void gen_add_A0_im(DisasContext *s, int val)
 500{
 501    tcg_gen_addi_tl(s->A0, s->A0, val);
 502    if (!CODE64(s)) {
 503        tcg_gen_ext32u_tl(s->A0, s->A0);
 504    }
 505}
 506
 507static inline void gen_op_jmp_v(DisasContext *s, TCGv dest)
 508{
 509    tcg_gen_mov_tl(cpu_eip, dest);
 510    s->pc_save = -1;
 511}
 512
 513static inline
 514void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val)
 515{
 516    tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val);
 517    gen_op_mov_reg_v(s, size, reg, s->tmp0);
 518}
 519
 520static inline void gen_op_add_reg_T0(DisasContext *s, MemOp size, int reg)
 521{
 522    tcg_gen_add_tl(s->tmp0, cpu_regs[reg], s->T0);
 523    gen_op_mov_reg_v(s, size, reg, s->tmp0);
 524}
 525
 526static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
 527{
 528    tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
 529}
 530
 531static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
 532{
 533    tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
 534}
 535
 536static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
 537{
 538    if (d == OR_TMP0) {
 539        gen_op_st_v(s, idx, s->T0, s->A0);
 540    } else {
 541        gen_op_mov_reg_v(s, idx, d, s->T0);
 542    }
 543}
 544
 545static void gen_update_eip_cur(DisasContext *s)
 546{
 547    assert(s->pc_save != -1);
 548    if (TARGET_TB_PCREL) {
 549        tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
 550    } else {
 551        tcg_gen_movi_tl(cpu_eip, s->base.pc_next - s->cs_base);
 552    }
 553    s->pc_save = s->base.pc_next;
 554}
 555
 556static void gen_update_eip_next(DisasContext *s)
 557{
 558    assert(s->pc_save != -1);
 559    if (TARGET_TB_PCREL) {
 560        tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
 561    } else {
 562        tcg_gen_movi_tl(cpu_eip, s->pc - s->cs_base);
 563    }
 564    s->pc_save = s->pc;
 565}
 566
 567static int cur_insn_len(DisasContext *s)
 568{
 569    return s->pc - s->base.pc_next;
 570}
 571
 572static TCGv_i32 cur_insn_len_i32(DisasContext *s)
 573{
 574    return tcg_constant_i32(cur_insn_len(s));
 575}
 576
 577static TCGv_i32 eip_next_i32(DisasContext *s)
 578{
 579    assert(s->pc_save != -1);
 580    /*
 581     * This function has two users: lcall_real (always 16-bit mode), and
 582     * iret_protected (16, 32, or 64-bit mode).  IRET only uses the value
 583     * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
 584     * why passing a 32-bit value isn't broken.  To avoid using this where
 585     * we shouldn't, return -1 in 64-bit mode so that execution goes into
 586     * the weeds quickly.
 587     */
 588    if (CODE64(s)) {
 589        return tcg_constant_i32(-1);
 590    }
 591    if (TARGET_TB_PCREL) {
 592        TCGv_i32 ret = tcg_temp_new_i32();
 593        tcg_gen_trunc_tl_i32(ret, cpu_eip);
 594        tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
 595        return ret;
 596    } else {
 597        return tcg_constant_i32(s->pc - s->cs_base);
 598    }
 599}
 600
 601static TCGv eip_next_tl(DisasContext *s)
 602{
 603    assert(s->pc_save != -1);
 604    if (TARGET_TB_PCREL) {
 605        TCGv ret = tcg_temp_new();
 606        tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
 607        return ret;
 608    } else {
 609        return tcg_constant_tl(s->pc - s->cs_base);
 610    }
 611}
 612
 613static TCGv eip_cur_tl(DisasContext *s)
 614{
 615    assert(s->pc_save != -1);
 616    if (TARGET_TB_PCREL) {
 617        TCGv ret = tcg_temp_new();
 618        tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
 619        return ret;
 620    } else {
 621        return tcg_constant_tl(s->base.pc_next - s->cs_base);
 622    }
 623}
 624
 625/* Compute SEG:REG into A0.  SEG is selected from the override segment
 626   (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
 627   indicate no override.  */
 628static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
 629                          int def_seg, int ovr_seg)
 630{
 631    switch (aflag) {
 632#ifdef TARGET_X86_64
 633    case MO_64:
 634        if (ovr_seg < 0) {
 635            tcg_gen_mov_tl(s->A0, a0);
 636            return;
 637        }
 638        break;
 639#endif
 640    case MO_32:
 641        /* 32 bit address */
 642        if (ovr_seg < 0 && ADDSEG(s)) {
 643            ovr_seg = def_seg;
 644        }
 645        if (ovr_seg < 0) {
 646            tcg_gen_ext32u_tl(s->A0, a0);
 647            return;
 648        }
 649        break;
 650    case MO_16:
 651        /* 16 bit address */
 652        tcg_gen_ext16u_tl(s->A0, a0);
 653        a0 = s->A0;
 654        if (ovr_seg < 0) {
 655            if (ADDSEG(s)) {
 656                ovr_seg = def_seg;
 657            } else {
 658                return;
 659            }
 660        }
 661        break;
 662    default:
 663        tcg_abort();
 664    }
 665
 666    if (ovr_seg >= 0) {
 667        TCGv seg = cpu_seg_base[ovr_seg];
 668
 669        if (aflag == MO_64) {
 670            tcg_gen_add_tl(s->A0, a0, seg);
 671        } else if (CODE64(s)) {
 672            tcg_gen_ext32u_tl(s->A0, a0);
 673            tcg_gen_add_tl(s->A0, s->A0, seg);
 674        } else {
 675            tcg_gen_add_tl(s->A0, a0, seg);
 676            tcg_gen_ext32u_tl(s->A0, s->A0);
 677        }
 678    }
 679}
 680
 681static inline void gen_string_movl_A0_ESI(DisasContext *s)
 682{
 683    gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
 684}
 685
 686static inline void gen_string_movl_A0_EDI(DisasContext *s)
 687{
 688    gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
 689}
 690
 691static inline void gen_op_movl_T0_Dshift(DisasContext *s, MemOp ot)
 692{
 693    tcg_gen_ld32s_tl(s->T0, cpu_env, offsetof(CPUX86State, df));
 694    tcg_gen_shli_tl(s->T0, s->T0, ot);
 695};
 696
 697static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)
 698{
 699    switch (size) {
 700    case MO_8:
 701        if (sign) {
 702            tcg_gen_ext8s_tl(dst, src);
 703        } else {
 704            tcg_gen_ext8u_tl(dst, src);
 705        }
 706        return dst;
 707    case MO_16:
 708        if (sign) {
 709            tcg_gen_ext16s_tl(dst, src);
 710        } else {
 711            tcg_gen_ext16u_tl(dst, src);
 712        }
 713        return dst;
 714#ifdef TARGET_X86_64
 715    case MO_32:
 716        if (sign) {
 717            tcg_gen_ext32s_tl(dst, src);
 718        } else {
 719            tcg_gen_ext32u_tl(dst, src);
 720        }
 721        return dst;
 722#endif
 723    default:
 724        return src;
 725    }
 726}
 727
 728static void gen_extu(MemOp ot, TCGv reg)
 729{
 730    gen_ext_tl(reg, reg, ot, false);
 731}
 732
 733static void gen_exts(MemOp ot, TCGv reg)
 734{
 735    gen_ext_tl(reg, reg, ot, true);
 736}
 737
 738static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1)
 739{
 740    tcg_gen_mov_tl(s->tmp0, cpu_regs[R_ECX]);
 741    gen_extu(s->aflag, s->tmp0);
 742    tcg_gen_brcondi_tl(cond, s->tmp0, 0, label1);
 743}
 744
 745static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1)
 746{
 747    gen_op_j_ecx(s, TCG_COND_EQ, label1);
 748}
 749
 750static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1)
 751{
 752    gen_op_j_ecx(s, TCG_COND_NE, label1);
 753}
 754
 755static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
 756{
 757    switch (ot) {
 758    case MO_8:
 759        gen_helper_inb(v, cpu_env, n);
 760        break;
 761    case MO_16:
 762        gen_helper_inw(v, cpu_env, n);
 763        break;
 764    case MO_32:
 765        gen_helper_inl(v, cpu_env, n);
 766        break;
 767    default:
 768        tcg_abort();
 769    }
 770}
 771
 772static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
 773{
 774    switch (ot) {
 775    case MO_8:
 776        gen_helper_outb(cpu_env, v, n);
 777        break;
 778    case MO_16:
 779        gen_helper_outw(cpu_env, v, n);
 780        break;
 781    case MO_32:
 782        gen_helper_outl(cpu_env, v, n);
 783        break;
 784    default:
 785        tcg_abort();
 786    }
 787}
 788
 789/*
 790 * Validate that access to [port, port + 1<<ot) is allowed.
 791 * Raise #GP, or VMM exit if not.
 792 */
 793static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
 794                         uint32_t svm_flags)
 795{
 796#ifdef CONFIG_USER_ONLY
 797    /*
 798     * We do not implement the ioperm(2) syscall, so the TSS check
 799     * will always fail.
 800     */
 801    gen_exception_gpf(s);
 802    return false;
 803#else
 804    if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
 805        gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
 806    }
 807    if (GUEST(s)) {
 808        gen_update_cc_op(s);
 809        gen_update_eip_cur(s);
 810        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
 811            svm_flags |= SVM_IOIO_REP_MASK;
 812        }
 813        svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
 814        gen_helper_svm_check_io(cpu_env, port,
 815                                tcg_constant_i32(svm_flags),
 816                                cur_insn_len_i32(s));
 817    }
 818    return true;
 819#endif
 820}
 821
 822static void gen_movs(DisasContext *s, MemOp ot)
 823{
 824    gen_string_movl_A0_ESI(s);
 825    gen_op_ld_v(s, ot, s->T0, s->A0);
 826    gen_string_movl_A0_EDI(s);
 827    gen_op_st_v(s, ot, s->T0, s->A0);
 828    gen_op_movl_T0_Dshift(s, ot);
 829    gen_op_add_reg_T0(s, s->aflag, R_ESI);
 830    gen_op_add_reg_T0(s, s->aflag, R_EDI);
 831}
 832
 833static void gen_op_update1_cc(DisasContext *s)
 834{
 835    tcg_gen_mov_tl(cpu_cc_dst, s->T0);
 836}
 837
 838static void gen_op_update2_cc(DisasContext *s)
 839{
 840    tcg_gen_mov_tl(cpu_cc_src, s->T1);
 841    tcg_gen_mov_tl(cpu_cc_dst, s->T0);
 842}
 843
 844static void gen_op_update3_cc(DisasContext *s, TCGv reg)
 845{
 846    tcg_gen_mov_tl(cpu_cc_src2, reg);
 847    tcg_gen_mov_tl(cpu_cc_src, s->T1);
 848    tcg_gen_mov_tl(cpu_cc_dst, s->T0);
 849}
 850
 851static inline void gen_op_testl_T0_T1_cc(DisasContext *s)
 852{
 853    tcg_gen_and_tl(cpu_cc_dst, s->T0, s->T1);
 854}
 855
 856static void gen_op_update_neg_cc(DisasContext *s)
 857{
 858    tcg_gen_mov_tl(cpu_cc_dst, s->T0);
 859    tcg_gen_neg_tl(cpu_cc_src, s->T0);
 860    tcg_gen_movi_tl(s->cc_srcT, 0);
 861}
 862
 863/* compute all eflags to cc_src */
 864static void gen_compute_eflags(DisasContext *s)
 865{
 866    TCGv zero, dst, src1, src2;
 867    int live, dead;
 868
 869    if (s->cc_op == CC_OP_EFLAGS) {
 870        return;
 871    }
 872    if (s->cc_op == CC_OP_CLR) {
 873        tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
 874        set_cc_op(s, CC_OP_EFLAGS);
 875        return;
 876    }
 877
 878    zero = NULL;
 879    dst = cpu_cc_dst;
 880    src1 = cpu_cc_src;
 881    src2 = cpu_cc_src2;
 882
 883    /* Take care to not read values that are not live.  */
 884    live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
 885    dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
 886    if (dead) {
 887        zero = tcg_const_tl(0);
 888        if (dead & USES_CC_DST) {
 889            dst = zero;
 890        }
 891        if (dead & USES_CC_SRC) {
 892            src1 = zero;
 893        }
 894        if (dead & USES_CC_SRC2) {
 895            src2 = zero;
 896        }
 897    }
 898
 899    gen_update_cc_op(s);
 900    gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
 901    set_cc_op(s, CC_OP_EFLAGS);
 902
 903    if (dead) {
 904        tcg_temp_free(zero);
 905    }
 906}
 907
 908typedef struct CCPrepare {
 909    TCGCond cond;
 910    TCGv reg;
 911    TCGv reg2;
 912    target_ulong imm;
 913    target_ulong mask;
 914    bool use_reg2;
 915    bool no_setcond;
 916} CCPrepare;
 917
 918/* compute eflags.C to reg */
 919static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
 920{
 921    TCGv t0, t1;
 922    int size, shift;
 923
 924    switch (s->cc_op) {
 925    case CC_OP_SUBB ... CC_OP_SUBQ:
 926        /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
 927        size = s->cc_op - CC_OP_SUBB;
 928        t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
 929        /* If no temporary was used, be careful not to alias t1 and t0.  */
 930        t0 = t1 == cpu_cc_src ? s->tmp0 : reg;
 931        tcg_gen_mov_tl(t0, s->cc_srcT);
 932        gen_extu(size, t0);
 933        goto add_sub;
 934
 935    case CC_OP_ADDB ... CC_OP_ADDQ:
 936        /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
 937        size = s->cc_op - CC_OP_ADDB;
 938        t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
 939        t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
 940    add_sub:
 941        return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
 942                             .reg2 = t1, .mask = -1, .use_reg2 = true };
 943
 944    case CC_OP_LOGICB ... CC_OP_LOGICQ:
 945    case CC_OP_CLR:
 946    case CC_OP_POPCNT:
 947        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
 948
 949    case CC_OP_INCB ... CC_OP_INCQ:
 950    case CC_OP_DECB ... CC_OP_DECQ:
 951        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 952                             .mask = -1, .no_setcond = true };
 953
 954    case CC_OP_SHLB ... CC_OP_SHLQ:
 955        /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
 956        size = s->cc_op - CC_OP_SHLB;
 957        shift = (8 << size) - 1;
 958        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 959                             .mask = (target_ulong)1 << shift };
 960
 961    case CC_OP_MULB ... CC_OP_MULQ:
 962        return (CCPrepare) { .cond = TCG_COND_NE,
 963                             .reg = cpu_cc_src, .mask = -1 };
 964
 965    case CC_OP_BMILGB ... CC_OP_BMILGQ:
 966        size = s->cc_op - CC_OP_BMILGB;
 967        t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
 968        return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
 969
 970    case CC_OP_ADCX:
 971    case CC_OP_ADCOX:
 972        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
 973                             .mask = -1, .no_setcond = true };
 974
 975    case CC_OP_EFLAGS:
 976    case CC_OP_SARB ... CC_OP_SARQ:
 977        /* CC_SRC & 1 */
 978        return (CCPrepare) { .cond = TCG_COND_NE,
 979                             .reg = cpu_cc_src, .mask = CC_C };
 980
 981    default:
 982       /* The need to compute only C from CC_OP_DYNAMIC is important
 983          in efficiently implementing e.g. INC at the start of a TB.  */
 984       gen_update_cc_op(s);
 985       gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
 986                               cpu_cc_src2, cpu_cc_op);
 987       return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
 988                            .mask = -1, .no_setcond = true };
 989    }
 990}
 991
 992/* compute eflags.P to reg */
 993static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
 994{
 995    gen_compute_eflags(s);
 996    return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
 997                         .mask = CC_P };
 998}
 999
1000/* compute eflags.S to reg */
1001static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
1002{
1003    switch (s->cc_op) {
1004    case CC_OP_DYNAMIC:
1005        gen_compute_eflags(s);
1006        /* FALLTHRU */
1007    case CC_OP_EFLAGS:
1008    case CC_OP_ADCX:
1009    case CC_OP_ADOX:
1010    case CC_OP_ADCOX:
1011        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1012                             .mask = CC_S };
1013    case CC_OP_CLR:
1014    case CC_OP_POPCNT:
1015        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1016    default:
1017        {
1018            MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1019            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1020            return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1021        }
1022    }
1023}
1024
1025/* compute eflags.O to reg */
1026static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1027{
1028    switch (s->cc_op) {
1029    case CC_OP_ADOX:
1030    case CC_OP_ADCOX:
1031        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1032                             .mask = -1, .no_setcond = true };
1033    case CC_OP_CLR:
1034    case CC_OP_POPCNT:
1035        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1036    default:
1037        gen_compute_eflags(s);
1038        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1039                             .mask = CC_O };
1040    }
1041}
1042
1043/* compute eflags.Z to reg */
1044static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1045{
1046    switch (s->cc_op) {
1047    case CC_OP_DYNAMIC:
1048        gen_compute_eflags(s);
1049        /* FALLTHRU */
1050    case CC_OP_EFLAGS:
1051    case CC_OP_ADCX:
1052    case CC_OP_ADOX:
1053    case CC_OP_ADCOX:
1054        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1055                             .mask = CC_Z };
1056    case CC_OP_CLR:
1057        return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
1058    case CC_OP_POPCNT:
1059        return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
1060                             .mask = -1 };
1061    default:
1062        {
1063            MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1064            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1065            return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1066        }
1067    }
1068}
1069
1070/* perform a conditional store into register 'reg' according to jump opcode
1071   value 'b'. In the fast case, T0 is guaranted not to be used. */
1072static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1073{
1074    int inv, jcc_op, cond;
1075    MemOp size;
1076    CCPrepare cc;
1077    TCGv t0;
1078
1079    inv = b & 1;
1080    jcc_op = (b >> 1) & 7;
1081
1082    switch (s->cc_op) {
1083    case CC_OP_SUBB ... CC_OP_SUBQ:
1084        /* We optimize relational operators for the cmp/jcc case.  */
1085        size = s->cc_op - CC_OP_SUBB;
1086        switch (jcc_op) {
1087        case JCC_BE:
1088            tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1089            gen_extu(size, s->tmp4);
1090            t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
1091            cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->tmp4,
1092                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1093            break;
1094
1095        case JCC_L:
1096            cond = TCG_COND_LT;
1097            goto fast_jcc_l;
1098        case JCC_LE:
1099            cond = TCG_COND_LE;
1100        fast_jcc_l:
1101            tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1102            gen_exts(size, s->tmp4);
1103            t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, true);
1104            cc = (CCPrepare) { .cond = cond, .reg = s->tmp4,
1105                               .reg2 = t0, .mask = -1, .use_reg2 = true };
1106            break;
1107
1108        default:
1109            goto slow_jcc;
1110        }
1111        break;
1112
1113    default:
1114    slow_jcc:
1115        /* This actually generates good code for JC, JZ and JS.  */
1116        switch (jcc_op) {
1117        case JCC_O:
1118            cc = gen_prepare_eflags_o(s, reg);
1119            break;
1120        case JCC_B:
1121            cc = gen_prepare_eflags_c(s, reg);
1122            break;
1123        case JCC_Z:
1124            cc = gen_prepare_eflags_z(s, reg);
1125            break;
1126        case JCC_BE:
1127            gen_compute_eflags(s);
1128            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1129                               .mask = CC_Z | CC_C };
1130            break;
1131        case JCC_S:
1132            cc = gen_prepare_eflags_s(s, reg);
1133            break;
1134        case JCC_P:
1135            cc = gen_prepare_eflags_p(s, reg);
1136            break;
1137        case JCC_L:
1138            gen_compute_eflags(s);
1139            if (reg == cpu_cc_src) {
1140                reg = s->tmp0;
1141            }
1142            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1143            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1144            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1145                               .mask = CC_S };
1146            break;
1147        default:
1148        case JCC_LE:
1149            gen_compute_eflags(s);
1150            if (reg == cpu_cc_src) {
1151                reg = s->tmp0;
1152            }
1153            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1154            tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1155            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1156                               .mask = CC_S | CC_Z };
1157            break;
1158        }
1159        break;
1160    }
1161
1162    if (inv) {
1163        cc.cond = tcg_invert_cond(cc.cond);
1164    }
1165    return cc;
1166}
1167
1168static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1169{
1170    CCPrepare cc = gen_prepare_cc(s, b, reg);
1171
1172    if (cc.no_setcond) {
1173        if (cc.cond == TCG_COND_EQ) {
1174            tcg_gen_xori_tl(reg, cc.reg, 1);
1175        } else {
1176            tcg_gen_mov_tl(reg, cc.reg);
1177        }
1178        return;
1179    }
1180
1181    if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1182        cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1183        tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1184        tcg_gen_andi_tl(reg, reg, 1);
1185        return;
1186    }
1187    if (cc.mask != -1) {
1188        tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1189        cc.reg = reg;
1190    }
1191    if (cc.use_reg2) {
1192        tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1193    } else {
1194        tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1195    }
1196}
1197
1198static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1199{
1200    gen_setcc1(s, JCC_B << 1, reg);
1201}
1202
1203/* generate a conditional jump to label 'l1' according to jump opcode
1204   value 'b'. In the fast case, T0 is guaranted not to be used. */
1205static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1206{
1207    CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1208
1209    if (cc.mask != -1) {
1210        tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1211        cc.reg = s->T0;
1212    }
1213    if (cc.use_reg2) {
1214        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1215    } else {
1216        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1217    }
1218}
1219
1220/* Generate a conditional jump to label 'l1' according to jump opcode
1221   value 'b'. In the fast case, T0 is guaranted not to be used.
1222   A translation block must end soon.  */
1223static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1224{
1225    CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1226
1227    gen_update_cc_op(s);
1228    if (cc.mask != -1) {
1229        tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1230        cc.reg = s->T0;
1231    }
1232    set_cc_op(s, CC_OP_DYNAMIC);
1233    if (cc.use_reg2) {
1234        tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1235    } else {
1236        tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1237    }
1238}
1239
1240/* XXX: does not work with gdbstub "ice" single step - not a
1241   serious problem */
1242static TCGLabel *gen_jz_ecx_string(DisasContext *s)
1243{
1244    TCGLabel *l1 = gen_new_label();
1245    TCGLabel *l2 = gen_new_label();
1246    gen_op_jnz_ecx(s, l1);
1247    gen_set_label(l2);
1248    gen_jmp_rel_csize(s, 0, 1);
1249    gen_set_label(l1);
1250    return l2;
1251}
1252
1253static void gen_stos(DisasContext *s, MemOp ot)
1254{
1255    gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
1256    gen_string_movl_A0_EDI(s);
1257    gen_op_st_v(s, ot, s->T0, s->A0);
1258    gen_op_movl_T0_Dshift(s, ot);
1259    gen_op_add_reg_T0(s, s->aflag, R_EDI);
1260}
1261
1262static void gen_lods(DisasContext *s, MemOp ot)
1263{
1264    gen_string_movl_A0_ESI(s);
1265    gen_op_ld_v(s, ot, s->T0, s->A0);
1266    gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
1267    gen_op_movl_T0_Dshift(s, ot);
1268    gen_op_add_reg_T0(s, s->aflag, R_ESI);
1269}
1270
1271static void gen_scas(DisasContext *s, MemOp ot)
1272{
1273    gen_string_movl_A0_EDI(s);
1274    gen_op_ld_v(s, ot, s->T1, s->A0);
1275    gen_op(s, OP_CMPL, ot, R_EAX);
1276    gen_op_movl_T0_Dshift(s, ot);
1277    gen_op_add_reg_T0(s, s->aflag, R_EDI);
1278}
1279
1280static void gen_cmps(DisasContext *s, MemOp ot)
1281{
1282    gen_string_movl_A0_EDI(s);
1283    gen_op_ld_v(s, ot, s->T1, s->A0);
1284    gen_string_movl_A0_ESI(s);
1285    gen_op(s, OP_CMPL, ot, OR_TMP0);
1286    gen_op_movl_T0_Dshift(s, ot);
1287    gen_op_add_reg_T0(s, s->aflag, R_ESI);
1288    gen_op_add_reg_T0(s, s->aflag, R_EDI);
1289}
1290
1291static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1292{
1293    if (s->flags & HF_IOBPT_MASK) {
1294#ifdef CONFIG_USER_ONLY
1295        /* user-mode cpu should not be in IOBPT mode */
1296        g_assert_not_reached();
1297#else
1298        TCGv_i32 t_size = tcg_constant_i32(1 << ot);
1299        TCGv t_next = eip_next_tl(s);
1300        gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1301#endif /* CONFIG_USER_ONLY */
1302    }
1303}
1304
1305static void gen_ins(DisasContext *s, MemOp ot)
1306{
1307    gen_string_movl_A0_EDI(s);
1308    /* Note: we must do this dummy write first to be restartable in
1309       case of page fault. */
1310    tcg_gen_movi_tl(s->T0, 0);
1311    gen_op_st_v(s, ot, s->T0, s->A0);
1312    tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1313    tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1314    gen_helper_in_func(ot, s->T0, s->tmp2_i32);
1315    gen_op_st_v(s, ot, s->T0, s->A0);
1316    gen_op_movl_T0_Dshift(s, ot);
1317    gen_op_add_reg_T0(s, s->aflag, R_EDI);
1318    gen_bpt_io(s, s->tmp2_i32, ot);
1319}
1320
1321static void gen_outs(DisasContext *s, MemOp ot)
1322{
1323    gen_string_movl_A0_ESI(s);
1324    gen_op_ld_v(s, ot, s->T0, s->A0);
1325
1326    tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1327    tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1328    tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0);
1329    gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
1330    gen_op_movl_T0_Dshift(s, ot);
1331    gen_op_add_reg_T0(s, s->aflag, R_ESI);
1332    gen_bpt_io(s, s->tmp2_i32, ot);
1333}
1334
1335/* Generate jumps to current or next instruction */
1336static void gen_repz(DisasContext *s, MemOp ot,
1337                     void (*fn)(DisasContext *s, MemOp ot))
1338{
1339    TCGLabel *l2;
1340    gen_update_cc_op(s);
1341    l2 = gen_jz_ecx_string(s);
1342    fn(s, ot);
1343    gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1344    /*
1345     * A loop would cause two single step exceptions if ECX = 1
1346     * before rep string_insn
1347     */
1348    if (s->repz_opt) {
1349        gen_op_jz_ecx(s, l2);
1350    }
1351    gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1352}
1353
1354#define GEN_REPZ(op) \
1355    static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
1356    { gen_repz(s, ot, gen_##op); }
1357
1358static void gen_repz2(DisasContext *s, MemOp ot, int nz,
1359                      void (*fn)(DisasContext *s, MemOp ot))
1360{
1361    TCGLabel *l2;
1362    gen_update_cc_op(s);
1363    l2 = gen_jz_ecx_string(s);
1364    fn(s, ot);
1365    gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1366    gen_update_cc_op(s);
1367    gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
1368    if (s->repz_opt) {
1369        gen_op_jz_ecx(s, l2);
1370    }
1371    gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1372}
1373
1374#define GEN_REPZ2(op) \
1375    static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
1376    { gen_repz2(s, ot, nz, gen_##op); }
1377
1378GEN_REPZ(movs)
1379GEN_REPZ(stos)
1380GEN_REPZ(lods)
1381GEN_REPZ(ins)
1382GEN_REPZ(outs)
1383GEN_REPZ2(scas)
1384GEN_REPZ2(cmps)
1385
1386static void gen_helper_fp_arith_ST0_FT0(int op)
1387{
1388    switch (op) {
1389    case 0:
1390        gen_helper_fadd_ST0_FT0(cpu_env);
1391        break;
1392    case 1:
1393        gen_helper_fmul_ST0_FT0(cpu_env);
1394        break;
1395    case 2:
1396        gen_helper_fcom_ST0_FT0(cpu_env);
1397        break;
1398    case 3:
1399        gen_helper_fcom_ST0_FT0(cpu_env);
1400        break;
1401    case 4:
1402        gen_helper_fsub_ST0_FT0(cpu_env);
1403        break;
1404    case 5:
1405        gen_helper_fsubr_ST0_FT0(cpu_env);
1406        break;
1407    case 6:
1408        gen_helper_fdiv_ST0_FT0(cpu_env);
1409        break;
1410    case 7:
1411        gen_helper_fdivr_ST0_FT0(cpu_env);
1412        break;
1413    }
1414}
1415
1416/* NOTE the exception in "r" op ordering */
1417static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1418{
1419    TCGv_i32 tmp = tcg_const_i32(opreg);
1420    switch (op) {
1421    case 0:
1422        gen_helper_fadd_STN_ST0(cpu_env, tmp);
1423        break;
1424    case 1:
1425        gen_helper_fmul_STN_ST0(cpu_env, tmp);
1426        break;
1427    case 4:
1428        gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1429        break;
1430    case 5:
1431        gen_helper_fsub_STN_ST0(cpu_env, tmp);
1432        break;
1433    case 6:
1434        gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1435        break;
1436    case 7:
1437        gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1438        break;
1439    }
1440}
1441
1442static void gen_exception(DisasContext *s, int trapno)
1443{
1444    gen_update_cc_op(s);
1445    gen_update_eip_cur(s);
1446    gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
1447    s->base.is_jmp = DISAS_NORETURN;
1448}
1449
1450/* Generate #UD for the current instruction.  The assumption here is that
1451   the instruction is known, but it isn't allowed in the current cpu mode.  */
1452static void gen_illegal_opcode(DisasContext *s)
1453{
1454    gen_exception(s, EXCP06_ILLOP);
1455}
1456
1457/* Generate #GP for the current instruction. */
1458static void gen_exception_gpf(DisasContext *s)
1459{
1460    gen_exception(s, EXCP0D_GPF);
1461}
1462
1463/* Check for cpl == 0; if not, raise #GP and return false. */
1464static bool check_cpl0(DisasContext *s)
1465{
1466    if (CPL(s) == 0) {
1467        return true;
1468    }
1469    gen_exception_gpf(s);
1470    return false;
1471}
1472
1473/* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1474static bool check_vm86_iopl(DisasContext *s)
1475{
1476    if (!VM86(s) || IOPL(s) == 3) {
1477        return true;
1478    }
1479    gen_exception_gpf(s);
1480    return false;
1481}
1482
1483/* Check for iopl allowing access; if not, raise #GP and return false. */
1484static bool check_iopl(DisasContext *s)
1485{
1486    if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
1487        return true;
1488    }
1489    gen_exception_gpf(s);
1490    return false;
1491}
1492
1493/* if d == OR_TMP0, it means memory operand (address in A0) */
1494static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
1495{
1496    if (d != OR_TMP0) {
1497        if (s1->prefix & PREFIX_LOCK) {
1498            /* Lock prefix when destination is not memory.  */
1499            gen_illegal_opcode(s1);
1500            return;
1501        }
1502        gen_op_mov_v_reg(s1, ot, s1->T0, d);
1503    } else if (!(s1->prefix & PREFIX_LOCK)) {
1504        gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1505    }
1506    switch(op) {
1507    case OP_ADCL:
1508        gen_compute_eflags_c(s1, s1->tmp4);
1509        if (s1->prefix & PREFIX_LOCK) {
1510            tcg_gen_add_tl(s1->T0, s1->tmp4, s1->T1);
1511            tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1512                                        s1->mem_index, ot | MO_LE);
1513        } else {
1514            tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1515            tcg_gen_add_tl(s1->T0, s1->T0, s1->tmp4);
1516            gen_op_st_rm_T0_A0(s1, ot, d);
1517        }
1518        gen_op_update3_cc(s1, s1->tmp4);
1519        set_cc_op(s1, CC_OP_ADCB + ot);
1520        break;
1521    case OP_SBBL:
1522        gen_compute_eflags_c(s1, s1->tmp4);
1523        if (s1->prefix & PREFIX_LOCK) {
1524            tcg_gen_add_tl(s1->T0, s1->T1, s1->tmp4);
1525            tcg_gen_neg_tl(s1->T0, s1->T0);
1526            tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1527                                        s1->mem_index, ot | MO_LE);
1528        } else {
1529            tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1530            tcg_gen_sub_tl(s1->T0, s1->T0, s1->tmp4);
1531            gen_op_st_rm_T0_A0(s1, ot, d);
1532        }
1533        gen_op_update3_cc(s1, s1->tmp4);
1534        set_cc_op(s1, CC_OP_SBBB + ot);
1535        break;
1536    case OP_ADDL:
1537        if (s1->prefix & PREFIX_LOCK) {
1538            tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T1,
1539                                        s1->mem_index, ot | MO_LE);
1540        } else {
1541            tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1542            gen_op_st_rm_T0_A0(s1, ot, d);
1543        }
1544        gen_op_update2_cc(s1);
1545        set_cc_op(s1, CC_OP_ADDB + ot);
1546        break;
1547    case OP_SUBL:
1548        if (s1->prefix & PREFIX_LOCK) {
1549            tcg_gen_neg_tl(s1->T0, s1->T1);
1550            tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0,
1551                                        s1->mem_index, ot | MO_LE);
1552            tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1);
1553        } else {
1554            tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1555            tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1556            gen_op_st_rm_T0_A0(s1, ot, d);
1557        }
1558        gen_op_update2_cc(s1);
1559        set_cc_op(s1, CC_OP_SUBB + ot);
1560        break;
1561    default:
1562    case OP_ANDL:
1563        if (s1->prefix & PREFIX_LOCK) {
1564            tcg_gen_atomic_and_fetch_tl(s1->T0, s1->A0, s1->T1,
1565                                        s1->mem_index, ot | MO_LE);
1566        } else {
1567            tcg_gen_and_tl(s1->T0, s1->T0, s1->T1);
1568            gen_op_st_rm_T0_A0(s1, ot, d);
1569        }
1570        gen_op_update1_cc(s1);
1571        set_cc_op(s1, CC_OP_LOGICB + ot);
1572        break;
1573    case OP_ORL:
1574        if (s1->prefix & PREFIX_LOCK) {
1575            tcg_gen_atomic_or_fetch_tl(s1->T0, s1->A0, s1->T1,
1576                                       s1->mem_index, ot | MO_LE);
1577        } else {
1578            tcg_gen_or_tl(s1->T0, s1->T0, s1->T1);
1579            gen_op_st_rm_T0_A0(s1, ot, d);
1580        }
1581        gen_op_update1_cc(s1);
1582        set_cc_op(s1, CC_OP_LOGICB + ot);
1583        break;
1584    case OP_XORL:
1585        if (s1->prefix & PREFIX_LOCK) {
1586            tcg_gen_atomic_xor_fetch_tl(s1->T0, s1->A0, s1->T1,
1587                                        s1->mem_index, ot | MO_LE);
1588        } else {
1589            tcg_gen_xor_tl(s1->T0, s1->T0, s1->T1);
1590            gen_op_st_rm_T0_A0(s1, ot, d);
1591        }
1592        gen_op_update1_cc(s1);
1593        set_cc_op(s1, CC_OP_LOGICB + ot);
1594        break;
1595    case OP_CMPL:
1596        tcg_gen_mov_tl(cpu_cc_src, s1->T1);
1597        tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1598        tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1);
1599        set_cc_op(s1, CC_OP_SUBB + ot);
1600        break;
1601    }
1602}
1603
1604/* if d == OR_TMP0, it means memory operand (address in A0) */
1605static void gen_inc(DisasContext *s1, MemOp ot, int d, int c)
1606{
1607    if (s1->prefix & PREFIX_LOCK) {
1608        if (d != OR_TMP0) {
1609            /* Lock prefix when destination is not memory */
1610            gen_illegal_opcode(s1);
1611            return;
1612        }
1613        tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1);
1614        tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1615                                    s1->mem_index, ot | MO_LE);
1616    } else {
1617        if (d != OR_TMP0) {
1618            gen_op_mov_v_reg(s1, ot, s1->T0, d);
1619        } else {
1620            gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1621        }
1622        tcg_gen_addi_tl(s1->T0, s1->T0, (c > 0 ? 1 : -1));
1623        gen_op_st_rm_T0_A0(s1, ot, d);
1624    }
1625
1626    gen_compute_eflags_c(s1, cpu_cc_src);
1627    tcg_gen_mov_tl(cpu_cc_dst, s1->T0);
1628    set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1629}
1630
1631static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result,
1632                            TCGv shm1, TCGv count, bool is_right)
1633{
1634    TCGv_i32 z32, s32, oldop;
1635    TCGv z_tl;
1636
1637    /* Store the results into the CC variables.  If we know that the
1638       variable must be dead, store unconditionally.  Otherwise we'll
1639       need to not disrupt the current contents.  */
1640    z_tl = tcg_const_tl(0);
1641    if (cc_op_live[s->cc_op] & USES_CC_DST) {
1642        tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1643                           result, cpu_cc_dst);
1644    } else {
1645        tcg_gen_mov_tl(cpu_cc_dst, result);
1646    }
1647    if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1648        tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1649                           shm1, cpu_cc_src);
1650    } else {
1651        tcg_gen_mov_tl(cpu_cc_src, shm1);
1652    }
1653    tcg_temp_free(z_tl);
1654
1655    /* Get the two potential CC_OP values into temporaries.  */
1656    tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1657    if (s->cc_op == CC_OP_DYNAMIC) {
1658        oldop = cpu_cc_op;
1659    } else {
1660        tcg_gen_movi_i32(s->tmp3_i32, s->cc_op);
1661        oldop = s->tmp3_i32;
1662    }
1663
1664    /* Conditionally store the CC_OP value.  */
1665    z32 = tcg_const_i32(0);
1666    s32 = tcg_temp_new_i32();
1667    tcg_gen_trunc_tl_i32(s32, count);
1668    tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop);
1669    tcg_temp_free_i32(z32);
1670    tcg_temp_free_i32(s32);
1671
1672    /* The CC_OP value is no longer predictable.  */
1673    set_cc_op(s, CC_OP_DYNAMIC);
1674}
1675
1676static void gen_shift_rm_T1(DisasContext *s, MemOp ot, int op1,
1677                            int is_right, int is_arith)
1678{
1679    target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1680
1681    /* load */
1682    if (op1 == OR_TMP0) {
1683        gen_op_ld_v(s, ot, s->T0, s->A0);
1684    } else {
1685        gen_op_mov_v_reg(s, ot, s->T0, op1);
1686    }
1687
1688    tcg_gen_andi_tl(s->T1, s->T1, mask);
1689    tcg_gen_subi_tl(s->tmp0, s->T1, 1);
1690
1691    if (is_right) {
1692        if (is_arith) {
1693            gen_exts(ot, s->T0);
1694            tcg_gen_sar_tl(s->tmp0, s->T0, s->tmp0);
1695            tcg_gen_sar_tl(s->T0, s->T0, s->T1);
1696        } else {
1697            gen_extu(ot, s->T0);
1698            tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
1699            tcg_gen_shr_tl(s->T0, s->T0, s->T1);
1700        }
1701    } else {
1702        tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
1703        tcg_gen_shl_tl(s->T0, s->T0, s->T1);
1704    }
1705
1706    /* store */
1707    gen_op_st_rm_T0_A0(s, ot, op1);
1708
1709    gen_shift_flags(s, ot, s->T0, s->tmp0, s->T1, is_right);
1710}
1711
1712static void gen_shift_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1713                            int is_right, int is_arith)
1714{
1715    int mask = (ot == MO_64 ? 0x3f : 0x1f);
1716
1717    /* load */
1718    if (op1 == OR_TMP0)
1719        gen_op_ld_v(s, ot, s->T0, s->A0);
1720    else
1721        gen_op_mov_v_reg(s, ot, s->T0, op1);
1722
1723    op2 &= mask;
1724    if (op2 != 0) {
1725        if (is_right) {
1726            if (is_arith) {
1727                gen_exts(ot, s->T0);
1728                tcg_gen_sari_tl(s->tmp4, s->T0, op2 - 1);
1729                tcg_gen_sari_tl(s->T0, s->T0, op2);
1730            } else {
1731                gen_extu(ot, s->T0);
1732                tcg_gen_shri_tl(s->tmp4, s->T0, op2 - 1);
1733                tcg_gen_shri_tl(s->T0, s->T0, op2);
1734            }
1735        } else {
1736            tcg_gen_shli_tl(s->tmp4, s->T0, op2 - 1);
1737            tcg_gen_shli_tl(s->T0, s->T0, op2);
1738        }
1739    }
1740
1741    /* store */
1742    gen_op_st_rm_T0_A0(s, ot, op1);
1743
1744    /* update eflags if non zero shift */
1745    if (op2 != 0) {
1746        tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
1747        tcg_gen_mov_tl(cpu_cc_dst, s->T0);
1748        set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1749    }
1750}
1751
1752static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right)
1753{
1754    target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1755    TCGv_i32 t0, t1;
1756
1757    /* load */
1758    if (op1 == OR_TMP0) {
1759        gen_op_ld_v(s, ot, s->T0, s->A0);
1760    } else {
1761        gen_op_mov_v_reg(s, ot, s->T0, op1);
1762    }
1763
1764    tcg_gen_andi_tl(s->T1, s->T1, mask);
1765
1766    switch (ot) {
1767    case MO_8:
1768        /* Replicate the 8-bit input so that a 32-bit rotate works.  */
1769        tcg_gen_ext8u_tl(s->T0, s->T0);
1770        tcg_gen_muli_tl(s->T0, s->T0, 0x01010101);
1771        goto do_long;
1772    case MO_16:
1773        /* Replicate the 16-bit input so that a 32-bit rotate works.  */
1774        tcg_gen_deposit_tl(s->T0, s->T0, s->T0, 16, 16);
1775        goto do_long;
1776    do_long:
1777#ifdef TARGET_X86_64
1778    case MO_32:
1779        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1780        tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
1781        if (is_right) {
1782            tcg_gen_rotr_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1783        } else {
1784            tcg_gen_rotl_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1785        }
1786        tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1787        break;
1788#endif
1789    default:
1790        if (is_right) {
1791            tcg_gen_rotr_tl(s->T0, s->T0, s->T1);
1792        } else {
1793            tcg_gen_rotl_tl(s->T0, s->T0, s->T1);
1794        }
1795        break;
1796    }
1797
1798    /* store */
1799    gen_op_st_rm_T0_A0(s, ot, op1);
1800
1801    /* We'll need the flags computed into CC_SRC.  */
1802    gen_compute_eflags(s);
1803
1804    /* The value that was "rotated out" is now present at the other end
1805       of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1806       since we've computed the flags into CC_SRC, these variables are
1807       currently dead.  */
1808    if (is_right) {
1809        tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1810        tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1811        tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1812    } else {
1813        tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1814        tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1815    }
1816    tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1817    tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1818
1819    /* Now conditionally store the new CC_OP value.  If the shift count
1820       is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1821       Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1822       exactly as we computed above.  */
1823    t0 = tcg_const_i32(0);
1824    t1 = tcg_temp_new_i32();
1825    tcg_gen_trunc_tl_i32(t1, s->T1);
1826    tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX);
1827    tcg_gen_movi_i32(s->tmp3_i32, CC_OP_EFLAGS);
1828    tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1829                        s->tmp2_i32, s->tmp3_i32);
1830    tcg_temp_free_i32(t0);
1831    tcg_temp_free_i32(t1);
1832
1833    /* The CC_OP value is no longer predictable.  */ 
1834    set_cc_op(s, CC_OP_DYNAMIC);
1835}
1836
1837static void gen_rot_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1838                          int is_right)
1839{
1840    int mask = (ot == MO_64 ? 0x3f : 0x1f);
1841    int shift;
1842
1843    /* load */
1844    if (op1 == OR_TMP0) {
1845        gen_op_ld_v(s, ot, s->T0, s->A0);
1846    } else {
1847        gen_op_mov_v_reg(s, ot, s->T0, op1);
1848    }
1849
1850    op2 &= mask;
1851    if (op2 != 0) {
1852        switch (ot) {
1853#ifdef TARGET_X86_64
1854        case MO_32:
1855            tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1856            if (is_right) {
1857                tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, op2);
1858            } else {
1859                tcg_gen_rotli_i32(s->tmp2_i32, s->tmp2_i32, op2);
1860            }
1861            tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1862            break;
1863#endif
1864        default:
1865            if (is_right) {
1866                tcg_gen_rotri_tl(s->T0, s->T0, op2);
1867            } else {
1868                tcg_gen_rotli_tl(s->T0, s->T0, op2);
1869            }
1870            break;
1871        case MO_8:
1872            mask = 7;
1873            goto do_shifts;
1874        case MO_16:
1875            mask = 15;
1876        do_shifts:
1877            shift = op2 & mask;
1878            if (is_right) {
1879                shift = mask + 1 - shift;
1880            }
1881            gen_extu(ot, s->T0);
1882            tcg_gen_shli_tl(s->tmp0, s->T0, shift);
1883            tcg_gen_shri_tl(s->T0, s->T0, mask + 1 - shift);
1884            tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
1885            break;
1886        }
1887    }
1888
1889    /* store */
1890    gen_op_st_rm_T0_A0(s, ot, op1);
1891
1892    if (op2 != 0) {
1893        /* Compute the flags into CC_SRC.  */
1894        gen_compute_eflags(s);
1895
1896        /* The value that was "rotated out" is now present at the other end
1897           of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1898           since we've computed the flags into CC_SRC, these variables are
1899           currently dead.  */
1900        if (is_right) {
1901            tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1902            tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1903            tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1904        } else {
1905            tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1906            tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1907        }
1908        tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1909        tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1910        set_cc_op(s, CC_OP_ADCOX);
1911    }
1912}
1913
1914/* XXX: add faster immediate = 1 case */
1915static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
1916                           int is_right)
1917{
1918    gen_compute_eflags(s);
1919    assert(s->cc_op == CC_OP_EFLAGS);
1920
1921    /* load */
1922    if (op1 == OR_TMP0)
1923        gen_op_ld_v(s, ot, s->T0, s->A0);
1924    else
1925        gen_op_mov_v_reg(s, ot, s->T0, op1);
1926    
1927    if (is_right) {
1928        switch (ot) {
1929        case MO_8:
1930            gen_helper_rcrb(s->T0, cpu_env, s->T0, s->T1);
1931            break;
1932        case MO_16:
1933            gen_helper_rcrw(s->T0, cpu_env, s->T0, s->T1);
1934            break;
1935        case MO_32:
1936            gen_helper_rcrl(s->T0, cpu_env, s->T0, s->T1);
1937            break;
1938#ifdef TARGET_X86_64
1939        case MO_64:
1940            gen_helper_rcrq(s->T0, cpu_env, s->T0, s->T1);
1941            break;
1942#endif
1943        default:
1944            tcg_abort();
1945        }
1946    } else {
1947        switch (ot) {
1948        case MO_8:
1949            gen_helper_rclb(s->T0, cpu_env, s->T0, s->T1);
1950            break;
1951        case MO_16:
1952            gen_helper_rclw(s->T0, cpu_env, s->T0, s->T1);
1953            break;
1954        case MO_32:
1955            gen_helper_rcll(s->T0, cpu_env, s->T0, s->T1);
1956            break;
1957#ifdef TARGET_X86_64
1958        case MO_64:
1959            gen_helper_rclq(s->T0, cpu_env, s->T0, s->T1);
1960            break;
1961#endif
1962        default:
1963            tcg_abort();
1964        }
1965    }
1966    /* store */
1967    gen_op_st_rm_T0_A0(s, ot, op1);
1968}
1969
1970/* XXX: add faster immediate case */
1971static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1,
1972                             bool is_right, TCGv count_in)
1973{
1974    target_ulong mask = (ot == MO_64 ? 63 : 31);
1975    TCGv count;
1976
1977    /* load */
1978    if (op1 == OR_TMP0) {
1979        gen_op_ld_v(s, ot, s->T0, s->A0);
1980    } else {
1981        gen_op_mov_v_reg(s, ot, s->T0, op1);
1982    }
1983
1984    count = tcg_temp_new();
1985    tcg_gen_andi_tl(count, count_in, mask);
1986
1987    switch (ot) {
1988    case MO_16:
1989        /* Note: we implement the Intel behaviour for shift count > 16.
1990           This means "shrdw C, B, A" shifts A:B:A >> C.  Build the B:A
1991           portion by constructing it as a 32-bit value.  */
1992        if (is_right) {
1993            tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16);
1994            tcg_gen_mov_tl(s->T1, s->T0);
1995            tcg_gen_mov_tl(s->T0, s->tmp0);
1996        } else {
1997            tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
1998        }
1999        /*
2000         * If TARGET_X86_64 defined then fall through into MO_32 case,
2001         * otherwise fall through default case.
2002         */
2003    case MO_32:
2004#ifdef TARGET_X86_64
2005        /* Concatenate the two 32-bit values and use a 64-bit shift.  */
2006        tcg_gen_subi_tl(s->tmp0, count, 1);
2007        if (is_right) {
2008            tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1);
2009            tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0);
2010            tcg_gen_shr_i64(s->T0, s->T0, count);
2011        } else {
2012            tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0);
2013            tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0);
2014            tcg_gen_shl_i64(s->T0, s->T0, count);
2015            tcg_gen_shri_i64(s->tmp0, s->tmp0, 32);
2016            tcg_gen_shri_i64(s->T0, s->T0, 32);
2017        }
2018        break;
2019#endif
2020    default:
2021        tcg_gen_subi_tl(s->tmp0, count, 1);
2022        if (is_right) {
2023            tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
2024
2025            tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2026            tcg_gen_shr_tl(s->T0, s->T0, count);
2027            tcg_gen_shl_tl(s->T1, s->T1, s->tmp4);
2028        } else {
2029            tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
2030            if (ot == MO_16) {
2031                /* Only needed if count > 16, for Intel behaviour.  */
2032                tcg_gen_subfi_tl(s->tmp4, 33, count);
2033                tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4);
2034                tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4);
2035            }
2036
2037            tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2038            tcg_gen_shl_tl(s->T0, s->T0, count);
2039            tcg_gen_shr_tl(s->T1, s->T1, s->tmp4);
2040        }
2041        tcg_gen_movi_tl(s->tmp4, 0);
2042        tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4,
2043                           s->tmp4, s->T1);
2044        tcg_gen_or_tl(s->T0, s->T0, s->T1);
2045        break;
2046    }
2047
2048    /* store */
2049    gen_op_st_rm_T0_A0(s, ot, op1);
2050
2051    gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right);
2052    tcg_temp_free(count);
2053}
2054
2055static void gen_shift(DisasContext *s1, int op, MemOp ot, int d, int s)
2056{
2057    if (s != OR_TMP1)
2058        gen_op_mov_v_reg(s1, ot, s1->T1, s);
2059    switch(op) {
2060    case OP_ROL:
2061        gen_rot_rm_T1(s1, ot, d, 0);
2062        break;
2063    case OP_ROR:
2064        gen_rot_rm_T1(s1, ot, d, 1);
2065        break;
2066    case OP_SHL:
2067    case OP_SHL1:
2068        gen_shift_rm_T1(s1, ot, d, 0, 0);
2069        break;
2070    case OP_SHR:
2071        gen_shift_rm_T1(s1, ot, d, 1, 0);
2072        break;
2073    case OP_SAR:
2074        gen_shift_rm_T1(s1, ot, d, 1, 1);
2075        break;
2076    case OP_RCL:
2077        gen_rotc_rm_T1(s1, ot, d, 0);
2078        break;
2079    case OP_RCR:
2080        gen_rotc_rm_T1(s1, ot, d, 1);
2081        break;
2082    }
2083}
2084
2085static void gen_shifti(DisasContext *s1, int op, MemOp ot, int d, int c)
2086{
2087    switch(op) {
2088    case OP_ROL:
2089        gen_rot_rm_im(s1, ot, d, c, 0);
2090        break;
2091    case OP_ROR:
2092        gen_rot_rm_im(s1, ot, d, c, 1);
2093        break;
2094    case OP_SHL:
2095    case OP_SHL1:
2096        gen_shift_rm_im(s1, ot, d, c, 0, 0);
2097        break;
2098    case OP_SHR:
2099        gen_shift_rm_im(s1, ot, d, c, 1, 0);
2100        break;
2101    case OP_SAR:
2102        gen_shift_rm_im(s1, ot, d, c, 1, 1);
2103        break;
2104    default:
2105        /* currently not optimized */
2106        tcg_gen_movi_tl(s1->T1, c);
2107        gen_shift(s1, op, ot, d, OR_TMP1);
2108        break;
2109    }
2110}
2111
2112#define X86_MAX_INSN_LENGTH 15
2113
2114static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
2115{
2116    uint64_t pc = s->pc;
2117
2118    /* This is a subsequent insn that crosses a page boundary.  */
2119    if (s->base.num_insns > 1 &&
2120        !is_same_page(&s->base, s->pc + num_bytes - 1)) {
2121        siglongjmp(s->jmpbuf, 2);
2122    }
2123
2124    s->pc += num_bytes;
2125    if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
2126        /* If the instruction's 16th byte is on a different page than the 1st, a
2127         * page fault on the second page wins over the general protection fault
2128         * caused by the instruction being too long.
2129         * This can happen even if the operand is only one byte long!
2130         */
2131        if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
2132            volatile uint8_t unused =
2133                cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
2134            (void) unused;
2135        }
2136        siglongjmp(s->jmpbuf, 1);
2137    }
2138
2139    return pc;
2140}
2141
2142static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
2143{
2144    return translator_ldub(env, &s->base, advance_pc(env, s, 1));
2145}
2146
2147static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
2148{
2149    return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2150}
2151
2152static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
2153{
2154    return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2155}
2156
2157static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
2158{
2159    return translator_ldl(env, &s->base, advance_pc(env, s, 4));
2160}
2161
2162#ifdef TARGET_X86_64
2163static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
2164{
2165    return translator_ldq(env, &s->base, advance_pc(env, s, 8));
2166}
2167#endif
2168
2169/* Decompose an address.  */
2170
2171typedef struct AddressParts {
2172    int def_seg;
2173    int base;
2174    int index;
2175    int scale;
2176    target_long disp;
2177} AddressParts;
2178
2179static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
2180                                    int modrm)
2181{
2182    int def_seg, base, index, scale, mod, rm;
2183    target_long disp;
2184    bool havesib;
2185
2186    def_seg = R_DS;
2187    index = -1;
2188    scale = 0;
2189    disp = 0;
2190
2191    mod = (modrm >> 6) & 3;
2192    rm = modrm & 7;
2193    base = rm | REX_B(s);
2194
2195    if (mod == 3) {
2196        /* Normally filtered out earlier, but including this path
2197           simplifies multi-byte nop, as well as bndcl, bndcu, bndcn.  */
2198        goto done;
2199    }
2200
2201    switch (s->aflag) {
2202    case MO_64:
2203    case MO_32:
2204        havesib = 0;
2205        if (rm == 4) {
2206            int code = x86_ldub_code(env, s);
2207            scale = (code >> 6) & 3;
2208            index = ((code >> 3) & 7) | REX_X(s);
2209            if (index == 4) {
2210                index = -1;  /* no index */
2211            }
2212            base = (code & 7) | REX_B(s);
2213            havesib = 1;
2214        }
2215
2216        switch (mod) {
2217        case 0:
2218            if ((base & 7) == 5) {
2219                base = -1;
2220                disp = (int32_t)x86_ldl_code(env, s);
2221                if (CODE64(s) && !havesib) {
2222                    base = -2;
2223                    disp += s->pc + s->rip_offset;
2224                }
2225            }
2226            break;
2227        case 1:
2228            disp = (int8_t)x86_ldub_code(env, s);
2229            break;
2230        default:
2231        case 2:
2232            disp = (int32_t)x86_ldl_code(env, s);
2233            break;
2234        }
2235
2236        /* For correct popl handling with esp.  */
2237        if (base == R_ESP && s->popl_esp_hack) {
2238            disp += s->popl_esp_hack;
2239        }
2240        if (base == R_EBP || base == R_ESP) {
2241            def_seg = R_SS;
2242        }
2243        break;
2244
2245    case MO_16:
2246        if (mod == 0) {
2247            if (rm == 6) {
2248                base = -1;
2249                disp = x86_lduw_code(env, s);
2250                break;
2251            }
2252        } else if (mod == 1) {
2253            disp = (int8_t)x86_ldub_code(env, s);
2254        } else {
2255            disp = (int16_t)x86_lduw_code(env, s);
2256        }
2257
2258        switch (rm) {
2259        case 0:
2260            base = R_EBX;
2261            index = R_ESI;
2262            break;
2263        case 1:
2264            base = R_EBX;
2265            index = R_EDI;
2266            break;
2267        case 2:
2268            base = R_EBP;
2269            index = R_ESI;
2270            def_seg = R_SS;
2271            break;
2272        case 3:
2273            base = R_EBP;
2274            index = R_EDI;
2275            def_seg = R_SS;
2276            break;
2277        case 4:
2278            base = R_ESI;
2279            break;
2280        case 5:
2281            base = R_EDI;
2282            break;
2283        case 6:
2284            base = R_EBP;
2285            def_seg = R_SS;
2286            break;
2287        default:
2288        case 7:
2289            base = R_EBX;
2290            break;
2291        }
2292        break;
2293
2294    default:
2295        tcg_abort();
2296    }
2297
2298 done:
2299    return (AddressParts){ def_seg, base, index, scale, disp };
2300}
2301
2302/* Compute the address, with a minimum number of TCG ops.  */
2303static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
2304{
2305    TCGv ea = NULL;
2306
2307    if (a.index >= 0 && !is_vsib) {
2308        if (a.scale == 0) {
2309            ea = cpu_regs[a.index];
2310        } else {
2311            tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale);
2312            ea = s->A0;
2313        }
2314        if (a.base >= 0) {
2315            tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]);
2316            ea = s->A0;
2317        }
2318    } else if (a.base >= 0) {
2319        ea = cpu_regs[a.base];
2320    }
2321    if (!ea) {
2322        if (TARGET_TB_PCREL && a.base == -2) {
2323            /* With cpu_eip ~= pc_save, the expression is pc-relative. */
2324            tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
2325        } else {
2326            tcg_gen_movi_tl(s->A0, a.disp);
2327        }
2328        ea = s->A0;
2329    } else if (a.disp != 0) {
2330        tcg_gen_addi_tl(s->A0, ea, a.disp);
2331        ea = s->A0;
2332    }
2333
2334    return ea;
2335}
2336
2337static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2338{
2339    AddressParts a = gen_lea_modrm_0(env, s, modrm);
2340    TCGv ea = gen_lea_modrm_1(s, a, false);
2341    gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2342}
2343
2344static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2345{
2346    (void)gen_lea_modrm_0(env, s, modrm);
2347}
2348
2349/* Used for BNDCL, BNDCU, BNDCN.  */
2350static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2351                      TCGCond cond, TCGv_i64 bndv)
2352{
2353    AddressParts a = gen_lea_modrm_0(env, s, modrm);
2354    TCGv ea = gen_lea_modrm_1(s, a, false);
2355
2356    tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
2357    if (!CODE64(s)) {
2358        tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64);
2359    }
2360    tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv);
2361    tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64);
2362    gen_helper_bndck(cpu_env, s->tmp2_i32);
2363}
2364
2365/* used for LEA and MOV AX, mem */
2366static void gen_add_A0_ds_seg(DisasContext *s)
2367{
2368    gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override);
2369}
2370
2371/* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2372   OR_TMP0 */
2373static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2374                           MemOp ot, int reg, int is_store)
2375{
2376    int mod, rm;
2377
2378    mod = (modrm >> 6) & 3;
2379    rm = (modrm & 7) | REX_B(s);
2380    if (mod == 3) {
2381        if (is_store) {
2382            if (reg != OR_TMP0)
2383                gen_op_mov_v_reg(s, ot, s->T0, reg);
2384            gen_op_mov_reg_v(s, ot, rm, s->T0);
2385        } else {
2386            gen_op_mov_v_reg(s, ot, s->T0, rm);
2387            if (reg != OR_TMP0)
2388                gen_op_mov_reg_v(s, ot, reg, s->T0);
2389        }
2390    } else {
2391        gen_lea_modrm(env, s, modrm);
2392        if (is_store) {
2393            if (reg != OR_TMP0)
2394                gen_op_mov_v_reg(s, ot, s->T0, reg);
2395            gen_op_st_v(s, ot, s->T0, s->A0);
2396        } else {
2397            gen_op_ld_v(s, ot, s->T0, s->A0);
2398            if (reg != OR_TMP0)
2399                gen_op_mov_reg_v(s, ot, reg, s->T0);
2400        }
2401    }
2402}
2403
2404static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
2405{
2406    target_ulong ret;
2407
2408    switch (ot) {
2409    case MO_8:
2410        ret = x86_ldub_code(env, s);
2411        break;
2412    case MO_16:
2413        ret = x86_lduw_code(env, s);
2414        break;
2415    case MO_32:
2416        ret = x86_ldl_code(env, s);
2417        break;
2418#ifdef TARGET_X86_64
2419    case MO_64:
2420        ret = x86_ldq_code(env, s);
2421        break;
2422#endif
2423    default:
2424        g_assert_not_reached();
2425    }
2426    return ret;
2427}
2428
2429static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
2430{
2431    uint32_t ret;
2432
2433    switch (ot) {
2434    case MO_8:
2435        ret = x86_ldub_code(env, s);
2436        break;
2437    case MO_16:
2438        ret = x86_lduw_code(env, s);
2439        break;
2440    case MO_32:
2441#ifdef TARGET_X86_64
2442    case MO_64:
2443#endif
2444        ret = x86_ldl_code(env, s);
2445        break;
2446    default:
2447        tcg_abort();
2448    }
2449    return ret;
2450}
2451
2452static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot)
2453{
2454    target_long ret;
2455
2456    switch (ot) {
2457    case MO_8:
2458        ret = (int8_t) x86_ldub_code(env, s);
2459        break;
2460    case MO_16:
2461        ret = (int16_t) x86_lduw_code(env, s);
2462        break;
2463    case MO_32:
2464        ret = (int32_t) x86_ldl_code(env, s);
2465        break;
2466#ifdef TARGET_X86_64
2467    case MO_64:
2468        ret = x86_ldq_code(env, s);
2469        break;
2470#endif
2471    default:
2472        g_assert_not_reached();
2473    }
2474    return ret;
2475}
2476
2477static inline int insn_const_size(MemOp ot)
2478{
2479    if (ot <= MO_32) {
2480        return 1 << ot;
2481    } else {
2482        return 4;
2483    }
2484}
2485
2486static void gen_jcc(DisasContext *s, int b, int diff)
2487{
2488    TCGLabel *l1 = gen_new_label();
2489
2490    gen_jcc1(s, b, l1);
2491    gen_jmp_rel_csize(s, 0, 1);
2492    gen_set_label(l1);
2493    gen_jmp_rel(s, s->dflag, diff, 0);
2494}
2495
2496static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
2497                        int modrm, int reg)
2498{
2499    CCPrepare cc;
2500
2501    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2502
2503    cc = gen_prepare_cc(s, b, s->T1);
2504    if (cc.mask != -1) {
2505        TCGv t0 = tcg_temp_new();
2506        tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2507        cc.reg = t0;
2508    }
2509    if (!cc.use_reg2) {
2510        cc.reg2 = tcg_const_tl(cc.imm);
2511    }
2512
2513    tcg_gen_movcond_tl(cc.cond, s->T0, cc.reg, cc.reg2,
2514                       s->T0, cpu_regs[reg]);
2515    gen_op_mov_reg_v(s, ot, reg, s->T0);
2516
2517    if (cc.mask != -1) {
2518        tcg_temp_free(cc.reg);
2519    }
2520    if (!cc.use_reg2) {
2521        tcg_temp_free(cc.reg2);
2522    }
2523}
2524
2525static inline void gen_op_movl_T0_seg(DisasContext *s, X86Seg seg_reg)
2526{
2527    tcg_gen_ld32u_tl(s->T0, cpu_env,
2528                     offsetof(CPUX86State,segs[seg_reg].selector));
2529}
2530
2531static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
2532{
2533    tcg_gen_ext16u_tl(s->T0, s->T0);
2534    tcg_gen_st32_tl(s->T0, cpu_env,
2535                    offsetof(CPUX86State,segs[seg_reg].selector));
2536    tcg_gen_shli_tl(cpu_seg_base[seg_reg], s->T0, 4);
2537}
2538
2539/* move T0 to seg_reg and compute if the CPU state may change. Never
2540   call this function with seg_reg == R_CS */
2541static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
2542{
2543    if (PE(s) && !VM86(s)) {
2544        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2545        gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32);
2546        /* abort translation because the addseg value may change or
2547           because ss32 may change. For R_SS, translation must always
2548           stop as a special handling must be done to disable hardware
2549           interrupts for the next instruction */
2550        if (seg_reg == R_SS) {
2551            s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2552        } else if (CODE32(s) && seg_reg < R_FS) {
2553            s->base.is_jmp = DISAS_EOB_NEXT;
2554        }
2555    } else {
2556        gen_op_movl_seg_T0_vm(s, seg_reg);
2557        if (seg_reg == R_SS) {
2558            s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2559        }
2560    }
2561}
2562
2563static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
2564{
2565    /* no SVM activated; fast case */
2566    if (likely(!GUEST(s))) {
2567        return;
2568    }
2569    gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type));
2570}
2571
2572static inline void gen_stack_update(DisasContext *s, int addend)
2573{
2574    gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend);
2575}
2576
2577/* Generate a push. It depends on ss32, addseg and dflag.  */
2578static void gen_push_v(DisasContext *s, TCGv val)
2579{
2580    MemOp d_ot = mo_pushpop(s, s->dflag);
2581    MemOp a_ot = mo_stacksize(s);
2582    int size = 1 << d_ot;
2583    TCGv new_esp = s->A0;
2584
2585    tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size);
2586
2587    if (!CODE64(s)) {
2588        if (ADDSEG(s)) {
2589            new_esp = s->tmp4;
2590            tcg_gen_mov_tl(new_esp, s->A0);
2591        }
2592        gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2593    }
2594
2595    gen_op_st_v(s, d_ot, val, s->A0);
2596    gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp);
2597}
2598
2599/* two step pop is necessary for precise exceptions */
2600static MemOp gen_pop_T0(DisasContext *s)
2601{
2602    MemOp d_ot = mo_pushpop(s, s->dflag);
2603
2604    gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2605    gen_op_ld_v(s, d_ot, s->T0, s->A0);
2606
2607    return d_ot;
2608}
2609
2610static inline void gen_pop_update(DisasContext *s, MemOp ot)
2611{
2612    gen_stack_update(s, 1 << ot);
2613}
2614
2615static inline void gen_stack_A0(DisasContext *s)
2616{
2617    gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2618}
2619
2620static void gen_pusha(DisasContext *s)
2621{
2622    MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2623    MemOp d_ot = s->dflag;
2624    int size = 1 << d_ot;
2625    int i;
2626
2627    for (i = 0; i < 8; i++) {
2628        tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size);
2629        gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2630        gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0);
2631    }
2632
2633    gen_stack_update(s, -8 * size);
2634}
2635
2636static void gen_popa(DisasContext *s)
2637{
2638    MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2639    MemOp d_ot = s->dflag;
2640    int size = 1 << d_ot;
2641    int i;
2642
2643    for (i = 0; i < 8; i++) {
2644        /* ESP is not reloaded */
2645        if (7 - i == R_ESP) {
2646            continue;
2647        }
2648        tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size);
2649        gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2650        gen_op_ld_v(s, d_ot, s->T0, s->A0);
2651        gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0);
2652    }
2653
2654    gen_stack_update(s, 8 * size);
2655}
2656
2657static void gen_enter(DisasContext *s, int esp_addend, int level)
2658{
2659    MemOp d_ot = mo_pushpop(s, s->dflag);
2660    MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
2661    int size = 1 << d_ot;
2662
2663    /* Push BP; compute FrameTemp into T1.  */
2664    tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size);
2665    gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1);
2666    gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0);
2667
2668    level &= 31;
2669    if (level != 0) {
2670        int i;
2671
2672        /* Copy level-1 pointers from the previous frame.  */
2673        for (i = 1; i < level; ++i) {
2674            tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i);
2675            gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2676            gen_op_ld_v(s, d_ot, s->tmp0, s->A0);
2677
2678            tcg_gen_subi_tl(s->A0, s->T1, size * i);
2679            gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2680            gen_op_st_v(s, d_ot, s->tmp0, s->A0);
2681        }
2682
2683        /* Push the current FrameTemp as the last level.  */
2684        tcg_gen_subi_tl(s->A0, s->T1, size * level);
2685        gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2686        gen_op_st_v(s, d_ot, s->T1, s->A0);
2687    }
2688
2689    /* Copy the FrameTemp value to EBP.  */
2690    gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1);
2691
2692    /* Compute the final value of ESP.  */
2693    tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
2694    gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2695}
2696
2697static void gen_leave(DisasContext *s)
2698{
2699    MemOp d_ot = mo_pushpop(s, s->dflag);
2700    MemOp a_ot = mo_stacksize(s);
2701
2702    gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2703    gen_op_ld_v(s, d_ot, s->T0, s->A0);
2704
2705    tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot);
2706
2707    gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0);
2708    gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2709}
2710
2711/* Similarly, except that the assumption here is that we don't decode
2712   the instruction at all -- either a missing opcode, an unimplemented
2713   feature, or just a bogus instruction stream.  */
2714static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2715{
2716    gen_illegal_opcode(s);
2717
2718    if (qemu_loglevel_mask(LOG_UNIMP)) {
2719        FILE *logfile = qemu_log_trylock();
2720        if (logfile) {
2721            target_ulong pc = s->base.pc_next, end = s->pc;
2722
2723            fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
2724            for (; pc < end; ++pc) {
2725                fprintf(logfile, " %02x", cpu_ldub_code(env, pc));
2726            }
2727            fprintf(logfile, "\n");
2728            qemu_log_unlock(logfile);
2729        }
2730    }
2731}
2732
2733/* an interrupt is different from an exception because of the
2734   privilege checks */
2735static void gen_interrupt(DisasContext *s, int intno)
2736{
2737    gen_update_cc_op(s);
2738    gen_update_eip_cur(s);
2739    gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
2740                               cur_insn_len_i32(s));
2741    s->base.is_jmp = DISAS_NORETURN;
2742}
2743
2744static void gen_set_hflag(DisasContext *s, uint32_t mask)
2745{
2746    if ((s->flags & mask) == 0) {
2747        TCGv_i32 t = tcg_temp_new_i32();
2748        tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2749        tcg_gen_ori_i32(t, t, mask);
2750        tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2751        tcg_temp_free_i32(t);
2752        s->flags |= mask;
2753    }
2754}
2755
2756static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2757{
2758    if (s->flags & mask) {
2759        TCGv_i32 t = tcg_temp_new_i32();
2760        tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2761        tcg_gen_andi_i32(t, t, ~mask);
2762        tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2763        tcg_temp_free_i32(t);
2764        s->flags &= ~mask;
2765    }
2766}
2767
2768static void gen_set_eflags(DisasContext *s, target_ulong mask)
2769{
2770    TCGv t = tcg_temp_new();
2771
2772    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
2773    tcg_gen_ori_tl(t, t, mask);
2774    tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
2775    tcg_temp_free(t);
2776}
2777
2778static void gen_reset_eflags(DisasContext *s, target_ulong mask)
2779{
2780    TCGv t = tcg_temp_new();
2781
2782    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags));
2783    tcg_gen_andi_tl(t, t, ~mask);
2784    tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags));
2785    tcg_temp_free(t);
2786}
2787
2788/* Clear BND registers during legacy branches.  */
2789static void gen_bnd_jmp(DisasContext *s)
2790{
2791    /* Clear the registers only if BND prefix is missing, MPX is enabled,
2792       and if the BNDREGs are known to be in use (non-zero) already.
2793       The helper itself will check BNDPRESERVE at runtime.  */
2794    if ((s->prefix & PREFIX_REPNZ) == 0
2795        && (s->flags & HF_MPX_EN_MASK) != 0
2796        && (s->flags & HF_MPX_IU_MASK) != 0) {
2797        gen_helper_bnd_jmp(cpu_env);
2798    }
2799}
2800
2801/* Generate an end of block. Trace exception is also generated if needed.
2802   If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2803   If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2804   S->TF.  This is used by the syscall/sysret insns.  */
2805static void
2806do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2807{
2808    gen_update_cc_op(s);
2809
2810    /* If several instructions disable interrupts, only the first does it.  */
2811    if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2812        gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2813    } else {
2814        gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2815    }
2816
2817    if (s->base.tb->flags & HF_RF_MASK) {
2818        gen_reset_eflags(s, RF_MASK);
2819    }
2820    if (recheck_tf) {
2821        gen_helper_rechecking_single_step(cpu_env);
2822        tcg_gen_exit_tb(NULL, 0);
2823    } else if (s->flags & HF_TF_MASK) {
2824        gen_helper_single_step(cpu_env);
2825    } else if (jr) {
2826        tcg_gen_lookup_and_goto_ptr();
2827    } else {
2828        tcg_gen_exit_tb(NULL, 0);
2829    }
2830    s->base.is_jmp = DISAS_NORETURN;
2831}
2832
2833static inline void
2834gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2835{
2836    do_gen_eob_worker(s, inhibit, recheck_tf, false);
2837}
2838
2839/* End of block.
2840   If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
2841static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2842{
2843    gen_eob_worker(s, inhibit, false);
2844}
2845
2846/* End of block, resetting the inhibit irq flag.  */
2847static void gen_eob(DisasContext *s)
2848{
2849    gen_eob_worker(s, false, false);
2850}
2851
2852/* Jump to register */
2853static void gen_jr(DisasContext *s)
2854{
2855    do_gen_eob_worker(s, false, false, true);
2856}
2857
2858/* Jump to eip+diff, truncating the result to OT. */
2859static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
2860{
2861    bool use_goto_tb = s->jmp_opt;
2862    target_ulong mask = -1;
2863    target_ulong new_pc = s->pc + diff;
2864    target_ulong new_eip = new_pc - s->cs_base;
2865
2866    /* In 64-bit mode, operand size is fixed at 64 bits. */
2867    if (!CODE64(s)) {
2868        if (ot == MO_16) {
2869            mask = 0xffff;
2870            if (TARGET_TB_PCREL && CODE32(s)) {
2871                use_goto_tb = false;
2872            }
2873        } else {
2874            mask = 0xffffffff;
2875        }
2876    }
2877    new_eip &= mask;
2878
2879    gen_update_cc_op(s);
2880    set_cc_op(s, CC_OP_DYNAMIC);
2881
2882    if (TARGET_TB_PCREL) {
2883        tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
2884        /*
2885         * If we can prove the branch does not leave the page and we have
2886         * no extra masking to apply (data16 branch in code32, see above),
2887         * then we have also proven that the addition does not wrap.
2888         */
2889        if (!use_goto_tb || !is_same_page(&s->base, new_pc)) {
2890            tcg_gen_andi_tl(cpu_eip, cpu_eip, mask);
2891            use_goto_tb = false;
2892        }
2893    }
2894
2895    if (use_goto_tb &&
2896        translator_use_goto_tb(&s->base, new_eip + s->cs_base)) {
2897        /* jump to same page: we can use a direct jump */
2898        tcg_gen_goto_tb(tb_num);
2899        if (!TARGET_TB_PCREL) {
2900            tcg_gen_movi_tl(cpu_eip, new_eip);
2901        }
2902        tcg_gen_exit_tb(s->base.tb, tb_num);
2903        s->base.is_jmp = DISAS_NORETURN;
2904    } else {
2905        if (!TARGET_TB_PCREL) {
2906            tcg_gen_movi_tl(cpu_eip, new_eip);
2907        }
2908        if (s->jmp_opt) {
2909            gen_jr(s);   /* jump to another page */
2910        } else {
2911            gen_eob(s);  /* exit to main loop */
2912        }
2913    }
2914}
2915
2916/* Jump to eip+diff, truncating to the current code size. */
2917static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num)
2918{
2919    /* CODE64 ignores the OT argument, so we need not consider it. */
2920    gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num);
2921}
2922
2923static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2924{
2925    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2926    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset);
2927}
2928
2929static inline void gen_stq_env_A0(DisasContext *s, int offset)
2930{
2931    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset);
2932    tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2933}
2934
2935static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align)
2936{
2937    int mem_index = s->mem_index;
2938    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index,
2939                        MO_LEUQ | (align ? MO_ALIGN_16 : 0));
2940    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2941    tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2942    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2943    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2944}
2945
2946static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align)
2947{
2948    int mem_index = s->mem_index;
2949    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2950    tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index,
2951                        MO_LEUQ | (align ? MO_ALIGN_16 : 0));
2952    tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2953    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2954    tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2955}
2956
2957static void gen_ldy_env_A0(DisasContext *s, int offset, bool align)
2958{
2959    int mem_index = s->mem_index;
2960    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index,
2961                        MO_LEUQ | (align ? MO_ALIGN_32 : 0));
2962    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0)));
2963    tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2964    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2965    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1)));
2966
2967    tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2968    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2969    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2)));
2970    tcg_gen_addi_tl(s->tmp0, s->A0, 24);
2971    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2972    tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3)));
2973}
2974
2975static void gen_sty_env_A0(DisasContext *s, int offset, bool align)
2976{
2977    int mem_index = s->mem_index;
2978    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0)));
2979    tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index,
2980                        MO_LEUQ | (align ? MO_ALIGN_32 : 0));
2981    tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2982    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1)));
2983    tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2984    tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2985    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2)));
2986    tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2987    tcg_gen_addi_tl(s->tmp0, s->A0, 24);
2988    tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3)));
2989    tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2990}
2991
2992#include "decode-new.h"
2993#include "emit.c.inc"
2994#include "decode-new.c.inc"
2995
2996/* convert one instruction. s->base.is_jmp is set if the translation must
2997   be stopped. Return the next pc value */
2998static bool disas_insn(DisasContext *s, CPUState *cpu)
2999{
3000    CPUX86State *env = cpu->env_ptr;
3001    int b, prefixes;
3002    int shift;
3003    MemOp ot, aflag, dflag;
3004    int modrm, reg, rm, mod, op, opreg, val;
3005    bool orig_cc_op_dirty = s->cc_op_dirty;
3006    CCOp orig_cc_op = s->cc_op;
3007    target_ulong orig_pc_save = s->pc_save;
3008
3009    s->pc = s->base.pc_next;
3010    s->override = -1;
3011#ifdef TARGET_X86_64
3012    s->rex_r = 0;
3013    s->rex_x = 0;
3014    s->rex_b = 0;
3015#endif
3016    s->rip_offset = 0; /* for relative ip address */
3017    s->vex_l = 0;
3018    s->vex_v = 0;
3019    s->vex_w = false;
3020    switch (sigsetjmp(s->jmpbuf, 0)) {
3021    case 0:
3022        break;
3023    case 1:
3024        gen_exception_gpf(s);
3025        return true;
3026    case 2:
3027        /* Restore state that may affect the next instruction. */
3028        s->pc = s->base.pc_next;
3029        /*
3030         * TODO: These save/restore can be removed after the table-based
3031         * decoder is complete; we will be decoding the insn completely
3032         * before any code generation that might affect these variables.
3033         */
3034        s->cc_op_dirty = orig_cc_op_dirty;
3035        s->cc_op = orig_cc_op;
3036        s->pc_save = orig_pc_save;
3037        /* END TODO */
3038        s->base.num_insns--;
3039        tcg_remove_ops_after(s->prev_insn_end);
3040        s->base.is_jmp = DISAS_TOO_MANY;
3041        return false;
3042    default:
3043        g_assert_not_reached();
3044    }
3045
3046    prefixes = 0;
3047
3048 next_byte:
3049    s->prefix = prefixes;
3050    b = x86_ldub_code(env, s);
3051    /* Collect prefixes.  */
3052    switch (b) {
3053    default:
3054        break;
3055    case 0x0f:
3056        b = x86_ldub_code(env, s) + 0x100;
3057        break;
3058    case 0xf3:
3059        prefixes |= PREFIX_REPZ;
3060        prefixes &= ~PREFIX_REPNZ;
3061        goto next_byte;
3062    case 0xf2:
3063        prefixes |= PREFIX_REPNZ;
3064        prefixes &= ~PREFIX_REPZ;
3065        goto next_byte;
3066    case 0xf0:
3067        prefixes |= PREFIX_LOCK;
3068        goto next_byte;
3069    case 0x2e:
3070        s->override = R_CS;
3071        goto next_byte;
3072    case 0x36:
3073        s->override = R_SS;
3074        goto next_byte;
3075    case 0x3e:
3076        s->override = R_DS;
3077        goto next_byte;
3078    case 0x26:
3079        s->override = R_ES;
3080        goto next_byte;
3081    case 0x64:
3082        s->override = R_FS;
3083        goto next_byte;
3084    case 0x65:
3085        s->override = R_GS;
3086        goto next_byte;
3087    case 0x66:
3088        prefixes |= PREFIX_DATA;
3089        goto next_byte;
3090    case 0x67:
3091        prefixes |= PREFIX_ADR;
3092        goto next_byte;
3093#ifdef TARGET_X86_64
3094    case 0x40 ... 0x4f:
3095        if (CODE64(s)) {
3096            /* REX prefix */
3097            prefixes |= PREFIX_REX;
3098            s->vex_w = (b >> 3) & 1;
3099            s->rex_r = (b & 0x4) << 1;
3100            s->rex_x = (b & 0x2) << 2;
3101            s->rex_b = (b & 0x1) << 3;
3102            goto next_byte;
3103        }
3104        break;
3105#endif
3106    case 0xc5: /* 2-byte VEX */
3107    case 0xc4: /* 3-byte VEX */
3108        if (CODE32(s) && !VM86(s)) {
3109            int vex2 = x86_ldub_code(env, s);
3110            s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
3111
3112            if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
3113                /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
3114                   otherwise the instruction is LES or LDS.  */
3115                break;
3116            }
3117            disas_insn_new(s, cpu, b);
3118            return s->pc;
3119        }
3120        break;
3121    }
3122
3123    /* Post-process prefixes.  */
3124    if (CODE64(s)) {
3125        /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
3126           data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
3127           over 0x66 if both are present.  */
3128        dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
3129        /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
3130        aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
3131    } else {
3132        /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
3133        if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) {
3134            dflag = MO_32;
3135        } else {
3136            dflag = MO_16;
3137        }
3138        /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
3139        if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) {
3140            aflag = MO_32;
3141        }  else {
3142            aflag = MO_16;
3143        }
3144    }
3145
3146    s->prefix = prefixes;
3147    s->aflag = aflag;
3148    s->dflag = dflag;
3149
3150    /* now check op code */
3151    switch (b) {
3152        /**************************/
3153        /* arith & logic */
3154    case 0x00 ... 0x05:
3155    case 0x08 ... 0x0d:
3156    case 0x10 ... 0x15:
3157    case 0x18 ... 0x1d:
3158    case 0x20 ... 0x25:
3159    case 0x28 ... 0x2d:
3160    case 0x30 ... 0x35:
3161    case 0x38 ... 0x3d:
3162        {
3163            int op, f, val;
3164            op = (b >> 3) & 7;
3165            f = (b >> 1) & 3;
3166
3167            ot = mo_b_d(b, dflag);
3168
3169            switch(f) {
3170            case 0: /* OP Ev, Gv */
3171                modrm = x86_ldub_code(env, s);
3172                reg = ((modrm >> 3) & 7) | REX_R(s);
3173                mod = (modrm >> 6) & 3;
3174                rm = (modrm & 7) | REX_B(s);
3175                if (mod != 3) {
3176                    gen_lea_modrm(env, s, modrm);
3177                    opreg = OR_TMP0;
3178                } else if (op == OP_XORL && rm == reg) {
3179                xor_zero:
3180                    /* xor reg, reg optimisation */
3181                    set_cc_op(s, CC_OP_CLR);
3182                    tcg_gen_movi_tl(s->T0, 0);
3183                    gen_op_mov_reg_v(s, ot, reg, s->T0);
3184                    break;
3185                } else {
3186                    opreg = rm;
3187                }
3188                gen_op_mov_v_reg(s, ot, s->T1, reg);
3189                gen_op(s, op, ot, opreg);
3190                break;
3191            case 1: /* OP Gv, Ev */
3192                modrm = x86_ldub_code(env, s);
3193                mod = (modrm >> 6) & 3;
3194                reg = ((modrm >> 3) & 7) | REX_R(s);
3195                rm = (modrm & 7) | REX_B(s);
3196                if (mod != 3) {
3197                    gen_lea_modrm(env, s, modrm);
3198                    gen_op_ld_v(s, ot, s->T1, s->A0);
3199                } else if (op == OP_XORL && rm == reg) {
3200                    goto xor_zero;
3201                } else {
3202                    gen_op_mov_v_reg(s, ot, s->T1, rm);
3203                }
3204                gen_op(s, op, ot, reg);
3205                break;
3206            case 2: /* OP A, Iv */
3207                val = insn_get(env, s, ot);
3208                tcg_gen_movi_tl(s->T1, val);
3209                gen_op(s, op, ot, OR_EAX);
3210                break;
3211            }
3212        }
3213        break;
3214
3215    case 0x82:
3216        if (CODE64(s))
3217            goto illegal_op;
3218        /* fall through */
3219    case 0x80: /* GRP1 */
3220    case 0x81:
3221    case 0x83:
3222        {
3223            int val;
3224
3225            ot = mo_b_d(b, dflag);
3226
3227            modrm = x86_ldub_code(env, s);
3228            mod = (modrm >> 6) & 3;
3229            rm = (modrm & 7) | REX_B(s);
3230            op = (modrm >> 3) & 7;
3231
3232            if (mod != 3) {
3233                if (b == 0x83)
3234                    s->rip_offset = 1;
3235                else
3236                    s->rip_offset = insn_const_size(ot);
3237                gen_lea_modrm(env, s, modrm);
3238                opreg = OR_TMP0;
3239            } else {
3240                opreg = rm;
3241            }
3242
3243            switch(b) {
3244            default:
3245            case 0x80:
3246            case 0x81:
3247            case 0x82:
3248                val = insn_get(env, s, ot);
3249                break;
3250            case 0x83:
3251                val = (int8_t)insn_get(env, s, MO_8);
3252                break;
3253            }
3254            tcg_gen_movi_tl(s->T1, val);
3255            gen_op(s, op, ot, opreg);
3256        }
3257        break;
3258
3259        /**************************/
3260        /* inc, dec, and other misc arith */
3261    case 0x40 ... 0x47: /* inc Gv */
3262        ot = dflag;
3263        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3264        break;
3265    case 0x48 ... 0x4f: /* dec Gv */
3266        ot = dflag;
3267        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3268        break;
3269    case 0xf6: /* GRP3 */
3270    case 0xf7:
3271        ot = mo_b_d(b, dflag);
3272
3273        modrm = x86_ldub_code(env, s);
3274        mod = (modrm >> 6) & 3;
3275        rm = (modrm & 7) | REX_B(s);
3276        op = (modrm >> 3) & 7;
3277        if (mod != 3) {
3278            if (op == 0) {
3279                s->rip_offset = insn_const_size(ot);
3280            }
3281            gen_lea_modrm(env, s, modrm);
3282            /* For those below that handle locked memory, don't load here.  */
3283            if (!(s->prefix & PREFIX_LOCK)
3284                || op != 2) {
3285                gen_op_ld_v(s, ot, s->T0, s->A0);
3286            }
3287        } else {
3288            gen_op_mov_v_reg(s, ot, s->T0, rm);
3289        }
3290
3291        switch(op) {
3292        case 0: /* test */
3293            val = insn_get(env, s, ot);
3294            tcg_gen_movi_tl(s->T1, val);
3295            gen_op_testl_T0_T1_cc(s);
3296            set_cc_op(s, CC_OP_LOGICB + ot);
3297            break;
3298        case 2: /* not */
3299            if (s->prefix & PREFIX_LOCK) {
3300                if (mod == 3) {
3301                    goto illegal_op;
3302                }
3303                tcg_gen_movi_tl(s->T0, ~0);
3304                tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
3305                                            s->mem_index, ot | MO_LE);
3306            } else {
3307                tcg_gen_not_tl(s->T0, s->T0);
3308                if (mod != 3) {
3309                    gen_op_st_v(s, ot, s->T0, s->A0);
3310                } else {
3311                    gen_op_mov_reg_v(s, ot, rm, s->T0);
3312                }
3313            }
3314            break;
3315        case 3: /* neg */
3316            if (s->prefix & PREFIX_LOCK) {
3317                TCGLabel *label1;
3318                TCGv a0, t0, t1, t2;
3319
3320                if (mod == 3) {
3321                    goto illegal_op;
3322                }
3323                a0 = tcg_temp_local_new();
3324                t0 = tcg_temp_local_new();
3325                label1 = gen_new_label();
3326
3327                tcg_gen_mov_tl(a0, s->A0);
3328                tcg_gen_mov_tl(t0, s->T0);
3329
3330                gen_set_label(label1);
3331                t1 = tcg_temp_new();
3332                t2 = tcg_temp_new();
3333                tcg_gen_mov_tl(t2, t0);
3334                tcg_gen_neg_tl(t1, t0);
3335                tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
3336                                          s->mem_index, ot | MO_LE);
3337                tcg_temp_free(t1);
3338                tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
3339
3340                tcg_temp_free(t2);
3341                tcg_temp_free(a0);
3342                tcg_gen_neg_tl(s->T0, t0);
3343                tcg_temp_free(t0);
3344            } else {
3345                tcg_gen_neg_tl(s->T0, s->T0);
3346                if (mod != 3) {
3347                    gen_op_st_v(s, ot, s->T0, s->A0);
3348                } else {
3349                    gen_op_mov_reg_v(s, ot, rm, s->T0);
3350                }
3351            }
3352            gen_op_update_neg_cc(s);
3353            set_cc_op(s, CC_OP_SUBB + ot);
3354            break;
3355        case 4: /* mul */
3356            switch(ot) {
3357            case MO_8:
3358                gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3359                tcg_gen_ext8u_tl(s->T0, s->T0);
3360                tcg_gen_ext8u_tl(s->T1, s->T1);
3361                /* XXX: use 32 bit mul which could be faster */
3362                tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3363                gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3364                tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3365                tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00);
3366                set_cc_op(s, CC_OP_MULB);
3367                break;
3368            case MO_16:
3369                gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3370                tcg_gen_ext16u_tl(s->T0, s->T0);
3371                tcg_gen_ext16u_tl(s->T1, s->T1);
3372                /* XXX: use 32 bit mul which could be faster */
3373                tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3374                gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3375                tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3376                tcg_gen_shri_tl(s->T0, s->T0, 16);
3377                gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3378                tcg_gen_mov_tl(cpu_cc_src, s->T0);
3379                set_cc_op(s, CC_OP_MULW);
3380                break;
3381            default:
3382            case MO_32:
3383                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3384                tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3385                tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
3386                                  s->tmp2_i32, s->tmp3_i32);
3387                tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3388                tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3389                tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3390                tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3391                set_cc_op(s, CC_OP_MULL);
3392                break;
3393#ifdef TARGET_X86_64
3394            case MO_64:
3395                tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3396                                  s->T0, cpu_regs[R_EAX]);
3397                tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3398                tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3399                set_cc_op(s, CC_OP_MULQ);
3400                break;
3401#endif
3402            }
3403            break;
3404        case 5: /* imul */
3405            switch(ot) {
3406            case MO_8:
3407                gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3408                tcg_gen_ext8s_tl(s->T0, s->T0);
3409                tcg_gen_ext8s_tl(s->T1, s->T1);
3410                /* XXX: use 32 bit mul which could be faster */
3411                tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3412                gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3413                tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3414                tcg_gen_ext8s_tl(s->tmp0, s->T0);
3415                tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3416                set_cc_op(s, CC_OP_MULB);
3417                break;
3418            case MO_16:
3419                gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3420                tcg_gen_ext16s_tl(s->T0, s->T0);
3421                tcg_gen_ext16s_tl(s->T1, s->T1);
3422                /* XXX: use 32 bit mul which could be faster */
3423                tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3424                gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3425                tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3426                tcg_gen_ext16s_tl(s->tmp0, s->T0);
3427                tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3428                tcg_gen_shri_tl(s->T0, s->T0, 16);
3429                gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3430                set_cc_op(s, CC_OP_MULW);
3431                break;
3432            default:
3433            case MO_32:
3434                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3435                tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3436                tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3437                                  s->tmp2_i32, s->tmp3_i32);
3438                tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3439                tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3440                tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3441                tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3442                tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3443                tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3444                set_cc_op(s, CC_OP_MULL);
3445                break;
3446#ifdef TARGET_X86_64
3447            case MO_64:
3448                tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3449                                  s->T0, cpu_regs[R_EAX]);
3450                tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3451                tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
3452                tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
3453                set_cc_op(s, CC_OP_MULQ);
3454                break;
3455#endif
3456            }
3457            break;
3458        case 6: /* div */
3459            switch(ot) {
3460            case MO_8:
3461                gen_helper_divb_AL(cpu_env, s->T0);
3462                break;
3463            case MO_16:
3464                gen_helper_divw_AX(cpu_env, s->T0);
3465                break;
3466            default:
3467            case MO_32:
3468                gen_helper_divl_EAX(cpu_env, s->T0);
3469                break;
3470#ifdef TARGET_X86_64
3471            case MO_64:
3472                gen_helper_divq_EAX(cpu_env, s->T0);
3473                break;
3474#endif
3475            }
3476            break;
3477        case 7: /* idiv */
3478            switch(ot) {
3479            case MO_8:
3480                gen_helper_idivb_AL(cpu_env, s->T0);
3481                break;
3482            case MO_16:
3483                gen_helper_idivw_AX(cpu_env, s->T0);
3484                break;
3485            default:
3486            case MO_32:
3487                gen_helper_idivl_EAX(cpu_env, s->T0);
3488                break;
3489#ifdef TARGET_X86_64
3490            case MO_64:
3491                gen_helper_idivq_EAX(cpu_env, s->T0);
3492                break;
3493#endif
3494            }
3495            break;
3496        default:
3497            goto unknown_op;
3498        }
3499        break;
3500
3501    case 0xfe: /* GRP4 */
3502    case 0xff: /* GRP5 */
3503        ot = mo_b_d(b, dflag);
3504
3505        modrm = x86_ldub_code(env, s);
3506        mod = (modrm >> 6) & 3;
3507        rm = (modrm & 7) | REX_B(s);
3508        op = (modrm >> 3) & 7;
3509        if (op >= 2 && b == 0xfe) {
3510            goto unknown_op;
3511        }
3512        if (CODE64(s)) {
3513            if (op == 2 || op == 4) {
3514                /* operand size for jumps is 64 bit */
3515                ot = MO_64;
3516            } else if (op == 3 || op == 5) {
3517                ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16;
3518            } else if (op == 6) {
3519                /* default push size is 64 bit */
3520                ot = mo_pushpop(s, dflag);
3521            }
3522        }
3523        if (mod != 3) {
3524            gen_lea_modrm(env, s, modrm);
3525            if (op >= 2 && op != 3 && op != 5)
3526                gen_op_ld_v(s, ot, s->T0, s->A0);
3527        } else {
3528            gen_op_mov_v_reg(s, ot, s->T0, rm);
3529        }
3530
3531        switch(op) {
3532        case 0: /* inc Ev */
3533            if (mod != 3)
3534                opreg = OR_TMP0;
3535            else
3536                opreg = rm;
3537            gen_inc(s, ot, opreg, 1);
3538            break;
3539        case 1: /* dec Ev */
3540            if (mod != 3)
3541                opreg = OR_TMP0;
3542            else
3543                opreg = rm;
3544            gen_inc(s, ot, opreg, -1);
3545            break;
3546        case 2: /* call Ev */
3547            /* XXX: optimize if memory (no 'and' is necessary) */
3548            if (dflag == MO_16) {
3549                tcg_gen_ext16u_tl(s->T0, s->T0);
3550            }
3551            gen_push_v(s, eip_next_tl(s));
3552            gen_op_jmp_v(s, s->T0);
3553            gen_bnd_jmp(s);
3554            s->base.is_jmp = DISAS_JUMP;
3555            break;
3556        case 3: /* lcall Ev */
3557            if (mod == 3) {
3558                goto illegal_op;
3559            }
3560            gen_op_ld_v(s, ot, s->T1, s->A0);
3561            gen_add_A0_im(s, 1 << ot);
3562            gen_op_ld_v(s, MO_16, s->T0, s->A0);
3563        do_lcall:
3564            if (PE(s) && !VM86(s)) {
3565                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3566                gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
3567                                           tcg_constant_i32(dflag - 1),
3568                                           eip_next_tl(s));
3569            } else {
3570                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3571                tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3572                gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
3573                                      tcg_constant_i32(dflag - 1),
3574                                      eip_next_i32(s));
3575            }
3576            s->base.is_jmp = DISAS_JUMP;
3577            break;
3578        case 4: /* jmp Ev */
3579            if (dflag == MO_16) {
3580                tcg_gen_ext16u_tl(s->T0, s->T0);
3581            }
3582            gen_op_jmp_v(s, s->T0);
3583            gen_bnd_jmp(s);
3584            s->base.is_jmp = DISAS_JUMP;
3585            break;
3586        case 5: /* ljmp Ev */
3587            if (mod == 3) {
3588                goto illegal_op;
3589            }
3590            gen_op_ld_v(s, ot, s->T1, s->A0);
3591            gen_add_A0_im(s, 1 << ot);
3592            gen_op_ld_v(s, MO_16, s->T0, s->A0);
3593        do_ljmp:
3594            if (PE(s) && !VM86(s)) {
3595                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3596                gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
3597                                          eip_next_tl(s));
3598            } else {
3599                gen_op_movl_seg_T0_vm(s, R_CS);
3600                gen_op_jmp_v(s, s->T1);
3601            }
3602            s->base.is_jmp = DISAS_JUMP;
3603            break;
3604        case 6: /* push Ev */
3605            gen_push_v(s, s->T0);
3606            break;
3607        default:
3608            goto unknown_op;
3609        }
3610        break;
3611
3612    case 0x84: /* test Ev, Gv */
3613    case 0x85:
3614        ot = mo_b_d(b, dflag);
3615
3616        modrm = x86_ldub_code(env, s);
3617        reg = ((modrm >> 3) & 7) | REX_R(s);
3618
3619        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3620        gen_op_mov_v_reg(s, ot, s->T1, reg);
3621        gen_op_testl_T0_T1_cc(s);
3622        set_cc_op(s, CC_OP_LOGICB + ot);
3623        break;
3624
3625    case 0xa8: /* test eAX, Iv */
3626    case 0xa9:
3627        ot = mo_b_d(b, dflag);
3628        val = insn_get(env, s, ot);
3629
3630        gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
3631        tcg_gen_movi_tl(s->T1, val);
3632        gen_op_testl_T0_T1_cc(s);
3633        set_cc_op(s, CC_OP_LOGICB + ot);
3634        break;
3635
3636    case 0x98: /* CWDE/CBW */
3637        switch (dflag) {
3638#ifdef TARGET_X86_64
3639        case MO_64:
3640            gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3641            tcg_gen_ext32s_tl(s->T0, s->T0);
3642            gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0);
3643            break;
3644#endif
3645        case MO_32:
3646            gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3647            tcg_gen_ext16s_tl(s->T0, s->T0);
3648            gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0);
3649            break;
3650        case MO_16:
3651            gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX);
3652            tcg_gen_ext8s_tl(s->T0, s->T0);
3653            gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3654            break;
3655        default:
3656            tcg_abort();
3657        }
3658        break;
3659    case 0x99: /* CDQ/CWD */
3660        switch (dflag) {
3661#ifdef TARGET_X86_64
3662        case MO_64:
3663            gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
3664            tcg_gen_sari_tl(s->T0, s->T0, 63);
3665            gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0);
3666            break;
3667#endif
3668        case MO_32:
3669            gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3670            tcg_gen_ext32s_tl(s->T0, s->T0);
3671            tcg_gen_sari_tl(s->T0, s->T0, 31);
3672            gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0);
3673            break;
3674        case MO_16:
3675            gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3676            tcg_gen_ext16s_tl(s->T0, s->T0);
3677            tcg_gen_sari_tl(s->T0, s->T0, 15);
3678            gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3679            break;
3680        default:
3681            tcg_abort();
3682        }
3683        break;
3684    case 0x1af: /* imul Gv, Ev */
3685    case 0x69: /* imul Gv, Ev, I */
3686    case 0x6b:
3687        ot = dflag;
3688        modrm = x86_ldub_code(env, s);
3689        reg = ((modrm >> 3) & 7) | REX_R(s);
3690        if (b == 0x69)
3691            s->rip_offset = insn_const_size(ot);
3692        else if (b == 0x6b)
3693            s->rip_offset = 1;
3694        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3695        if (b == 0x69) {
3696            val = insn_get(env, s, ot);
3697            tcg_gen_movi_tl(s->T1, val);
3698        } else if (b == 0x6b) {
3699            val = (int8_t)insn_get(env, s, MO_8);
3700            tcg_gen_movi_tl(s->T1, val);
3701        } else {
3702            gen_op_mov_v_reg(s, ot, s->T1, reg);
3703        }
3704        switch (ot) {
3705#ifdef TARGET_X86_64
3706        case MO_64:
3707            tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1);
3708            tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3709            tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
3710            tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1);
3711            break;
3712#endif
3713        case MO_32:
3714            tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3715            tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3716            tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3717                              s->tmp2_i32, s->tmp3_i32);
3718            tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3719            tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3720            tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3721            tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3722            tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3723            break;
3724        default:
3725            tcg_gen_ext16s_tl(s->T0, s->T0);
3726            tcg_gen_ext16s_tl(s->T1, s->T1);
3727            /* XXX: use 32 bit mul which could be faster */
3728            tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3729            tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3730            tcg_gen_ext16s_tl(s->tmp0, s->T0);
3731            tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3732            gen_op_mov_reg_v(s, ot, reg, s->T0);
3733            break;
3734        }
3735        set_cc_op(s, CC_OP_MULB + ot);
3736        break;
3737    case 0x1c0:
3738    case 0x1c1: /* xadd Ev, Gv */
3739        ot = mo_b_d(b, dflag);
3740        modrm = x86_ldub_code(env, s);
3741        reg = ((modrm >> 3) & 7) | REX_R(s);
3742        mod = (modrm >> 6) & 3;
3743        gen_op_mov_v_reg(s, ot, s->T0, reg);
3744        if (mod == 3) {
3745            rm = (modrm & 7) | REX_B(s);
3746            gen_op_mov_v_reg(s, ot, s->T1, rm);
3747            tcg_gen_add_tl(s->T0, s->T0, s->T1);
3748            gen_op_mov_reg_v(s, ot, reg, s->T1);
3749            gen_op_mov_reg_v(s, ot, rm, s->T0);
3750        } else {
3751            gen_lea_modrm(env, s, modrm);
3752            if (s->prefix & PREFIX_LOCK) {
3753                tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0,
3754                                            s->mem_index, ot | MO_LE);
3755                tcg_gen_add_tl(s->T0, s->T0, s->T1);
3756            } else {
3757                gen_op_ld_v(s, ot, s->T1, s->A0);
3758                tcg_gen_add_tl(s->T0, s->T0, s->T1);
3759                gen_op_st_v(s, ot, s->T0, s->A0);
3760            }
3761            gen_op_mov_reg_v(s, ot, reg, s->T1);
3762        }
3763        gen_op_update2_cc(s);
3764        set_cc_op(s, CC_OP_ADDB + ot);
3765        break;
3766    case 0x1b0:
3767    case 0x1b1: /* cmpxchg Ev, Gv */
3768        {
3769            TCGv oldv, newv, cmpv, dest;
3770
3771            ot = mo_b_d(b, dflag);
3772            modrm = x86_ldub_code(env, s);
3773            reg = ((modrm >> 3) & 7) | REX_R(s);
3774            mod = (modrm >> 6) & 3;
3775            oldv = tcg_temp_new();
3776            newv = tcg_temp_new();
3777            cmpv = tcg_temp_new();
3778            gen_op_mov_v_reg(s, ot, newv, reg);
3779            tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
3780            gen_extu(ot, cmpv);
3781            if (s->prefix & PREFIX_LOCK) {
3782                if (mod == 3) {
3783                    goto illegal_op;
3784                }
3785                gen_lea_modrm(env, s, modrm);
3786                tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
3787                                          s->mem_index, ot | MO_LE);
3788            } else {
3789                if (mod == 3) {
3790                    rm = (modrm & 7) | REX_B(s);
3791                    gen_op_mov_v_reg(s, ot, oldv, rm);
3792                    gen_extu(ot, oldv);
3793
3794                    /*
3795                     * Unlike the memory case, where "the destination operand receives
3796                     * a write cycle without regard to the result of the comparison",
3797                     * rm must not be touched altogether if the write fails, including
3798                     * not zero-extending it on 64-bit processors.  So, precompute
3799                     * the result of a successful writeback and perform the movcond
3800                     * directly on cpu_regs.  Also need to write accumulator first, in
3801                     * case rm is part of RAX too.
3802                     */
3803                    dest = gen_op_deposit_reg_v(s, ot, rm, newv, newv);
3804                    tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest);
3805                } else {
3806                    gen_lea_modrm(env, s, modrm);
3807                    gen_op_ld_v(s, ot, oldv, s->A0);
3808
3809                    /*
3810                     * Perform an unconditional store cycle like physical cpu;
3811                     * must be before changing accumulator to ensure
3812                     * idempotency if the store faults and the instruction
3813                     * is restarted
3814                     */
3815                    tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
3816                    gen_op_st_v(s, ot, newv, s->A0);
3817                }
3818            }
3819            /*
3820             * Write EAX only if the cmpxchg fails; reuse newv as the destination,
3821             * since it's dead here.
3822             */
3823            dest = gen_op_deposit_reg_v(s, ot, R_EAX, newv, oldv);
3824            tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, dest, newv);
3825            tcg_gen_mov_tl(cpu_cc_src, oldv);
3826            tcg_gen_mov_tl(s->cc_srcT, cmpv);
3827            tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
3828            set_cc_op(s, CC_OP_SUBB + ot);
3829            tcg_temp_free(oldv);
3830            tcg_temp_free(newv);
3831            tcg_temp_free(cmpv);
3832        }
3833        break;
3834    case 0x1c7: /* cmpxchg8b */
3835        modrm = x86_ldub_code(env, s);
3836        mod = (modrm >> 6) & 3;
3837        switch ((modrm >> 3) & 7) {
3838        case 1: /* CMPXCHG8, CMPXCHG16 */
3839            if (mod == 3) {
3840                goto illegal_op;
3841            }
3842#ifdef TARGET_X86_64
3843            if (dflag == MO_64) {
3844                if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
3845                    goto illegal_op;
3846                }
3847                gen_lea_modrm(env, s, modrm);
3848                if ((s->prefix & PREFIX_LOCK) &&
3849                    (tb_cflags(s->base.tb) & CF_PARALLEL)) {
3850                    gen_helper_cmpxchg16b(cpu_env, s->A0);
3851                } else {
3852                    gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
3853                }
3854                set_cc_op(s, CC_OP_EFLAGS);
3855                break;
3856            }
3857#endif        
3858            if (!(s->cpuid_features & CPUID_CX8)) {
3859                goto illegal_op;
3860            }
3861            gen_lea_modrm(env, s, modrm);
3862            if ((s->prefix & PREFIX_LOCK) &&
3863                (tb_cflags(s->base.tb) & CF_PARALLEL)) {
3864                gen_helper_cmpxchg8b(cpu_env, s->A0);
3865            } else {
3866                gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
3867            }
3868            set_cc_op(s, CC_OP_EFLAGS);
3869            break;
3870
3871        case 7: /* RDSEED */
3872        case 6: /* RDRAND */
3873            if (mod != 3 ||
3874                (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
3875                !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
3876                goto illegal_op;
3877            }
3878            if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3879                gen_io_start();
3880                s->base.is_jmp = DISAS_TOO_MANY;
3881            }
3882            gen_helper_rdrand(s->T0, cpu_env);
3883            rm = (modrm & 7) | REX_B(s);
3884            gen_op_mov_reg_v(s, dflag, rm, s->T0);
3885            set_cc_op(s, CC_OP_EFLAGS);
3886            break;
3887
3888        default:
3889            goto illegal_op;
3890        }
3891        break;
3892
3893        /**************************/
3894        /* push/pop */
3895    case 0x50 ... 0x57: /* push */
3896        gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
3897        gen_push_v(s, s->T0);
3898        break;
3899    case 0x58 ... 0x5f: /* pop */
3900        ot = gen_pop_T0(s);
3901        /* NOTE: order is important for pop %sp */
3902        gen_pop_update(s, ot);
3903        gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
3904        break;
3905    case 0x60: /* pusha */
3906        if (CODE64(s))
3907            goto illegal_op;
3908        gen_pusha(s);
3909        break;
3910    case 0x61: /* popa */
3911        if (CODE64(s))
3912            goto illegal_op;
3913        gen_popa(s);
3914        break;
3915    case 0x68: /* push Iv */
3916    case 0x6a:
3917        ot = mo_pushpop(s, dflag);
3918        if (b == 0x68)
3919            val = insn_get(env, s, ot);
3920        else
3921            val = (int8_t)insn_get(env, s, MO_8);
3922        tcg_gen_movi_tl(s->T0, val);
3923        gen_push_v(s, s->T0);
3924        break;
3925    case 0x8f: /* pop Ev */
3926        modrm = x86_ldub_code(env, s);
3927        mod = (modrm >> 6) & 3;
3928        ot = gen_pop_T0(s);
3929        if (mod == 3) {
3930            /* NOTE: order is important for pop %sp */
3931            gen_pop_update(s, ot);
3932            rm = (modrm & 7) | REX_B(s);
3933            gen_op_mov_reg_v(s, ot, rm, s->T0);
3934        } else {
3935            /* NOTE: order is important too for MMU exceptions */
3936            s->popl_esp_hack = 1 << ot;
3937            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
3938            s->popl_esp_hack = 0;
3939            gen_pop_update(s, ot);
3940        }
3941        break;
3942    case 0xc8: /* enter */
3943        {
3944            int level;
3945            val = x86_lduw_code(env, s);
3946            level = x86_ldub_code(env, s);
3947            gen_enter(s, val, level);
3948        }
3949        break;
3950    case 0xc9: /* leave */
3951        gen_leave(s);
3952        break;
3953    case 0x06: /* push es */
3954    case 0x0e: /* push cs */
3955    case 0x16: /* push ss */
3956    case 0x1e: /* push ds */
3957        if (CODE64(s))
3958            goto illegal_op;
3959        gen_op_movl_T0_seg(s, b >> 3);
3960        gen_push_v(s, s->T0);
3961        break;
3962    case 0x1a0: /* push fs */
3963    case 0x1a8: /* push gs */
3964        gen_op_movl_T0_seg(s, (b >> 3) & 7);
3965        gen_push_v(s, s->T0);
3966        break;
3967    case 0x07: /* pop es */
3968    case 0x17: /* pop ss */
3969    case 0x1f: /* pop ds */
3970        if (CODE64(s))
3971            goto illegal_op;
3972        reg = b >> 3;
3973        ot = gen_pop_T0(s);
3974        gen_movl_seg_T0(s, reg);
3975        gen_pop_update(s, ot);
3976        break;
3977    case 0x1a1: /* pop fs */
3978    case 0x1a9: /* pop gs */
3979        ot = gen_pop_T0(s);
3980        gen_movl_seg_T0(s, (b >> 3) & 7);
3981        gen_pop_update(s, ot);
3982        break;
3983
3984        /**************************/
3985        /* mov */
3986    case 0x88:
3987    case 0x89: /* mov Gv, Ev */
3988        ot = mo_b_d(b, dflag);
3989        modrm = x86_ldub_code(env, s);
3990        reg = ((modrm >> 3) & 7) | REX_R(s);
3991
3992        /* generate a generic store */
3993        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
3994        break;
3995    case 0xc6:
3996    case 0xc7: /* mov Ev, Iv */
3997        ot = mo_b_d(b, dflag);
3998        modrm = x86_ldub_code(env, s);
3999        mod = (modrm >> 6) & 3;
4000        if (mod != 3) {
4001            s->rip_offset = insn_const_size(ot);
4002            gen_lea_modrm(env, s, modrm);
4003        }
4004        val = insn_get(env, s, ot);
4005        tcg_gen_movi_tl(s->T0, val);
4006        if (mod != 3) {
4007            gen_op_st_v(s, ot, s->T0, s->A0);
4008        } else {
4009            gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
4010        }
4011        break;
4012    case 0x8a:
4013    case 0x8b: /* mov Ev, Gv */
4014        ot = mo_b_d(b, dflag);
4015        modrm = x86_ldub_code(env, s);
4016        reg = ((modrm >> 3) & 7) | REX_R(s);
4017
4018        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4019        gen_op_mov_reg_v(s, ot, reg, s->T0);
4020        break;
4021    case 0x8e: /* mov seg, Gv */
4022        modrm = x86_ldub_code(env, s);
4023        reg = (modrm >> 3) & 7;
4024        if (reg >= 6 || reg == R_CS)
4025            goto illegal_op;
4026        gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
4027        gen_movl_seg_T0(s, reg);
4028        break;
4029    case 0x8c: /* mov Gv, seg */
4030        modrm = x86_ldub_code(env, s);
4031        reg = (modrm >> 3) & 7;
4032        mod = (modrm >> 6) & 3;
4033        if (reg >= 6)
4034            goto illegal_op;
4035        gen_op_movl_T0_seg(s, reg);
4036        ot = mod == 3 ? dflag : MO_16;
4037        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4038        break;
4039
4040    case 0x1b6: /* movzbS Gv, Eb */
4041    case 0x1b7: /* movzwS Gv, Eb */
4042    case 0x1be: /* movsbS Gv, Eb */
4043    case 0x1bf: /* movswS Gv, Eb */
4044        {
4045            MemOp d_ot;
4046            MemOp s_ot;
4047
4048            /* d_ot is the size of destination */
4049            d_ot = dflag;
4050            /* ot is the size of source */
4051            ot = (b & 1) + MO_8;
4052            /* s_ot is the sign+size of source */
4053            s_ot = b & 8 ? MO_SIGN | ot : ot;
4054
4055            modrm = x86_ldub_code(env, s);
4056            reg = ((modrm >> 3) & 7) | REX_R(s);
4057            mod = (modrm >> 6) & 3;
4058            rm = (modrm & 7) | REX_B(s);
4059
4060            if (mod == 3) {
4061                if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
4062                    tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
4063                } else {
4064                    gen_op_mov_v_reg(s, ot, s->T0, rm);
4065                    switch (s_ot) {
4066                    case MO_UB:
4067                        tcg_gen_ext8u_tl(s->T0, s->T0);
4068                        break;
4069                    case MO_SB:
4070                        tcg_gen_ext8s_tl(s->T0, s->T0);
4071                        break;
4072                    case MO_UW:
4073                        tcg_gen_ext16u_tl(s->T0, s->T0);
4074                        break;
4075                    default:
4076                    case MO_SW:
4077                        tcg_gen_ext16s_tl(s->T0, s->T0);
4078                        break;
4079                    }
4080                }
4081                gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4082            } else {
4083                gen_lea_modrm(env, s, modrm);
4084                gen_op_ld_v(s, s_ot, s->T0, s->A0);
4085                gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4086            }
4087        }
4088        break;
4089
4090    case 0x8d: /* lea */
4091        modrm = x86_ldub_code(env, s);
4092        mod = (modrm >> 6) & 3;
4093        if (mod == 3)
4094            goto illegal_op;
4095        reg = ((modrm >> 3) & 7) | REX_R(s);
4096        {
4097            AddressParts a = gen_lea_modrm_0(env, s, modrm);
4098            TCGv ea = gen_lea_modrm_1(s, a, false);
4099            gen_lea_v_seg(s, s->aflag, ea, -1, -1);
4100            gen_op_mov_reg_v(s, dflag, reg, s->A0);
4101        }
4102        break;
4103
4104    case 0xa0: /* mov EAX, Ov */
4105    case 0xa1:
4106    case 0xa2: /* mov Ov, EAX */
4107    case 0xa3:
4108        {
4109            target_ulong offset_addr;
4110
4111            ot = mo_b_d(b, dflag);
4112            offset_addr = insn_get_addr(env, s, s->aflag);
4113            tcg_gen_movi_tl(s->A0, offset_addr);
4114            gen_add_A0_ds_seg(s);
4115            if ((b & 2) == 0) {
4116                gen_op_ld_v(s, ot, s->T0, s->A0);
4117                gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
4118            } else {
4119                gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
4120                gen_op_st_v(s, ot, s->T0, s->A0);
4121            }
4122        }
4123        break;
4124    case 0xd7: /* xlat */
4125        tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
4126        tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
4127        tcg_gen_add_tl(s->A0, s->A0, s->T0);
4128        gen_extu(s->aflag, s->A0);
4129        gen_add_A0_ds_seg(s);
4130        gen_op_ld_v(s, MO_8, s->T0, s->A0);
4131        gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
4132        break;
4133    case 0xb0 ... 0xb7: /* mov R, Ib */
4134        val = insn_get(env, s, MO_8);
4135        tcg_gen_movi_tl(s->T0, val);
4136        gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
4137        break;
4138    case 0xb8 ... 0xbf: /* mov R, Iv */
4139#ifdef TARGET_X86_64
4140        if (dflag == MO_64) {
4141            uint64_t tmp;
4142            /* 64 bit case */
4143            tmp = x86_ldq_code(env, s);
4144            reg = (b & 7) | REX_B(s);
4145            tcg_gen_movi_tl(s->T0, tmp);
4146            gen_op_mov_reg_v(s, MO_64, reg, s->T0);
4147        } else
4148#endif
4149        {
4150            ot = dflag;
4151            val = insn_get(env, s, ot);
4152            reg = (b & 7) | REX_B(s);
4153            tcg_gen_movi_tl(s->T0, val);
4154            gen_op_mov_reg_v(s, ot, reg, s->T0);
4155        }
4156        break;
4157
4158    case 0x91 ... 0x97: /* xchg R, EAX */
4159    do_xchg_reg_eax:
4160        ot = dflag;
4161        reg = (b & 7) | REX_B(s);
4162        rm = R_EAX;
4163        goto do_xchg_reg;
4164    case 0x86:
4165    case 0x87: /* xchg Ev, Gv */
4166        ot = mo_b_d(b, dflag);
4167        modrm = x86_ldub_code(env, s);
4168        reg = ((modrm >> 3) & 7) | REX_R(s);
4169        mod = (modrm >> 6) & 3;
4170        if (mod == 3) {
4171            rm = (modrm & 7) | REX_B(s);
4172        do_xchg_reg:
4173            gen_op_mov_v_reg(s, ot, s->T0, reg);
4174            gen_op_mov_v_reg(s, ot, s->T1, rm);
4175            gen_op_mov_reg_v(s, ot, rm, s->T0);
4176            gen_op_mov_reg_v(s, ot, reg, s->T1);
4177        } else {
4178            gen_lea_modrm(env, s, modrm);
4179            gen_op_mov_v_reg(s, ot, s->T0, reg);
4180            /* for xchg, lock is implicit */
4181            tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
4182                                   s->mem_index, ot | MO_LE);
4183            gen_op_mov_reg_v(s, ot, reg, s->T1);
4184        }
4185        break;
4186    case 0xc4: /* les Gv */
4187        /* In CODE64 this is VEX3; see above.  */
4188        op = R_ES;
4189        goto do_lxx;
4190    case 0xc5: /* lds Gv */
4191        /* In CODE64 this is VEX2; see above.  */
4192        op = R_DS;
4193        goto do_lxx;
4194    case 0x1b2: /* lss Gv */
4195        op = R_SS;
4196        goto do_lxx;
4197    case 0x1b4: /* lfs Gv */
4198        op = R_FS;
4199        goto do_lxx;
4200    case 0x1b5: /* lgs Gv */
4201        op = R_GS;
4202    do_lxx:
4203        ot = dflag != MO_16 ? MO_32 : MO_16;
4204        modrm = x86_ldub_code(env, s);
4205        reg = ((modrm >> 3) & 7) | REX_R(s);
4206        mod = (modrm >> 6) & 3;
4207        if (mod == 3)
4208            goto illegal_op;
4209        gen_lea_modrm(env, s, modrm);
4210        gen_op_ld_v(s, ot, s->T1, s->A0);
4211        gen_add_A0_im(s, 1 << ot);
4212        /* load the segment first to handle exceptions properly */
4213        gen_op_ld_v(s, MO_16, s->T0, s->A0);
4214        gen_movl_seg_T0(s, op);
4215        /* then put the data */
4216        gen_op_mov_reg_v(s, ot, reg, s->T1);
4217        break;
4218
4219        /************************/
4220        /* shifts */
4221    case 0xc0:
4222    case 0xc1:
4223        /* shift Ev,Ib */
4224        shift = 2;
4225    grp2:
4226        {
4227            ot = mo_b_d(b, dflag);
4228            modrm = x86_ldub_code(env, s);
4229            mod = (modrm >> 6) & 3;
4230            op = (modrm >> 3) & 7;
4231
4232            if (mod != 3) {
4233                if (shift == 2) {
4234                    s->rip_offset = 1;
4235                }
4236                gen_lea_modrm(env, s, modrm);
4237                opreg = OR_TMP0;
4238            } else {
4239                opreg = (modrm & 7) | REX_B(s);
4240            }
4241
4242            /* simpler op */
4243            if (shift == 0) {
4244                gen_shift(s, op, ot, opreg, OR_ECX);
4245            } else {
4246                if (shift == 2) {
4247                    shift = x86_ldub_code(env, s);
4248                }
4249                gen_shifti(s, op, ot, opreg, shift);
4250            }
4251        }
4252        break;
4253    case 0xd0:
4254    case 0xd1:
4255        /* shift Ev,1 */
4256        shift = 1;
4257        goto grp2;
4258    case 0xd2:
4259    case 0xd3:
4260        /* shift Ev,cl */
4261        shift = 0;
4262        goto grp2;
4263
4264    case 0x1a4: /* shld imm */
4265        op = 0;
4266        shift = 1;
4267        goto do_shiftd;
4268    case 0x1a5: /* shld cl */
4269        op = 0;
4270        shift = 0;
4271        goto do_shiftd;
4272    case 0x1ac: /* shrd imm */
4273        op = 1;
4274        shift = 1;
4275        goto do_shiftd;
4276    case 0x1ad: /* shrd cl */
4277        op = 1;
4278        shift = 0;
4279    do_shiftd:
4280        ot = dflag;
4281        modrm = x86_ldub_code(env, s);
4282        mod = (modrm >> 6) & 3;
4283        rm = (modrm & 7) | REX_B(s);
4284        reg = ((modrm >> 3) & 7) | REX_R(s);
4285        if (mod != 3) {
4286            gen_lea_modrm(env, s, modrm);
4287            opreg = OR_TMP0;
4288        } else {
4289            opreg = rm;
4290        }
4291        gen_op_mov_v_reg(s, ot, s->T1, reg);
4292
4293        if (shift) {
4294            TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
4295            gen_shiftd_rm_T1(s, ot, opreg, op, imm);
4296            tcg_temp_free(imm);
4297        } else {
4298            gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
4299        }
4300        break;
4301
4302        /************************/
4303        /* floats */
4304    case 0xd8 ... 0xdf:
4305        {
4306            bool update_fip = true;
4307
4308            if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4309                /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4310                /* XXX: what to do if illegal op ? */
4311                gen_exception(s, EXCP07_PREX);
4312                break;
4313            }
4314            modrm = x86_ldub_code(env, s);
4315            mod = (modrm >> 6) & 3;
4316            rm = modrm & 7;
4317            op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4318            if (mod != 3) {
4319                /* memory op */
4320                AddressParts a = gen_lea_modrm_0(env, s, modrm);
4321                TCGv ea = gen_lea_modrm_1(s, a, false);
4322                TCGv last_addr = tcg_temp_new();
4323                bool update_fdp = true;
4324
4325                tcg_gen_mov_tl(last_addr, ea);
4326                gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
4327
4328                switch (op) {
4329                case 0x00 ... 0x07: /* fxxxs */
4330                case 0x10 ... 0x17: /* fixxxl */
4331                case 0x20 ... 0x27: /* fxxxl */
4332                case 0x30 ... 0x37: /* fixxx */
4333                    {
4334                        int op1;
4335                        op1 = op & 7;
4336
4337                        switch (op >> 4) {
4338                        case 0:
4339                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4340                                                s->mem_index, MO_LEUL);
4341                            gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
4342                            break;
4343                        case 1:
4344                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4345                                                s->mem_index, MO_LEUL);
4346                            gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
4347                            break;
4348                        case 2:
4349                            tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4350                                                s->mem_index, MO_LEUQ);
4351                            gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
4352                            break;
4353                        case 3:
4354                        default:
4355                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4356                                                s->mem_index, MO_LESW);
4357                            gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
4358                            break;
4359                        }
4360
4361                        gen_helper_fp_arith_ST0_FT0(op1);
4362                        if (op1 == 3) {
4363                            /* fcomp needs pop */
4364                            gen_helper_fpop(cpu_env);
4365                        }
4366                    }
4367                    break;
4368                case 0x08: /* flds */
4369                case 0x0a: /* fsts */
4370                case 0x0b: /* fstps */
4371                case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4372                case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4373                case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4374                    switch (op & 7) {
4375                    case 0:
4376                        switch (op >> 4) {
4377                        case 0:
4378                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4379                                                s->mem_index, MO_LEUL);
4380                            gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
4381                            break;
4382                        case 1:
4383                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4384                                                s->mem_index, MO_LEUL);
4385                            gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
4386                            break;
4387                        case 2:
4388                            tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4389                                                s->mem_index, MO_LEUQ);
4390                            gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
4391                            break;
4392                        case 3:
4393                        default:
4394                            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4395                                                s->mem_index, MO_LESW);
4396                            gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
4397                            break;
4398                        }
4399                        break;
4400                    case 1:
4401                        /* XXX: the corresponding CPUID bit must be tested ! */
4402                        switch (op >> 4) {
4403                        case 1:
4404                            gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
4405                            tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4406                                                s->mem_index, MO_LEUL);
4407                            break;
4408                        case 2:
4409                            gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
4410                            tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4411                                                s->mem_index, MO_LEUQ);
4412                            break;
4413                        case 3:
4414                        default:
4415                            gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
4416                            tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4417                                                s->mem_index, MO_LEUW);
4418                            break;
4419                        }
4420                        gen_helper_fpop(cpu_env);
4421                        break;
4422                    default:
4423                        switch (op >> 4) {
4424                        case 0:
4425                            gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
4426                            tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4427                                                s->mem_index, MO_LEUL);
4428                            break;
4429                        case 1:
4430                            gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
4431                            tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4432                                                s->mem_index, MO_LEUL);
4433                            break;
4434                        case 2:
4435                            gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
4436                            tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4437                                                s->mem_index, MO_LEUQ);
4438                            break;
4439                        case 3:
4440                        default:
4441                            gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
4442                            tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4443                                                s->mem_index, MO_LEUW);
4444                            break;
4445                        }
4446                        if ((op & 7) == 3) {
4447                            gen_helper_fpop(cpu_env);
4448                        }
4449                        break;
4450                    }
4451                    break;
4452                case 0x0c: /* fldenv mem */
4453                    gen_helper_fldenv(cpu_env, s->A0,
4454                                      tcg_const_i32(dflag - 1));
4455                    update_fip = update_fdp = false;
4456                    break;
4457                case 0x0d: /* fldcw mem */
4458                    tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4459                                        s->mem_index, MO_LEUW);
4460                    gen_helper_fldcw(cpu_env, s->tmp2_i32);
4461                    update_fip = update_fdp = false;
4462                    break;
4463                case 0x0e: /* fnstenv mem */
4464                    gen_helper_fstenv(cpu_env, s->A0,
4465                                      tcg_const_i32(dflag - 1));
4466                    update_fip = update_fdp = false;
4467                    break;
4468                case 0x0f: /* fnstcw mem */
4469                    gen_helper_fnstcw(s->tmp2_i32, cpu_env);
4470                    tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4471                                        s->mem_index, MO_LEUW);
4472                    update_fip = update_fdp = false;
4473                    break;
4474                case 0x1d: /* fldt mem */
4475                    gen_helper_fldt_ST0(cpu_env, s->A0);
4476                    break;
4477                case 0x1f: /* fstpt mem */
4478                    gen_helper_fstt_ST0(cpu_env, s->A0);
4479                    gen_helper_fpop(cpu_env);
4480                    break;
4481                case 0x2c: /* frstor mem */
4482                    gen_helper_frstor(cpu_env, s->A0,
4483                                      tcg_const_i32(dflag - 1));
4484                    update_fip = update_fdp = false;
4485                    break;
4486                case 0x2e: /* fnsave mem */
4487                    gen_helper_fsave(cpu_env, s->A0,
4488                                     tcg_const_i32(dflag - 1));
4489                    update_fip = update_fdp = false;
4490                    break;
4491                case 0x2f: /* fnstsw mem */
4492                    gen_helper_fnstsw(s->tmp2_i32, cpu_env);
4493                    tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4494                                        s->mem_index, MO_LEUW);
4495                    update_fip = update_fdp = false;
4496                    break;
4497                case 0x3c: /* fbld */
4498                    gen_helper_fbld_ST0(cpu_env, s->A0);
4499                    break;
4500                case 0x3e: /* fbstp */
4501                    gen_helper_fbst_ST0(cpu_env, s->A0);
4502                    gen_helper_fpop(cpu_env);
4503                    break;
4504                case 0x3d: /* fildll */
4505                    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4506                                        s->mem_index, MO_LEUQ);
4507                    gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
4508                    break;
4509                case 0x3f: /* fistpll */
4510                    gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
4511                    tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4512                                        s->mem_index, MO_LEUQ);
4513                    gen_helper_fpop(cpu_env);
4514                    break;
4515                default:
4516                    goto unknown_op;
4517                }
4518
4519                if (update_fdp) {
4520                    int last_seg = s->override >= 0 ? s->override : a.def_seg;
4521
4522                    tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4523                                   offsetof(CPUX86State,
4524                                            segs[last_seg].selector));
4525                    tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
4526                                     offsetof(CPUX86State, fpds));
4527                    tcg_gen_st_tl(last_addr, cpu_env,
4528                                  offsetof(CPUX86State, fpdp));
4529                }
4530                tcg_temp_free(last_addr);
4531            } else {
4532                /* register float ops */
4533                opreg = rm;
4534
4535                switch (op) {
4536                case 0x08: /* fld sti */
4537                    gen_helper_fpush(cpu_env);
4538                    gen_helper_fmov_ST0_STN(cpu_env,
4539                                            tcg_const_i32((opreg + 1) & 7));
4540                    break;
4541                case 0x09: /* fxchg sti */
4542                case 0x29: /* fxchg4 sti, undocumented op */
4543                case 0x39: /* fxchg7 sti, undocumented op */
4544                    gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
4545                    break;
4546                case 0x0a: /* grp d9/2 */
4547                    switch (rm) {
4548                    case 0: /* fnop */
4549                        /* check exceptions (FreeBSD FPU probe) */
4550                        gen_helper_fwait(cpu_env);
4551                        update_fip = false;
4552                        break;
4553                    default:
4554                        goto unknown_op;
4555                    }
4556                    break;
4557                case 0x0c: /* grp d9/4 */
4558                    switch (rm) {
4559                    case 0: /* fchs */
4560                        gen_helper_fchs_ST0(cpu_env);
4561                        break;
4562                    case 1: /* fabs */
4563                        gen_helper_fabs_ST0(cpu_env);
4564                        break;
4565                    case 4: /* ftst */
4566                        gen_helper_fldz_FT0(cpu_env);
4567                        gen_helper_fcom_ST0_FT0(cpu_env);
4568                        break;
4569                    case 5: /* fxam */
4570                        gen_helper_fxam_ST0(cpu_env);
4571                        break;
4572                    default:
4573                        goto unknown_op;
4574                    }
4575                    break;
4576                case 0x0d: /* grp d9/5 */
4577                    {
4578                        switch (rm) {
4579                        case 0:
4580                            gen_helper_fpush(cpu_env);
4581                            gen_helper_fld1_ST0(cpu_env);
4582                            break;
4583                        case 1:
4584                            gen_helper_fpush(cpu_env);
4585                            gen_helper_fldl2t_ST0(cpu_env);
4586                            break;
4587                        case 2:
4588                            gen_helper_fpush(cpu_env);
4589                            gen_helper_fldl2e_ST0(cpu_env);
4590                            break;
4591                        case 3:
4592                            gen_helper_fpush(cpu_env);
4593                            gen_helper_fldpi_ST0(cpu_env);
4594                            break;
4595                        case 4:
4596                            gen_helper_fpush(cpu_env);
4597                            gen_helper_fldlg2_ST0(cpu_env);
4598                            break;
4599                        case 5:
4600                            gen_helper_fpush(cpu_env);
4601                            gen_helper_fldln2_ST0(cpu_env);
4602                            break;
4603                        case 6:
4604                            gen_helper_fpush(cpu_env);
4605                            gen_helper_fldz_ST0(cpu_env);
4606                            break;
4607                        default:
4608                            goto unknown_op;
4609                        }
4610                    }
4611                    break;
4612                case 0x0e: /* grp d9/6 */
4613                    switch (rm) {
4614                    case 0: /* f2xm1 */
4615                        gen_helper_f2xm1(cpu_env);
4616                        break;
4617                    case 1: /* fyl2x */
4618                        gen_helper_fyl2x(cpu_env);
4619                        break;
4620                    case 2: /* fptan */
4621                        gen_helper_fptan(cpu_env);
4622                        break;
4623                    case 3: /* fpatan */
4624                        gen_helper_fpatan(cpu_env);
4625                        break;
4626                    case 4: /* fxtract */
4627                        gen_helper_fxtract(cpu_env);
4628                        break;
4629                    case 5: /* fprem1 */
4630                        gen_helper_fprem1(cpu_env);
4631                        break;
4632                    case 6: /* fdecstp */
4633                        gen_helper_fdecstp(cpu_env);
4634                        break;
4635                    default:
4636                    case 7: /* fincstp */
4637                        gen_helper_fincstp(cpu_env);
4638                        break;
4639                    }
4640                    break;
4641                case 0x0f: /* grp d9/7 */
4642                    switch (rm) {
4643                    case 0: /* fprem */
4644                        gen_helper_fprem(cpu_env);
4645                        break;
4646                    case 1: /* fyl2xp1 */
4647                        gen_helper_fyl2xp1(cpu_env);
4648                        break;
4649                    case 2: /* fsqrt */
4650                        gen_helper_fsqrt(cpu_env);
4651                        break;
4652                    case 3: /* fsincos */
4653                        gen_helper_fsincos(cpu_env);
4654                        break;
4655                    case 5: /* fscale */
4656                        gen_helper_fscale(cpu_env);
4657                        break;
4658                    case 4: /* frndint */
4659                        gen_helper_frndint(cpu_env);
4660                        break;
4661                    case 6: /* fsin */
4662                        gen_helper_fsin(cpu_env);
4663                        break;
4664                    default:
4665                    case 7: /* fcos */
4666                        gen_helper_fcos(cpu_env);
4667                        break;
4668                    }
4669                    break;
4670                case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4671                case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4672                case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4673                    {
4674                        int op1;
4675
4676                        op1 = op & 7;
4677                        if (op >= 0x20) {
4678                            gen_helper_fp_arith_STN_ST0(op1, opreg);
4679                            if (op >= 0x30) {
4680                                gen_helper_fpop(cpu_env);
4681                            }
4682                        } else {
4683                            gen_helper_fmov_FT0_STN(cpu_env,
4684                                                    tcg_const_i32(opreg));
4685                            gen_helper_fp_arith_ST0_FT0(op1);
4686                        }
4687                    }
4688                    break;
4689                case 0x02: /* fcom */
4690                case 0x22: /* fcom2, undocumented op */
4691                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4692                    gen_helper_fcom_ST0_FT0(cpu_env);
4693                    break;
4694                case 0x03: /* fcomp */
4695                case 0x23: /* fcomp3, undocumented op */
4696                case 0x32: /* fcomp5, undocumented op */
4697                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4698                    gen_helper_fcom_ST0_FT0(cpu_env);
4699                    gen_helper_fpop(cpu_env);
4700                    break;
4701                case 0x15: /* da/5 */
4702                    switch (rm) {
4703                    case 1: /* fucompp */
4704                        gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
4705                        gen_helper_fucom_ST0_FT0(cpu_env);
4706                        gen_helper_fpop(cpu_env);
4707                        gen_helper_fpop(cpu_env);
4708                        break;
4709                    default:
4710                        goto unknown_op;
4711                    }
4712                    break;
4713                case 0x1c:
4714                    switch (rm) {
4715                    case 0: /* feni (287 only, just do nop here) */
4716                        break;
4717                    case 1: /* fdisi (287 only, just do nop here) */
4718                        break;
4719                    case 2: /* fclex */
4720                        gen_helper_fclex(cpu_env);
4721                        update_fip = false;
4722                        break;
4723                    case 3: /* fninit */
4724                        gen_helper_fninit(cpu_env);
4725                        update_fip = false;
4726                        break;
4727                    case 4: /* fsetpm (287 only, just do nop here) */
4728                        break;
4729                    default:
4730                        goto unknown_op;
4731                    }
4732                    break;
4733                case 0x1d: /* fucomi */
4734                    if (!(s->cpuid_features & CPUID_CMOV)) {
4735                        goto illegal_op;
4736                    }
4737                    gen_update_cc_op(s);
4738                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4739                    gen_helper_fucomi_ST0_FT0(cpu_env);
4740                    set_cc_op(s, CC_OP_EFLAGS);
4741                    break;
4742                case 0x1e: /* fcomi */
4743                    if (!(s->cpuid_features & CPUID_CMOV)) {
4744                        goto illegal_op;
4745                    }
4746                    gen_update_cc_op(s);
4747                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4748                    gen_helper_fcomi_ST0_FT0(cpu_env);
4749                    set_cc_op(s, CC_OP_EFLAGS);
4750                    break;
4751                case 0x28: /* ffree sti */
4752                    gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
4753                    break;
4754                case 0x2a: /* fst sti */
4755                    gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
4756                    break;
4757                case 0x2b: /* fstp sti */
4758                case 0x0b: /* fstp1 sti, undocumented op */
4759                case 0x3a: /* fstp8 sti, undocumented op */
4760                case 0x3b: /* fstp9 sti, undocumented op */
4761                    gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
4762                    gen_helper_fpop(cpu_env);
4763                    break;
4764                case 0x2c: /* fucom st(i) */
4765                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4766                    gen_helper_fucom_ST0_FT0(cpu_env);
4767                    break;
4768                case 0x2d: /* fucomp st(i) */
4769                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4770                    gen_helper_fucom_ST0_FT0(cpu_env);
4771                    gen_helper_fpop(cpu_env);
4772                    break;
4773                case 0x33: /* de/3 */
4774                    switch (rm) {
4775                    case 1: /* fcompp */
4776                        gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
4777                        gen_helper_fcom_ST0_FT0(cpu_env);
4778                        gen_helper_fpop(cpu_env);
4779                        gen_helper_fpop(cpu_env);
4780                        break;
4781                    default:
4782                        goto unknown_op;
4783                    }
4784                    break;
4785                case 0x38: /* ffreep sti, undocumented op */
4786                    gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
4787                    gen_helper_fpop(cpu_env);
4788                    break;
4789                case 0x3c: /* df/4 */
4790                    switch (rm) {
4791                    case 0:
4792                        gen_helper_fnstsw(s->tmp2_i32, cpu_env);
4793                        tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4794                        gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4795                        break;
4796                    default:
4797                        goto unknown_op;
4798                    }
4799                    break;
4800                case 0x3d: /* fucomip */
4801                    if (!(s->cpuid_features & CPUID_CMOV)) {
4802                        goto illegal_op;
4803                    }
4804                    gen_update_cc_op(s);
4805                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4806                    gen_helper_fucomi_ST0_FT0(cpu_env);
4807                    gen_helper_fpop(cpu_env);
4808                    set_cc_op(s, CC_OP_EFLAGS);
4809                    break;
4810                case 0x3e: /* fcomip */
4811                    if (!(s->cpuid_features & CPUID_CMOV)) {
4812                        goto illegal_op;
4813                    }
4814                    gen_update_cc_op(s);
4815                    gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
4816                    gen_helper_fcomi_ST0_FT0(cpu_env);
4817                    gen_helper_fpop(cpu_env);
4818                    set_cc_op(s, CC_OP_EFLAGS);
4819                    break;
4820                case 0x10 ... 0x13: /* fcmovxx */
4821                case 0x18 ... 0x1b:
4822                    {
4823                        int op1;
4824                        TCGLabel *l1;
4825                        static const uint8_t fcmov_cc[8] = {
4826                            (JCC_B << 1),
4827                            (JCC_Z << 1),
4828                            (JCC_BE << 1),
4829                            (JCC_P << 1),
4830                        };
4831
4832                        if (!(s->cpuid_features & CPUID_CMOV)) {
4833                            goto illegal_op;
4834                        }
4835                        op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
4836                        l1 = gen_new_label();
4837                        gen_jcc1_noeob(s, op1, l1);
4838                        gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
4839                        gen_set_label(l1);
4840                    }
4841                    break;
4842                default:
4843                    goto unknown_op;
4844                }
4845            }
4846
4847            if (update_fip) {
4848                tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4849                               offsetof(CPUX86State, segs[R_CS].selector));
4850                tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
4851                                 offsetof(CPUX86State, fpcs));
4852                tcg_gen_st_tl(eip_cur_tl(s),
4853                              cpu_env, offsetof(CPUX86State, fpip));
4854            }
4855        }
4856        break;
4857        /************************/
4858        /* string ops */
4859
4860    case 0xa4: /* movsS */
4861    case 0xa5:
4862        ot = mo_b_d(b, dflag);
4863        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4864            gen_repz_movs(s, ot);
4865        } else {
4866            gen_movs(s, ot);
4867        }
4868        break;
4869
4870    case 0xaa: /* stosS */
4871    case 0xab:
4872        ot = mo_b_d(b, dflag);
4873        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4874            gen_repz_stos(s, ot);
4875        } else {
4876            gen_stos(s, ot);
4877        }
4878        break;
4879    case 0xac: /* lodsS */
4880    case 0xad:
4881        ot = mo_b_d(b, dflag);
4882        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4883            gen_repz_lods(s, ot);
4884        } else {
4885            gen_lods(s, ot);
4886        }
4887        break;
4888    case 0xae: /* scasS */
4889    case 0xaf:
4890        ot = mo_b_d(b, dflag);
4891        if (prefixes & PREFIX_REPNZ) {
4892            gen_repz_scas(s, ot, 1);
4893        } else if (prefixes & PREFIX_REPZ) {
4894            gen_repz_scas(s, ot, 0);
4895        } else {
4896            gen_scas(s, ot);
4897        }
4898        break;
4899
4900    case 0xa6: /* cmpsS */
4901    case 0xa7:
4902        ot = mo_b_d(b, dflag);
4903        if (prefixes & PREFIX_REPNZ) {
4904            gen_repz_cmps(s, ot, 1);
4905        } else if (prefixes & PREFIX_REPZ) {
4906            gen_repz_cmps(s, ot, 0);
4907        } else {
4908            gen_cmps(s, ot);
4909        }
4910        break;
4911    case 0x6c: /* insS */
4912    case 0x6d:
4913        ot = mo_b_d32(b, dflag);
4914        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4915        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4916        if (!gen_check_io(s, ot, s->tmp2_i32,
4917                          SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
4918            break;
4919        }
4920        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4921            gen_io_start();
4922            s->base.is_jmp = DISAS_TOO_MANY;
4923        }
4924        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4925            gen_repz_ins(s, ot);
4926        } else {
4927            gen_ins(s, ot);
4928        }
4929        break;
4930    case 0x6e: /* outsS */
4931    case 0x6f:
4932        ot = mo_b_d32(b, dflag);
4933        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4934        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4935        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
4936            break;
4937        }
4938        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4939            gen_io_start();
4940            s->base.is_jmp = DISAS_TOO_MANY;
4941        }
4942        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4943            gen_repz_outs(s, ot);
4944        } else {
4945            gen_outs(s, ot);
4946        }
4947        break;
4948
4949        /************************/
4950        /* port I/O */
4951
4952    case 0xe4:
4953    case 0xe5:
4954        ot = mo_b_d32(b, dflag);
4955        val = x86_ldub_code(env, s);
4956        tcg_gen_movi_i32(s->tmp2_i32, val);
4957        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
4958            break;
4959        }
4960        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4961            gen_io_start();
4962            s->base.is_jmp = DISAS_TOO_MANY;
4963        }
4964        gen_helper_in_func(ot, s->T1, s->tmp2_i32);
4965        gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
4966        gen_bpt_io(s, s->tmp2_i32, ot);
4967        break;
4968    case 0xe6:
4969    case 0xe7:
4970        ot = mo_b_d32(b, dflag);
4971        val = x86_ldub_code(env, s);
4972        tcg_gen_movi_i32(s->tmp2_i32, val);
4973        if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
4974            break;
4975        }
4976        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4977            gen_io_start();
4978            s->base.is_jmp = DISAS_TOO_MANY;
4979        }
4980        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
4981        tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
4982        gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
4983        gen_bpt_io(s, s->tmp2_i32, ot);
4984        break;
4985    case 0xec:
4986    case 0xed:
4987        ot = mo_b_d32(b, dflag);
4988        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4989        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4990        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
4991            break;
4992        }
4993        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4994            gen_io_start();
4995            s->base.is_jmp = DISAS_TOO_MANY;
4996        }
4997        gen_helper_in_func(ot, s->T1, s->tmp2_i32);
4998        gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
4999        gen_bpt_io(s, s->tmp2_i32, ot);
5000        break;
5001    case 0xee:
5002    case 0xef:
5003        ot = mo_b_d32(b, dflag);
5004        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5005        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5006        if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5007            break;
5008        }
5009        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5010            gen_io_start();
5011            s->base.is_jmp = DISAS_TOO_MANY;
5012        }
5013        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5014        tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5015        gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5016        gen_bpt_io(s, s->tmp2_i32, ot);
5017        break;
5018
5019        /************************/
5020        /* control */
5021    case 0xc2: /* ret im */
5022        val = x86_ldsw_code(env, s);
5023        ot = gen_pop_T0(s);
5024        gen_stack_update(s, val + (1 << ot));
5025        /* Note that gen_pop_T0 uses a zero-extending load.  */
5026        gen_op_jmp_v(s, s->T0);
5027        gen_bnd_jmp(s);
5028        s->base.is_jmp = DISAS_JUMP;
5029        break;
5030    case 0xc3: /* ret */
5031        ot = gen_pop_T0(s);
5032        gen_pop_update(s, ot);
5033        /* Note that gen_pop_T0 uses a zero-extending load.  */
5034        gen_op_jmp_v(s, s->T0);
5035        gen_bnd_jmp(s);
5036        s->base.is_jmp = DISAS_JUMP;
5037        break;
5038    case 0xca: /* lret im */
5039        val = x86_ldsw_code(env, s);
5040    do_lret:
5041        if (PE(s) && !VM86(s)) {
5042            gen_update_cc_op(s);
5043            gen_update_eip_cur(s);
5044            gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
5045                                      tcg_const_i32(val));
5046        } else {
5047            gen_stack_A0(s);
5048            /* pop offset */
5049            gen_op_ld_v(s, dflag, s->T0, s->A0);
5050            /* NOTE: keeping EIP updated is not a problem in case of
5051               exception */
5052            gen_op_jmp_v(s, s->T0);
5053            /* pop selector */
5054            gen_add_A0_im(s, 1 << dflag);
5055            gen_op_ld_v(s, dflag, s->T0, s->A0);
5056            gen_op_movl_seg_T0_vm(s, R_CS);
5057            /* add stack offset */
5058            gen_stack_update(s, val + (2 << dflag));
5059        }
5060        s->base.is_jmp = DISAS_EOB_ONLY;
5061        break;
5062    case 0xcb: /* lret */
5063        val = 0;
5064        goto do_lret;
5065    case 0xcf: /* iret */
5066        gen_svm_check_intercept(s, SVM_EXIT_IRET);
5067        if (!PE(s) || VM86(s)) {
5068            /* real mode or vm86 mode */
5069            if (!check_vm86_iopl(s)) {
5070                break;
5071            }
5072            gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
5073        } else {
5074            gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
5075                                      eip_next_i32(s));
5076        }
5077        set_cc_op(s, CC_OP_EFLAGS);
5078        s->base.is_jmp = DISAS_EOB_ONLY;
5079        break;
5080    case 0xe8: /* call im */
5081        {
5082            int diff = (dflag != MO_16
5083                        ? (int32_t)insn_get(env, s, MO_32)
5084                        : (int16_t)insn_get(env, s, MO_16));
5085            gen_push_v(s, eip_next_tl(s));
5086            gen_bnd_jmp(s);
5087            gen_jmp_rel(s, dflag, diff, 0);
5088        }
5089        break;
5090    case 0x9a: /* lcall im */
5091        {
5092            unsigned int selector, offset;
5093
5094            if (CODE64(s))
5095                goto illegal_op;
5096            ot = dflag;
5097            offset = insn_get(env, s, ot);
5098            selector = insn_get(env, s, MO_16);
5099
5100            tcg_gen_movi_tl(s->T0, selector);
5101            tcg_gen_movi_tl(s->T1, offset);
5102        }
5103        goto do_lcall;
5104    case 0xe9: /* jmp im */
5105        {
5106            int diff = (dflag != MO_16
5107                        ? (int32_t)insn_get(env, s, MO_32)
5108                        : (int16_t)insn_get(env, s, MO_16));
5109            gen_bnd_jmp(s);
5110            gen_jmp_rel(s, dflag, diff, 0);
5111        }
5112        break;
5113    case 0xea: /* ljmp im */
5114        {
5115            unsigned int selector, offset;
5116
5117            if (CODE64(s))
5118                goto illegal_op;
5119            ot = dflag;
5120            offset = insn_get(env, s, ot);
5121            selector = insn_get(env, s, MO_16);
5122
5123            tcg_gen_movi_tl(s->T0, selector);
5124            tcg_gen_movi_tl(s->T1, offset);
5125        }
5126        goto do_ljmp;
5127    case 0xeb: /* jmp Jb */
5128        {
5129            int diff = (int8_t)insn_get(env, s, MO_8);
5130            gen_jmp_rel(s, dflag, diff, 0);
5131        }
5132        break;
5133    case 0x70 ... 0x7f: /* jcc Jb */
5134        {
5135            int diff = (int8_t)insn_get(env, s, MO_8);
5136            gen_bnd_jmp(s);
5137            gen_jcc(s, b, diff);
5138        }
5139        break;
5140    case 0x180 ... 0x18f: /* jcc Jv */
5141        {
5142            int diff = (dflag != MO_16
5143                        ? (int32_t)insn_get(env, s, MO_32)
5144                        : (int16_t)insn_get(env, s, MO_16));
5145            gen_bnd_jmp(s);
5146            gen_jcc(s, b, diff);
5147        }
5148        break;
5149
5150    case 0x190 ... 0x19f: /* setcc Gv */
5151        modrm = x86_ldub_code(env, s);
5152        gen_setcc1(s, b, s->T0);
5153        gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
5154        break;
5155    case 0x140 ... 0x14f: /* cmov Gv, Ev */
5156        if (!(s->cpuid_features & CPUID_CMOV)) {
5157            goto illegal_op;
5158        }
5159        ot = dflag;
5160        modrm = x86_ldub_code(env, s);
5161        reg = ((modrm >> 3) & 7) | REX_R(s);
5162        gen_cmovcc1(env, s, ot, b, modrm, reg);
5163        break;
5164
5165        /************************/
5166        /* flags */
5167    case 0x9c: /* pushf */
5168        gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
5169        if (check_vm86_iopl(s)) {
5170            gen_update_cc_op(s);
5171            gen_helper_read_eflags(s->T0, cpu_env);
5172            gen_push_v(s, s->T0);
5173        }
5174        break;
5175    case 0x9d: /* popf */
5176        gen_svm_check_intercept(s, SVM_EXIT_POPF);
5177        if (check_vm86_iopl(s)) {
5178            ot = gen_pop_T0(s);
5179            if (CPL(s) == 0) {
5180                if (dflag != MO_16) {
5181                    gen_helper_write_eflags(cpu_env, s->T0,
5182                                            tcg_const_i32((TF_MASK | AC_MASK |
5183                                                           ID_MASK | NT_MASK |
5184                                                           IF_MASK |
5185                                                           IOPL_MASK)));
5186                } else {
5187                    gen_helper_write_eflags(cpu_env, s->T0,
5188                                            tcg_const_i32((TF_MASK | AC_MASK |
5189                                                           ID_MASK | NT_MASK |
5190                                                           IF_MASK | IOPL_MASK)
5191                                                          & 0xffff));
5192                }
5193            } else {
5194                if (CPL(s) <= IOPL(s)) {
5195                    if (dflag != MO_16) {
5196                        gen_helper_write_eflags(cpu_env, s->T0,
5197                                                tcg_const_i32((TF_MASK |
5198                                                               AC_MASK |
5199                                                               ID_MASK |
5200                                                               NT_MASK |
5201                                                               IF_MASK)));
5202                    } else {
5203                        gen_helper_write_eflags(cpu_env, s->T0,
5204                                                tcg_const_i32((TF_MASK |
5205                                                               AC_MASK |
5206                                                               ID_MASK |
5207                                                               NT_MASK |
5208                                                               IF_MASK)
5209                                                              & 0xffff));
5210                    }
5211                } else {
5212                    if (dflag != MO_16) {
5213                        gen_helper_write_eflags(cpu_env, s->T0,
5214                                           tcg_const_i32((TF_MASK | AC_MASK |
5215                                                          ID_MASK | NT_MASK)));
5216                    } else {
5217                        gen_helper_write_eflags(cpu_env, s->T0,
5218                                           tcg_const_i32((TF_MASK | AC_MASK |
5219                                                          ID_MASK | NT_MASK)
5220                                                         & 0xffff));
5221                    }
5222                }
5223            }
5224            gen_pop_update(s, ot);
5225            set_cc_op(s, CC_OP_EFLAGS);
5226            /* abort translation because TF/AC flag may change */
5227            s->base.is_jmp = DISAS_EOB_NEXT;
5228        }
5229        break;
5230    case 0x9e: /* sahf */
5231        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5232            goto illegal_op;
5233        tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
5234        gen_compute_eflags(s);
5235        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5236        tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
5237        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
5238        break;
5239    case 0x9f: /* lahf */
5240        if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5241            goto illegal_op;
5242        gen_compute_eflags(s);
5243        /* Note: gen_compute_eflags() only gives the condition codes */
5244        tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
5245        tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
5246        break;
5247    case 0xf5: /* cmc */
5248        gen_compute_eflags(s);
5249        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5250        break;
5251    case 0xf8: /* clc */
5252        gen_compute_eflags(s);
5253        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5254        break;
5255    case 0xf9: /* stc */
5256        gen_compute_eflags(s);
5257        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5258        break;
5259    case 0xfc: /* cld */
5260        tcg_gen_movi_i32(s->tmp2_i32, 1);
5261        tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
5262        break;
5263    case 0xfd: /* std */
5264        tcg_gen_movi_i32(s->tmp2_i32, -1);
5265        tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
5266        break;
5267
5268        /************************/
5269        /* bit operations */
5270    case 0x1ba: /* bt/bts/btr/btc Gv, im */
5271        ot = dflag;
5272        modrm = x86_ldub_code(env, s);
5273        op = (modrm >> 3) & 7;
5274        mod = (modrm >> 6) & 3;
5275        rm = (modrm & 7) | REX_B(s);
5276        if (mod != 3) {
5277            s->rip_offset = 1;
5278            gen_lea_modrm(env, s, modrm);
5279            if (!(s->prefix & PREFIX_LOCK)) {
5280                gen_op_ld_v(s, ot, s->T0, s->A0);
5281            }
5282        } else {
5283            gen_op_mov_v_reg(s, ot, s->T0, rm);
5284        }
5285        /* load shift */
5286        val = x86_ldub_code(env, s);
5287        tcg_gen_movi_tl(s->T1, val);
5288        if (op < 4)
5289            goto unknown_op;
5290        op -= 4;
5291        goto bt_op;
5292    case 0x1a3: /* bt Gv, Ev */
5293        op = 0;
5294        goto do_btx;
5295    case 0x1ab: /* bts */
5296        op = 1;
5297        goto do_btx;
5298    case 0x1b3: /* btr */
5299        op = 2;
5300        goto do_btx;
5301    case 0x1bb: /* btc */
5302        op = 3;
5303    do_btx:
5304        ot = dflag;
5305        modrm = x86_ldub_code(env, s);
5306        reg = ((modrm >> 3) & 7) | REX_R(s);
5307        mod = (modrm >> 6) & 3;
5308        rm = (modrm & 7) | REX_B(s);
5309        gen_op_mov_v_reg(s, MO_32, s->T1, reg);
5310        if (mod != 3) {
5311            AddressParts a = gen_lea_modrm_0(env, s, modrm);
5312            /* specific case: we need to add a displacement */
5313            gen_exts(ot, s->T1);
5314            tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
5315            tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
5316            tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0);
5317            gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
5318            if (!(s->prefix & PREFIX_LOCK)) {
5319                gen_op_ld_v(s, ot, s->T0, s->A0);
5320            }
5321        } else {
5322            gen_op_mov_v_reg(s, ot, s->T0, rm);
5323        }
5324    bt_op:
5325        tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
5326        tcg_gen_movi_tl(s->tmp0, 1);
5327        tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
5328        if (s->prefix & PREFIX_LOCK) {
5329            switch (op) {
5330            case 0: /* bt */
5331                /* Needs no atomic ops; we surpressed the normal
5332                   memory load for LOCK above so do it now.  */
5333                gen_op_ld_v(s, ot, s->T0, s->A0);
5334                break;
5335            case 1: /* bts */
5336                tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
5337                                           s->mem_index, ot | MO_LE);
5338                break;
5339            case 2: /* btr */
5340                tcg_gen_not_tl(s->tmp0, s->tmp0);
5341                tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
5342                                            s->mem_index, ot | MO_LE);
5343                break;
5344            default:
5345            case 3: /* btc */
5346                tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
5347                                            s->mem_index, ot | MO_LE);
5348                break;
5349            }
5350            tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5351        } else {
5352            tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5353            switch (op) {
5354            case 0: /* bt */
5355                /* Data already loaded; nothing to do.  */
5356                break;
5357            case 1: /* bts */
5358                tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
5359                break;
5360            case 2: /* btr */
5361                tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
5362                break;
5363            default:
5364            case 3: /* btc */
5365                tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
5366                break;
5367            }
5368            if (op != 0) {
5369                if (mod != 3) {
5370                    gen_op_st_v(s, ot, s->T0, s->A0);
5371                } else {
5372                    gen_op_mov_reg_v(s, ot, rm, s->T0);
5373                }
5374            }
5375        }
5376
5377        /* Delay all CC updates until after the store above.  Note that
5378           C is the result of the test, Z is unchanged, and the others
5379           are all undefined.  */
5380        switch (s->cc_op) {
5381        case CC_OP_MULB ... CC_OP_MULQ:
5382        case CC_OP_ADDB ... CC_OP_ADDQ:
5383        case CC_OP_ADCB ... CC_OP_ADCQ:
5384        case CC_OP_SUBB ... CC_OP_SUBQ:
5385        case CC_OP_SBBB ... CC_OP_SBBQ:
5386        case CC_OP_LOGICB ... CC_OP_LOGICQ:
5387        case CC_OP_INCB ... CC_OP_INCQ:
5388        case CC_OP_DECB ... CC_OP_DECQ:
5389        case CC_OP_SHLB ... CC_OP_SHLQ:
5390        case CC_OP_SARB ... CC_OP_SARQ:
5391        case CC_OP_BMILGB ... CC_OP_BMILGQ:
5392            /* Z was going to be computed from the non-zero status of CC_DST.
5393               We can get that same Z value (and the new C value) by leaving
5394               CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
5395               same width.  */
5396            tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
5397            set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
5398            break;
5399        default:
5400            /* Otherwise, generate EFLAGS and replace the C bit.  */
5401            gen_compute_eflags(s);
5402            tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
5403                               ctz32(CC_C), 1);
5404            break;
5405        }
5406        break;
5407    case 0x1bc: /* bsf / tzcnt */
5408    case 0x1bd: /* bsr / lzcnt */
5409        ot = dflag;
5410        modrm = x86_ldub_code(env, s);
5411        reg = ((modrm >> 3) & 7) | REX_R(s);
5412        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5413        gen_extu(ot, s->T0);
5414
5415        /* Note that lzcnt and tzcnt are in different extensions.  */
5416        if ((prefixes & PREFIX_REPZ)
5417            && (b & 1
5418                ? s->cpuid_ext3_features & CPUID_EXT3_ABM
5419                : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
5420            int size = 8 << ot;
5421            /* For lzcnt/tzcnt, C bit is defined related to the input. */
5422            tcg_gen_mov_tl(cpu_cc_src, s->T0);
5423            if (b & 1) {
5424                /* For lzcnt, reduce the target_ulong result by the
5425                   number of zeros that we expect to find at the top.  */
5426                tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
5427                tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
5428            } else {
5429                /* For tzcnt, a zero input must return the operand size.  */
5430                tcg_gen_ctzi_tl(s->T0, s->T0, size);
5431            }
5432            /* For lzcnt/tzcnt, Z bit is defined related to the result.  */
5433            gen_op_update1_cc(s);
5434            set_cc_op(s, CC_OP_BMILGB + ot);
5435        } else {
5436            /* For bsr/bsf, only the Z bit is defined and it is related
5437               to the input and not the result.  */
5438            tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5439            set_cc_op(s, CC_OP_LOGICB + ot);
5440
5441            /* ??? The manual says that the output is undefined when the
5442               input is zero, but real hardware leaves it unchanged, and
5443               real programs appear to depend on that.  Accomplish this
5444               by passing the output as the value to return upon zero.  */
5445            if (b & 1) {
5446                /* For bsr, return the bit index of the first 1 bit,
5447                   not the count of leading zeros.  */
5448                tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
5449                tcg_gen_clz_tl(s->T0, s->T0, s->T1);
5450                tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
5451            } else {
5452                tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
5453            }
5454        }
5455        gen_op_mov_reg_v(s, ot, reg, s->T0);
5456        break;
5457        /************************/
5458        /* bcd */
5459    case 0x27: /* daa */
5460        if (CODE64(s))
5461            goto illegal_op;
5462        gen_update_cc_op(s);
5463        gen_helper_daa(cpu_env);
5464        set_cc_op(s, CC_OP_EFLAGS);
5465        break;
5466    case 0x2f: /* das */
5467        if (CODE64(s))
5468            goto illegal_op;
5469        gen_update_cc_op(s);
5470        gen_helper_das(cpu_env);
5471        set_cc_op(s, CC_OP_EFLAGS);
5472        break;
5473    case 0x37: /* aaa */
5474        if (CODE64(s))
5475            goto illegal_op;
5476        gen_update_cc_op(s);
5477        gen_helper_aaa(cpu_env);
5478        set_cc_op(s, CC_OP_EFLAGS);
5479        break;
5480    case 0x3f: /* aas */
5481        if (CODE64(s))
5482            goto illegal_op;
5483        gen_update_cc_op(s);
5484        gen_helper_aas(cpu_env);
5485        set_cc_op(s, CC_OP_EFLAGS);
5486        break;
5487    case 0xd4: /* aam */
5488        if (CODE64(s))
5489            goto illegal_op;
5490        val = x86_ldub_code(env, s);
5491        if (val == 0) {
5492            gen_exception(s, EXCP00_DIVZ);
5493        } else {
5494            gen_helper_aam(cpu_env, tcg_const_i32(val));
5495            set_cc_op(s, CC_OP_LOGICB);
5496        }
5497        break;
5498    case 0xd5: /* aad */
5499        if (CODE64(s))
5500            goto illegal_op;
5501        val = x86_ldub_code(env, s);
5502        gen_helper_aad(cpu_env, tcg_const_i32(val));
5503        set_cc_op(s, CC_OP_LOGICB);
5504        break;
5505        /************************/
5506        /* misc */
5507    case 0x90: /* nop */
5508        /* XXX: correct lock test for all insn */
5509        if (prefixes & PREFIX_LOCK) {
5510            goto illegal_op;
5511        }
5512        /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
5513        if (REX_B(s)) {
5514            goto do_xchg_reg_eax;
5515        }
5516        if (prefixes & PREFIX_REPZ) {
5517            gen_update_cc_op(s);
5518            gen_update_eip_cur(s);
5519            gen_helper_pause(cpu_env, cur_insn_len_i32(s));
5520            s->base.is_jmp = DISAS_NORETURN;
5521        }
5522        break;
5523    case 0x9b: /* fwait */
5524        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
5525            (HF_MP_MASK | HF_TS_MASK)) {
5526            gen_exception(s, EXCP07_PREX);
5527        } else {
5528            gen_helper_fwait(cpu_env);
5529        }
5530        break;
5531    case 0xcc: /* int3 */
5532        gen_interrupt(s, EXCP03_INT3);
5533        break;
5534    case 0xcd: /* int N */
5535        val = x86_ldub_code(env, s);
5536        if (check_vm86_iopl(s)) {
5537            gen_interrupt(s, val);
5538        }
5539        break;
5540    case 0xce: /* into */
5541        if (CODE64(s))
5542            goto illegal_op;
5543        gen_update_cc_op(s);
5544        gen_update_eip_cur(s);
5545        gen_helper_into(cpu_env, cur_insn_len_i32(s));
5546        break;
5547#ifdef WANT_ICEBP
5548    case 0xf1: /* icebp (undocumented, exits to external debugger) */
5549        gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
5550        gen_debug(s);
5551        break;
5552#endif
5553    case 0xfa: /* cli */
5554        if (check_iopl(s)) {
5555            gen_reset_eflags(s, IF_MASK);
5556        }
5557        break;
5558    case 0xfb: /* sti */
5559        if (check_iopl(s)) {
5560            gen_set_eflags(s, IF_MASK);
5561            /* interruptions are enabled only the first insn after sti */
5562            gen_update_eip_next(s);
5563            gen_eob_inhibit_irq(s, true);
5564        }
5565        break;
5566    case 0x62: /* bound */
5567        if (CODE64(s))
5568            goto illegal_op;
5569        ot = dflag;
5570        modrm = x86_ldub_code(env, s);
5571        reg = (modrm >> 3) & 7;
5572        mod = (modrm >> 6) & 3;
5573        if (mod == 3)
5574            goto illegal_op;
5575        gen_op_mov_v_reg(s, ot, s->T0, reg);
5576        gen_lea_modrm(env, s, modrm);
5577        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5578        if (ot == MO_16) {
5579            gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32);
5580        } else {
5581            gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32);
5582        }
5583        break;
5584    case 0x1c8 ... 0x1cf: /* bswap reg */
5585        reg = (b & 7) | REX_B(s);
5586#ifdef TARGET_X86_64
5587        if (dflag == MO_64) {
5588            tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]);
5589            break;
5590        }
5591#endif
5592        tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ);
5593        break;
5594    case 0xd6: /* salc */
5595        if (CODE64(s))
5596            goto illegal_op;
5597        gen_compute_eflags_c(s, s->T0);
5598        tcg_gen_neg_tl(s->T0, s->T0);
5599        gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5600        break;
5601    case 0xe0: /* loopnz */
5602    case 0xe1: /* loopz */
5603    case 0xe2: /* loop */
5604    case 0xe3: /* jecxz */
5605        {
5606            TCGLabel *l1, *l2;
5607            int diff = (int8_t)insn_get(env, s, MO_8);
5608
5609            l1 = gen_new_label();
5610            l2 = gen_new_label();
5611            gen_update_cc_op(s);
5612            b &= 3;
5613            switch(b) {
5614            case 0: /* loopnz */
5615            case 1: /* loopz */
5616                gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5617                gen_op_jz_ecx(s, l2);
5618                gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
5619                break;
5620            case 2: /* loop */
5621                gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5622                gen_op_jnz_ecx(s, l1);
5623                break;
5624            default:
5625            case 3: /* jcxz */
5626                gen_op_jz_ecx(s, l1);
5627                break;
5628            }
5629
5630            gen_set_label(l2);
5631            gen_jmp_rel_csize(s, 0, 1);
5632
5633            gen_set_label(l1);
5634            gen_jmp_rel(s, dflag, diff, 0);
5635        }
5636        break;
5637    case 0x130: /* wrmsr */
5638    case 0x132: /* rdmsr */
5639        if (check_cpl0(s)) {
5640            gen_update_cc_op(s);
5641            gen_update_eip_cur(s);
5642            if (b & 2) {
5643                gen_helper_rdmsr(cpu_env);
5644            } else {
5645                gen_helper_wrmsr(cpu_env);
5646                s->base.is_jmp = DISAS_EOB_NEXT;
5647            }
5648        }
5649        break;
5650    case 0x131: /* rdtsc */
5651        gen_update_cc_op(s);
5652        gen_update_eip_cur(s);
5653        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5654            gen_io_start();
5655            s->base.is_jmp = DISAS_TOO_MANY;
5656        }
5657        gen_helper_rdtsc(cpu_env);
5658        break;
5659    case 0x133: /* rdpmc */
5660        gen_update_cc_op(s);
5661        gen_update_eip_cur(s);
5662        gen_helper_rdpmc(cpu_env);
5663        s->base.is_jmp = DISAS_NORETURN;
5664        break;
5665    case 0x134: /* sysenter */
5666        /* For Intel SYSENTER is valid on 64-bit */
5667        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
5668            goto illegal_op;
5669        if (!PE(s)) {
5670            gen_exception_gpf(s);
5671        } else {
5672            gen_helper_sysenter(cpu_env);
5673            s->base.is_jmp = DISAS_EOB_ONLY;
5674        }
5675        break;
5676    case 0x135: /* sysexit */
5677        /* For Intel SYSEXIT is valid on 64-bit */
5678        if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
5679            goto illegal_op;
5680        if (!PE(s)) {
5681            gen_exception_gpf(s);
5682        } else {
5683            gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
5684            s->base.is_jmp = DISAS_EOB_ONLY;
5685        }
5686        break;
5687#ifdef TARGET_X86_64
5688    case 0x105: /* syscall */
5689        /* XXX: is it usable in real mode ? */
5690        gen_update_cc_op(s);
5691        gen_update_eip_cur(s);
5692        gen_helper_syscall(cpu_env, cur_insn_len_i32(s));
5693        /* TF handling for the syscall insn is different. The TF bit is  checked
5694           after the syscall insn completes. This allows #DB to not be
5695           generated after one has entered CPL0 if TF is set in FMASK.  */
5696        gen_eob_worker(s, false, true);
5697        break;
5698    case 0x107: /* sysret */
5699        if (!PE(s)) {
5700            gen_exception_gpf(s);
5701        } else {
5702            gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
5703            /* condition codes are modified only in long mode */
5704            if (LMA(s)) {
5705                set_cc_op(s, CC_OP_EFLAGS);
5706            }
5707            /* TF handling for the sysret insn is different. The TF bit is
5708               checked after the sysret insn completes. This allows #DB to be
5709               generated "as if" the syscall insn in userspace has just
5710               completed.  */
5711            gen_eob_worker(s, false, true);
5712        }
5713        break;
5714#endif
5715    case 0x1a2: /* cpuid */
5716        gen_update_cc_op(s);
5717        gen_update_eip_cur(s);
5718        gen_helper_cpuid(cpu_env);
5719        break;
5720    case 0xf4: /* hlt */
5721        if (check_cpl0(s)) {
5722            gen_update_cc_op(s);
5723            gen_update_eip_cur(s);
5724            gen_helper_hlt(cpu_env, cur_insn_len_i32(s));
5725            s->base.is_jmp = DISAS_NORETURN;
5726        }
5727        break;
5728    case 0x100:
5729        modrm = x86_ldub_code(env, s);
5730        mod = (modrm >> 6) & 3;
5731        op = (modrm >> 3) & 7;
5732        switch(op) {
5733        case 0: /* sldt */
5734            if (!PE(s) || VM86(s))
5735                goto illegal_op;
5736            if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5737                break;
5738            }
5739            gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
5740            tcg_gen_ld32u_tl(s->T0, cpu_env,
5741                             offsetof(CPUX86State, ldt.selector));
5742            ot = mod == 3 ? dflag : MO_16;
5743            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5744            break;
5745        case 2: /* lldt */
5746            if (!PE(s) || VM86(s))
5747                goto illegal_op;
5748            if (check_cpl0(s)) {
5749                gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
5750                gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5751                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5752                gen_helper_lldt(cpu_env, s->tmp2_i32);
5753            }
5754            break;
5755        case 1: /* str */
5756            if (!PE(s) || VM86(s))
5757                goto illegal_op;
5758            if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5759                break;
5760            }
5761            gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
5762            tcg_gen_ld32u_tl(s->T0, cpu_env,
5763                             offsetof(CPUX86State, tr.selector));
5764            ot = mod == 3 ? dflag : MO_16;
5765            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5766            break;
5767        case 3: /* ltr */
5768            if (!PE(s) || VM86(s))
5769                goto illegal_op;
5770            if (check_cpl0(s)) {
5771                gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
5772                gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5773                tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5774                gen_helper_ltr(cpu_env, s->tmp2_i32);
5775            }
5776            break;
5777        case 4: /* verr */
5778        case 5: /* verw */
5779            if (!PE(s) || VM86(s))
5780                goto illegal_op;
5781            gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5782            gen_update_cc_op(s);
5783            if (op == 4) {
5784                gen_helper_verr(cpu_env, s->T0);
5785            } else {
5786                gen_helper_verw(cpu_env, s->T0);
5787            }
5788            set_cc_op(s, CC_OP_EFLAGS);
5789            break;
5790        default:
5791            goto unknown_op;
5792        }
5793        break;
5794
5795    case 0x101:
5796        modrm = x86_ldub_code(env, s);
5797        switch (modrm) {
5798        CASE_MODRM_MEM_OP(0): /* sgdt */
5799            if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5800                break;
5801            }
5802            gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
5803            gen_lea_modrm(env, s, modrm);
5804            tcg_gen_ld32u_tl(s->T0,
5805                             cpu_env, offsetof(CPUX86State, gdt.limit));
5806            gen_op_st_v(s, MO_16, s->T0, s->A0);
5807            gen_add_A0_im(s, 2);
5808            tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
5809            if (dflag == MO_16) {
5810                tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5811            }
5812            gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5813            break;
5814
5815        case 0xc8: /* monitor */
5816            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5817                goto illegal_op;
5818            }
5819            gen_update_cc_op(s);
5820            gen_update_eip_cur(s);
5821            tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
5822            gen_extu(s->aflag, s->A0);
5823            gen_add_A0_ds_seg(s);
5824            gen_helper_monitor(cpu_env, s->A0);
5825            break;
5826
5827        case 0xc9: /* mwait */
5828            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5829                goto illegal_op;
5830            }
5831            gen_update_cc_op(s);
5832            gen_update_eip_cur(s);
5833            gen_helper_mwait(cpu_env, cur_insn_len_i32(s));
5834            s->base.is_jmp = DISAS_NORETURN;
5835            break;
5836
5837        case 0xca: /* clac */
5838            if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5839                || CPL(s) != 0) {
5840                goto illegal_op;
5841            }
5842            gen_reset_eflags(s, AC_MASK);
5843            s->base.is_jmp = DISAS_EOB_NEXT;
5844            break;
5845
5846        case 0xcb: /* stac */
5847            if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5848                || CPL(s) != 0) {
5849                goto illegal_op;
5850            }
5851            gen_set_eflags(s, AC_MASK);
5852            s->base.is_jmp = DISAS_EOB_NEXT;
5853            break;
5854
5855        CASE_MODRM_MEM_OP(1): /* sidt */
5856            if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5857                break;
5858            }
5859            gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
5860            gen_lea_modrm(env, s, modrm);
5861            tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
5862            gen_op_st_v(s, MO_16, s->T0, s->A0);
5863            gen_add_A0_im(s, 2);
5864            tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
5865            if (dflag == MO_16) {
5866                tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5867            }
5868            gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5869            break;
5870
5871        case 0xd0: /* xgetbv */
5872            if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5873                || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5874                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
5875                goto illegal_op;
5876            }
5877            tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5878            gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32);
5879            tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
5880            break;
5881
5882        case 0xd1: /* xsetbv */
5883            if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5884                || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5885                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
5886                goto illegal_op;
5887            }
5888            if (!check_cpl0(s)) {
5889                break;
5890            }
5891            tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
5892                                  cpu_regs[R_EDX]);
5893            tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5894            gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
5895            /* End TB because translation flags may change.  */
5896            s->base.is_jmp = DISAS_EOB_NEXT;
5897            break;
5898
5899        case 0xd8: /* VMRUN */
5900            if (!SVME(s) || !PE(s)) {
5901                goto illegal_op;
5902            }
5903            if (!check_cpl0(s)) {
5904                break;
5905            }
5906            gen_update_cc_op(s);
5907            gen_update_eip_cur(s);
5908            gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
5909                             cur_insn_len_i32(s));
5910            tcg_gen_exit_tb(NULL, 0);
5911            s->base.is_jmp = DISAS_NORETURN;
5912            break;
5913
5914        case 0xd9: /* VMMCALL */
5915            if (!SVME(s)) {
5916                goto illegal_op;
5917            }
5918            gen_update_cc_op(s);
5919            gen_update_eip_cur(s);
5920            gen_helper_vmmcall(cpu_env);
5921            break;
5922
5923        case 0xda: /* VMLOAD */
5924            if (!SVME(s) || !PE(s)) {
5925                goto illegal_op;
5926            }
5927            if (!check_cpl0(s)) {
5928                break;
5929            }
5930            gen_update_cc_op(s);
5931            gen_update_eip_cur(s);
5932            gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
5933            break;
5934
5935        case 0xdb: /* VMSAVE */
5936            if (!SVME(s) || !PE(s)) {
5937                goto illegal_op;
5938            }
5939            if (!check_cpl0(s)) {
5940                break;
5941            }
5942            gen_update_cc_op(s);
5943            gen_update_eip_cur(s);
5944            gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
5945            break;
5946
5947        case 0xdc: /* STGI */
5948            if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5949                || !PE(s)) {
5950                goto illegal_op;
5951            }
5952            if (!check_cpl0(s)) {
5953                break;
5954            }
5955            gen_update_cc_op(s);
5956            gen_helper_stgi(cpu_env);
5957            s->base.is_jmp = DISAS_EOB_NEXT;
5958            break;
5959
5960        case 0xdd: /* CLGI */
5961            if (!SVME(s) || !PE(s)) {
5962                goto illegal_op;
5963            }
5964            if (!check_cpl0(s)) {
5965                break;
5966            }
5967            gen_update_cc_op(s);
5968            gen_update_eip_cur(s);
5969            gen_helper_clgi(cpu_env);
5970            break;
5971
5972        case 0xde: /* SKINIT */
5973            if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5974                || !PE(s)) {
5975                goto illegal_op;
5976            }
5977            gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
5978            /* If not intercepted, not implemented -- raise #UD. */
5979            goto illegal_op;
5980
5981        case 0xdf: /* INVLPGA */
5982            if (!SVME(s) || !PE(s)) {
5983                goto illegal_op;
5984            }
5985            if (!check_cpl0(s)) {
5986                break;
5987            }
5988            gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
5989            if (s->aflag == MO_64) {
5990                tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
5991            } else {
5992                tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
5993            }
5994            gen_helper_flush_page(cpu_env, s->A0);
5995            s->base.is_jmp = DISAS_EOB_NEXT;
5996            break;
5997
5998        CASE_MODRM_MEM_OP(2): /* lgdt */
5999            if (!check_cpl0(s)) {
6000                break;
6001            }
6002            gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
6003            gen_lea_modrm(env, s, modrm);
6004            gen_op_ld_v(s, MO_16, s->T1, s->A0);
6005            gen_add_A0_im(s, 2);
6006            gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6007            if (dflag == MO_16) {
6008                tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6009            }
6010            tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
6011            tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit));
6012            break;
6013
6014        CASE_MODRM_MEM_OP(3): /* lidt */
6015            if (!check_cpl0(s)) {
6016                break;
6017            }
6018            gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
6019            gen_lea_modrm(env, s, modrm);
6020            gen_op_ld_v(s, MO_16, s->T1, s->A0);
6021            gen_add_A0_im(s, 2);
6022            gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6023            if (dflag == MO_16) {
6024                tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6025            }
6026            tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
6027            tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit));
6028            break;
6029
6030        CASE_MODRM_OP(4): /* smsw */
6031            if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
6032                break;
6033            }
6034            gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
6035            tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
6036            /*
6037             * In 32-bit mode, the higher 16 bits of the destination
6038             * register are undefined.  In practice CR0[31:0] is stored
6039             * just like in 64-bit mode.
6040             */
6041            mod = (modrm >> 6) & 3;
6042            ot = (mod != 3 ? MO_16 : s->dflag);
6043            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
6044            break;
6045        case 0xee: /* rdpkru */
6046            if (prefixes & PREFIX_LOCK) {
6047                goto illegal_op;
6048            }
6049            tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6050            gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32);
6051            tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
6052            break;
6053        case 0xef: /* wrpkru */
6054            if (prefixes & PREFIX_LOCK) {
6055                goto illegal_op;
6056            }
6057            tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6058                                  cpu_regs[R_EDX]);
6059            tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6060            gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
6061            break;
6062
6063        CASE_MODRM_OP(6): /* lmsw */
6064            if (!check_cpl0(s)) {
6065                break;
6066            }
6067            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6068            gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6069            /*
6070             * Only the 4 lower bits of CR0 are modified.
6071             * PE cannot be set to zero if already set to one.
6072             */
6073            tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0]));
6074            tcg_gen_andi_tl(s->T0, s->T0, 0xf);
6075            tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
6076            tcg_gen_or_tl(s->T0, s->T0, s->T1);
6077            gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
6078            s->base.is_jmp = DISAS_EOB_NEXT;
6079            break;
6080
6081        CASE_MODRM_MEM_OP(7): /* invlpg */
6082            if (!check_cpl0(s)) {
6083                break;
6084            }
6085            gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
6086            gen_lea_modrm(env, s, modrm);
6087            gen_helper_flush_page(cpu_env, s->A0);
6088            s->base.is_jmp = DISAS_EOB_NEXT;
6089            break;
6090
6091        case 0xf8: /* swapgs */
6092#ifdef TARGET_X86_64
6093            if (CODE64(s)) {
6094                if (check_cpl0(s)) {
6095                    tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
6096                    tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
6097                                  offsetof(CPUX86State, kernelgsbase));
6098                    tcg_gen_st_tl(s->T0, cpu_env,
6099                                  offsetof(CPUX86State, kernelgsbase));
6100                }
6101                break;
6102            }
6103#endif
6104            goto illegal_op;
6105
6106        case 0xf9: /* rdtscp */
6107            if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
6108                goto illegal_op;
6109            }
6110            gen_update_cc_op(s);
6111            gen_update_eip_cur(s);
6112            if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6113                gen_io_start();
6114                s->base.is_jmp = DISAS_TOO_MANY;
6115            }
6116            gen_helper_rdtscp(cpu_env);
6117            break;
6118
6119        default:
6120            goto unknown_op;
6121        }
6122        break;
6123
6124    case 0x108: /* invd */
6125    case 0x109: /* wbinvd */
6126        if (check_cpl0(s)) {
6127            gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
6128            /* nothing to do */
6129        }
6130        break;
6131    case 0x63: /* arpl or movslS (x86_64) */
6132#ifdef TARGET_X86_64
6133        if (CODE64(s)) {
6134            int d_ot;
6135            /* d_ot is the size of destination */
6136            d_ot = dflag;
6137
6138            modrm = x86_ldub_code(env, s);
6139            reg = ((modrm >> 3) & 7) | REX_R(s);
6140            mod = (modrm >> 6) & 3;
6141            rm = (modrm & 7) | REX_B(s);
6142
6143            if (mod == 3) {
6144                gen_op_mov_v_reg(s, MO_32, s->T0, rm);
6145                /* sign extend */
6146                if (d_ot == MO_64) {
6147                    tcg_gen_ext32s_tl(s->T0, s->T0);
6148                }
6149                gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6150            } else {
6151                gen_lea_modrm(env, s, modrm);
6152                gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
6153                gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6154            }
6155        } else
6156#endif
6157        {
6158            TCGLabel *label1;
6159            TCGv t0, t1, t2, a0;
6160
6161            if (!PE(s) || VM86(s))
6162                goto illegal_op;
6163            t0 = tcg_temp_local_new();
6164            t1 = tcg_temp_local_new();
6165            t2 = tcg_temp_local_new();
6166            ot = MO_16;
6167            modrm = x86_ldub_code(env, s);
6168            reg = (modrm >> 3) & 7;
6169            mod = (modrm >> 6) & 3;
6170            rm = modrm & 7;
6171            if (mod != 3) {
6172                gen_lea_modrm(env, s, modrm);
6173                gen_op_ld_v(s, ot, t0, s->A0);
6174                a0 = tcg_temp_local_new();
6175                tcg_gen_mov_tl(a0, s->A0);
6176            } else {
6177                gen_op_mov_v_reg(s, ot, t0, rm);
6178                a0 = NULL;
6179            }
6180            gen_op_mov_v_reg(s, ot, t1, reg);
6181            tcg_gen_andi_tl(s->tmp0, t0, 3);
6182            tcg_gen_andi_tl(t1, t1, 3);
6183            tcg_gen_movi_tl(t2, 0);
6184            label1 = gen_new_label();
6185            tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
6186            tcg_gen_andi_tl(t0, t0, ~3);
6187            tcg_gen_or_tl(t0, t0, t1);
6188            tcg_gen_movi_tl(t2, CC_Z);
6189            gen_set_label(label1);
6190            if (mod != 3) {
6191                gen_op_st_v(s, ot, t0, a0);
6192                tcg_temp_free(a0);
6193           } else {
6194                gen_op_mov_reg_v(s, ot, rm, t0);
6195            }
6196            gen_compute_eflags(s);
6197            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6198            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
6199            tcg_temp_free(t0);
6200            tcg_temp_free(t1);
6201            tcg_temp_free(t2);
6202        }
6203        break;
6204    case 0x102: /* lar */
6205    case 0x103: /* lsl */
6206        {
6207            TCGLabel *label1;
6208            TCGv t0;
6209            if (!PE(s) || VM86(s))
6210                goto illegal_op;
6211            ot = dflag != MO_16 ? MO_32 : MO_16;
6212            modrm = x86_ldub_code(env, s);
6213            reg = ((modrm >> 3) & 7) | REX_R(s);
6214            gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6215            t0 = tcg_temp_local_new();
6216            gen_update_cc_op(s);
6217            if (b == 0x102) {
6218                gen_helper_lar(t0, cpu_env, s->T0);
6219            } else {
6220                gen_helper_lsl(t0, cpu_env, s->T0);
6221            }
6222            tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
6223            label1 = gen_new_label();
6224            tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
6225            gen_op_mov_reg_v(s, ot, reg, t0);
6226            gen_set_label(label1);
6227            set_cc_op(s, CC_OP_EFLAGS);
6228            tcg_temp_free(t0);
6229        }
6230        break;
6231    case 0x118:
6232        modrm = x86_ldub_code(env, s);
6233        mod = (modrm >> 6) & 3;
6234        op = (modrm >> 3) & 7;
6235        switch(op) {
6236        case 0: /* prefetchnta */
6237        case 1: /* prefetchnt0 */
6238        case 2: /* prefetchnt0 */
6239        case 3: /* prefetchnt0 */
6240            if (mod == 3)
6241                goto illegal_op;
6242            gen_nop_modrm(env, s, modrm);
6243            /* nothing more to do */
6244            break;
6245        default: /* nop (multi byte) */
6246            gen_nop_modrm(env, s, modrm);
6247            break;
6248        }
6249        break;
6250    case 0x11a:
6251        modrm = x86_ldub_code(env, s);
6252        if (s->flags & HF_MPX_EN_MASK) {
6253            mod = (modrm >> 6) & 3;
6254            reg = ((modrm >> 3) & 7) | REX_R(s);
6255            if (prefixes & PREFIX_REPZ) {
6256                /* bndcl */
6257                if (reg >= 4
6258                    || (prefixes & PREFIX_LOCK)
6259                    || s->aflag == MO_16) {
6260                    goto illegal_op;
6261                }
6262                gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
6263            } else if (prefixes & PREFIX_REPNZ) {
6264                /* bndcu */
6265                if (reg >= 4
6266                    || (prefixes & PREFIX_LOCK)
6267                    || s->aflag == MO_16) {
6268                    goto illegal_op;
6269                }
6270                TCGv_i64 notu = tcg_temp_new_i64();
6271                tcg_gen_not_i64(notu, cpu_bndu[reg]);
6272                gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
6273                tcg_temp_free_i64(notu);
6274            } else if (prefixes & PREFIX_DATA) {
6275                /* bndmov -- from reg/mem */
6276                if (reg >= 4 || s->aflag == MO_16) {
6277                    goto illegal_op;
6278                }
6279                if (mod == 3) {
6280                    int reg2 = (modrm & 7) | REX_B(s);
6281                    if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6282                        goto illegal_op;
6283                    }
6284                    if (s->flags & HF_MPX_IU_MASK) {
6285                        tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
6286                        tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
6287                    }
6288                } else {
6289                    gen_lea_modrm(env, s, modrm);
6290                    if (CODE64(s)) {
6291                        tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6292                                            s->mem_index, MO_LEUQ);
6293                        tcg_gen_addi_tl(s->A0, s->A0, 8);
6294                        tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6295                                            s->mem_index, MO_LEUQ);
6296                    } else {
6297                        tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6298                                            s->mem_index, MO_LEUL);
6299                        tcg_gen_addi_tl(s->A0, s->A0, 4);
6300                        tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6301                                            s->mem_index, MO_LEUL);
6302                    }
6303                    /* bnd registers are now in-use */
6304                    gen_set_hflag(s, HF_MPX_IU_MASK);
6305                }
6306            } else if (mod != 3) {
6307                /* bndldx */
6308                AddressParts a = gen_lea_modrm_0(env, s, modrm);
6309                if (reg >= 4
6310                    || (prefixes & PREFIX_LOCK)
6311                    || s->aflag == MO_16
6312                    || a.base < -1) {
6313                    goto illegal_op;
6314                }
6315                if (a.base >= 0) {
6316                    tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6317                } else {
6318                    tcg_gen_movi_tl(s->A0, 0);
6319                }
6320                gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6321                if (a.index >= 0) {
6322                    tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6323                } else {
6324                    tcg_gen_movi_tl(s->T0, 0);
6325                }
6326                if (CODE64(s)) {
6327                    gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0);
6328                    tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
6329                                   offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
6330                } else {
6331                    gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0);
6332                    tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
6333                    tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
6334                }
6335                gen_set_hflag(s, HF_MPX_IU_MASK);
6336            }
6337        }
6338        gen_nop_modrm(env, s, modrm);
6339        break;
6340    case 0x11b:
6341        modrm = x86_ldub_code(env, s);
6342        if (s->flags & HF_MPX_EN_MASK) {
6343            mod = (modrm >> 6) & 3;
6344            reg = ((modrm >> 3) & 7) | REX_R(s);
6345            if (mod != 3 && (prefixes & PREFIX_REPZ)) {
6346                /* bndmk */
6347                if (reg >= 4
6348                    || (prefixes & PREFIX_LOCK)
6349                    || s->aflag == MO_16) {
6350                    goto illegal_op;
6351                }
6352                AddressParts a = gen_lea_modrm_0(env, s, modrm);
6353                if (a.base >= 0) {
6354                    tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
6355                    if (!CODE64(s)) {
6356                        tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
6357                    }
6358                } else if (a.base == -1) {
6359                    /* no base register has lower bound of 0 */
6360                    tcg_gen_movi_i64(cpu_bndl[reg], 0);
6361                } else {
6362                    /* rip-relative generates #ud */
6363                    goto illegal_op;
6364                }
6365                tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false));
6366                if (!CODE64(s)) {
6367                    tcg_gen_ext32u_tl(s->A0, s->A0);
6368                }
6369                tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
6370                /* bnd registers are now in-use */
6371                gen_set_hflag(s, HF_MPX_IU_MASK);
6372                break;
6373            } else if (prefixes & PREFIX_REPNZ) {
6374                /* bndcn */
6375                if (reg >= 4
6376                    || (prefixes & PREFIX_LOCK)
6377                    || s->aflag == MO_16) {
6378                    goto illegal_op;
6379                }
6380                gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
6381            } else if (prefixes & PREFIX_DATA) {
6382                /* bndmov -- to reg/mem */
6383                if (reg >= 4 || s->aflag == MO_16) {
6384                    goto illegal_op;
6385                }
6386                if (mod == 3) {
6387                    int reg2 = (modrm & 7) | REX_B(s);
6388                    if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6389                        goto illegal_op;
6390                    }
6391                    if (s->flags & HF_MPX_IU_MASK) {
6392                        tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
6393                        tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
6394                    }
6395                } else {
6396                    gen_lea_modrm(env, s, modrm);
6397                    if (CODE64(s)) {
6398                        tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6399                                            s->mem_index, MO_LEUQ);
6400                        tcg_gen_addi_tl(s->A0, s->A0, 8);
6401                        tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6402                                            s->mem_index, MO_LEUQ);
6403                    } else {
6404                        tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6405                                            s->mem_index, MO_LEUL);
6406                        tcg_gen_addi_tl(s->A0, s->A0, 4);
6407                        tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6408                                            s->mem_index, MO_LEUL);
6409                    }
6410                }
6411            } else if (mod != 3) {
6412                /* bndstx */
6413                AddressParts a = gen_lea_modrm_0(env, s, modrm);
6414                if (reg >= 4
6415                    || (prefixes & PREFIX_LOCK)
6416                    || s->aflag == MO_16
6417                    || a.base < -1) {
6418                    goto illegal_op;
6419                }
6420                if (a.base >= 0) {
6421                    tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6422                } else {
6423                    tcg_gen_movi_tl(s->A0, 0);
6424                }
6425                gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6426                if (a.index >= 0) {
6427                    tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6428                } else {
6429                    tcg_gen_movi_tl(s->T0, 0);
6430                }
6431                if (CODE64(s)) {
6432                    gen_helper_bndstx64(cpu_env, s->A0, s->T0,
6433                                        cpu_bndl[reg], cpu_bndu[reg]);
6434                } else {
6435                    gen_helper_bndstx32(cpu_env, s->A0, s->T0,
6436                                        cpu_bndl[reg], cpu_bndu[reg]);
6437                }
6438            }
6439        }
6440        gen_nop_modrm(env, s, modrm);
6441        break;
6442    case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
6443        modrm = x86_ldub_code(env, s);
6444        gen_nop_modrm(env, s, modrm);
6445        break;
6446
6447    case 0x120: /* mov reg, crN */
6448    case 0x122: /* mov crN, reg */
6449        if (!check_cpl0(s)) {
6450            break;
6451        }
6452        modrm = x86_ldub_code(env, s);
6453        /*
6454         * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6455         * AMD documentation (24594.pdf) and testing of Intel 386 and 486
6456         * processors all show that the mod bits are assumed to be 1's,
6457         * regardless of actual values.
6458         */
6459        rm = (modrm & 7) | REX_B(s);
6460        reg = ((modrm >> 3) & 7) | REX_R(s);
6461        switch (reg) {
6462        case 0:
6463            if ((prefixes & PREFIX_LOCK) &&
6464                (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
6465                reg = 8;
6466            }
6467            break;
6468        case 2:
6469        case 3:
6470        case 4:
6471        case 8:
6472            break;
6473        default:
6474            goto unknown_op;
6475        }
6476        ot  = (CODE64(s) ? MO_64 : MO_32);
6477
6478        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6479            gen_io_start();
6480            s->base.is_jmp = DISAS_TOO_MANY;
6481        }
6482        if (b & 2) {
6483            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
6484            gen_op_mov_v_reg(s, ot, s->T0, rm);
6485            gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
6486            s->base.is_jmp = DISAS_EOB_NEXT;
6487        } else {
6488            gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
6489            gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
6490            gen_op_mov_reg_v(s, ot, rm, s->T0);
6491        }
6492        break;
6493
6494    case 0x121: /* mov reg, drN */
6495    case 0x123: /* mov drN, reg */
6496        if (check_cpl0(s)) {
6497            modrm = x86_ldub_code(env, s);
6498            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6499             * AMD documentation (24594.pdf) and testing of
6500             * intel 386 and 486 processors all show that the mod bits
6501             * are assumed to be 1's, regardless of actual values.
6502             */
6503            rm = (modrm & 7) | REX_B(s);
6504            reg = ((modrm >> 3) & 7) | REX_R(s);
6505            if (CODE64(s))
6506                ot = MO_64;
6507            else
6508                ot = MO_32;
6509            if (reg >= 8) {
6510                goto illegal_op;
6511            }
6512            if (b & 2) {
6513                gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
6514                gen_op_mov_v_reg(s, ot, s->T0, rm);
6515                tcg_gen_movi_i32(s->tmp2_i32, reg);
6516                gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
6517                s->base.is_jmp = DISAS_EOB_NEXT;
6518            } else {
6519                gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
6520                tcg_gen_movi_i32(s->tmp2_i32, reg);
6521                gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
6522                gen_op_mov_reg_v(s, ot, rm, s->T0);
6523            }
6524        }
6525        break;
6526    case 0x106: /* clts */
6527        if (check_cpl0(s)) {
6528            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6529            gen_helper_clts(cpu_env);
6530            /* abort block because static cpu state changed */
6531            s->base.is_jmp = DISAS_EOB_NEXT;
6532        }
6533        break;
6534    /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
6535    case 0x1c3: /* MOVNTI reg, mem */
6536        if (!(s->cpuid_features & CPUID_SSE2))
6537            goto illegal_op;
6538        ot = mo_64_32(dflag);
6539        modrm = x86_ldub_code(env, s);
6540        mod = (modrm >> 6) & 3;
6541        if (mod == 3)
6542            goto illegal_op;
6543        reg = ((modrm >> 3) & 7) | REX_R(s);
6544        /* generate a generic store */
6545        gen_ldst_modrm(env, s, modrm, ot, reg, 1);
6546        break;
6547    case 0x1ae:
6548        modrm = x86_ldub_code(env, s);
6549        switch (modrm) {
6550        CASE_MODRM_MEM_OP(0): /* fxsave */
6551            if (!(s->cpuid_features & CPUID_FXSR)
6552                || (prefixes & PREFIX_LOCK)) {
6553                goto illegal_op;
6554            }
6555            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6556                gen_exception(s, EXCP07_PREX);
6557                break;
6558            }
6559            gen_lea_modrm(env, s, modrm);
6560            gen_helper_fxsave(cpu_env, s->A0);
6561            break;
6562
6563        CASE_MODRM_MEM_OP(1): /* fxrstor */
6564            if (!(s->cpuid_features & CPUID_FXSR)
6565                || (prefixes & PREFIX_LOCK)) {
6566                goto illegal_op;
6567            }
6568            if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6569                gen_exception(s, EXCP07_PREX);
6570                break;
6571            }
6572            gen_lea_modrm(env, s, modrm);
6573            gen_helper_fxrstor(cpu_env, s->A0);
6574            break;
6575
6576        CASE_MODRM_MEM_OP(2): /* ldmxcsr */
6577            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6578                goto illegal_op;
6579            }
6580            if (s->flags & HF_TS_MASK) {
6581                gen_exception(s, EXCP07_PREX);
6582                break;
6583            }
6584            gen_lea_modrm(env, s, modrm);
6585            tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
6586            gen_helper_ldmxcsr(cpu_env, s->tmp2_i32);
6587            break;
6588
6589        CASE_MODRM_MEM_OP(3): /* stmxcsr */
6590            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6591                goto illegal_op;
6592            }
6593            if (s->flags & HF_TS_MASK) {
6594                gen_exception(s, EXCP07_PREX);
6595                break;
6596            }
6597            gen_helper_update_mxcsr(cpu_env);
6598            gen_lea_modrm(env, s, modrm);
6599            tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr));
6600            gen_op_st_v(s, MO_32, s->T0, s->A0);
6601            break;
6602
6603        CASE_MODRM_MEM_OP(4): /* xsave */
6604            if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6605                || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6606                                | PREFIX_REPZ | PREFIX_REPNZ))) {
6607                goto illegal_op;
6608            }
6609            gen_lea_modrm(env, s, modrm);
6610            tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6611                                  cpu_regs[R_EDX]);
6612            gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64);
6613            break;
6614
6615        CASE_MODRM_MEM_OP(5): /* xrstor */
6616            if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6617                || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6618                                | PREFIX_REPZ | PREFIX_REPNZ))) {
6619                goto illegal_op;
6620            }
6621            gen_lea_modrm(env, s, modrm);
6622            tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6623                                  cpu_regs[R_EDX]);
6624            gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
6625            /* XRSTOR is how MPX is enabled, which changes how
6626               we translate.  Thus we need to end the TB.  */
6627            s->base.is_jmp = DISAS_EOB_NEXT;
6628            break;
6629
6630        CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
6631            if (prefixes & PREFIX_LOCK) {
6632                goto illegal_op;
6633            }
6634            if (prefixes & PREFIX_DATA) {
6635                /* clwb */
6636                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
6637                    goto illegal_op;
6638                }
6639                gen_nop_modrm(env, s, modrm);
6640            } else {
6641                /* xsaveopt */
6642                if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6643                    || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
6644                    || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
6645                    goto illegal_op;
6646                }
6647                gen_lea_modrm(env, s, modrm);
6648                tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6649                                      cpu_regs[R_EDX]);
6650                gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64);
6651            }
6652            break;
6653
6654        CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
6655            if (prefixes & PREFIX_LOCK) {
6656                goto illegal_op;
6657            }
6658            if (prefixes & PREFIX_DATA) {
6659                /* clflushopt */
6660                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
6661                    goto illegal_op;
6662                }
6663            } else {
6664                /* clflush */
6665                if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
6666                    || !(s->cpuid_features & CPUID_CLFLUSH)) {
6667                    goto illegal_op;
6668                }
6669            }
6670            gen_nop_modrm(env, s, modrm);
6671            break;
6672
6673        case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
6674        case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
6675        case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
6676        case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
6677            if (CODE64(s)
6678                && (prefixes & PREFIX_REPZ)
6679                && !(prefixes & PREFIX_LOCK)
6680                && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
6681                TCGv base, treg, src, dst;
6682
6683                /* Preserve hflags bits by testing CR4 at runtime.  */
6684                tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
6685                gen_helper_cr4_testbit(cpu_env, s->tmp2_i32);
6686
6687                base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
6688                treg = cpu_regs[(modrm & 7) | REX_B(s)];
6689
6690                if (modrm & 0x10) {
6691                    /* wr*base */
6692                    dst = base, src = treg;
6693                } else {
6694                    /* rd*base */
6695                    dst = treg, src = base;
6696                }
6697
6698                if (s->dflag == MO_32) {
6699                    tcg_gen_ext32u_tl(dst, src);
6700                } else {
6701                    tcg_gen_mov_tl(dst, src);
6702                }
6703                break;
6704            }
6705            goto unknown_op;
6706
6707        case 0xf8: /* sfence / pcommit */
6708            if (prefixes & PREFIX_DATA) {
6709                /* pcommit */
6710                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
6711                    || (prefixes & PREFIX_LOCK)) {
6712                    goto illegal_op;
6713                }
6714                break;
6715            }
6716            /* fallthru */
6717        case 0xf9 ... 0xff: /* sfence */
6718            if (!(s->cpuid_features & CPUID_SSE)
6719                || (prefixes & PREFIX_LOCK)) {
6720                goto illegal_op;
6721            }
6722            tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
6723            break;
6724        case 0xe8 ... 0xef: /* lfence */
6725            if (!(s->cpuid_features & CPUID_SSE)
6726                || (prefixes & PREFIX_LOCK)) {
6727                goto illegal_op;
6728            }
6729            tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
6730            break;
6731        case 0xf0 ... 0xf7: /* mfence */
6732            if (!(s->cpuid_features & CPUID_SSE2)
6733                || (prefixes & PREFIX_LOCK)) {
6734                goto illegal_op;
6735            }
6736            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
6737            break;
6738
6739        default:
6740            goto unknown_op;
6741        }
6742        break;
6743
6744    case 0x10d: /* 3DNow! prefetch(w) */
6745        modrm = x86_ldub_code(env, s);
6746        mod = (modrm >> 6) & 3;
6747        if (mod == 3)
6748            goto illegal_op;
6749        gen_nop_modrm(env, s, modrm);
6750        break;
6751    case 0x1aa: /* rsm */
6752        gen_svm_check_intercept(s, SVM_EXIT_RSM);
6753        if (!(s->flags & HF_SMM_MASK))
6754            goto illegal_op;
6755#ifdef CONFIG_USER_ONLY
6756        /* we should not be in SMM mode */
6757        g_assert_not_reached();
6758#else
6759        gen_update_cc_op(s);
6760        gen_update_eip_next(s);
6761        gen_helper_rsm(cpu_env);
6762#endif /* CONFIG_USER_ONLY */
6763        s->base.is_jmp = DISAS_EOB_ONLY;
6764        break;
6765    case 0x1b8: /* SSE4.2 popcnt */
6766        if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
6767             PREFIX_REPZ)
6768            goto illegal_op;
6769        if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
6770            goto illegal_op;
6771
6772        modrm = x86_ldub_code(env, s);
6773        reg = ((modrm >> 3) & 7) | REX_R(s);
6774
6775        if (s->prefix & PREFIX_DATA) {
6776            ot = MO_16;
6777        } else {
6778            ot = mo_64_32(dflag);
6779        }
6780
6781        gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6782        gen_extu(ot, s->T0);
6783        tcg_gen_mov_tl(cpu_cc_src, s->T0);
6784        tcg_gen_ctpop_tl(s->T0, s->T0);
6785        gen_op_mov_reg_v(s, ot, reg, s->T0);
6786
6787        set_cc_op(s, CC_OP_POPCNT);
6788        break;
6789    case 0x10e ... 0x117:
6790    case 0x128 ... 0x12f:
6791    case 0x138 ... 0x13a:
6792    case 0x150 ... 0x179:
6793    case 0x17c ... 0x17f:
6794    case 0x1c2:
6795    case 0x1c4 ... 0x1c6:
6796    case 0x1d0 ... 0x1fe:
6797        disas_insn_new(s, cpu, b);
6798        break;
6799    default:
6800        goto unknown_op;
6801    }
6802    return true;
6803 illegal_op:
6804    gen_illegal_opcode(s);
6805    return true;
6806 unknown_op:
6807    gen_unknown_opcode(env, s);
6808    return true;
6809}
6810
6811void tcg_x86_init(void)
6812{
6813    static const char reg_names[CPU_NB_REGS][4] = {
6814#ifdef TARGET_X86_64
6815        [R_EAX] = "rax",
6816        [R_EBX] = "rbx",
6817        [R_ECX] = "rcx",
6818        [R_EDX] = "rdx",
6819        [R_ESI] = "rsi",
6820        [R_EDI] = "rdi",
6821        [R_EBP] = "rbp",
6822        [R_ESP] = "rsp",
6823        [8]  = "r8",
6824        [9]  = "r9",
6825        [10] = "r10",
6826        [11] = "r11",
6827        [12] = "r12",
6828        [13] = "r13",
6829        [14] = "r14",
6830        [15] = "r15",
6831#else
6832        [R_EAX] = "eax",
6833        [R_EBX] = "ebx",
6834        [R_ECX] = "ecx",
6835        [R_EDX] = "edx",
6836        [R_ESI] = "esi",
6837        [R_EDI] = "edi",
6838        [R_EBP] = "ebp",
6839        [R_ESP] = "esp",
6840#endif
6841    };
6842    static const char eip_name[] = {
6843#ifdef TARGET_X86_64
6844        "rip"
6845#else
6846        "eip"
6847#endif
6848    };
6849    static const char seg_base_names[6][8] = {
6850        [R_CS] = "cs_base",
6851        [R_DS] = "ds_base",
6852        [R_ES] = "es_base",
6853        [R_FS] = "fs_base",
6854        [R_GS] = "gs_base",
6855        [R_SS] = "ss_base",
6856    };
6857    static const char bnd_regl_names[4][8] = {
6858        "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
6859    };
6860    static const char bnd_regu_names[4][8] = {
6861        "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
6862    };
6863    int i;
6864
6865    cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
6866                                       offsetof(CPUX86State, cc_op), "cc_op");
6867    cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
6868                                    "cc_dst");
6869    cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
6870                                    "cc_src");
6871    cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
6872                                     "cc_src2");
6873    cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name);
6874
6875    for (i = 0; i < CPU_NB_REGS; ++i) {
6876        cpu_regs[i] = tcg_global_mem_new(cpu_env,
6877                                         offsetof(CPUX86State, regs[i]),
6878                                         reg_names[i]);
6879    }
6880
6881    for (i = 0; i < 6; ++i) {
6882        cpu_seg_base[i]
6883            = tcg_global_mem_new(cpu_env,
6884                                 offsetof(CPUX86State, segs[i].base),
6885                                 seg_base_names[i]);
6886    }
6887
6888    for (i = 0; i < 4; ++i) {
6889        cpu_bndl[i]
6890            = tcg_global_mem_new_i64(cpu_env,
6891                                     offsetof(CPUX86State, bnd_regs[i].lb),
6892                                     bnd_regl_names[i]);
6893        cpu_bndu[i]
6894            = tcg_global_mem_new_i64(cpu_env,
6895                                     offsetof(CPUX86State, bnd_regs[i].ub),
6896                                     bnd_regu_names[i]);
6897    }
6898}
6899
6900static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
6901{
6902    DisasContext *dc = container_of(dcbase, DisasContext, base);
6903    CPUX86State *env = cpu->env_ptr;
6904    uint32_t flags = dc->base.tb->flags;
6905    uint32_t cflags = tb_cflags(dc->base.tb);
6906    int cpl = (flags >> HF_CPL_SHIFT) & 3;
6907    int iopl = (flags >> IOPL_SHIFT) & 3;
6908
6909    dc->cs_base = dc->base.tb->cs_base;
6910    dc->pc_save = dc->base.pc_next;
6911    dc->flags = flags;
6912#ifndef CONFIG_USER_ONLY
6913    dc->cpl = cpl;
6914    dc->iopl = iopl;
6915#endif
6916
6917    /* We make some simplifying assumptions; validate they're correct. */
6918    g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
6919    g_assert(CPL(dc) == cpl);
6920    g_assert(IOPL(dc) == iopl);
6921    g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
6922    g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
6923    g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
6924    g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
6925    g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
6926    g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
6927    g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
6928    g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
6929
6930    dc->cc_op = CC_OP_DYNAMIC;
6931    dc->cc_op_dirty = false;
6932    dc->popl_esp_hack = 0;
6933    /* select memory access functions */
6934    dc->mem_index = 0;
6935#ifdef CONFIG_SOFTMMU
6936    dc->mem_index = cpu_mmu_index(env, false);
6937#endif
6938    dc->cpuid_features = env->features[FEAT_1_EDX];
6939    dc->cpuid_ext_features = env->features[FEAT_1_ECX];
6940    dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
6941    dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
6942    dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
6943    dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
6944    dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
6945    dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
6946                    (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
6947    /*
6948     * If jmp_opt, we want to handle each string instruction individually.
6949     * For icount also disable repz optimization so that each iteration
6950     * is accounted separately.
6951     */
6952    dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
6953
6954    dc->T0 = tcg_temp_new();
6955    dc->T1 = tcg_temp_new();
6956    dc->A0 = tcg_temp_new();
6957
6958    dc->tmp0 = tcg_temp_new();
6959    dc->tmp1_i64 = tcg_temp_new_i64();
6960    dc->tmp2_i32 = tcg_temp_new_i32();
6961    dc->tmp3_i32 = tcg_temp_new_i32();
6962    dc->tmp4 = tcg_temp_new();
6963    dc->cc_srcT = tcg_temp_local_new();
6964}
6965
6966static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
6967{
6968}
6969
6970static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
6971{
6972    DisasContext *dc = container_of(dcbase, DisasContext, base);
6973    target_ulong pc_arg = dc->base.pc_next;
6974
6975    dc->prev_insn_end = tcg_last_op();
6976    if (TARGET_TB_PCREL) {
6977        pc_arg -= dc->cs_base;
6978        pc_arg &= ~TARGET_PAGE_MASK;
6979    }
6980    tcg_gen_insn_start(pc_arg, dc->cc_op);
6981}
6982
6983static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
6984{
6985    DisasContext *dc = container_of(dcbase, DisasContext, base);
6986
6987#ifdef TARGET_VSYSCALL_PAGE
6988    /*
6989     * Detect entry into the vsyscall page and invoke the syscall.
6990     */
6991    if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
6992        gen_exception(dc, EXCP_VSYSCALL);
6993        dc->base.pc_next = dc->pc + 1;
6994        return;
6995    }
6996#endif
6997
6998    if (disas_insn(dc, cpu)) {
6999        target_ulong pc_next = dc->pc;
7000        dc->base.pc_next = pc_next;
7001
7002        if (dc->base.is_jmp == DISAS_NEXT) {
7003            if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
7004                /*
7005                 * If single step mode, we generate only one instruction and
7006                 * generate an exception.
7007                 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7008                 * the flag and abort the translation to give the irqs a
7009                 * chance to happen.
7010                 */
7011                dc->base.is_jmp = DISAS_EOB_NEXT;
7012            } else if (!is_same_page(&dc->base, pc_next)) {
7013                dc->base.is_jmp = DISAS_TOO_MANY;
7014            }
7015        }
7016    }
7017}
7018
7019static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
7020{
7021    DisasContext *dc = container_of(dcbase, DisasContext, base);
7022
7023    switch (dc->base.is_jmp) {
7024    case DISAS_NORETURN:
7025        break;
7026    case DISAS_TOO_MANY:
7027        gen_update_cc_op(dc);
7028        gen_jmp_rel_csize(dc, 0, 0);
7029        break;
7030    case DISAS_EOB_NEXT:
7031        gen_update_cc_op(dc);
7032        gen_update_eip_cur(dc);
7033        /* fall through */
7034    case DISAS_EOB_ONLY:
7035        gen_eob(dc);
7036        break;
7037    case DISAS_EOB_INHIBIT_IRQ:
7038        gen_update_cc_op(dc);
7039        gen_update_eip_cur(dc);
7040        gen_eob_inhibit_irq(dc, true);
7041        break;
7042    case DISAS_JUMP:
7043        gen_jr(dc);
7044        break;
7045    default:
7046        g_assert_not_reached();
7047    }
7048}
7049
7050static void i386_tr_disas_log(const DisasContextBase *dcbase,
7051                              CPUState *cpu, FILE *logfile)
7052{
7053    DisasContext *dc = container_of(dcbase, DisasContext, base);
7054
7055    fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
7056    target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
7057}
7058
7059static const TranslatorOps i386_tr_ops = {
7060    .init_disas_context = i386_tr_init_disas_context,
7061    .tb_start           = i386_tr_tb_start,
7062    .insn_start         = i386_tr_insn_start,
7063    .translate_insn     = i386_tr_translate_insn,
7064    .tb_stop            = i386_tr_tb_stop,
7065    .disas_log          = i386_tr_disas_log,
7066};
7067
7068/* generate intermediate code for basic block 'tb'.  */
7069void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
7070                           target_ulong pc, void *host_pc)
7071{
7072    DisasContext dc;
7073
7074    translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
7075}
7076