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