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