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