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, 0}; 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 RFLAGS_MASK_NONE}, 1461 {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false, 1462 decode_x87_modrm_bytep, NULL, NULL}, 1463 1464 {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false, 1465 decode_x87_modrm_bytep, NULL, NULL}, 1466 {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false, 1467 decode_x87_modrm_bytep, NULL, NULL}, 1468 1469 {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, 1470 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1471 {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, 1472 decode_x87_modrm_intp, NULL}, 1473 {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, 1474 decode_decode_x87_modrm_st0, NULL}, 1475 {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, 1476 decode_x87_modrm_intp, NULL}, 1477 {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, 1478 decode_x87_modrm_st0, NULL}, 1479 {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, 1480 decode_x87_modrm_st0, NULL}, 1481 {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, 1482 RFLAGS_MASK_NONE}, 1483 {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, 1484 decode_x87_modrm_intp, NULL}, 1485 {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0, 1486 decode_decode_x87_modrm_st0, NULL}, 1487 {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, 1488 decode_x87_modrm_intp, NULL}, 1489 {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, 1490 RFLAGS_MASK_NONE}, 1491 {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, 1492 decode_x87_modrm_intp, NULL}, 1493 {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, 1494 RFLAGS_MASK_NONE}, 1495 {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, 1496 decode_x87_modrm_intp, NULL}, 1497 1498 {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, 1499 decode_x87_modrm_st0, NULL}, 1500 {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, 1501 decode_x87_modrm_intp, NULL, NULL}, 1502 {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, 1503 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1504 {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, 1505 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1506 {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false, 1507 decode_x87_modrm_intp, NULL, NULL}, 1508 {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, 1509 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1510 {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true, 1511 decode_x87_modrm_intp, NULL, NULL}, 1512 {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, 1513 decode_db_4}, 1514 {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, 1515 RFLAGS_MASK_NONE}, 1516 {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false, 1517 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1518 {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false, 1519 decode_x87_modrm_floatp, NULL, NULL}, 1520 {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true, 1521 decode_x87_modrm_floatp, NULL, NULL}, 1522 1523 {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, 1524 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1525 {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false, 1526 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1527 {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, 1528 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1529 {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false, 1530 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1531 {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false, 1532 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1533 {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false, 1534 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1535 {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false, 1536 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1537 {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false, 1538 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1539 {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false, 1540 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1541 {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false, 1542 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1543 {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false, 1544 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1545 {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false, 1546 decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, 1547 1548 {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false, 1549 decode_x87_modrm_floatp, NULL, NULL}, 1550 {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, 1551 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1552 {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false, 1553 decode_x87_modrm_st0, NULL, NULL}, 1554 {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false, 1555 decode_x87_modrm_floatp, NULL, NULL}, 1556 {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true, 1557 decode_x87_modrm_st0, NULL, NULL}, 1558 {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true, 1559 decode_x87_modrm_floatp, NULL, NULL}, 1560 {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false, 1561 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1562 {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false, 1563 decode_x87_modrm_bytep, NULL, NULL}, 1564 {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, 1565 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1566 {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false, 1567 decode_x87_modrm_bytep, NULL, NULL}, 1568 {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false, 1569 decode_x87_modrm_bytep, NULL, NULL}, 1570 1571 {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true, 1572 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1573 {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false, 1574 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1575 {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true, 1576 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1577 {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false, 1578 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1579 {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true, 1580 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1581 {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false, 1582 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1583 {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true, 1584 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1585 {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false, 1586 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1587 {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true, 1588 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1589 {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false, 1590 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1591 {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true, 1592 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1593 {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false, 1594 decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, 1595 1596 {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false, 1597 decode_x87_modrm_intp, NULL, NULL}, 1598 {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, 1599 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1600 {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true, 1601 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1602 {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false, 1603 decode_x87_modrm_intp, NULL, NULL}, 1604 {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true, 1605 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1606 {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true, 1607 decode_x87_modrm_intp, NULL, NULL}, 1608 {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true, 1609 decode_x87_modrm_bytep, NULL, NULL}, 1610 {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true, 1611 decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, 1612 {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false, 1613 decode_x87_modrm_intp, NULL, NULL}, 1614 {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true, 1615 decode_x87_modrm_intp, NULL, NULL}, 1616 }; 1617 1618 void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, 1619 struct x86_decode_op *op) 1620 { 1621 target_ulong ptr = 0; 1622 X86Seg seg = R_DS; 1623 1624 if (!decode->modrm.mod && 6 == decode->modrm.rm) { 1625 ptr = decode->displacement; 1626 goto calc_addr; 1627 } 1628 1629 if (decode->displacement_size) { 1630 ptr = sign(decode->displacement, decode->displacement_size); 1631 } 1632 1633 switch (decode->modrm.rm) { 1634 case 0: 1635 ptr += BX(env) + SI(env); 1636 break; 1637 case 1: 1638 ptr += BX(env) + DI(env); 1639 break; 1640 case 2: 1641 ptr += BP(env) + SI(env); 1642 seg = R_SS; 1643 break; 1644 case 3: 1645 ptr += BP(env) + DI(env); 1646 seg = R_SS; 1647 break; 1648 case 4: 1649 ptr += SI(env); 1650 break; 1651 case 5: 1652 ptr += DI(env); 1653 break; 1654 case 6: 1655 ptr += BP(env); 1656 seg = R_SS; 1657 break; 1658 case 7: 1659 ptr += BX(env); 1660 break; 1661 } 1662 calc_addr: 1663 if (X86_DECODE_CMD_LEA == decode->cmd) { 1664 op->ptr = (uint16_t)ptr; 1665 } else { 1666 op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg); 1667 } 1668 } 1669 1670 target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, 1671 int is_extended, int size) 1672 { 1673 target_ulong ptr = 0; 1674 1675 if (is_extended) { 1676 reg |= R_R8; 1677 } 1678 1679 switch (size) { 1680 case 1: 1681 if (is_extended || reg < 4 || rex_present) { 1682 ptr = (target_ulong)&RL(env, reg); 1683 } else { 1684 ptr = (target_ulong)&RH(env, reg - 4); 1685 } 1686 break; 1687 default: 1688 ptr = (target_ulong)&RRX(env, reg); 1689 break; 1690 } 1691 return ptr; 1692 } 1693 1694 target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present, 1695 int is_extended, int size) 1696 { 1697 target_ulong val = 0; 1698 memcpy(&val, 1699 (void *)get_reg_ref(env, reg, rex_present, is_extended, size), 1700 size); 1701 return val; 1702 } 1703 1704 static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode, 1705 X86Seg *sel) 1706 { 1707 target_ulong base = 0; 1708 target_ulong scaled_index = 0; 1709 int addr_size = decode->addressing_size; 1710 int base_reg = decode->sib.base; 1711 int index_reg = decode->sib.index; 1712 1713 *sel = R_DS; 1714 1715 if (decode->modrm.mod || base_reg != R_EBP) { 1716 if (decode->rex.b) { 1717 base_reg |= R_R8; 1718 } 1719 if (base_reg == R_ESP || base_reg == R_EBP) { 1720 *sel = R_SS; 1721 } 1722 base = get_reg_val(env, decode->sib.base, decode->rex.rex, 1723 decode->rex.b, addr_size); 1724 } 1725 1726 if (decode->rex.x) { 1727 index_reg |= R_R8; 1728 } 1729 1730 if (index_reg != R_ESP) { 1731 scaled_index = get_reg_val(env, index_reg, decode->rex.rex, 1732 decode->rex.x, addr_size) << 1733 decode->sib.scale; 1734 } 1735 return base + scaled_index; 1736 } 1737 1738 void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode, 1739 struct x86_decode_op *op) 1740 { 1741 X86Seg seg = R_DS; 1742 target_ulong ptr = 0; 1743 int addr_size = decode->addressing_size; 1744 1745 if (decode->displacement_size) { 1746 ptr = sign(decode->displacement, decode->displacement_size); 1747 } 1748 1749 if (4 == decode->modrm.rm) { 1750 ptr += get_sib_val(env, decode, &seg); 1751 } else if (!decode->modrm.mod && 5 == decode->modrm.rm) { 1752 if (x86_is_long_mode(env_cpu(env))) { 1753 ptr += env->eip + decode->len; 1754 } else { 1755 ptr = decode->displacement; 1756 } 1757 } else { 1758 if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) { 1759 seg = R_SS; 1760 } 1761 ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex, 1762 decode->rex.b, addr_size); 1763 } 1764 1765 if (X86_DECODE_CMD_LEA == decode->cmd) { 1766 op->ptr = (uint32_t)ptr; 1767 } else { 1768 op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg); 1769 } 1770 } 1771 1772 void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode, 1773 struct x86_decode_op *op) 1774 { 1775 X86Seg seg = R_DS; 1776 int32_t offset = 0; 1777 int mod = decode->modrm.mod; 1778 int rm = decode->modrm.rm; 1779 target_ulong ptr; 1780 int src = decode->modrm.rm; 1781 1782 if (decode->displacement_size) { 1783 offset = sign(decode->displacement, decode->displacement_size); 1784 } 1785 1786 if (4 == rm) { 1787 ptr = get_sib_val(env, decode, &seg) + offset; 1788 } else if (0 == mod && 5 == rm) { 1789 ptr = env->eip + decode->len + (int32_t) offset; 1790 } else { 1791 ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) + 1792 (int64_t) offset; 1793 } 1794 1795 if (X86_DECODE_CMD_LEA == decode->cmd) { 1796 op->ptr = ptr; 1797 } else { 1798 op->ptr = decode_linear_addr(env, decode, ptr, seg); 1799 } 1800 } 1801 1802 1803 void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode, 1804 struct x86_decode_op *op) 1805 { 1806 if (3 == decode->modrm.mod) { 1807 op->reg = decode->modrm.reg; 1808 op->type = X86_VAR_REG; 1809 op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex, 1810 decode->rex.b, decode->operand_size); 1811 return; 1812 } 1813 1814 switch (decode->addressing_size) { 1815 case 2: 1816 calc_modrm_operand16(env, decode, op); 1817 break; 1818 case 4: 1819 calc_modrm_operand32(env, decode, op); 1820 break; 1821 case 8: 1822 calc_modrm_operand64(env, decode, op); 1823 break; 1824 default: 1825 VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size); 1826 break; 1827 } 1828 } 1829 1830 static void decode_prefix(CPUX86State *env, struct x86_decode *decode) 1831 { 1832 while (1) { 1833 /* 1834 * REX prefix must come after legacy prefixes. 1835 * REX before legacy is ignored. 1836 * Clear rex to simulate this. 1837 */ 1838 uint8_t byte = decode_byte(env, decode); 1839 switch (byte) { 1840 case PREFIX_LOCK: 1841 decode->lock = byte; 1842 decode->rex.rex = 0; 1843 break; 1844 case PREFIX_REPN: 1845 case PREFIX_REP: 1846 decode->rep = byte; 1847 decode->rex.rex = 0; 1848 break; 1849 case PREFIX_CS_SEG_OVERRIDE: 1850 case PREFIX_SS_SEG_OVERRIDE: 1851 case PREFIX_DS_SEG_OVERRIDE: 1852 case PREFIX_ES_SEG_OVERRIDE: 1853 case PREFIX_FS_SEG_OVERRIDE: 1854 case PREFIX_GS_SEG_OVERRIDE: 1855 decode->segment_override = byte; 1856 decode->rex.rex = 0; 1857 break; 1858 case PREFIX_OP_SIZE_OVERRIDE: 1859 decode->op_size_override = byte; 1860 decode->rex.rex = 0; 1861 break; 1862 case PREFIX_ADDR_SIZE_OVERRIDE: 1863 decode->addr_size_override = byte; 1864 decode->rex.rex = 0; 1865 break; 1866 case PREFIX_REX ... (PREFIX_REX + 0xf): 1867 if (x86_is_long_mode(env_cpu(env))) { 1868 decode->rex.rex = byte; 1869 break; 1870 } 1871 /* fall through when not in long mode */ 1872 default: 1873 decode->len--; 1874 return; 1875 } 1876 } 1877 } 1878 1879 void set_addressing_size(CPUX86State *env, struct x86_decode *decode) 1880 { 1881 decode->addressing_size = -1; 1882 if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) { 1883 if (decode->addr_size_override) { 1884 decode->addressing_size = 4; 1885 } else { 1886 decode->addressing_size = 2; 1887 } 1888 } else if (!x86_is_long_mode(env_cpu(env))) { 1889 /* protected */ 1890 x86_segment_descriptor cs; 1891 emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS); 1892 /* check db */ 1893 if (cs.db) { 1894 if (decode->addr_size_override) { 1895 decode->addressing_size = 2; 1896 } else { 1897 decode->addressing_size = 4; 1898 } 1899 } else { 1900 if (decode->addr_size_override) { 1901 decode->addressing_size = 4; 1902 } else { 1903 decode->addressing_size = 2; 1904 } 1905 } 1906 } else { 1907 /* long */ 1908 if (decode->addr_size_override) { 1909 decode->addressing_size = 4; 1910 } else { 1911 decode->addressing_size = 8; 1912 } 1913 } 1914 } 1915 1916 void set_operand_size(CPUX86State *env, struct x86_decode *decode) 1917 { 1918 decode->operand_size = -1; 1919 if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) { 1920 if (decode->op_size_override) { 1921 decode->operand_size = 4; 1922 } else { 1923 decode->operand_size = 2; 1924 } 1925 } else if (!x86_is_long_mode(env_cpu(env))) { 1926 /* protected */ 1927 x86_segment_descriptor cs; 1928 emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS); 1929 /* check db */ 1930 if (cs.db) { 1931 if (decode->op_size_override) { 1932 decode->operand_size = 2; 1933 } else{ 1934 decode->operand_size = 4; 1935 } 1936 } else { 1937 if (decode->op_size_override) { 1938 decode->operand_size = 4; 1939 } else { 1940 decode->operand_size = 2; 1941 } 1942 } 1943 } else { 1944 /* long */ 1945 if (decode->op_size_override) { 1946 decode->operand_size = 2; 1947 } else { 1948 decode->operand_size = 4; 1949 } 1950 1951 if (decode->rex.w) { 1952 decode->operand_size = 8; 1953 } 1954 } 1955 } 1956 1957 static void decode_sib(CPUX86State *env, struct x86_decode *decode) 1958 { 1959 if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) && 1960 (decode->addressing_size != 2)) { 1961 decode->sib.sib = decode_byte(env, decode); 1962 decode->sib_present = true; 1963 } 1964 } 1965 1966 /* 16 bit modrm */ 1967 int disp16_tbl[4][8] = { 1968 {0, 0, 0, 0, 0, 0, 2, 0}, 1969 {1, 1, 1, 1, 1, 1, 1, 1}, 1970 {2, 2, 2, 2, 2, 2, 2, 2}, 1971 {0, 0, 0, 0, 0, 0, 0, 0} 1972 }; 1973 1974 /* 32/64-bit modrm */ 1975 int disp32_tbl[4][8] = { 1976 {0, 0, 0, 0, -1, 4, 0, 0}, 1977 {1, 1, 1, 1, 1, 1, 1, 1}, 1978 {4, 4, 4, 4, 4, 4, 4, 4}, 1979 {0, 0, 0, 0, 0, 0, 0, 0} 1980 }; 1981 1982 static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode) 1983 { 1984 int addressing_size = decode->addressing_size; 1985 int mod = decode->modrm.mod; 1986 int rm = decode->modrm.rm; 1987 1988 decode->displacement_size = 0; 1989 switch (addressing_size) { 1990 case 2: 1991 decode->displacement_size = disp16_tbl[mod][rm]; 1992 if (decode->displacement_size) { 1993 decode->displacement = (uint16_t)decode_bytes(env, decode, 1994 decode->displacement_size); 1995 } 1996 break; 1997 case 4: 1998 case 8: 1999 if (-1 == disp32_tbl[mod][rm]) { 2000 if (5 == decode->sib.base) { 2001 decode->displacement_size = 4; 2002 } 2003 } else { 2004 decode->displacement_size = disp32_tbl[mod][rm]; 2005 } 2006 2007 if (decode->displacement_size) { 2008 decode->displacement = (uint32_t)decode_bytes(env, decode, 2009 decode->displacement_size); 2010 } 2011 break; 2012 } 2013 } 2014 2015 static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode) 2016 { 2017 decode->modrm.modrm = decode_byte(env, decode); 2018 decode->is_modrm = true; 2019 2020 decode_sib(env, decode); 2021 decode_displacement(env, decode); 2022 } 2023 2024 static inline void decode_opcode_general(CPUX86State *env, 2025 struct x86_decode *decode, 2026 uint8_t opcode, 2027 struct decode_tbl *inst_decoder) 2028 { 2029 decode->cmd = inst_decoder->cmd; 2030 if (inst_decoder->operand_size) { 2031 decode->operand_size = inst_decoder->operand_size; 2032 } 2033 2034 if (inst_decoder->is_modrm) { 2035 decode_modrm(env, decode); 2036 } 2037 if (inst_decoder->decode_op1) { 2038 inst_decoder->decode_op1(env, decode, &decode->op[0]); 2039 } 2040 if (inst_decoder->decode_op2) { 2041 inst_decoder->decode_op2(env, decode, &decode->op[1]); 2042 } 2043 if (inst_decoder->decode_op3) { 2044 inst_decoder->decode_op3(env, decode, &decode->op[2]); 2045 } 2046 if (inst_decoder->decode_op4) { 2047 inst_decoder->decode_op4(env, decode, &decode->op[3]); 2048 } 2049 if (inst_decoder->decode_postfix) { 2050 inst_decoder->decode_postfix(env, decode); 2051 } 2052 } 2053 2054 static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode, 2055 uint8_t opcode) 2056 { 2057 struct decode_tbl *inst_decoder = &_decode_tbl1[opcode]; 2058 decode_opcode_general(env, decode, opcode, inst_decoder); 2059 } 2060 2061 2062 static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode, 2063 uint8_t opcode) 2064 { 2065 struct decode_tbl *inst_decoder = &_decode_tbl2[opcode]; 2066 decode_opcode_general(env, decode, opcode, inst_decoder); 2067 } 2068 2069 static void decode_opcodes(CPUX86State *env, struct x86_decode *decode) 2070 { 2071 uint8_t opcode; 2072 2073 opcode = decode_byte(env, decode); 2074 decode->opcode[decode->opcode_len++] = opcode; 2075 if (opcode != OPCODE_ESCAPE) { 2076 decode_opcode_1(env, decode, opcode); 2077 } else { 2078 opcode = decode_byte(env, decode); 2079 decode->opcode[decode->opcode_len++] = opcode; 2080 decode_opcode_2(env, decode, opcode); 2081 } 2082 } 2083 2084 uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode) 2085 { 2086 memset(decode, 0, sizeof(*decode)); 2087 decode_prefix(env, decode); 2088 set_addressing_size(env, decode); 2089 set_operand_size(env, decode); 2090 2091 decode_opcodes(env, decode); 2092 2093 return decode->len; 2094 } 2095 2096 void init_decoder(void) 2097 { 2098 int i; 2099 2100 for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) { 2101 memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst)); 2102 } 2103 for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) { 2104 memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst)); 2105 } 2106 for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) { 2107 memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87)); 2108 2109 } 2110 for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) { 2111 _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i]; 2112 } 2113 for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) { 2114 _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i]; 2115 } 2116 for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) { 2117 int index = ((_x87_inst[i].opcode & 0xf) << 4) | 2118 ((_x87_inst[i].modrm_mod & 1) << 3) | 2119 _x87_inst[i].modrm_reg; 2120 _decode_tbl3[index] = _x87_inst[i]; 2121 } 2122 } 2123 2124 2125 const char *decode_cmd_to_string(enum x86_decode_cmd cmd) 2126 { 2127 static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG", 2128 "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT", 2129 "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD", 2130 "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST", 2131 "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR", 2132 "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG", 2133 "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN", 2134 "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW", 2135 "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR", 2136 "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR", 2137 "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL", 2138 "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS", 2139 "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT", 2140 "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA", 2141 "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT", 2142 "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES", 2143 "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT", 2144 "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW", 2145 "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV", 2146 "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE", 2147 "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW", 2148 "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"}; 2149 return cmds[cmd]; 2150 } 2151 2152 target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode, 2153 target_ulong addr, X86Seg seg) 2154 { 2155 switch (decode->segment_override) { 2156 case PREFIX_CS_SEG_OVERRIDE: 2157 seg = R_CS; 2158 break; 2159 case PREFIX_SS_SEG_OVERRIDE: 2160 seg = R_SS; 2161 break; 2162 case PREFIX_DS_SEG_OVERRIDE: 2163 seg = R_DS; 2164 break; 2165 case PREFIX_ES_SEG_OVERRIDE: 2166 seg = R_ES; 2167 break; 2168 case PREFIX_FS_SEG_OVERRIDE: 2169 seg = R_FS; 2170 break; 2171 case PREFIX_GS_SEG_OVERRIDE: 2172 seg = R_GS; 2173 break; 2174 default: 2175 break; 2176 } 2177 return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg); 2178 } 2179