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