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