qemu/target/i386/hvf/x86_decode.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Veertu Inc,
   3 * Copyright (C) 2017 Google Inc,
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU Lesser General Public
   7 * License as published by the Free Software Foundation; either
   8 * version 2 of the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * Lesser General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU Lesser General Public
  16 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include "qemu/osdep.h"
  20
  21#include "qemu-common.h"
  22#include "panic.h"
  23#include "x86_decode.h"
  24#include "vmx.h"
  25#include "x86_mmu.h"
  26#include "x86_descr.h"
  27
  28#define OPCODE_ESCAPE   0xf
  29
  30static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
  31{
  32    printf("%llx: failed to decode instruction ", env->hvf_emul->fetch_rip -
  33           decode->len);
  34    for (int i = 0; i < decode->opcode_len; i++) {
  35        printf("%x ", decode->opcode[i]);
  36    }
  37    printf("\n");
  38    VM_PANIC("decoder failed\n");
  39}
  40
  41uint64_t sign(uint64_t val, int size)
  42{
  43    switch (size) {
  44    case 1:
  45        val = (int8_t)val;
  46        break;
  47    case 2:
  48        val = (int16_t)val;
  49        break;
  50    case 4:
  51        val = (int32_t)val;
  52        break;
  53    case 8:
  54        val = (int64_t)val;
  55        break;
  56    default:
  57        VM_PANIC_EX("%s invalid size %d\n", __func__, size);
  58        break;
  59    }
  60    return val;
  61}
  62
  63static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
  64                                    int size)
  65{
  66    target_ulong val = 0;
  67    
  68    switch (size) {
  69    case 1:
  70    case 2:
  71    case 4:
  72    case 8:
  73        break;
  74    default:
  75        VM_PANIC_EX("%s invalid size %d\n", __func__, size);
  76        break;
  77    }
  78    target_ulong va  = linear_rip(ENV_GET_CPU(env), RIP(env)) + decode->len;
  79    vmx_read_mem(ENV_GET_CPU(env), &val, va, size);
  80    decode->len += size;
  81    
  82    return val;
  83}
  84
  85static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode)
  86{
  87    return (uint8_t)decode_bytes(env, decode, 1);
  88}
  89
  90static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode)
  91{
  92    return (uint16_t)decode_bytes(env, decode, 2);
  93}
  94
  95static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode)
  96{
  97    return (uint32_t)decode_bytes(env, decode, 4);
  98}
  99
 100static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode)
 101{
 102    return decode_bytes(env, decode, 8);
 103}
 104
 105static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode,
 106                            struct x86_decode_op *op)
 107{
 108    op->type = X86_VAR_RM;
 109}
 110
 111static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode,
 112                             struct x86_decode_op *op)
 113{
 114    op->type = X86_VAR_REG;
 115    op->reg = decode->modrm.reg;
 116    op->ptr = get_reg_ref(env, op->reg, decode->rex.r, decode->operand_size);
 117}
 118
 119static void decode_rax(CPUX86State *env, struct x86_decode *decode,
 120                       struct x86_decode_op *op)
 121{
 122    op->type = X86_VAR_REG;
 123    op->reg = R_EAX;
 124    op->ptr = get_reg_ref(env, op->reg, 0, decode->operand_size);
 125}
 126
 127static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode,
 128                                    struct x86_decode_op *var, int size)
 129{
 130    var->type = X86_VAR_IMMEDIATE;
 131    var->size = size;
 132    switch (size) {
 133    case 1:
 134        var->val = decode_byte(env, decode);
 135        break;
 136    case 2:
 137        var->val = decode_word(env, decode);
 138        break;
 139    case 4:
 140        var->val = decode_dword(env, decode);
 141        break;
 142    case 8:
 143        var->val = decode_qword(env, decode);
 144        break;
 145    default:
 146        VM_PANIC_EX("bad size %d\n", size);
 147    }
 148}
 149
 150static void decode_imm8(CPUX86State *env, struct x86_decode *decode,
 151                        struct x86_decode_op *op)
 152{
 153    decode_immediate(env, decode, op, 1);
 154    op->type = X86_VAR_IMMEDIATE;
 155}
 156
 157static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode,
 158                               struct x86_decode_op *op)
 159{
 160    decode_immediate(env, decode, op, 1);
 161    op->val = sign(op->val, 1);
 162    op->type = X86_VAR_IMMEDIATE;
 163}
 164
 165static void decode_imm16(CPUX86State *env, struct x86_decode *decode,
 166                         struct x86_decode_op *op)
 167{
 168    decode_immediate(env, decode, op, 2);
 169    op->type = X86_VAR_IMMEDIATE;
 170}
 171
 172
 173static void decode_imm(CPUX86State *env, struct x86_decode *decode,
 174                       struct x86_decode_op *op)
 175{
 176    if (8 == decode->operand_size) {
 177        decode_immediate(env, decode, op, 4);
 178        op->val = sign(op->val, decode->operand_size);
 179    } else {
 180        decode_immediate(env, decode, op, decode->operand_size);
 181    }
 182    op->type = X86_VAR_IMMEDIATE;
 183}
 184
 185static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode,
 186                              struct x86_decode_op *op)
 187{
 188    decode_immediate(env, decode, op, decode->operand_size);
 189    op->val = sign(op->val, decode->operand_size);
 190    op->type = X86_VAR_IMMEDIATE;
 191}
 192
 193static void decode_imm_1(CPUX86State *env, struct x86_decode *decode,
 194                         struct x86_decode_op *op)
 195{
 196    op->type = X86_VAR_IMMEDIATE;
 197    op->val = 1;
 198}
 199
 200static void decode_imm_0(CPUX86State *env, struct x86_decode *decode,
 201                         struct x86_decode_op *op)
 202{
 203    op->type = X86_VAR_IMMEDIATE;
 204    op->val = 0;
 205}
 206
 207
 208static void decode_pushseg(CPUX86State *env, struct x86_decode *decode)
 209{
 210    uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
 211    
 212    decode->op[0].type = X86_VAR_REG;
 213    switch (op) {
 214    case 0xe:
 215        decode->op[0].reg = R_CS;
 216        break;
 217    case 0x16:
 218        decode->op[0].reg = R_SS;
 219        break;
 220    case 0x1e:
 221        decode->op[0].reg = R_DS;
 222        break;
 223    case 0x06:
 224        decode->op[0].reg = R_ES;
 225        break;
 226    case 0xa0:
 227        decode->op[0].reg = R_FS;
 228        break;
 229    case 0xa8:
 230        decode->op[0].reg = R_GS;
 231        break;
 232    }
 233}
 234
 235static void decode_popseg(CPUX86State *env, struct x86_decode *decode)
 236{
 237    uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0];
 238    
 239    decode->op[0].type = X86_VAR_REG;
 240    switch (op) {
 241    case 0xf:
 242        decode->op[0].reg = R_CS;
 243        break;
 244    case 0x17:
 245        decode->op[0].reg = R_SS;
 246        break;
 247    case 0x1f:
 248        decode->op[0].reg = R_DS;
 249        break;
 250    case 0x07:
 251        decode->op[0].reg = R_ES;
 252        break;
 253    case 0xa1:
 254        decode->op[0].reg = R_FS;
 255        break;
 256    case 0xa9:
 257        decode->op[0].reg = R_GS;
 258        break;
 259    }
 260}
 261
 262static void decode_incgroup(CPUX86State *env, struct x86_decode *decode)
 263{
 264    decode->op[0].type = X86_VAR_REG;
 265    decode->op[0].reg = decode->opcode[0] - 0x40;
 266    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 267                                    decode->operand_size);
 268}
 269
 270static void decode_decgroup(CPUX86State *env, struct x86_decode *decode)
 271{
 272    decode->op[0].type = X86_VAR_REG;
 273    decode->op[0].reg = decode->opcode[0] - 0x48;
 274    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 275                                    decode->operand_size);
 276}
 277
 278static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode)
 279{
 280    if (!decode->modrm.reg) {
 281        decode->cmd = X86_DECODE_CMD_INC;
 282    } else if (1 == decode->modrm.reg) {
 283        decode->cmd = X86_DECODE_CMD_DEC;
 284    }
 285}
 286
 287static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode)
 288{
 289    decode->op[0].type = X86_VAR_REG;
 290    decode->op[0].reg = decode->opcode[0] - 0x50;
 291    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 292                                    decode->operand_size);
 293}
 294
 295static void decode_popgroup(CPUX86State *env, struct x86_decode *decode)
 296{
 297    decode->op[0].type = X86_VAR_REG;
 298    decode->op[0].reg = decode->opcode[0] - 0x58;
 299    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 300                                    decode->operand_size);
 301}
 302
 303static void decode_jxx(CPUX86State *env, struct x86_decode *decode)
 304{
 305    decode->displacement = decode_bytes(env, decode, decode->operand_size);
 306    decode->displacement_size = decode->operand_size;
 307}
 308
 309static void decode_farjmp(CPUX86State *env, struct x86_decode *decode)
 310{
 311    decode->op[0].type = X86_VAR_IMMEDIATE;
 312    decode->op[0].val = decode_bytes(env, decode, decode->operand_size);
 313    decode->displacement = decode_word(env, decode);
 314}
 315
 316static void decode_addgroup(CPUX86State *env, struct x86_decode *decode)
 317{
 318    enum x86_decode_cmd group[] = {
 319        X86_DECODE_CMD_ADD,
 320        X86_DECODE_CMD_OR,
 321        X86_DECODE_CMD_ADC,
 322        X86_DECODE_CMD_SBB,
 323        X86_DECODE_CMD_AND,
 324        X86_DECODE_CMD_SUB,
 325        X86_DECODE_CMD_XOR,
 326        X86_DECODE_CMD_CMP
 327    };
 328    decode->cmd = group[decode->modrm.reg];
 329}
 330
 331static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode)
 332{
 333    enum x86_decode_cmd group[] = {
 334        X86_DECODE_CMD_ROL,
 335        X86_DECODE_CMD_ROR,
 336        X86_DECODE_CMD_RCL,
 337        X86_DECODE_CMD_RCR,
 338        X86_DECODE_CMD_SHL,
 339        X86_DECODE_CMD_SHR,
 340        X86_DECODE_CMD_SHL,
 341        X86_DECODE_CMD_SAR
 342    };
 343    decode->cmd = group[decode->modrm.reg];
 344}
 345
 346static void decode_f7group(CPUX86State *env, struct x86_decode *decode)
 347{
 348    enum x86_decode_cmd group[] = {
 349        X86_DECODE_CMD_TST,
 350        X86_DECODE_CMD_TST,
 351        X86_DECODE_CMD_NOT,
 352        X86_DECODE_CMD_NEG,
 353        X86_DECODE_CMD_MUL,
 354        X86_DECODE_CMD_IMUL_1,
 355        X86_DECODE_CMD_DIV,
 356        X86_DECODE_CMD_IDIV
 357    };
 358    decode->cmd = group[decode->modrm.reg];
 359    decode_modrm_rm(env, decode, &decode->op[0]);
 360
 361    switch (decode->modrm.reg) {
 362    case 0:
 363    case 1:
 364        decode_imm(env, decode, &decode->op[1]);
 365        break;
 366    case 2:
 367        break;
 368    case 3:
 369        decode->op[1].type = X86_VAR_IMMEDIATE;
 370        decode->op[1].val = 0;
 371        break;
 372    default:
 373        break;
 374    }
 375}
 376
 377static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode)
 378{
 379    decode->op[0].type = X86_VAR_REG;
 380    decode->op[0].reg = decode->opcode[0] - 0x90;
 381    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 382                                    decode->operand_size);
 383}
 384
 385static void decode_movgroup(CPUX86State *env, struct x86_decode *decode)
 386{
 387    decode->op[0].type = X86_VAR_REG;
 388    decode->op[0].reg = decode->opcode[0] - 0xb8;
 389    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 390                                    decode->operand_size);
 391    decode_immediate(env, decode, &decode->op[1], decode->operand_size);
 392}
 393
 394static void fetch_moffs(CPUX86State *env, struct x86_decode *decode,
 395                        struct x86_decode_op *op)
 396{
 397    op->type = X86_VAR_OFFSET;
 398    op->ptr = decode_bytes(env, decode, decode->addressing_size);
 399}
 400
 401static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode)
 402{
 403    decode->op[0].type = X86_VAR_REG;
 404    decode->op[0].reg = decode->opcode[0] - 0xb0;
 405    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 406                                    decode->operand_size);
 407    decode_immediate(env, decode, &decode->op[1], decode->operand_size);
 408}
 409
 410static void decode_rcx(CPUX86State *env, struct x86_decode *decode,
 411                       struct x86_decode_op *op)
 412{
 413    op->type = X86_VAR_REG;
 414    op->reg = R_ECX;
 415    op->ptr = get_reg_ref(env, op->reg, decode->rex.b, decode->operand_size);
 416}
 417
 418struct decode_tbl {
 419    uint8_t opcode;
 420    enum x86_decode_cmd cmd;
 421    uint8_t operand_size;
 422    bool is_modrm;
 423    void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
 424                       struct x86_decode_op *op1);
 425    void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
 426                       struct x86_decode_op *op2);
 427    void (*decode_op3)(CPUX86State *env, struct x86_decode *decode,
 428                       struct x86_decode_op *op3);
 429    void (*decode_op4)(CPUX86State *env, struct x86_decode *decode,
 430                       struct x86_decode_op *op4);
 431    void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
 432    uint32_t flags_mask;
 433};
 434
 435struct decode_x87_tbl {
 436    uint8_t opcode;
 437    uint8_t modrm_reg;
 438    uint8_t modrm_mod;
 439    enum x86_decode_cmd cmd;
 440    uint8_t operand_size;
 441    bool rev;
 442    bool pop;
 443    void (*decode_op1)(CPUX86State *env, struct x86_decode *decode,
 444                       struct x86_decode_op *op1);
 445    void (*decode_op2)(CPUX86State *env, struct x86_decode *decode,
 446                       struct x86_decode_op *op2);
 447    void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode);
 448    uint32_t flags_mask;
 449};
 450
 451struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
 452                               decode_invalid};
 453
 454struct decode_tbl _decode_tbl1[255];
 455struct decode_tbl _decode_tbl2[255];
 456struct decode_x87_tbl _decode_tbl3[255];
 457
 458static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
 459{
 460    struct decode_x87_tbl *decoder;
 461    
 462    decode->is_fpu = true;
 463    int mode = decode->modrm.mod == 3 ? 1 : 0;
 464    int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
 465                 decode->modrm.reg;
 466
 467    decoder = &_decode_tbl3[index];
 468    
 469    decode->cmd = decoder->cmd;
 470    if (decoder->operand_size) {
 471        decode->operand_size = decoder->operand_size;
 472    }
 473    decode->flags_mask = decoder->flags_mask;
 474    decode->fpop_stack = decoder->pop;
 475    decode->frev = decoder->rev;
 476    
 477    if (decoder->decode_op1) {
 478        decoder->decode_op1(env, decode, &decode->op[0]);
 479    }
 480    if (decoder->decode_op2) {
 481        decoder->decode_op2(env, decode, &decode->op[1]);
 482    }
 483    if (decoder->decode_postfix) {
 484        decoder->decode_postfix(env, decode);
 485    }
 486
 487    VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n",
 488                   decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg,
 489                   decoder->modrm_mod);
 490}
 491
 492static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode)
 493{
 494    enum x86_decode_cmd group[] = {
 495        X86_DECODE_CMD_INC,
 496        X86_DECODE_CMD_DEC,
 497        X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT,
 498        X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT,
 499        X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT,
 500        X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT,
 501        X86_DECODE_CMD_PUSH,
 502        X86_DECODE_CMD_INVL,
 503        X86_DECODE_CMD_INVL
 504    };
 505    decode->cmd = group[decode->modrm.reg];
 506    if (decode->modrm.reg > 2) {
 507        decode->flags_mask = 0;
 508    }
 509}
 510
 511static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode)
 512{
 513
 514    enum x86_decode_cmd group[] = {
 515        X86_DECODE_CMD_SLDT,
 516        X86_DECODE_CMD_STR,
 517        X86_DECODE_CMD_LLDT,
 518        X86_DECODE_CMD_LTR,
 519        X86_DECODE_CMD_VERR,
 520        X86_DECODE_CMD_VERW,
 521        X86_DECODE_CMD_INVL,
 522        X86_DECODE_CMD_INVL
 523    };
 524    decode->cmd = group[decode->modrm.reg];
 525    printf("%llx: decode_sldtgroup: %d\n", env->hvf_emul->fetch_rip,
 526            decode->modrm.reg);
 527}
 528
 529static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode)
 530{
 531    enum x86_decode_cmd group[] = {
 532        X86_DECODE_CMD_SGDT,
 533        X86_DECODE_CMD_SIDT,
 534        X86_DECODE_CMD_LGDT,
 535        X86_DECODE_CMD_LIDT,
 536        X86_DECODE_CMD_SMSW,
 537        X86_DECODE_CMD_LMSW,
 538        X86_DECODE_CMD_LMSW,
 539        X86_DECODE_CMD_INVLPG
 540    };
 541    decode->cmd = group[decode->modrm.reg];
 542    if (0xf9 == decode->modrm.modrm) {
 543        decode->opcode[decode->len++] = decode->modrm.modrm;
 544        decode->cmd = X86_DECODE_CMD_RDTSCP;
 545    }
 546}
 547
 548static void decode_btgroup(CPUX86State *env, struct x86_decode *decode)
 549{
 550    enum x86_decode_cmd group[] = {
 551        X86_DECODE_CMD_INVL,
 552        X86_DECODE_CMD_INVL,
 553        X86_DECODE_CMD_INVL,
 554        X86_DECODE_CMD_INVL,
 555        X86_DECODE_CMD_BT,
 556        X86_DECODE_CMD_BTS,
 557        X86_DECODE_CMD_BTR,
 558        X86_DECODE_CMD_BTC
 559    };
 560    decode->cmd = group[decode->modrm.reg];
 561}
 562
 563static void decode_x87_general(CPUX86State *env, struct x86_decode *decode)
 564{
 565    decode->is_fpu = true;
 566}
 567
 568static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode,
 569                                    struct x86_decode_op *op)
 570{
 571    op->type = X87_VAR_FLOATP;
 572}
 573
 574static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode,
 575                                  struct x86_decode_op *op)
 576{
 577    op->type = X87_VAR_INTP;
 578}
 579
 580static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode,
 581                                   struct x86_decode_op *op)
 582{
 583    op->type = X87_VAR_BYTEP;
 584}
 585
 586static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode,
 587                                 struct x86_decode_op *op)
 588{
 589    op->type = X87_VAR_REG;
 590    op->reg = 0;
 591}
 592
 593static void decode_decode_x87_modrm_st0(CPUX86State *env,
 594                                        struct x86_decode *decode,
 595                                        struct x86_decode_op *op)
 596{
 597    op->type = X87_VAR_REG;
 598    op->reg = decode->modrm.modrm & 7;
 599}
 600
 601
 602static void decode_aegroup(CPUX86State *env, struct x86_decode *decode)
 603{
 604    decode->is_fpu = true;
 605    switch (decode->modrm.reg) {
 606    case 0:
 607        decode->cmd = X86_DECODE_CMD_FXSAVE;
 608        decode_x87_modrm_bytep(env, decode, &decode->op[0]);
 609        break;
 610    case 1:
 611        decode_x87_modrm_bytep(env, decode, &decode->op[0]);
 612        decode->cmd = X86_DECODE_CMD_FXRSTOR;
 613        break;
 614    case 5:
 615        if (decode->modrm.modrm == 0xe8) {
 616            decode->cmd = X86_DECODE_CMD_LFENCE;
 617        } else {
 618            VM_PANIC("xrstor");
 619        }
 620        break;
 621    case 6:
 622        VM_PANIC_ON(decode->modrm.modrm != 0xf0);
 623        decode->cmd = X86_DECODE_CMD_MFENCE;
 624        break;
 625    case 7:
 626        if (decode->modrm.modrm == 0xf8) {
 627            decode->cmd = X86_DECODE_CMD_SFENCE;
 628        } else {
 629            decode->cmd = X86_DECODE_CMD_CLFLUSH;
 630        }
 631        break;
 632    default:
 633        VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg);
 634        break;
 635    }
 636}
 637
 638static void decode_bswap(CPUX86State *env, struct x86_decode *decode)
 639{
 640    decode->op[0].type = X86_VAR_REG;
 641    decode->op[0].reg = decode->opcode[1] - 0xc8;
 642    decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.b,
 643                                    decode->operand_size);
 644}
 645
 646static void decode_d9_4(CPUX86State *env, struct x86_decode *decode)
 647{
 648    switch (decode->modrm.modrm) {
 649    case 0xe0:
 650        /* FCHS */
 651        decode->cmd = X86_DECODE_CMD_FCHS;
 652        break;
 653    case 0xe1:
 654        decode->cmd = X86_DECODE_CMD_FABS;
 655        break;
 656    case 0xe4:
 657        VM_PANIC("FTST");
 658        break;
 659    case 0xe5:
 660        /* FXAM */
 661        decode->cmd = X86_DECODE_CMD_FXAM;
 662        break;
 663    default:
 664        VM_PANIC("FLDENV");
 665        break;
 666    }
 667}
 668
 669static void decode_db_4(CPUX86State *env, struct x86_decode *decode)
 670{
 671    switch (decode->modrm.modrm) {
 672    case 0xe0:
 673        VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0],
 674                    decode->modrm.modrm);
 675        break;
 676    case 0xe1:
 677        VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0],
 678                    decode->modrm.modrm);
 679        break;
 680    case 0xe2:
 681        VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0],
 682                    decode->modrm.modrm);
 683        break;
 684    case 0xe3:
 685        decode->cmd = X86_DECODE_CMD_FNINIT;
 686        break;
 687    case 0xe4:
 688        decode->cmd = X86_DECODE_CMD_FNSETPM;
 689        break;
 690    default:
 691        VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0],
 692                    decode->modrm.modrm);
 693        break;
 694    }
 695}
 696
 697
 698#define RFLAGS_MASK_NONE    0
 699#define RFLAGS_MASK_OSZAPC  (RFLAGS_OF | RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | \
 700                             RFLAGS_PF | RFLAGS_CF)
 701#define RFLAGS_MASK_LAHF    (RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | \
 702                             RFLAGS_CF)
 703#define RFLAGS_MASK_CF      (RFLAGS_CF)
 704#define RFLAGS_MASK_IF      (RFLAGS_IF)
 705#define RFLAGS_MASK_TF      (RFLAGS_TF)
 706#define RFLAGS_MASK_DF      (RFLAGS_DF)
 707#define RFLAGS_MASK_ZF      (RFLAGS_ZF)
 708
 709struct decode_tbl _1op_inst[] = {
 710    {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
 711     NULL, NULL, RFLAGS_MASK_OSZAPC},
 712    {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
 713     NULL, NULL, RFLAGS_MASK_OSZAPC},
 714    {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
 715     NULL, NULL, RFLAGS_MASK_OSZAPC},
 716    {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL,
 717     NULL, NULL, RFLAGS_MASK_OSZAPC},
 718    {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL,
 719     NULL, RFLAGS_MASK_OSZAPC},
 720    {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL,
 721     NULL, RFLAGS_MASK_OSZAPC},
 722    {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL,
 723     decode_pushseg, RFLAGS_MASK_NONE},
 724    {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL,
 725     decode_popseg, RFLAGS_MASK_NONE},
 726    {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
 727     NULL, NULL, RFLAGS_MASK_OSZAPC},
 728    {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL,
 729     NULL, NULL, RFLAGS_MASK_OSZAPC},
 730    {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL,
 731     NULL, NULL, RFLAGS_MASK_OSZAPC},
 732    {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm,
 733     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 734    {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8,
 735     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 736    {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm,
 737     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 738
 739    {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
 740     NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
 741    {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false,
 742     NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
 743
 744    {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg,
 745     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 746    {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg,
 747     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 748    {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm,
 749     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 750    {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm,
 751     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 752    {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm,
 753     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 754    {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm,
 755     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 756
 757    {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
 758     NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
 759    {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false,
 760     NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
 761
 762    {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg,
 763     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 764    {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg,
 765     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 766    {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm,
 767     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 768    {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm,
 769     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 770    {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8,
 771     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 772    {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm,
 773     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 774
 775    {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
 776     NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
 777    {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false,
 778     NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
 779
 780    {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg,
 781     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 782    {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg,
 783     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 784    {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm,
 785     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 786    {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm,
 787     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 788    {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm,
 789     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 790    {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm,
 791     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 792    {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg,
 793     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 794    {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg,
 795     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 796    {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm,
 797     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 798    {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm,
 799     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 800    {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm,
 801     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 802    {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm,
 803     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 804    {0x2f, X86_DECODE_CMD_DAS, 0, false,
 805     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 806    {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg,
 807     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 808    {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg,
 809     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 810    {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm,
 811     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 812    {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm,
 813     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 814    {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm,
 815     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 816    {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm,
 817     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 818
 819    {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg,
 820     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 821    {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg,
 822     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 823    {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm,
 824     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 825    {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm,
 826     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 827    {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8,
 828     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 829    {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm,
 830     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 831
 832    {0x3f, X86_DECODE_CMD_AAS, 0, false,
 833     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 834
 835    {0x40, X86_DECODE_CMD_INC, 0, false,
 836     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 837    {0x41, X86_DECODE_CMD_INC, 0, false,
 838     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 839    {0x42, X86_DECODE_CMD_INC, 0, false,
 840     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 841    {0x43, X86_DECODE_CMD_INC, 0, false,
 842     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 843    {0x44, X86_DECODE_CMD_INC, 0, false,
 844     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 845    {0x45, X86_DECODE_CMD_INC, 0, false,
 846     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 847    {0x46, X86_DECODE_CMD_INC, 0, false,
 848     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 849    {0x47, X86_DECODE_CMD_INC, 0, false,
 850     NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC},
 851
 852    {0x48, X86_DECODE_CMD_DEC, 0, false,
 853     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 854    {0x49, X86_DECODE_CMD_DEC, 0, false,
 855     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 856    {0x4a, X86_DECODE_CMD_DEC, 0, false,
 857     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 858    {0x4b, X86_DECODE_CMD_DEC, 0, false,
 859     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 860    {0x4c, X86_DECODE_CMD_DEC, 0, false,
 861     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 862    {0x4d, X86_DECODE_CMD_DEC, 0, false,
 863     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 864    {0x4e, X86_DECODE_CMD_DEC, 0, false,
 865     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 866    {0x4f, X86_DECODE_CMD_DEC, 0, false,
 867     NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC},
 868
 869    {0x50, X86_DECODE_CMD_PUSH, 0, false,
 870     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 871    {0x51, X86_DECODE_CMD_PUSH, 0, false,
 872     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 873    {0x52, X86_DECODE_CMD_PUSH, 0, false,
 874     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 875    {0x53, X86_DECODE_CMD_PUSH, 0, false,
 876     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 877    {0x54, X86_DECODE_CMD_PUSH, 0, false,
 878     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 879    {0x55, X86_DECODE_CMD_PUSH, 0, false,
 880     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 881    {0x56, X86_DECODE_CMD_PUSH, 0, false,
 882     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 883    {0x57, X86_DECODE_CMD_PUSH, 0, false,
 884     NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE},
 885
 886    {0x58, X86_DECODE_CMD_POP, 0, false,
 887     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 888    {0x59, X86_DECODE_CMD_POP, 0, false,
 889     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 890    {0x5a, X86_DECODE_CMD_POP, 0, false,
 891     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 892    {0x5b, X86_DECODE_CMD_POP, 0, false,
 893     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 894    {0x5c, X86_DECODE_CMD_POP, 0, false,
 895     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 896    {0x5d, X86_DECODE_CMD_POP, 0, false,
 897     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 898    {0x5e, X86_DECODE_CMD_POP, 0, false,
 899     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 900    {0x5f, X86_DECODE_CMD_POP, 0, false,
 901     NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE},
 902
 903    {0x60, X86_DECODE_CMD_PUSHA, 0, false,
 904     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 905    {0x61, X86_DECODE_CMD_POPA, 0, false,
 906     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 907
 908    {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm,
 909     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 910    {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed,
 911     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 912    {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg,
 913     decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC},
 914    {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm,
 915     decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC},
 916
 917    {0x6c, X86_DECODE_CMD_INS, 1, false,
 918     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 919    {0x6d, X86_DECODE_CMD_INS, 0, false,
 920     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 921    {0x6e, X86_DECODE_CMD_OUTS, 1, false,
 922     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 923    {0x6f, X86_DECODE_CMD_OUTS, 0, false,
 924     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 925
 926    {0x70, X86_DECODE_CMD_JXX, 1, false,
 927     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 928    {0x71, X86_DECODE_CMD_JXX, 1, false,
 929     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 930    {0x72, X86_DECODE_CMD_JXX, 1, false,
 931     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 932    {0x73, X86_DECODE_CMD_JXX, 1, false,
 933     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 934    {0x74, X86_DECODE_CMD_JXX, 1, false,
 935     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 936    {0x75, X86_DECODE_CMD_JXX, 1, false,
 937     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 938    {0x76, X86_DECODE_CMD_JXX, 1, false,
 939     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 940    {0x77, X86_DECODE_CMD_JXX, 1, false,
 941     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 942    {0x78, X86_DECODE_CMD_JXX, 1, false,
 943     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 944    {0x79, X86_DECODE_CMD_JXX, 1, false,
 945     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 946    {0x7a, X86_DECODE_CMD_JXX, 1, false,
 947     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 948    {0x7b, X86_DECODE_CMD_JXX, 1, false,
 949     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 950    {0x7c, X86_DECODE_CMD_JXX, 1, false,
 951     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 952    {0x7d, X86_DECODE_CMD_JXX, 1, false,
 953     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 954    {0x7e, X86_DECODE_CMD_JXX, 1, false,
 955     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 956    {0x7f, X86_DECODE_CMD_JXX, 1, false,
 957     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
 958
 959    {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
 960     NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
 961    {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm,
 962     NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
 963    {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
 964     NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
 965    {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed,
 966     NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC},
 967    {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg,
 968     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 969    {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg,
 970     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
 971    {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm,
 972     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 973    {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm,
 974     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 975    {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg,
 976     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 977    {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg,
 978     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 979    {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm,
 980     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 981    {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm,
 982     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 983    {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm,
 984     decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 985    {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm,
 986     NULL, NULL, NULL, RFLAGS_MASK_NONE},
 987    {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg,
 988     decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 989    {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm,
 990     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 991
 992    {0x90, X86_DECODE_CMD_NOP, 0, false,
 993     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
 994    {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
 995     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
 996    {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
 997     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
 998    {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
 999     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1000    {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1001     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1002    {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1003     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1004    {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1005     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1006    {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax,
1007     NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE},
1008
1009    {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL,
1010     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1011    {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL,
1012     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1013
1014    {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL,
1015     NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
1016
1017    {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL,
1018     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1019    /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL,
1020     NULL, NULL, NULL, RFLAGS_MASK_POPF},*/
1021    {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL,
1022     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1023    {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL,
1024     NULL, NULL, NULL, RFLAGS_MASK_LAHF},
1025
1026    {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs,
1027     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1028    {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs,
1029     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1030    {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax,
1031     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1032    {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax,
1033     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1034
1035    {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL,
1036     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1037    {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL,
1038     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1039    {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL,
1040     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1041    {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL,
1042     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1043    {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL,
1044     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1045    {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL,
1046     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1047    {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL,
1048     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1049    {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL,
1050     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1051    {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL,
1052     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1053    {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL,
1054     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1055
1056    {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm,
1057     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1058    {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm,
1059     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1060
1061    {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL,
1062     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1063    {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL,
1064     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1065    {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL,
1066     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1067    {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL,
1068     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1069    {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL,
1070     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1071    {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL,
1072     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1073    {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL,
1074     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1075    {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL,
1076     NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE},
1077
1078    {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL,
1079     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1080    {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL,
1081     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1082    {0xba, X86_DECODE_CMD_MOV, 0, false, NULL,
1083     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1084    {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL,
1085     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1086    {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL,
1087     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1088    {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL,
1089     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1090    {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL,
1091     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1092    {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL,
1093     NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE},
1094
1095    {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8,
1096     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1097    {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1098     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1099
1100    {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16,
1101     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1102    {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL,
1103     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1104
1105    {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm,
1106     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1107    {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm,
1108     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1109
1110    {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8,
1111     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1112    {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm,
1113     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1114
1115    {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8,
1116     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1117    {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL,
1118     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1119    {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL,
1120     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1121    {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL,
1122     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1123    {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL,
1124     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1125    /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL,
1126     NULL, NULL, NULL, RFLAGS_MASK_IRET},*/
1127
1128    {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1,
1129     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1130    {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1,
1131     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1132    {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx,
1133     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1134    {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx,
1135     NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC},
1136
1137    {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8,
1138     NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1139    {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8,
1140     NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1141
1142    {0xd7, X86_DECODE_CMD_XLAT, 0, false,
1143     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1144
1145    {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL,
1146     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1147    {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL,
1148     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1149    {0xda, X86_DECODE_CMD_INVL, 0, true, NULL,
1150     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1151    {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL,
1152     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1153    {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL,
1154     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1155    {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL,
1156     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1157    {0xde, X86_DECODE_CMD_INVL, 0, true, NULL,
1158     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1159    {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL,
1160     NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE},
1161
1162    {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1163     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1164    {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1165     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1166    {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed,
1167     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1168
1169    {0xe3, X86_DECODE_CMD_JCXZ, 1, false,
1170     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1171
1172    {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8,
1173     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1174    {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8,
1175     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1176    {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8,
1177     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1178    {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8,
1179     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1180    {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed,
1181     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1182    {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed,
1183     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1184    {0xea, X86_DECODE_CMD_JMP_FAR, 0, false,
1185     NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE},
1186    {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed,
1187     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1188    {0xec, X86_DECODE_CMD_IN, 1, false,
1189     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1190    {0xed, X86_DECODE_CMD_IN, 0, false,
1191     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1192    {0xee, X86_DECODE_CMD_OUT, 1, false,
1193     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1194    {0xef, X86_DECODE_CMD_OUT, 0, false,
1195     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1196
1197    {0xf4, X86_DECODE_CMD_HLT, 0, false,
1198     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1199
1200    {0xf5, X86_DECODE_CMD_CMC, 0, false,
1201     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1202
1203    {0xf6, X86_DECODE_CMD_INVL, 1, true,
1204     NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
1205    {0xf7, X86_DECODE_CMD_INVL, 0, true,
1206     NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC},
1207
1208    {0xf8, X86_DECODE_CMD_CLC, 0, false,
1209     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1210    {0xf9, X86_DECODE_CMD_STC, 0, false,
1211     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF},
1212
1213    {0xfa, X86_DECODE_CMD_CLI, 0, false,
1214     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
1215    {0xfb, X86_DECODE_CMD_STI, 0, false,
1216     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF},
1217    {0xfc, X86_DECODE_CMD_CLD, 0, false,
1218     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
1219    {0xfd, X86_DECODE_CMD_STD, 0, false,
1220     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF},
1221    {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm,
1222     NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC},
1223    {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1224     NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC},
1225};
1226
1227struct decode_tbl _2op_inst[] = {
1228    {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1229     NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE},
1230    {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1231     NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE},
1232    {0x6, X86_DECODE_CMD_CLTS, 0, false,
1233     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF},
1234    {0x9, X86_DECODE_CMD_WBINVD, 0, false,
1235     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1236    {0x18, X86_DECODE_CMD_PREFETCH, 0, true,
1237     NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
1238    {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm,
1239     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1240    {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm,
1241     decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1242    {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm,
1243     decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1244    {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg,
1245     decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1246    {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg,
1247     decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1248    {0x30, X86_DECODE_CMD_WRMSR, 0, false,
1249     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1250    {0x31, X86_DECODE_CMD_RDTSC, 0, false,
1251     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1252    {0x32, X86_DECODE_CMD_RDMSR, 0, false,
1253     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1254    {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1255     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1256    {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1257     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1258    {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1259     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1260    {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1261     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1262    {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1263     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1264    {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1265     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1266    {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1267     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1268    {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1269     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1270    {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1271     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1272    {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1273     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1274    {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1275     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1276    {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1277     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1278    {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1279     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1280    {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1281     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1282    {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1283     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1284    {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm,
1285     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1286    {0x77, X86_DECODE_CMD_EMMS, 0, false,
1287     NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE},
1288    {0x82, X86_DECODE_CMD_JXX, 0, false,
1289     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1290    {0x83, X86_DECODE_CMD_JXX, 0, false,
1291     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1292    {0x84, X86_DECODE_CMD_JXX, 0, false,
1293     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1294    {0x85, X86_DECODE_CMD_JXX, 0, false,
1295     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1296    {0x86, X86_DECODE_CMD_JXX, 0, false,
1297     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1298    {0x87, X86_DECODE_CMD_JXX, 0, false,
1299     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1300    {0x88, X86_DECODE_CMD_JXX, 0, false,
1301     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1302    {0x89, X86_DECODE_CMD_JXX, 0, false,
1303     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1304    {0x8a, X86_DECODE_CMD_JXX, 0, false,
1305     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1306    {0x8b, X86_DECODE_CMD_JXX, 0, false,
1307     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1308    {0x8c, X86_DECODE_CMD_JXX, 0, false,
1309     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1310    {0x8d, X86_DECODE_CMD_JXX, 0, false,
1311     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1312    {0x8e, X86_DECODE_CMD_JXX, 0, false,
1313     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1314    {0x8f, X86_DECODE_CMD_JXX, 0, false,
1315     NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE},
1316    {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1317     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1318    {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1319     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1320    {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1321     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1322    {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1323     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1324    {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1325     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1326    {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1327     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1328    {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1329     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1330    {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1331     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1332    {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1333     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1334    {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1335     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1336    {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1337     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1338    {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1339     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1340    {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1341     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1342    {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1343     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1344    {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1345     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1346    {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm,
1347     NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1348
1349    {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg,
1350     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1351    {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg,
1352     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1353
1354    {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1355     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1356    {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm,
1357     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1358    {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm,
1359     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1360    {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1361     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1362    {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm,
1363     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1364    {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1365     NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
1366    {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false,
1367     NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
1368    {0xa2, X86_DECODE_CMD_CPUID, 0, false,
1369     NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE},
1370    {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg,
1371     NULL, NULL, NULL, RFLAGS_MASK_CF},
1372    {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1373     decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
1374    {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg,
1375     decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
1376    {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false,
1377     NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE},
1378    {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false,
1379     NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE},
1380    {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg,
1381     NULL, NULL, NULL, RFLAGS_MASK_CF},
1382    {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1383     decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC},
1384    {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg,
1385     decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC},
1386
1387    {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm,
1388     NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE},
1389
1390    {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm,
1391     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1392    {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm,
1393     NULL, NULL, NULL, RFLAGS_MASK_NONE},
1394    {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg,
1395     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1396    {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8,
1397     NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC},
1398    {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg,
1399     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1400    {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm,
1401     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1402    {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm,
1403     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1404
1405    {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg,
1406     NULL, NULL, NULL, RFLAGS_MASK_OSZAPC},
1407
1408    {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm,
1409     NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF},
1410
1411    {0xc8, X86_DECODE_CMD_BSWAP, 0, false,
1412     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1413    {0xc9, X86_DECODE_CMD_BSWAP, 0, false,
1414     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1415    {0xca, X86_DECODE_CMD_BSWAP, 0, false,
1416     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1417    {0xcb, X86_DECODE_CMD_BSWAP, 0, false,
1418     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1419    {0xcc, X86_DECODE_CMD_BSWAP, 0, false,
1420     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1421    {0xcd, X86_DECODE_CMD_BSWAP, 0, false,
1422     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1423    {0xce, X86_DECODE_CMD_BSWAP, 0, false,
1424     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1425    {0xcf, X86_DECODE_CMD_BSWAP, 0, false,
1426     NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE},
1427};
1428
1429struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL,
1430                                       NULL, decode_invalid, 0};
1431
1432struct decode_x87_tbl _x87_inst[] = {
1433    {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1434     decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1435    {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1436     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1437    {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0,
1438     decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1439    {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1440     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1441    {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0,
1442     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1443    {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1444     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1445    {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0,
1446     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1447    {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1448     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1449    {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0,
1450     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1451    {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1452     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1453    {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0,
1454     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1455    {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1456     decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1457
1458    {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false,
1459     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1460    {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1461     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1462    {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0,
1463     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1464    {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false,
1465     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1466    {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false,
1467     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1468    {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1469     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1470    {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false,
1471     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1472    {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1473     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1474    {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false,
1475     decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE},
1476    {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false,
1477     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1478    {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL,
1479     RFLAGS_MASK_NONE},
1480    {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false,
1481     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1482
1483    {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false,
1484     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1485    {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false,
1486     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1487
1488    {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1489     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1490    {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0,
1491     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1492    {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1493     decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1494    {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0,
1495     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1496    {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1497     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1498    {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1499     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1500    {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1501     RFLAGS_MASK_NONE},
1502    {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0,
1503     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1504    {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0,
1505     decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1506    {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0,
1507     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1508    {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1509     RFLAGS_MASK_NONE},
1510    {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0,
1511     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1512    {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1513     RFLAGS_MASK_NONE},
1514    {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0,
1515     decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1516
1517    {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0,
1518     decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1519    {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false,
1520     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1521    {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1522     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1523    {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1524     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1525    {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false,
1526     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1527    {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false,
1528     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1529    {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true,
1530     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1531    {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL,
1532     decode_db_4, RFLAGS_MASK_NONE},
1533    {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL,
1534     RFLAGS_MASK_NONE},
1535    {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false,
1536     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1537    {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false,
1538     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1539    {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true,
1540     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1541
1542    {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false,
1543     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1544    {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false,
1545     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1546    {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false,
1547     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1548    {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false,
1549     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1550    {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false,
1551     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1552    {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false,
1553     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1554    {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false,
1555     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1556    {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false,
1557     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1558    {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false,
1559     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1560    {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false,
1561     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1562    {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false,
1563     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1564    {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false,
1565     decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE},
1566
1567    {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false,
1568     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1569    {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1570     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1571    {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false,
1572     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1573    {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false,
1574     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1575    {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1576     decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE},
1577    {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true,
1578     decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE},
1579    {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false,
1580     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1581    {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false,
1582     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1583    {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true,
1584     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1585    {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false,
1586     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1587    {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false,
1588     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1589
1590    {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true,
1591     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1592    {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false,
1593     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1594    {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true,
1595     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1596    {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false,
1597     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1598    {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true,
1599     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1600    {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false,
1601     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1602    {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true,
1603     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1604    {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false,
1605     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1606    {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true,
1607     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1608    {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false,
1609     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1610    {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true,
1611     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1612    {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false,
1613     decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE},
1614
1615    {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false,
1616     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1617    {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false,
1618     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1619    {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true,
1620     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1621    {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false,
1622     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1623    {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true,
1624     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1625    {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true,
1626     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1627    {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true,
1628     decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE},
1629    {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true,
1630     decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE},
1631    {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false,
1632     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1633    {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true,
1634     decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE},
1635};
1636
1637void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
1638                          struct x86_decode_op *op)
1639{
1640    target_ulong ptr = 0;
1641    X86Seg seg = R_DS;
1642
1643    if (!decode->modrm.mod && 6 == decode->modrm.rm) {
1644        op->ptr = (uint16_t)decode->displacement;
1645        goto calc_addr;
1646    }
1647
1648    if (decode->displacement_size) {
1649        ptr = sign(decode->displacement, decode->displacement_size);
1650    }
1651
1652    switch (decode->modrm.rm) {
1653    case 0:
1654        ptr += BX(env) + SI(env);
1655        break;
1656    case 1:
1657        ptr += BX(env) + DI(env);
1658        break;
1659    case 2:
1660        ptr += BP(env) + SI(env);
1661        seg = R_SS;
1662        break;
1663    case 3:
1664        ptr += BP(env) + DI(env);
1665        seg = R_SS;
1666        break;
1667    case 4:
1668        ptr += SI(env);
1669        break;
1670    case 5:
1671        ptr += DI(env);
1672        break;
1673    case 6:
1674        ptr += BP(env);
1675        seg = R_SS;
1676        break;
1677    case 7:
1678        ptr += BX(env);
1679        break;
1680    }
1681calc_addr:
1682    if (X86_DECODE_CMD_LEA == decode->cmd) {
1683        op->ptr = (uint16_t)ptr;
1684    } else {
1685        op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg);
1686    }
1687}
1688
1689target_ulong get_reg_ref(CPUX86State *env, int reg, int is_extended, int size)
1690{
1691    target_ulong ptr = 0;
1692    int which = 0;
1693
1694    if (is_extended) {
1695        reg |= R_R8;
1696    }
1697
1698
1699    switch (size) {
1700    case 1:
1701        if (is_extended || reg < 4) {
1702            which = 1;
1703            ptr = (target_ulong)&RL(env, reg);
1704        } else {
1705            which = 2;
1706            ptr = (target_ulong)&RH(env, reg - 4);
1707        }
1708        break;
1709    default:
1710        which = 3;
1711        ptr = (target_ulong)&RRX(env, reg);
1712        break;
1713    }
1714    return ptr;
1715}
1716
1717target_ulong get_reg_val(CPUX86State *env, int reg, int is_extended, int size)
1718{
1719    target_ulong val = 0;
1720    memcpy(&val, (void *)get_reg_ref(env, reg, is_extended, size), size);
1721    return val;
1722}
1723
1724static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode,
1725                          X86Seg *sel)
1726{
1727    target_ulong base = 0;
1728    target_ulong scaled_index = 0;
1729    int addr_size = decode->addressing_size;
1730    int base_reg = decode->sib.base;
1731    int index_reg = decode->sib.index;
1732
1733    *sel = R_DS;
1734
1735    if (decode->modrm.mod || base_reg != R_EBP) {
1736        if (decode->rex.b) {
1737            base_reg |= R_R8;
1738        }
1739        if (base_reg == R_ESP || base_reg == R_EBP) {
1740            *sel = R_SS;
1741        }
1742        base = get_reg_val(env, decode->sib.base, decode->rex.b, addr_size);
1743    }
1744
1745    if (decode->rex.x) {
1746        index_reg |= R_R8;
1747    }
1748
1749    if (index_reg != R_ESP) {
1750        scaled_index = get_reg_val(env, index_reg, decode->rex.x, addr_size) <<
1751                                   decode->sib.scale;
1752    }
1753    return base + scaled_index;
1754}
1755
1756void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode,
1757                          struct x86_decode_op *op)
1758{
1759    X86Seg seg = R_DS;
1760    target_ulong ptr = 0;
1761    int addr_size = decode->addressing_size;
1762
1763    if (decode->displacement_size) {
1764        ptr = sign(decode->displacement, decode->displacement_size);
1765    }
1766
1767    if (4 == decode->modrm.rm) {
1768        ptr += get_sib_val(env, decode, &seg);
1769    } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
1770        if (x86_is_long_mode(ENV_GET_CPU(env))) {
1771            ptr += RIP(env) + decode->len;
1772        } else {
1773            ptr = decode->displacement;
1774        }
1775    } else {
1776        if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) {
1777            seg = R_SS;
1778        }
1779        ptr += get_reg_val(env, decode->modrm.rm, decode->rex.b, addr_size);
1780    }
1781
1782    if (X86_DECODE_CMD_LEA == decode->cmd) {
1783        op->ptr = (uint32_t)ptr;
1784    } else {
1785        op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg);
1786    }
1787}
1788
1789void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode,
1790                          struct x86_decode_op *op)
1791{
1792    X86Seg seg = R_DS;
1793    int32_t offset = 0;
1794    int mod = decode->modrm.mod;
1795    int rm = decode->modrm.rm;
1796    target_ulong ptr;
1797    int src = decode->modrm.rm;
1798
1799    if (decode->displacement_size) {
1800        offset = sign(decode->displacement, decode->displacement_size);
1801    }
1802
1803    if (4 == rm) {
1804        ptr = get_sib_val(env, decode, &seg) + offset;
1805    } else if (0 == mod && 5 == rm) {
1806        ptr = RIP(env) + decode->len + (int32_t) offset;
1807    } else {
1808        ptr = get_reg_val(env, src, decode->rex.b, 8) + (int64_t) offset;
1809    }
1810
1811    if (X86_DECODE_CMD_LEA == decode->cmd) {
1812        op->ptr = ptr;
1813    } else {
1814        op->ptr = decode_linear_addr(env, decode, ptr, seg);
1815    }
1816}
1817
1818
1819void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode,
1820                        struct x86_decode_op *op)
1821{
1822    if (3 == decode->modrm.mod) {
1823        op->reg = decode->modrm.reg;
1824        op->type = X86_VAR_REG;
1825        op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.b,
1826                              decode->operand_size);
1827        return;
1828    }
1829
1830    switch (decode->addressing_size) {
1831    case 2:
1832        calc_modrm_operand16(env, decode, op);
1833        break;
1834    case 4:
1835        calc_modrm_operand32(env, decode, op);
1836        break;
1837    case 8:
1838        calc_modrm_operand64(env, decode, op);
1839        break;
1840    default:
1841        VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
1842        break;
1843    }
1844}
1845
1846static void decode_prefix(CPUX86State *env, struct x86_decode *decode)
1847{
1848    while (1) {
1849        uint8_t byte = decode_byte(env, decode);
1850        switch (byte) {
1851        case PREFIX_LOCK:
1852            decode->lock = byte;
1853            break;
1854        case PREFIX_REPN:
1855        case PREFIX_REP:
1856            decode->rep = byte;
1857            break;
1858        case PREFIX_CS_SEG_OVEERIDE:
1859        case PREFIX_SS_SEG_OVEERIDE:
1860        case PREFIX_DS_SEG_OVEERIDE:
1861        case PREFIX_ES_SEG_OVEERIDE:
1862        case PREFIX_FS_SEG_OVEERIDE:
1863        case PREFIX_GS_SEG_OVEERIDE:
1864            decode->segment_override = byte;
1865            break;
1866        case PREFIX_OP_SIZE_OVERRIDE:
1867            decode->op_size_override = byte;
1868            break;
1869        case PREFIX_ADDR_SIZE_OVERRIDE:
1870            decode->addr_size_override = byte;
1871            break;
1872        case PREFIX_REX ... (PREFIX_REX + 0xf):
1873            if (x86_is_long_mode(ENV_GET_CPU(env))) {
1874                decode->rex.rex = byte;
1875                break;
1876            }
1877            /* fall through when not in long mode */
1878        default:
1879            decode->len--;
1880            return;
1881        }
1882    }
1883}
1884
1885void set_addressing_size(CPUX86State *env, struct x86_decode *decode)
1886{
1887    decode->addressing_size = -1;
1888    if (x86_is_real(ENV_GET_CPU(env)) || x86_is_v8086(ENV_GET_CPU(env))) {
1889        if (decode->addr_size_override) {
1890            decode->addressing_size = 4;
1891        } else {
1892            decode->addressing_size = 2;
1893        }
1894    } else if (!x86_is_long_mode(ENV_GET_CPU(env))) {
1895        /* protected */
1896        struct vmx_segment cs;
1897        vmx_read_segment_descriptor(ENV_GET_CPU(env), &cs, R_CS);
1898        /* check db */
1899        if ((cs.ar >> 14) & 1) {
1900            if (decode->addr_size_override) {
1901                decode->addressing_size = 2;
1902            } else {
1903                decode->addressing_size = 4;
1904            }
1905        } else {
1906            if (decode->addr_size_override) {
1907                decode->addressing_size = 4;
1908            } else {
1909                decode->addressing_size = 2;
1910            }
1911        }
1912    } else {
1913        /* long */
1914        if (decode->addr_size_override) {
1915            decode->addressing_size = 4;
1916        } else {
1917            decode->addressing_size = 8;
1918        }
1919    }
1920}
1921
1922void set_operand_size(CPUX86State *env, struct x86_decode *decode)
1923{
1924    decode->operand_size = -1;
1925    if (x86_is_real(ENV_GET_CPU(env)) || x86_is_v8086(ENV_GET_CPU(env))) {
1926        if (decode->op_size_override) {
1927            decode->operand_size = 4;
1928        } else {
1929            decode->operand_size = 2;
1930        }
1931    } else if (!x86_is_long_mode(ENV_GET_CPU(env))) {
1932        /* protected */
1933        struct vmx_segment cs;
1934        vmx_read_segment_descriptor(ENV_GET_CPU(env), &cs, R_CS);
1935        /* check db */
1936        if ((cs.ar >> 14) & 1) {
1937            if (decode->op_size_override) {
1938                decode->operand_size = 2;
1939            } else{
1940                decode->operand_size = 4;
1941            }
1942        } else {
1943            if (decode->op_size_override) {
1944                decode->operand_size = 4;
1945            } else {
1946                decode->operand_size = 2;
1947            }
1948        }
1949    } else {
1950        /* long */
1951        if (decode->op_size_override) {
1952            decode->operand_size = 2;
1953        } else {
1954            decode->operand_size = 4;
1955        }
1956
1957        if (decode->rex.w) {
1958            decode->operand_size = 8;
1959        }
1960    }
1961}
1962
1963static void decode_sib(CPUX86State *env, struct x86_decode *decode)
1964{
1965    if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
1966        (decode->addressing_size != 2)) {
1967        decode->sib.sib = decode_byte(env, decode);
1968        decode->sib_present = true;
1969    }
1970}
1971
1972/* 16 bit modrm */
1973int disp16_tbl[4][8] = {
1974    {0, 0, 0, 0, 0, 0, 2, 0},
1975    {1, 1, 1, 1, 1, 1, 1, 1},
1976    {2, 2, 2, 2, 2, 2, 2, 2},
1977    {0, 0, 0, 0, 0, 0, 0, 0}
1978};
1979
1980/* 32/64-bit modrm */
1981int disp32_tbl[4][8] = {
1982    {0, 0, 0, 0, -1, 4, 0, 0},
1983    {1, 1, 1, 1, 1, 1, 1, 1},
1984    {4, 4, 4, 4, 4, 4, 4, 4},
1985    {0, 0, 0, 0, 0, 0, 0, 0}
1986};
1987
1988static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode)
1989{
1990    int addressing_size = decode->addressing_size;
1991    int mod = decode->modrm.mod;
1992    int rm = decode->modrm.rm;
1993    
1994    decode->displacement_size = 0;
1995    switch (addressing_size) {
1996    case 2:
1997        decode->displacement_size = disp16_tbl[mod][rm];
1998        if (decode->displacement_size) {
1999            decode->displacement = (uint16_t)decode_bytes(env, decode,
2000                                    decode->displacement_size);
2001        }
2002        break;
2003    case 4:
2004    case 8:
2005        if (-1 == disp32_tbl[mod][rm]) {
2006            if (5 == decode->sib.base) {
2007                decode->displacement_size = 4;
2008            }
2009        } else {
2010            decode->displacement_size = disp32_tbl[mod][rm];
2011        }
2012
2013        if (decode->displacement_size) {
2014            decode->displacement = (uint32_t)decode_bytes(env, decode,
2015                                                decode->displacement_size);
2016        }
2017        break;
2018    }
2019}
2020
2021static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode)
2022{
2023    decode->modrm.modrm = decode_byte(env, decode);
2024    decode->is_modrm = true;
2025
2026    decode_sib(env, decode);
2027    decode_displacement(env, decode);
2028}
2029
2030static inline void decode_opcode_general(CPUX86State *env,
2031                                         struct x86_decode *decode,
2032                                         uint8_t opcode,
2033                                         struct decode_tbl *inst_decoder)
2034{
2035    decode->cmd = inst_decoder->cmd;
2036    if (inst_decoder->operand_size) {
2037        decode->operand_size = inst_decoder->operand_size;
2038    }
2039    decode->flags_mask = inst_decoder->flags_mask;
2040
2041    if (inst_decoder->is_modrm) {
2042        decode_modrm(env, decode);
2043    }
2044    if (inst_decoder->decode_op1) {
2045        inst_decoder->decode_op1(env, decode, &decode->op[0]);
2046    }
2047    if (inst_decoder->decode_op2) {
2048        inst_decoder->decode_op2(env, decode, &decode->op[1]);
2049    }
2050    if (inst_decoder->decode_op3) {
2051        inst_decoder->decode_op3(env, decode, &decode->op[2]);
2052    }
2053    if (inst_decoder->decode_op4) {
2054        inst_decoder->decode_op4(env, decode, &decode->op[3]);
2055    }
2056    if (inst_decoder->decode_postfix) {
2057        inst_decoder->decode_postfix(env, decode);
2058    }
2059}
2060
2061static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode,
2062                                   uint8_t opcode)
2063{
2064    struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
2065    decode_opcode_general(env, decode, opcode, inst_decoder);
2066}
2067
2068
2069static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode,
2070                                   uint8_t opcode)
2071{
2072    struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
2073    decode_opcode_general(env, decode, opcode, inst_decoder);
2074}
2075
2076static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
2077{
2078    uint8_t opcode;
2079
2080    opcode = decode_byte(env, decode);
2081    decode->opcode[decode->opcode_len++] = opcode;
2082    if (opcode != OPCODE_ESCAPE) {
2083        decode_opcode_1(env, decode, opcode);
2084    } else {
2085        opcode = decode_byte(env, decode);
2086        decode->opcode[decode->opcode_len++] = opcode;
2087        decode_opcode_2(env, decode, opcode);
2088    }
2089}
2090
2091uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
2092{
2093    memset(decode, 0, sizeof(*decode));
2094    decode_prefix(env, decode);
2095    set_addressing_size(env, decode);
2096    set_operand_size(env, decode);
2097
2098    decode_opcodes(env, decode);
2099
2100    return decode->len;
2101}
2102
2103void init_decoder()
2104{
2105    int i;
2106    
2107    for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
2108        memcpy(_decode_tbl1, &invl_inst, sizeof(invl_inst));
2109    }
2110    for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
2111        memcpy(_decode_tbl2, &invl_inst, sizeof(invl_inst));
2112    }
2113    for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
2114        memcpy(_decode_tbl3, &invl_inst, sizeof(invl_inst_x87));
2115    
2116    }
2117    for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
2118        _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
2119    }
2120    for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) {
2121        _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i];
2122    }
2123    for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) {
2124        int index = ((_x87_inst[i].opcode & 0xf) << 4) |
2125                    ((_x87_inst[i].modrm_mod & 1) << 3) |
2126                    _x87_inst[i].modrm_reg;
2127        _decode_tbl3[index] = _x87_inst[i];
2128    }
2129}
2130
2131
2132const char *decode_cmd_to_string(enum x86_decode_cmd cmd)
2133{
2134    static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG",
2135        "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT",
2136        "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD",
2137        "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST",
2138        "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR",
2139        "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG",
2140        "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN",
2141        "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW",
2142        "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR",
2143        "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR",
2144        "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL",
2145        "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS",
2146        "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT",
2147        "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA",
2148        "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT",
2149        "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES",
2150        "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT",
2151        "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW",
2152        "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV",
2153        "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE",
2154        "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW",
2155        "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"};
2156    return cmds[cmd];
2157}
2158
2159target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode,
2160                               target_ulong addr, X86Seg seg)
2161{
2162    switch (decode->segment_override) {
2163    case PREFIX_CS_SEG_OVEERIDE:
2164        seg = R_CS;
2165        break;
2166    case PREFIX_SS_SEG_OVEERIDE:
2167        seg = R_SS;
2168        break;
2169    case PREFIX_DS_SEG_OVEERIDE:
2170        seg = R_DS;
2171        break;
2172    case PREFIX_ES_SEG_OVEERIDE:
2173        seg = R_ES;
2174        break;
2175    case PREFIX_FS_SEG_OVEERIDE:
2176        seg = R_FS;
2177        break;
2178    case PREFIX_GS_SEG_OVEERIDE:
2179        seg = R_GS;
2180        break;
2181    default:
2182        break;
2183    }
2184    return linear_addr_size(ENV_GET_CPU(env), addr, decode->addressing_size, seg);
2185}
2186