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