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