1 /**************************************************************************** 2 * 3 * Realmode X86 Emulator Library 4 * 5 * Copyright (C) 1996-1999 SciTech Software, Inc. 6 * Copyright (C) David Mosberger-Tang 7 * Copyright (C) 1999 Egbert Eich 8 * 9 * ======================================================================== 10 * 11 * Permission to use, copy, modify, distribute, and sell this software and 12 * its documentation for any purpose is hereby granted without fee, 13 * provided that the above copyright notice appear in all copies and that 14 * both that copyright notice and this permission notice appear in 15 * supporting documentation, and that the name of the authors not be used 16 * in advertising or publicity pertaining to distribution of the software 17 * without specific, written prior permission. The authors makes no 18 * representations about the suitability of this software for any purpose. 19 * It is provided "as is" without express or implied warranty. 20 * 21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 27 * PERFORMANCE OF THIS SOFTWARE. 28 * 29 * ======================================================================== 30 * 31 * Language: ANSI C 32 * Environment: Any 33 * Developer: Kendall Bennett 34 * 35 * Description: This file includes subroutines to implement the decoding 36 * and emulation of all the x86 extended two-byte processor 37 * instructions. 38 * 39 ****************************************************************************/ 40 41 #include "x86emu/x86emui.h" 42 43 #undef bswap_32 44 #define bswap_32(x) (((x & 0xff000000) >> 24) | \ 45 ((x & 0x00ff0000) >> 8) | \ 46 ((x & 0x0000ff00) << 8) | \ 47 ((x & 0x000000ff) << 24)) 48 49 /*----------------------------- Implementation ----------------------------*/ 50 51 /**************************************************************************** 52 PARAMETERS: 53 op1 - Instruction op code 54 55 REMARKS: 56 Handles illegal opcodes. 57 ****************************************************************************/ 58 static void 59 x86emuOp2_illegal_op(u8 op2) 60 { 61 START_OF_INSTR(); 62 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 63 TRACE_REGS(); 64 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", 65 M.x86.R_CS, M.x86.R_IP - 2, op2); 66 HALT_SYS(); 67 END_OF_INSTR(); 68 } 69 70 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) 71 72 /**************************************************************************** 73 REMARKS: 74 Handles opcode 0x0f,0x31 75 ****************************************************************************/ 76 static void 77 x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2)) 78 { 79 #ifdef __HAS_LONG_LONG__ 80 static u64 counter = 0; 81 #else 82 static u32 counter = 0; 83 #endif 84 85 counter += 0x10000; 86 87 /* read timestamp counter */ 88 /* 89 * Note that instead of actually trying to accurately measure this, we just 90 * increase the counter by a fixed amount every time we hit one of these 91 * instructions. Feel free to come up with a better method. 92 */ 93 START_OF_INSTR(); 94 DECODE_PRINTF("RDTSC\n"); 95 TRACE_AND_STEP(); 96 #ifdef __HAS_LONG_LONG__ 97 M.x86.R_EAX = counter & 0xffffffff; 98 M.x86.R_EDX = counter >> 32; 99 #else 100 M.x86.R_EAX = counter; 101 M.x86.R_EDX = 0; 102 #endif 103 DECODE_CLEAR_SEGOVR(); 104 END_OF_INSTR(); 105 } 106 107 /**************************************************************************** 108 REMARKS: 109 Handles opcode 0x0f,0x80-0x8F 110 ****************************************************************************/ 111 static void 112 x86emuOp2_long_jump(u8 op2) 113 { 114 s32 target; 115 const char *name = NULL; 116 int cond = 0; 117 118 /* conditional jump to word offset. */ 119 START_OF_INSTR(); 120 switch (op2) { 121 case 0x80: 122 name = "JO\t"; 123 cond = ACCESS_FLAG(F_OF); 124 break; 125 case 0x81: 126 name = "JNO\t"; 127 cond = !ACCESS_FLAG(F_OF); 128 break; 129 case 0x82: 130 name = "JB\t"; 131 cond = ACCESS_FLAG(F_CF); 132 break; 133 case 0x83: 134 name = "JNB\t"; 135 cond = !ACCESS_FLAG(F_CF); 136 break; 137 case 0x84: 138 name = "JZ\t"; 139 cond = ACCESS_FLAG(F_ZF); 140 break; 141 case 0x85: 142 name = "JNZ\t"; 143 cond = !ACCESS_FLAG(F_ZF); 144 break; 145 case 0x86: 146 name = "JBE\t"; 147 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 148 break; 149 case 0x87: 150 name = "JNBE\t"; 151 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 152 break; 153 case 0x88: 154 name = "JS\t"; 155 cond = ACCESS_FLAG(F_SF); 156 break; 157 case 0x89: 158 name = "JNS\t"; 159 cond = !ACCESS_FLAG(F_SF); 160 break; 161 case 0x8a: 162 name = "JP\t"; 163 cond = ACCESS_FLAG(F_PF); 164 break; 165 case 0x8b: 166 name = "JNP\t"; 167 cond = !ACCESS_FLAG(F_PF); 168 break; 169 case 0x8c: 170 name = "JL\t"; 171 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 172 break; 173 case 0x8d: 174 name = "JNL\t"; 175 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); 176 break; 177 case 0x8e: 178 name = "JLE\t"; 179 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 180 ACCESS_FLAG(F_ZF)); 181 break; 182 case 0x8f: 183 name = "JNLE\t"; 184 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 185 ACCESS_FLAG(F_ZF)); 186 break; 187 } 188 DECODE_PRINTF(name); 189 (void) name; 190 target = (s16) fetch_word_imm(); 191 target += (s16) M.x86.R_IP; 192 DECODE_PRINTF2("%04x\n", target); 193 TRACE_AND_STEP(); 194 if (cond) 195 M.x86.R_IP = (u16) target; 196 DECODE_CLEAR_SEGOVR(); 197 END_OF_INSTR(); 198 } 199 200 /**************************************************************************** 201 REMARKS: 202 Handles opcode 0x0f,0x90-0x9F 203 ****************************************************************************/ 204 static void 205 x86emuOp2_set_byte(u8 op2) 206 { 207 int mod, rl, rh; 208 uint destoffset; 209 u8 *destreg; 210 const char *name = NULL; 211 int cond = 0; 212 213 START_OF_INSTR(); 214 switch (op2) { 215 case 0x90: 216 name = "SETO\t"; 217 cond = ACCESS_FLAG(F_OF); 218 break; 219 case 0x91: 220 name = "SETNO\t"; 221 cond = !ACCESS_FLAG(F_OF); 222 break; 223 case 0x92: 224 name = "SETB\t"; 225 cond = ACCESS_FLAG(F_CF); 226 break; 227 case 0x93: 228 name = "SETNB\t"; 229 cond = !ACCESS_FLAG(F_CF); 230 break; 231 case 0x94: 232 name = "SETZ\t"; 233 cond = ACCESS_FLAG(F_ZF); 234 break; 235 case 0x95: 236 name = "SETNZ\t"; 237 cond = !ACCESS_FLAG(F_ZF); 238 break; 239 case 0x96: 240 name = "SETBE\t"; 241 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 242 break; 243 case 0x97: 244 name = "SETNBE\t"; 245 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 246 break; 247 case 0x98: 248 name = "SETS\t"; 249 cond = ACCESS_FLAG(F_SF); 250 break; 251 case 0x99: 252 name = "SETNS\t"; 253 cond = !ACCESS_FLAG(F_SF); 254 break; 255 case 0x9a: 256 name = "SETP\t"; 257 cond = ACCESS_FLAG(F_PF); 258 break; 259 case 0x9b: 260 name = "SETNP\t"; 261 cond = !ACCESS_FLAG(F_PF); 262 break; 263 case 0x9c: 264 name = "SETL\t"; 265 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 266 break; 267 case 0x9d: 268 name = "SETNL\t"; 269 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 270 break; 271 case 0x9e: 272 name = "SETLE\t"; 273 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 274 ACCESS_FLAG(F_ZF)); 275 break; 276 case 0x9f: 277 name = "SETNLE\t"; 278 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 279 ACCESS_FLAG(F_ZF)); 280 break; 281 } 282 DECODE_PRINTF(name); 283 (void) name; 284 FETCH_DECODE_MODRM(mod, rh, rl); 285 switch (mod) { 286 case 0: 287 destoffset = decode_rm00_address(rl); 288 TRACE_AND_STEP(); 289 store_data_byte(destoffset, cond ? 0x01 : 0x00); 290 break; 291 case 1: 292 destoffset = decode_rm01_address(rl); 293 TRACE_AND_STEP(); 294 store_data_byte(destoffset, cond ? 0x01 : 0x00); 295 break; 296 case 2: 297 destoffset = decode_rm10_address(rl); 298 TRACE_AND_STEP(); 299 store_data_byte(destoffset, cond ? 0x01 : 0x00); 300 break; 301 case 3: /* register to register */ 302 destreg = DECODE_RM_BYTE_REGISTER(rl); 303 TRACE_AND_STEP(); 304 *destreg = cond ? 0x01 : 0x00; 305 break; 306 } 307 DECODE_CLEAR_SEGOVR(); 308 END_OF_INSTR(); 309 } 310 311 /**************************************************************************** 312 REMARKS: 313 Handles opcode 0x0f,0xa0 314 ****************************************************************************/ 315 static void 316 x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)) 317 { 318 START_OF_INSTR(); 319 DECODE_PRINTF("PUSH\tFS\n"); 320 TRACE_AND_STEP(); 321 push_word(M.x86.R_FS); 322 DECODE_CLEAR_SEGOVR(); 323 END_OF_INSTR(); 324 } 325 326 /**************************************************************************** 327 REMARKS: 328 Handles opcode 0x0f,0xa1 329 ****************************************************************************/ 330 static void 331 x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) 332 { 333 START_OF_INSTR(); 334 DECODE_PRINTF("POP\tFS\n"); 335 TRACE_AND_STEP(); 336 M.x86.R_FS = pop_word(); 337 DECODE_CLEAR_SEGOVR(); 338 END_OF_INSTR(); 339 } 340 341 /**************************************************************************** 342 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output 343 Handles opcode 0x0f,0xa2 344 ****************************************************************************/ 345 static void 346 x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2)) 347 { 348 START_OF_INSTR(); 349 DECODE_PRINTF("CPUID\n"); 350 TRACE_AND_STEP(); 351 cpuid(); 352 DECODE_CLEAR_SEGOVR(); 353 END_OF_INSTR(); 354 } 355 356 /**************************************************************************** 357 REMARKS: 358 Handles opcode 0x0f,0xa3 359 ****************************************************************************/ 360 static void 361 x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)) 362 { 363 int mod, rl, rh; 364 uint srcoffset; 365 int bit, disp; 366 367 START_OF_INSTR(); 368 DECODE_PRINTF("BT\t"); 369 FETCH_DECODE_MODRM(mod, rh, rl); 370 switch (mod) { 371 case 0: 372 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 373 u32 srcval; 374 u32 *shiftreg; 375 376 srcoffset = decode_rm00_address(rl); 377 DECODE_PRINTF(","); 378 shiftreg = DECODE_RM_LONG_REGISTER(rh); 379 TRACE_AND_STEP(); 380 bit = *shiftreg & 0x1F; 381 disp = (s16) * shiftreg >> 5; 382 srcval = fetch_data_long(srcoffset + disp); 383 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 384 } 385 else { 386 u16 srcval; 387 u16 *shiftreg; 388 389 srcoffset = decode_rm00_address(rl); 390 DECODE_PRINTF(","); 391 shiftreg = DECODE_RM_WORD_REGISTER(rh); 392 TRACE_AND_STEP(); 393 bit = *shiftreg & 0xF; 394 disp = (s16) * shiftreg >> 4; 395 srcval = fetch_data_word(srcoffset + disp); 396 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 397 } 398 break; 399 case 1: 400 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 401 u32 srcval; 402 u32 *shiftreg; 403 404 srcoffset = decode_rm01_address(rl); 405 DECODE_PRINTF(","); 406 shiftreg = DECODE_RM_LONG_REGISTER(rh); 407 TRACE_AND_STEP(); 408 bit = *shiftreg & 0x1F; 409 disp = (s16) * shiftreg >> 5; 410 srcval = fetch_data_long(srcoffset + disp); 411 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 412 } 413 else { 414 u16 srcval; 415 u16 *shiftreg; 416 417 srcoffset = decode_rm01_address(rl); 418 DECODE_PRINTF(","); 419 shiftreg = DECODE_RM_WORD_REGISTER(rh); 420 TRACE_AND_STEP(); 421 bit = *shiftreg & 0xF; 422 disp = (s16) * shiftreg >> 4; 423 srcval = fetch_data_word(srcoffset + disp); 424 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 425 } 426 break; 427 case 2: 428 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 429 u32 srcval; 430 u32 *shiftreg; 431 432 srcoffset = decode_rm10_address(rl); 433 DECODE_PRINTF(","); 434 shiftreg = DECODE_RM_LONG_REGISTER(rh); 435 TRACE_AND_STEP(); 436 bit = *shiftreg & 0x1F; 437 disp = (s16) * shiftreg >> 5; 438 srcval = fetch_data_long(srcoffset + disp); 439 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 440 } 441 else { 442 u16 srcval; 443 u16 *shiftreg; 444 445 srcoffset = decode_rm10_address(rl); 446 DECODE_PRINTF(","); 447 shiftreg = DECODE_RM_WORD_REGISTER(rh); 448 TRACE_AND_STEP(); 449 bit = *shiftreg & 0xF; 450 disp = (s16) * shiftreg >> 4; 451 srcval = fetch_data_word(srcoffset + disp); 452 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 453 } 454 break; 455 case 3: /* register to register */ 456 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 457 u32 *srcreg, *shiftreg; 458 459 srcreg = DECODE_RM_LONG_REGISTER(rl); 460 DECODE_PRINTF(","); 461 shiftreg = DECODE_RM_LONG_REGISTER(rh); 462 TRACE_AND_STEP(); 463 bit = *shiftreg & 0x1F; 464 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); 465 } 466 else { 467 u16 *srcreg, *shiftreg; 468 469 srcreg = DECODE_RM_WORD_REGISTER(rl); 470 DECODE_PRINTF(","); 471 shiftreg = DECODE_RM_WORD_REGISTER(rh); 472 TRACE_AND_STEP(); 473 bit = *shiftreg & 0xF; 474 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); 475 } 476 break; 477 } 478 DECODE_CLEAR_SEGOVR(); 479 END_OF_INSTR(); 480 } 481 482 /**************************************************************************** 483 REMARKS: 484 Handles opcode 0x0f,0xa4 485 ****************************************************************************/ 486 static void 487 x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)) 488 { 489 int mod, rl, rh; 490 uint destoffset; 491 u8 shift; 492 493 START_OF_INSTR(); 494 DECODE_PRINTF("SHLD\t"); 495 FETCH_DECODE_MODRM(mod, rh, rl); 496 switch (mod) { 497 case 0: 498 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 499 u32 destval; 500 u32 *shiftreg; 501 502 destoffset = decode_rm00_address(rl); 503 DECODE_PRINTF(","); 504 shiftreg = DECODE_RM_LONG_REGISTER(rh); 505 DECODE_PRINTF(","); 506 shift = fetch_byte_imm(); 507 DECODE_PRINTF2("%d\n", shift); 508 TRACE_AND_STEP(); 509 destval = fetch_data_long(destoffset); 510 destval = shld_long(destval, *shiftreg, shift); 511 store_data_long(destoffset, destval); 512 } 513 else { 514 u16 destval; 515 u16 *shiftreg; 516 517 destoffset = decode_rm00_address(rl); 518 DECODE_PRINTF(","); 519 shiftreg = DECODE_RM_WORD_REGISTER(rh); 520 DECODE_PRINTF(","); 521 shift = fetch_byte_imm(); 522 DECODE_PRINTF2("%d\n", shift); 523 TRACE_AND_STEP(); 524 destval = fetch_data_word(destoffset); 525 destval = shld_word(destval, *shiftreg, shift); 526 store_data_word(destoffset, destval); 527 } 528 break; 529 case 1: 530 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 531 u32 destval; 532 u32 *shiftreg; 533 534 destoffset = decode_rm01_address(rl); 535 DECODE_PRINTF(","); 536 shiftreg = DECODE_RM_LONG_REGISTER(rh); 537 DECODE_PRINTF(","); 538 shift = fetch_byte_imm(); 539 DECODE_PRINTF2("%d\n", shift); 540 TRACE_AND_STEP(); 541 destval = fetch_data_long(destoffset); 542 destval = shld_long(destval, *shiftreg, shift); 543 store_data_long(destoffset, destval); 544 } 545 else { 546 u16 destval; 547 u16 *shiftreg; 548 549 destoffset = decode_rm01_address(rl); 550 DECODE_PRINTF(","); 551 shiftreg = DECODE_RM_WORD_REGISTER(rh); 552 DECODE_PRINTF(","); 553 shift = fetch_byte_imm(); 554 DECODE_PRINTF2("%d\n", shift); 555 TRACE_AND_STEP(); 556 destval = fetch_data_word(destoffset); 557 destval = shld_word(destval, *shiftreg, shift); 558 store_data_word(destoffset, destval); 559 } 560 break; 561 case 2: 562 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 563 u32 destval; 564 u32 *shiftreg; 565 566 destoffset = decode_rm10_address(rl); 567 DECODE_PRINTF(","); 568 shiftreg = DECODE_RM_LONG_REGISTER(rh); 569 DECODE_PRINTF(","); 570 shift = fetch_byte_imm(); 571 DECODE_PRINTF2("%d\n", shift); 572 TRACE_AND_STEP(); 573 destval = fetch_data_long(destoffset); 574 destval = shld_long(destval, *shiftreg, shift); 575 store_data_long(destoffset, destval); 576 } 577 else { 578 u16 destval; 579 u16 *shiftreg; 580 581 destoffset = decode_rm10_address(rl); 582 DECODE_PRINTF(","); 583 shiftreg = DECODE_RM_WORD_REGISTER(rh); 584 DECODE_PRINTF(","); 585 shift = fetch_byte_imm(); 586 DECODE_PRINTF2("%d\n", shift); 587 TRACE_AND_STEP(); 588 destval = fetch_data_word(destoffset); 589 destval = shld_word(destval, *shiftreg, shift); 590 store_data_word(destoffset, destval); 591 } 592 break; 593 case 3: /* register to register */ 594 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 595 u32 *destreg, *shiftreg; 596 597 destreg = DECODE_RM_LONG_REGISTER(rl); 598 DECODE_PRINTF(","); 599 shiftreg = DECODE_RM_LONG_REGISTER(rh); 600 DECODE_PRINTF(","); 601 shift = fetch_byte_imm(); 602 DECODE_PRINTF2("%d\n", shift); 603 TRACE_AND_STEP(); 604 *destreg = shld_long(*destreg, *shiftreg, shift); 605 } 606 else { 607 u16 *destreg, *shiftreg; 608 609 destreg = DECODE_RM_WORD_REGISTER(rl); 610 DECODE_PRINTF(","); 611 shiftreg = DECODE_RM_WORD_REGISTER(rh); 612 DECODE_PRINTF(","); 613 shift = fetch_byte_imm(); 614 DECODE_PRINTF2("%d\n", shift); 615 TRACE_AND_STEP(); 616 *destreg = shld_word(*destreg, *shiftreg, shift); 617 } 618 break; 619 } 620 DECODE_CLEAR_SEGOVR(); 621 END_OF_INSTR(); 622 } 623 624 /**************************************************************************** 625 REMARKS: 626 Handles opcode 0x0f,0xa5 627 ****************************************************************************/ 628 static void 629 x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)) 630 { 631 int mod, rl, rh; 632 uint destoffset; 633 634 START_OF_INSTR(); 635 DECODE_PRINTF("SHLD\t"); 636 FETCH_DECODE_MODRM(mod, rh, rl); 637 switch (mod) { 638 case 0: 639 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 640 u32 destval; 641 u32 *shiftreg; 642 643 destoffset = decode_rm00_address(rl); 644 DECODE_PRINTF(","); 645 shiftreg = DECODE_RM_LONG_REGISTER(rh); 646 DECODE_PRINTF(",CL\n"); 647 TRACE_AND_STEP(); 648 destval = fetch_data_long(destoffset); 649 destval = shld_long(destval, *shiftreg, M.x86.R_CL); 650 store_data_long(destoffset, destval); 651 } 652 else { 653 u16 destval; 654 u16 *shiftreg; 655 656 destoffset = decode_rm00_address(rl); 657 DECODE_PRINTF(","); 658 shiftreg = DECODE_RM_WORD_REGISTER(rh); 659 DECODE_PRINTF(",CL\n"); 660 TRACE_AND_STEP(); 661 destval = fetch_data_word(destoffset); 662 destval = shld_word(destval, *shiftreg, M.x86.R_CL); 663 store_data_word(destoffset, destval); 664 } 665 break; 666 case 1: 667 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 668 u32 destval; 669 u32 *shiftreg; 670 671 destoffset = decode_rm01_address(rl); 672 DECODE_PRINTF(","); 673 shiftreg = DECODE_RM_LONG_REGISTER(rh); 674 DECODE_PRINTF(",CL\n"); 675 TRACE_AND_STEP(); 676 destval = fetch_data_long(destoffset); 677 destval = shld_long(destval, *shiftreg, M.x86.R_CL); 678 store_data_long(destoffset, destval); 679 } 680 else { 681 u16 destval; 682 u16 *shiftreg; 683 684 destoffset = decode_rm01_address(rl); 685 DECODE_PRINTF(","); 686 shiftreg = DECODE_RM_WORD_REGISTER(rh); 687 DECODE_PRINTF(",CL\n"); 688 TRACE_AND_STEP(); 689 destval = fetch_data_word(destoffset); 690 destval = shld_word(destval, *shiftreg, M.x86.R_CL); 691 store_data_word(destoffset, destval); 692 } 693 break; 694 case 2: 695 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 696 u32 destval; 697 u32 *shiftreg; 698 699 destoffset = decode_rm10_address(rl); 700 DECODE_PRINTF(","); 701 shiftreg = DECODE_RM_LONG_REGISTER(rh); 702 DECODE_PRINTF(",CL\n"); 703 TRACE_AND_STEP(); 704 destval = fetch_data_long(destoffset); 705 destval = shld_long(destval, *shiftreg, M.x86.R_CL); 706 store_data_long(destoffset, destval); 707 } 708 else { 709 u16 destval; 710 u16 *shiftreg; 711 712 destoffset = decode_rm10_address(rl); 713 DECODE_PRINTF(","); 714 shiftreg = DECODE_RM_WORD_REGISTER(rh); 715 DECODE_PRINTF(",CL\n"); 716 TRACE_AND_STEP(); 717 destval = fetch_data_word(destoffset); 718 destval = shld_word(destval, *shiftreg, M.x86.R_CL); 719 store_data_word(destoffset, destval); 720 } 721 break; 722 case 3: /* register to register */ 723 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 724 u32 *destreg, *shiftreg; 725 726 destreg = DECODE_RM_LONG_REGISTER(rl); 727 DECODE_PRINTF(","); 728 shiftreg = DECODE_RM_LONG_REGISTER(rh); 729 DECODE_PRINTF(",CL\n"); 730 TRACE_AND_STEP(); 731 *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL); 732 } 733 else { 734 u16 *destreg, *shiftreg; 735 736 destreg = DECODE_RM_WORD_REGISTER(rl); 737 DECODE_PRINTF(","); 738 shiftreg = DECODE_RM_WORD_REGISTER(rh); 739 DECODE_PRINTF(",CL\n"); 740 TRACE_AND_STEP(); 741 *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL); 742 } 743 break; 744 } 745 DECODE_CLEAR_SEGOVR(); 746 END_OF_INSTR(); 747 } 748 749 /**************************************************************************** 750 REMARKS: 751 Handles opcode 0x0f,0xa8 752 ****************************************************************************/ 753 static void 754 x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2)) 755 { 756 START_OF_INSTR(); 757 DECODE_PRINTF("PUSH\tGS\n"); 758 TRACE_AND_STEP(); 759 push_word(M.x86.R_GS); 760 DECODE_CLEAR_SEGOVR(); 761 END_OF_INSTR(); 762 } 763 764 /**************************************************************************** 765 REMARKS: 766 Handles opcode 0x0f,0xa9 767 ****************************************************************************/ 768 static void 769 x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2)) 770 { 771 START_OF_INSTR(); 772 DECODE_PRINTF("POP\tGS\n"); 773 TRACE_AND_STEP(); 774 M.x86.R_GS = pop_word(); 775 DECODE_CLEAR_SEGOVR(); 776 END_OF_INSTR(); 777 } 778 779 /**************************************************************************** 780 REMARKS: 781 Handles opcode 0x0f,0xab 782 ****************************************************************************/ 783 static void 784 x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2)) 785 { 786 int mod, rl, rh; 787 uint srcoffset; 788 int bit, disp; 789 790 START_OF_INSTR(); 791 DECODE_PRINTF("BTS\t"); 792 FETCH_DECODE_MODRM(mod, rh, rl); 793 switch (mod) { 794 case 0: 795 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 796 u32 srcval, mask; 797 u32 *shiftreg; 798 799 srcoffset = decode_rm00_address(rl); 800 DECODE_PRINTF(","); 801 shiftreg = DECODE_RM_LONG_REGISTER(rh); 802 TRACE_AND_STEP(); 803 bit = *shiftreg & 0x1F; 804 disp = (s16) * shiftreg >> 5; 805 srcval = fetch_data_long(srcoffset + disp); 806 mask = (0x1 << bit); 807 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 808 store_data_long(srcoffset + disp, srcval | mask); 809 } 810 else { 811 u16 srcval, mask; 812 u16 *shiftreg; 813 814 srcoffset = decode_rm00_address(rl); 815 DECODE_PRINTF(","); 816 shiftreg = DECODE_RM_WORD_REGISTER(rh); 817 TRACE_AND_STEP(); 818 bit = *shiftreg & 0xF; 819 disp = (s16) * shiftreg >> 4; 820 srcval = fetch_data_word(srcoffset + disp); 821 mask = (u16) (0x1 << bit); 822 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 823 store_data_word(srcoffset + disp, srcval | mask); 824 } 825 break; 826 case 1: 827 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 828 u32 srcval, mask; 829 u32 *shiftreg; 830 831 srcoffset = decode_rm01_address(rl); 832 DECODE_PRINTF(","); 833 shiftreg = DECODE_RM_LONG_REGISTER(rh); 834 TRACE_AND_STEP(); 835 bit = *shiftreg & 0x1F; 836 disp = (s16) * shiftreg >> 5; 837 srcval = fetch_data_long(srcoffset + disp); 838 mask = (0x1 << bit); 839 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 840 store_data_long(srcoffset + disp, srcval | mask); 841 } 842 else { 843 u16 srcval, mask; 844 u16 *shiftreg; 845 846 srcoffset = decode_rm01_address(rl); 847 DECODE_PRINTF(","); 848 shiftreg = DECODE_RM_WORD_REGISTER(rh); 849 TRACE_AND_STEP(); 850 bit = *shiftreg & 0xF; 851 disp = (s16) * shiftreg >> 4; 852 srcval = fetch_data_word(srcoffset + disp); 853 mask = (u16) (0x1 << bit); 854 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 855 store_data_word(srcoffset + disp, srcval | mask); 856 } 857 break; 858 case 2: 859 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 860 u32 srcval, mask; 861 u32 *shiftreg; 862 863 srcoffset = decode_rm10_address(rl); 864 DECODE_PRINTF(","); 865 shiftreg = DECODE_RM_LONG_REGISTER(rh); 866 TRACE_AND_STEP(); 867 bit = *shiftreg & 0x1F; 868 disp = (s16) * shiftreg >> 5; 869 srcval = fetch_data_long(srcoffset + disp); 870 mask = (0x1 << bit); 871 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 872 store_data_long(srcoffset + disp, srcval | mask); 873 } 874 else { 875 u16 srcval, mask; 876 u16 *shiftreg; 877 878 srcoffset = decode_rm10_address(rl); 879 DECODE_PRINTF(","); 880 shiftreg = DECODE_RM_WORD_REGISTER(rh); 881 TRACE_AND_STEP(); 882 bit = *shiftreg & 0xF; 883 disp = (s16) * shiftreg >> 4; 884 srcval = fetch_data_word(srcoffset + disp); 885 mask = (u16) (0x1 << bit); 886 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 887 store_data_word(srcoffset + disp, srcval | mask); 888 } 889 break; 890 case 3: /* register to register */ 891 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 892 u32 *srcreg, *shiftreg; 893 u32 mask; 894 895 srcreg = DECODE_RM_LONG_REGISTER(rl); 896 DECODE_PRINTF(","); 897 shiftreg = DECODE_RM_LONG_REGISTER(rh); 898 TRACE_AND_STEP(); 899 bit = *shiftreg & 0x1F; 900 mask = (0x1 << bit); 901 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 902 *srcreg |= mask; 903 } 904 else { 905 u16 *srcreg, *shiftreg; 906 u16 mask; 907 908 srcreg = DECODE_RM_WORD_REGISTER(rl); 909 DECODE_PRINTF(","); 910 shiftreg = DECODE_RM_WORD_REGISTER(rh); 911 TRACE_AND_STEP(); 912 bit = *shiftreg & 0xF; 913 mask = (u16) (0x1 << bit); 914 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 915 *srcreg |= mask; 916 } 917 break; 918 } 919 DECODE_CLEAR_SEGOVR(); 920 END_OF_INSTR(); 921 } 922 923 /**************************************************************************** 924 REMARKS: 925 Handles opcode 0x0f,0xac 926 ****************************************************************************/ 927 static void 928 x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)) 929 { 930 int mod, rl, rh; 931 uint destoffset; 932 u8 shift; 933 934 START_OF_INSTR(); 935 DECODE_PRINTF("SHLD\t"); 936 FETCH_DECODE_MODRM(mod, rh, rl); 937 switch (mod) { 938 case 0: 939 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 940 u32 destval; 941 u32 *shiftreg; 942 943 destoffset = decode_rm00_address(rl); 944 DECODE_PRINTF(","); 945 shiftreg = DECODE_RM_LONG_REGISTER(rh); 946 DECODE_PRINTF(","); 947 shift = fetch_byte_imm(); 948 DECODE_PRINTF2("%d\n", shift); 949 TRACE_AND_STEP(); 950 destval = fetch_data_long(destoffset); 951 destval = shrd_long(destval, *shiftreg, shift); 952 store_data_long(destoffset, destval); 953 } 954 else { 955 u16 destval; 956 u16 *shiftreg; 957 958 destoffset = decode_rm00_address(rl); 959 DECODE_PRINTF(","); 960 shiftreg = DECODE_RM_WORD_REGISTER(rh); 961 DECODE_PRINTF(","); 962 shift = fetch_byte_imm(); 963 DECODE_PRINTF2("%d\n", shift); 964 TRACE_AND_STEP(); 965 destval = fetch_data_word(destoffset); 966 destval = shrd_word(destval, *shiftreg, shift); 967 store_data_word(destoffset, destval); 968 } 969 break; 970 case 1: 971 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 972 u32 destval; 973 u32 *shiftreg; 974 975 destoffset = decode_rm01_address(rl); 976 DECODE_PRINTF(","); 977 shiftreg = DECODE_RM_LONG_REGISTER(rh); 978 DECODE_PRINTF(","); 979 shift = fetch_byte_imm(); 980 DECODE_PRINTF2("%d\n", shift); 981 TRACE_AND_STEP(); 982 destval = fetch_data_long(destoffset); 983 destval = shrd_long(destval, *shiftreg, shift); 984 store_data_long(destoffset, destval); 985 } 986 else { 987 u16 destval; 988 u16 *shiftreg; 989 990 destoffset = decode_rm01_address(rl); 991 DECODE_PRINTF(","); 992 shiftreg = DECODE_RM_WORD_REGISTER(rh); 993 DECODE_PRINTF(","); 994 shift = fetch_byte_imm(); 995 DECODE_PRINTF2("%d\n", shift); 996 TRACE_AND_STEP(); 997 destval = fetch_data_word(destoffset); 998 destval = shrd_word(destval, *shiftreg, shift); 999 store_data_word(destoffset, destval); 1000 } 1001 break; 1002 case 2: 1003 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1004 u32 destval; 1005 u32 *shiftreg; 1006 1007 destoffset = decode_rm10_address(rl); 1008 DECODE_PRINTF(","); 1009 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1010 DECODE_PRINTF(","); 1011 shift = fetch_byte_imm(); 1012 DECODE_PRINTF2("%d\n", shift); 1013 TRACE_AND_STEP(); 1014 destval = fetch_data_long(destoffset); 1015 destval = shrd_long(destval, *shiftreg, shift); 1016 store_data_long(destoffset, destval); 1017 } 1018 else { 1019 u16 destval; 1020 u16 *shiftreg; 1021 1022 destoffset = decode_rm10_address(rl); 1023 DECODE_PRINTF(","); 1024 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1025 DECODE_PRINTF(","); 1026 shift = fetch_byte_imm(); 1027 DECODE_PRINTF2("%d\n", shift); 1028 TRACE_AND_STEP(); 1029 destval = fetch_data_word(destoffset); 1030 destval = shrd_word(destval, *shiftreg, shift); 1031 store_data_word(destoffset, destval); 1032 } 1033 break; 1034 case 3: /* register to register */ 1035 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1036 u32 *destreg, *shiftreg; 1037 1038 destreg = DECODE_RM_LONG_REGISTER(rl); 1039 DECODE_PRINTF(","); 1040 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1041 DECODE_PRINTF(","); 1042 shift = fetch_byte_imm(); 1043 DECODE_PRINTF2("%d\n", shift); 1044 TRACE_AND_STEP(); 1045 *destreg = shrd_long(*destreg, *shiftreg, shift); 1046 } 1047 else { 1048 u16 *destreg, *shiftreg; 1049 1050 destreg = DECODE_RM_WORD_REGISTER(rl); 1051 DECODE_PRINTF(","); 1052 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1053 DECODE_PRINTF(","); 1054 shift = fetch_byte_imm(); 1055 DECODE_PRINTF2("%d\n", shift); 1056 TRACE_AND_STEP(); 1057 *destreg = shrd_word(*destreg, *shiftreg, shift); 1058 } 1059 break; 1060 } 1061 DECODE_CLEAR_SEGOVR(); 1062 END_OF_INSTR(); 1063 } 1064 1065 /**************************************************************************** 1066 REMARKS: 1067 Handles opcode 0x0f,0xad 1068 ****************************************************************************/ 1069 static void 1070 x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)) 1071 { 1072 int mod, rl, rh; 1073 uint destoffset; 1074 1075 START_OF_INSTR(); 1076 DECODE_PRINTF("SHLD\t"); 1077 FETCH_DECODE_MODRM(mod, rh, rl); 1078 switch (mod) { 1079 case 0: 1080 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1081 u32 destval; 1082 u32 *shiftreg; 1083 1084 destoffset = decode_rm00_address(rl); 1085 DECODE_PRINTF(","); 1086 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1087 DECODE_PRINTF(",CL\n"); 1088 TRACE_AND_STEP(); 1089 destval = fetch_data_long(destoffset); 1090 destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 1091 store_data_long(destoffset, destval); 1092 } 1093 else { 1094 u16 destval; 1095 u16 *shiftreg; 1096 1097 destoffset = decode_rm00_address(rl); 1098 DECODE_PRINTF(","); 1099 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1100 DECODE_PRINTF(",CL\n"); 1101 TRACE_AND_STEP(); 1102 destval = fetch_data_word(destoffset); 1103 destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 1104 store_data_word(destoffset, destval); 1105 } 1106 break; 1107 case 1: 1108 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1109 u32 destval; 1110 u32 *shiftreg; 1111 1112 destoffset = decode_rm01_address(rl); 1113 DECODE_PRINTF(","); 1114 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1115 DECODE_PRINTF(",CL\n"); 1116 TRACE_AND_STEP(); 1117 destval = fetch_data_long(destoffset); 1118 destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 1119 store_data_long(destoffset, destval); 1120 } 1121 else { 1122 u16 destval; 1123 u16 *shiftreg; 1124 1125 destoffset = decode_rm01_address(rl); 1126 DECODE_PRINTF(","); 1127 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1128 DECODE_PRINTF(",CL\n"); 1129 TRACE_AND_STEP(); 1130 destval = fetch_data_word(destoffset); 1131 destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 1132 store_data_word(destoffset, destval); 1133 } 1134 break; 1135 case 2: 1136 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1137 u32 destval; 1138 u32 *shiftreg; 1139 1140 destoffset = decode_rm10_address(rl); 1141 DECODE_PRINTF(","); 1142 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1143 DECODE_PRINTF(",CL\n"); 1144 TRACE_AND_STEP(); 1145 destval = fetch_data_long(destoffset); 1146 destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 1147 store_data_long(destoffset, destval); 1148 } 1149 else { 1150 u16 destval; 1151 u16 *shiftreg; 1152 1153 destoffset = decode_rm10_address(rl); 1154 DECODE_PRINTF(","); 1155 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1156 DECODE_PRINTF(",CL\n"); 1157 TRACE_AND_STEP(); 1158 destval = fetch_data_word(destoffset); 1159 destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 1160 store_data_word(destoffset, destval); 1161 } 1162 break; 1163 case 3: /* register to register */ 1164 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1165 u32 *destreg, *shiftreg; 1166 1167 destreg = DECODE_RM_LONG_REGISTER(rl); 1168 DECODE_PRINTF(","); 1169 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1170 DECODE_PRINTF(",CL\n"); 1171 TRACE_AND_STEP(); 1172 *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL); 1173 } 1174 else { 1175 u16 *destreg, *shiftreg; 1176 1177 destreg = DECODE_RM_WORD_REGISTER(rl); 1178 DECODE_PRINTF(","); 1179 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1180 DECODE_PRINTF(",CL\n"); 1181 TRACE_AND_STEP(); 1182 *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL); 1183 } 1184 break; 1185 } 1186 DECODE_CLEAR_SEGOVR(); 1187 END_OF_INSTR(); 1188 } 1189 1190 /**************************************************************************** 1191 REMARKS: 1192 Handles opcode 0x0f,0xaf 1193 ****************************************************************************/ 1194 static void 1195 x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)) 1196 { 1197 int mod, rl, rh; 1198 uint srcoffset; 1199 1200 START_OF_INSTR(); 1201 DECODE_PRINTF("IMUL\t"); 1202 FETCH_DECODE_MODRM(mod, rh, rl); 1203 switch (mod) { 1204 case 0: 1205 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1206 u32 *destreg; 1207 u32 srcval; 1208 u32 res_lo, res_hi; 1209 1210 destreg = DECODE_RM_LONG_REGISTER(rh); 1211 DECODE_PRINTF(","); 1212 srcoffset = decode_rm00_address(rl); 1213 srcval = fetch_data_long(srcoffset); 1214 TRACE_AND_STEP(); 1215 imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 1216 if (res_hi != 0) { 1217 SET_FLAG(F_CF); 1218 SET_FLAG(F_OF); 1219 } 1220 else { 1221 CLEAR_FLAG(F_CF); 1222 CLEAR_FLAG(F_OF); 1223 } 1224 *destreg = (u32) res_lo; 1225 } 1226 else { 1227 u16 *destreg; 1228 u16 srcval; 1229 u32 res; 1230 1231 destreg = DECODE_RM_WORD_REGISTER(rh); 1232 DECODE_PRINTF(","); 1233 srcoffset = decode_rm00_address(rl); 1234 srcval = fetch_data_word(srcoffset); 1235 TRACE_AND_STEP(); 1236 res = (s16) * destreg * (s16) srcval; 1237 if (res > 0xFFFF) { 1238 SET_FLAG(F_CF); 1239 SET_FLAG(F_OF); 1240 } 1241 else { 1242 CLEAR_FLAG(F_CF); 1243 CLEAR_FLAG(F_OF); 1244 } 1245 *destreg = (u16) res; 1246 } 1247 break; 1248 case 1: 1249 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1250 u32 *destreg; 1251 u32 srcval; 1252 u32 res_lo, res_hi; 1253 1254 destreg = DECODE_RM_LONG_REGISTER(rh); 1255 DECODE_PRINTF(","); 1256 srcoffset = decode_rm01_address(rl); 1257 srcval = fetch_data_long(srcoffset); 1258 TRACE_AND_STEP(); 1259 imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 1260 if (res_hi != 0) { 1261 SET_FLAG(F_CF); 1262 SET_FLAG(F_OF); 1263 } 1264 else { 1265 CLEAR_FLAG(F_CF); 1266 CLEAR_FLAG(F_OF); 1267 } 1268 *destreg = (u32) res_lo; 1269 } 1270 else { 1271 u16 *destreg; 1272 u16 srcval; 1273 u32 res; 1274 1275 destreg = DECODE_RM_WORD_REGISTER(rh); 1276 DECODE_PRINTF(","); 1277 srcoffset = decode_rm01_address(rl); 1278 srcval = fetch_data_word(srcoffset); 1279 TRACE_AND_STEP(); 1280 res = (s16) * destreg * (s16) srcval; 1281 if (res > 0xFFFF) { 1282 SET_FLAG(F_CF); 1283 SET_FLAG(F_OF); 1284 } 1285 else { 1286 CLEAR_FLAG(F_CF); 1287 CLEAR_FLAG(F_OF); 1288 } 1289 *destreg = (u16) res; 1290 } 1291 break; 1292 case 2: 1293 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1294 u32 *destreg; 1295 u32 srcval; 1296 u32 res_lo, res_hi; 1297 1298 destreg = DECODE_RM_LONG_REGISTER(rh); 1299 DECODE_PRINTF(","); 1300 srcoffset = decode_rm10_address(rl); 1301 srcval = fetch_data_long(srcoffset); 1302 TRACE_AND_STEP(); 1303 imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 1304 if (res_hi != 0) { 1305 SET_FLAG(F_CF); 1306 SET_FLAG(F_OF); 1307 } 1308 else { 1309 CLEAR_FLAG(F_CF); 1310 CLEAR_FLAG(F_OF); 1311 } 1312 *destreg = (u32) res_lo; 1313 } 1314 else { 1315 u16 *destreg; 1316 u16 srcval; 1317 u32 res; 1318 1319 destreg = DECODE_RM_WORD_REGISTER(rh); 1320 DECODE_PRINTF(","); 1321 srcoffset = decode_rm10_address(rl); 1322 srcval = fetch_data_word(srcoffset); 1323 TRACE_AND_STEP(); 1324 res = (s16) * destreg * (s16) srcval; 1325 if (res > 0xFFFF) { 1326 SET_FLAG(F_CF); 1327 SET_FLAG(F_OF); 1328 } 1329 else { 1330 CLEAR_FLAG(F_CF); 1331 CLEAR_FLAG(F_OF); 1332 } 1333 *destreg = (u16) res; 1334 } 1335 break; 1336 case 3: /* register to register */ 1337 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1338 u32 *destreg, *srcreg; 1339 u32 res_lo, res_hi; 1340 1341 destreg = DECODE_RM_LONG_REGISTER(rh); 1342 DECODE_PRINTF(","); 1343 srcreg = DECODE_RM_LONG_REGISTER(rl); 1344 TRACE_AND_STEP(); 1345 imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg); 1346 if (res_hi != 0) { 1347 SET_FLAG(F_CF); 1348 SET_FLAG(F_OF); 1349 } 1350 else { 1351 CLEAR_FLAG(F_CF); 1352 CLEAR_FLAG(F_OF); 1353 } 1354 *destreg = (u32) res_lo; 1355 } 1356 else { 1357 u16 *destreg, *srcreg; 1358 u32 res; 1359 1360 destreg = DECODE_RM_WORD_REGISTER(rh); 1361 DECODE_PRINTF(","); 1362 srcreg = DECODE_RM_WORD_REGISTER(rl); 1363 res = (s16) * destreg * (s16) * srcreg; 1364 if (res > 0xFFFF) { 1365 SET_FLAG(F_CF); 1366 SET_FLAG(F_OF); 1367 } 1368 else { 1369 CLEAR_FLAG(F_CF); 1370 CLEAR_FLAG(F_OF); 1371 } 1372 *destreg = (u16) res; 1373 } 1374 break; 1375 } 1376 DECODE_CLEAR_SEGOVR(); 1377 END_OF_INSTR(); 1378 } 1379 1380 /**************************************************************************** 1381 REMARKS: 1382 Handles opcode 0x0f,0xb2 1383 ****************************************************************************/ 1384 static void 1385 x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2)) 1386 { 1387 int mod, rh, rl; 1388 u16 *dstreg; 1389 uint srcoffset; 1390 1391 START_OF_INSTR(); 1392 DECODE_PRINTF("LSS\t"); 1393 FETCH_DECODE_MODRM(mod, rh, rl); 1394 switch (mod) { 1395 case 0: 1396 dstreg = DECODE_RM_WORD_REGISTER(rh); 1397 DECODE_PRINTF(","); 1398 srcoffset = decode_rm00_address(rl); 1399 DECODE_PRINTF("\n"); 1400 TRACE_AND_STEP(); 1401 *dstreg = fetch_data_word(srcoffset); 1402 M.x86.R_SS = fetch_data_word(srcoffset + 2); 1403 break; 1404 case 1: 1405 dstreg = DECODE_RM_WORD_REGISTER(rh); 1406 DECODE_PRINTF(","); 1407 srcoffset = decode_rm01_address(rl); 1408 DECODE_PRINTF("\n"); 1409 TRACE_AND_STEP(); 1410 *dstreg = fetch_data_word(srcoffset); 1411 M.x86.R_SS = fetch_data_word(srcoffset + 2); 1412 break; 1413 case 2: 1414 dstreg = DECODE_RM_WORD_REGISTER(rh); 1415 DECODE_PRINTF(","); 1416 srcoffset = decode_rm10_address(rl); 1417 DECODE_PRINTF("\n"); 1418 TRACE_AND_STEP(); 1419 *dstreg = fetch_data_word(srcoffset); 1420 M.x86.R_SS = fetch_data_word(srcoffset + 2); 1421 break; 1422 case 3: /* register to register */ 1423 /* UNDEFINED! */ 1424 TRACE_AND_STEP(); 1425 } 1426 DECODE_CLEAR_SEGOVR(); 1427 END_OF_INSTR(); 1428 } 1429 1430 /**************************************************************************** 1431 REMARKS: 1432 Handles opcode 0x0f,0xb3 1433 ****************************************************************************/ 1434 static void 1435 x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2)) 1436 { 1437 int mod, rl, rh; 1438 uint srcoffset; 1439 int bit, disp; 1440 1441 START_OF_INSTR(); 1442 DECODE_PRINTF("BTR\t"); 1443 FETCH_DECODE_MODRM(mod, rh, rl); 1444 switch (mod) { 1445 case 0: 1446 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1447 u32 srcval, mask; 1448 u32 *shiftreg; 1449 1450 srcoffset = decode_rm00_address(rl); 1451 DECODE_PRINTF(","); 1452 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1453 TRACE_AND_STEP(); 1454 bit = *shiftreg & 0x1F; 1455 disp = (s16) * shiftreg >> 5; 1456 srcval = fetch_data_long(srcoffset + disp); 1457 mask = (0x1 << bit); 1458 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1459 store_data_long(srcoffset + disp, srcval & ~mask); 1460 } 1461 else { 1462 u16 srcval, mask; 1463 u16 *shiftreg; 1464 1465 srcoffset = decode_rm00_address(rl); 1466 DECODE_PRINTF(","); 1467 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1468 TRACE_AND_STEP(); 1469 bit = *shiftreg & 0xF; 1470 disp = (s16) * shiftreg >> 4; 1471 srcval = fetch_data_word(srcoffset + disp); 1472 mask = (u16) (0x1 << bit); 1473 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1474 store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 1475 } 1476 break; 1477 case 1: 1478 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1479 u32 srcval, mask; 1480 u32 *shiftreg; 1481 1482 srcoffset = decode_rm01_address(rl); 1483 DECODE_PRINTF(","); 1484 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1485 TRACE_AND_STEP(); 1486 bit = *shiftreg & 0x1F; 1487 disp = (s16) * shiftreg >> 5; 1488 srcval = fetch_data_long(srcoffset + disp); 1489 mask = (0x1 << bit); 1490 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1491 store_data_long(srcoffset + disp, srcval & ~mask); 1492 } 1493 else { 1494 u16 srcval, mask; 1495 u16 *shiftreg; 1496 1497 srcoffset = decode_rm01_address(rl); 1498 DECODE_PRINTF(","); 1499 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1500 TRACE_AND_STEP(); 1501 bit = *shiftreg & 0xF; 1502 disp = (s16) * shiftreg >> 4; 1503 srcval = fetch_data_word(srcoffset + disp); 1504 mask = (u16) (0x1 << bit); 1505 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1506 store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 1507 } 1508 break; 1509 case 2: 1510 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1511 u32 srcval, mask; 1512 u32 *shiftreg; 1513 1514 srcoffset = decode_rm10_address(rl); 1515 DECODE_PRINTF(","); 1516 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1517 TRACE_AND_STEP(); 1518 bit = *shiftreg & 0x1F; 1519 disp = (s16) * shiftreg >> 5; 1520 srcval = fetch_data_long(srcoffset + disp); 1521 mask = (0x1 << bit); 1522 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1523 store_data_long(srcoffset + disp, srcval & ~mask); 1524 } 1525 else { 1526 u16 srcval, mask; 1527 u16 *shiftreg; 1528 1529 srcoffset = decode_rm10_address(rl); 1530 DECODE_PRINTF(","); 1531 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1532 TRACE_AND_STEP(); 1533 bit = *shiftreg & 0xF; 1534 disp = (s16) * shiftreg >> 4; 1535 srcval = fetch_data_word(srcoffset + disp); 1536 mask = (u16) (0x1 << bit); 1537 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1538 store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 1539 } 1540 break; 1541 case 3: /* register to register */ 1542 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1543 u32 *srcreg, *shiftreg; 1544 u32 mask; 1545 1546 srcreg = DECODE_RM_LONG_REGISTER(rl); 1547 DECODE_PRINTF(","); 1548 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1549 TRACE_AND_STEP(); 1550 bit = *shiftreg & 0x1F; 1551 mask = (0x1 << bit); 1552 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 1553 *srcreg &= ~mask; 1554 } 1555 else { 1556 u16 *srcreg, *shiftreg; 1557 u16 mask; 1558 1559 srcreg = DECODE_RM_WORD_REGISTER(rl); 1560 DECODE_PRINTF(","); 1561 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1562 TRACE_AND_STEP(); 1563 bit = *shiftreg & 0xF; 1564 mask = (u16) (0x1 << bit); 1565 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 1566 *srcreg &= ~mask; 1567 } 1568 break; 1569 } 1570 DECODE_CLEAR_SEGOVR(); 1571 END_OF_INSTR(); 1572 } 1573 1574 /**************************************************************************** 1575 REMARKS: 1576 Handles opcode 0x0f,0xb4 1577 ****************************************************************************/ 1578 static void 1579 x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2)) 1580 { 1581 int mod, rh, rl; 1582 u16 *dstreg; 1583 uint srcoffset; 1584 1585 START_OF_INSTR(); 1586 DECODE_PRINTF("LFS\t"); 1587 FETCH_DECODE_MODRM(mod, rh, rl); 1588 switch (mod) { 1589 case 0: 1590 dstreg = DECODE_RM_WORD_REGISTER(rh); 1591 DECODE_PRINTF(","); 1592 srcoffset = decode_rm00_address(rl); 1593 DECODE_PRINTF("\n"); 1594 TRACE_AND_STEP(); 1595 *dstreg = fetch_data_word(srcoffset); 1596 M.x86.R_FS = fetch_data_word(srcoffset + 2); 1597 break; 1598 case 1: 1599 dstreg = DECODE_RM_WORD_REGISTER(rh); 1600 DECODE_PRINTF(","); 1601 srcoffset = decode_rm01_address(rl); 1602 DECODE_PRINTF("\n"); 1603 TRACE_AND_STEP(); 1604 *dstreg = fetch_data_word(srcoffset); 1605 M.x86.R_FS = fetch_data_word(srcoffset + 2); 1606 break; 1607 case 2: 1608 dstreg = DECODE_RM_WORD_REGISTER(rh); 1609 DECODE_PRINTF(","); 1610 srcoffset = decode_rm10_address(rl); 1611 DECODE_PRINTF("\n"); 1612 TRACE_AND_STEP(); 1613 *dstreg = fetch_data_word(srcoffset); 1614 M.x86.R_FS = fetch_data_word(srcoffset + 2); 1615 break; 1616 case 3: /* register to register */ 1617 /* UNDEFINED! */ 1618 TRACE_AND_STEP(); 1619 } 1620 DECODE_CLEAR_SEGOVR(); 1621 END_OF_INSTR(); 1622 } 1623 1624 /**************************************************************************** 1625 REMARKS: 1626 Handles opcode 0x0f,0xb5 1627 ****************************************************************************/ 1628 static void 1629 x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2)) 1630 { 1631 int mod, rh, rl; 1632 u16 *dstreg; 1633 uint srcoffset; 1634 1635 START_OF_INSTR(); 1636 DECODE_PRINTF("LGS\t"); 1637 FETCH_DECODE_MODRM(mod, rh, rl); 1638 switch (mod) { 1639 case 0: 1640 dstreg = DECODE_RM_WORD_REGISTER(rh); 1641 DECODE_PRINTF(","); 1642 srcoffset = decode_rm00_address(rl); 1643 DECODE_PRINTF("\n"); 1644 TRACE_AND_STEP(); 1645 *dstreg = fetch_data_word(srcoffset); 1646 M.x86.R_GS = fetch_data_word(srcoffset + 2); 1647 break; 1648 case 1: 1649 dstreg = DECODE_RM_WORD_REGISTER(rh); 1650 DECODE_PRINTF(","); 1651 srcoffset = decode_rm01_address(rl); 1652 DECODE_PRINTF("\n"); 1653 TRACE_AND_STEP(); 1654 *dstreg = fetch_data_word(srcoffset); 1655 M.x86.R_GS = fetch_data_word(srcoffset + 2); 1656 break; 1657 case 2: 1658 dstreg = DECODE_RM_WORD_REGISTER(rh); 1659 DECODE_PRINTF(","); 1660 srcoffset = decode_rm10_address(rl); 1661 DECODE_PRINTF("\n"); 1662 TRACE_AND_STEP(); 1663 *dstreg = fetch_data_word(srcoffset); 1664 M.x86.R_GS = fetch_data_word(srcoffset + 2); 1665 break; 1666 case 3: /* register to register */ 1667 /* UNDEFINED! */ 1668 TRACE_AND_STEP(); 1669 } 1670 DECODE_CLEAR_SEGOVR(); 1671 END_OF_INSTR(); 1672 } 1673 1674 /**************************************************************************** 1675 REMARKS: 1676 Handles opcode 0x0f,0xb6 1677 ****************************************************************************/ 1678 static void 1679 x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 1680 { 1681 int mod, rl, rh; 1682 uint srcoffset; 1683 1684 START_OF_INSTR(); 1685 DECODE_PRINTF("MOVZX\t"); 1686 FETCH_DECODE_MODRM(mod, rh, rl); 1687 switch (mod) { 1688 case 0: 1689 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1690 u32 *destreg; 1691 u32 srcval; 1692 1693 destreg = DECODE_RM_LONG_REGISTER(rh); 1694 DECODE_PRINTF(","); 1695 srcoffset = decode_rm00_address(rl); 1696 srcval = fetch_data_byte(srcoffset); 1697 DECODE_PRINTF("\n"); 1698 TRACE_AND_STEP(); 1699 *destreg = srcval; 1700 } 1701 else { 1702 u16 *destreg; 1703 u16 srcval; 1704 1705 destreg = DECODE_RM_WORD_REGISTER(rh); 1706 DECODE_PRINTF(","); 1707 srcoffset = decode_rm00_address(rl); 1708 srcval = fetch_data_byte(srcoffset); 1709 DECODE_PRINTF("\n"); 1710 TRACE_AND_STEP(); 1711 *destreg = srcval; 1712 } 1713 break; 1714 case 1: 1715 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1716 u32 *destreg; 1717 u32 srcval; 1718 1719 destreg = DECODE_RM_LONG_REGISTER(rh); 1720 DECODE_PRINTF(","); 1721 srcoffset = decode_rm01_address(rl); 1722 srcval = fetch_data_byte(srcoffset); 1723 DECODE_PRINTF("\n"); 1724 TRACE_AND_STEP(); 1725 *destreg = srcval; 1726 } 1727 else { 1728 u16 *destreg; 1729 u16 srcval; 1730 1731 destreg = DECODE_RM_WORD_REGISTER(rh); 1732 DECODE_PRINTF(","); 1733 srcoffset = decode_rm01_address(rl); 1734 srcval = fetch_data_byte(srcoffset); 1735 DECODE_PRINTF("\n"); 1736 TRACE_AND_STEP(); 1737 *destreg = srcval; 1738 } 1739 break; 1740 case 2: 1741 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1742 u32 *destreg; 1743 u32 srcval; 1744 1745 destreg = DECODE_RM_LONG_REGISTER(rh); 1746 DECODE_PRINTF(","); 1747 srcoffset = decode_rm10_address(rl); 1748 srcval = fetch_data_byte(srcoffset); 1749 DECODE_PRINTF("\n"); 1750 TRACE_AND_STEP(); 1751 *destreg = srcval; 1752 } 1753 else { 1754 u16 *destreg; 1755 u16 srcval; 1756 1757 destreg = DECODE_RM_WORD_REGISTER(rh); 1758 DECODE_PRINTF(","); 1759 srcoffset = decode_rm10_address(rl); 1760 srcval = fetch_data_byte(srcoffset); 1761 DECODE_PRINTF("\n"); 1762 TRACE_AND_STEP(); 1763 *destreg = srcval; 1764 } 1765 break; 1766 case 3: /* register to register */ 1767 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1768 u32 *destreg; 1769 u8 *srcreg; 1770 1771 destreg = DECODE_RM_LONG_REGISTER(rh); 1772 DECODE_PRINTF(","); 1773 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1774 DECODE_PRINTF("\n"); 1775 TRACE_AND_STEP(); 1776 *destreg = *srcreg; 1777 } 1778 else { 1779 u16 *destreg; 1780 u8 *srcreg; 1781 1782 destreg = DECODE_RM_WORD_REGISTER(rh); 1783 DECODE_PRINTF(","); 1784 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1785 DECODE_PRINTF("\n"); 1786 TRACE_AND_STEP(); 1787 *destreg = *srcreg; 1788 } 1789 break; 1790 } 1791 DECODE_CLEAR_SEGOVR(); 1792 END_OF_INSTR(); 1793 } 1794 1795 /**************************************************************************** 1796 REMARKS: 1797 Handles opcode 0x0f,0xb7 1798 ****************************************************************************/ 1799 static void 1800 x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2)) 1801 { 1802 int mod, rl, rh; 1803 uint srcoffset; 1804 u32 *destreg; 1805 u32 srcval; 1806 u16 *srcreg; 1807 1808 START_OF_INSTR(); 1809 DECODE_PRINTF("MOVZX\t"); 1810 FETCH_DECODE_MODRM(mod, rh, rl); 1811 switch (mod) { 1812 case 0: 1813 destreg = DECODE_RM_LONG_REGISTER(rh); 1814 DECODE_PRINTF(","); 1815 srcoffset = decode_rm00_address(rl); 1816 srcval = fetch_data_word(srcoffset); 1817 DECODE_PRINTF("\n"); 1818 TRACE_AND_STEP(); 1819 *destreg = srcval; 1820 break; 1821 case 1: 1822 destreg = DECODE_RM_LONG_REGISTER(rh); 1823 DECODE_PRINTF(","); 1824 srcoffset = decode_rm01_address(rl); 1825 srcval = fetch_data_word(srcoffset); 1826 DECODE_PRINTF("\n"); 1827 TRACE_AND_STEP(); 1828 *destreg = srcval; 1829 break; 1830 case 2: 1831 destreg = DECODE_RM_LONG_REGISTER(rh); 1832 DECODE_PRINTF(","); 1833 srcoffset = decode_rm10_address(rl); 1834 srcval = fetch_data_word(srcoffset); 1835 DECODE_PRINTF("\n"); 1836 TRACE_AND_STEP(); 1837 *destreg = srcval; 1838 break; 1839 case 3: /* register to register */ 1840 destreg = DECODE_RM_LONG_REGISTER(rh); 1841 DECODE_PRINTF(","); 1842 srcreg = DECODE_RM_WORD_REGISTER(rl); 1843 DECODE_PRINTF("\n"); 1844 TRACE_AND_STEP(); 1845 *destreg = *srcreg; 1846 break; 1847 } 1848 DECODE_CLEAR_SEGOVR(); 1849 END_OF_INSTR(); 1850 } 1851 1852 /**************************************************************************** 1853 REMARKS: 1854 Handles opcode 0x0f,0xba 1855 ****************************************************************************/ 1856 static void 1857 x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) 1858 { 1859 int mod, rl, rh; 1860 uint srcoffset; 1861 int bit; 1862 1863 START_OF_INSTR(); 1864 FETCH_DECODE_MODRM(mod, rh, rl); 1865 switch (rh) { 1866 case 4: 1867 DECODE_PRINTF("BT\t"); 1868 break; 1869 case 5: 1870 DECODE_PRINTF("BTS\t"); 1871 break; 1872 case 6: 1873 DECODE_PRINTF("BTR\t"); 1874 break; 1875 case 7: 1876 DECODE_PRINTF("BTC\t"); 1877 break; 1878 default: 1879 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 1880 TRACE_REGS(); 1881 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", 1882 M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl); 1883 HALT_SYS(); 1884 } 1885 switch (mod) { 1886 case 0: 1887 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1888 u32 srcval, mask; 1889 u8 shift; 1890 1891 srcoffset = decode_rm00_address(rl); 1892 DECODE_PRINTF(","); 1893 shift = fetch_byte_imm(); 1894 TRACE_AND_STEP(); 1895 bit = shift & 0x1F; 1896 srcval = fetch_data_long(srcoffset); 1897 mask = (0x1 << bit); 1898 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1899 switch (rh) { 1900 case 5: 1901 store_data_long(srcoffset, srcval | mask); 1902 break; 1903 case 6: 1904 store_data_long(srcoffset, srcval & ~mask); 1905 break; 1906 case 7: 1907 store_data_long(srcoffset, srcval ^ mask); 1908 break; 1909 default: 1910 break; 1911 } 1912 } 1913 else { 1914 u16 srcval, mask; 1915 u8 shift; 1916 1917 srcoffset = decode_rm00_address(rl); 1918 DECODE_PRINTF(","); 1919 shift = fetch_byte_imm(); 1920 TRACE_AND_STEP(); 1921 bit = shift & 0xF; 1922 srcval = fetch_data_word(srcoffset); 1923 mask = (0x1 << bit); 1924 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1925 switch (rh) { 1926 case 5: 1927 store_data_word(srcoffset, srcval | mask); 1928 break; 1929 case 6: 1930 store_data_word(srcoffset, srcval & ~mask); 1931 break; 1932 case 7: 1933 store_data_word(srcoffset, srcval ^ mask); 1934 break; 1935 default: 1936 break; 1937 } 1938 } 1939 break; 1940 case 1: 1941 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1942 u32 srcval, mask; 1943 u8 shift; 1944 1945 srcoffset = decode_rm01_address(rl); 1946 DECODE_PRINTF(","); 1947 shift = fetch_byte_imm(); 1948 TRACE_AND_STEP(); 1949 bit = shift & 0x1F; 1950 srcval = fetch_data_long(srcoffset); 1951 mask = (0x1 << bit); 1952 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1953 switch (rh) { 1954 case 5: 1955 store_data_long(srcoffset, srcval | mask); 1956 break; 1957 case 6: 1958 store_data_long(srcoffset, srcval & ~mask); 1959 break; 1960 case 7: 1961 store_data_long(srcoffset, srcval ^ mask); 1962 break; 1963 default: 1964 break; 1965 } 1966 } 1967 else { 1968 u16 srcval, mask; 1969 u8 shift; 1970 1971 srcoffset = decode_rm01_address(rl); 1972 DECODE_PRINTF(","); 1973 shift = fetch_byte_imm(); 1974 TRACE_AND_STEP(); 1975 bit = shift & 0xF; 1976 srcval = fetch_data_word(srcoffset); 1977 mask = (0x1 << bit); 1978 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 1979 switch (rh) { 1980 case 5: 1981 store_data_word(srcoffset, srcval | mask); 1982 break; 1983 case 6: 1984 store_data_word(srcoffset, srcval & ~mask); 1985 break; 1986 case 7: 1987 store_data_word(srcoffset, srcval ^ mask); 1988 break; 1989 default: 1990 break; 1991 } 1992 } 1993 break; 1994 case 2: 1995 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1996 u32 srcval, mask; 1997 u8 shift; 1998 1999 srcoffset = decode_rm10_address(rl); 2000 DECODE_PRINTF(","); 2001 shift = fetch_byte_imm(); 2002 TRACE_AND_STEP(); 2003 bit = shift & 0x1F; 2004 srcval = fetch_data_long(srcoffset); 2005 mask = (0x1 << bit); 2006 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2007 switch (rh) { 2008 case 5: 2009 store_data_long(srcoffset, srcval | mask); 2010 break; 2011 case 6: 2012 store_data_long(srcoffset, srcval & ~mask); 2013 break; 2014 case 7: 2015 store_data_long(srcoffset, srcval ^ mask); 2016 break; 2017 default: 2018 break; 2019 } 2020 } 2021 else { 2022 u16 srcval, mask; 2023 u8 shift; 2024 2025 srcoffset = decode_rm10_address(rl); 2026 DECODE_PRINTF(","); 2027 shift = fetch_byte_imm(); 2028 TRACE_AND_STEP(); 2029 bit = shift & 0xF; 2030 srcval = fetch_data_word(srcoffset); 2031 mask = (0x1 << bit); 2032 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2033 switch (rh) { 2034 case 5: 2035 store_data_word(srcoffset, srcval | mask); 2036 break; 2037 case 6: 2038 store_data_word(srcoffset, srcval & ~mask); 2039 break; 2040 case 7: 2041 store_data_word(srcoffset, srcval ^ mask); 2042 break; 2043 default: 2044 break; 2045 } 2046 } 2047 break; 2048 case 3: /* register to register */ 2049 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2050 u32 *srcreg; 2051 u32 mask; 2052 u8 shift; 2053 2054 srcreg = DECODE_RM_LONG_REGISTER(rl); 2055 DECODE_PRINTF(","); 2056 shift = fetch_byte_imm(); 2057 TRACE_AND_STEP(); 2058 bit = shift & 0x1F; 2059 mask = (0x1 << bit); 2060 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 2061 switch (rh) { 2062 case 5: 2063 *srcreg |= mask; 2064 break; 2065 case 6: 2066 *srcreg &= ~mask; 2067 break; 2068 case 7: 2069 *srcreg ^= mask; 2070 break; 2071 default: 2072 break; 2073 } 2074 } 2075 else { 2076 u16 *srcreg; 2077 u16 mask; 2078 u8 shift; 2079 2080 srcreg = DECODE_RM_WORD_REGISTER(rl); 2081 DECODE_PRINTF(","); 2082 shift = fetch_byte_imm(); 2083 TRACE_AND_STEP(); 2084 bit = shift & 0xF; 2085 mask = (0x1 << bit); 2086 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 2087 switch (rh) { 2088 case 5: 2089 *srcreg |= mask; 2090 break; 2091 case 6: 2092 *srcreg &= ~mask; 2093 break; 2094 case 7: 2095 *srcreg ^= mask; 2096 break; 2097 default: 2098 break; 2099 } 2100 } 2101 break; 2102 } 2103 DECODE_CLEAR_SEGOVR(); 2104 END_OF_INSTR(); 2105 } 2106 2107 /**************************************************************************** 2108 REMARKS: 2109 Handles opcode 0x0f,0xbb 2110 ****************************************************************************/ 2111 static void 2112 x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2)) 2113 { 2114 int mod, rl, rh; 2115 uint srcoffset; 2116 int bit, disp; 2117 2118 START_OF_INSTR(); 2119 DECODE_PRINTF("BTC\t"); 2120 FETCH_DECODE_MODRM(mod, rh, rl); 2121 switch (mod) { 2122 case 0: 2123 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2124 u32 srcval, mask; 2125 u32 *shiftreg; 2126 2127 srcoffset = decode_rm00_address(rl); 2128 DECODE_PRINTF(","); 2129 shiftreg = DECODE_RM_LONG_REGISTER(rh); 2130 TRACE_AND_STEP(); 2131 bit = *shiftreg & 0x1F; 2132 disp = (s16) * shiftreg >> 5; 2133 srcval = fetch_data_long(srcoffset + disp); 2134 mask = (0x1 << bit); 2135 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2136 store_data_long(srcoffset + disp, srcval ^ mask); 2137 } 2138 else { 2139 u16 srcval, mask; 2140 u16 *shiftreg; 2141 2142 srcoffset = decode_rm00_address(rl); 2143 DECODE_PRINTF(","); 2144 shiftreg = DECODE_RM_WORD_REGISTER(rh); 2145 TRACE_AND_STEP(); 2146 bit = *shiftreg & 0xF; 2147 disp = (s16) * shiftreg >> 4; 2148 srcval = fetch_data_word(srcoffset + disp); 2149 mask = (u16) (0x1 << bit); 2150 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2151 store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 2152 } 2153 break; 2154 case 1: 2155 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2156 u32 srcval, mask; 2157 u32 *shiftreg; 2158 2159 srcoffset = decode_rm01_address(rl); 2160 DECODE_PRINTF(","); 2161 shiftreg = DECODE_RM_LONG_REGISTER(rh); 2162 TRACE_AND_STEP(); 2163 bit = *shiftreg & 0x1F; 2164 disp = (s16) * shiftreg >> 5; 2165 srcval = fetch_data_long(srcoffset + disp); 2166 mask = (0x1 << bit); 2167 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2168 store_data_long(srcoffset + disp, srcval ^ mask); 2169 } 2170 else { 2171 u16 srcval, mask; 2172 u16 *shiftreg; 2173 2174 srcoffset = decode_rm01_address(rl); 2175 DECODE_PRINTF(","); 2176 shiftreg = DECODE_RM_WORD_REGISTER(rh); 2177 TRACE_AND_STEP(); 2178 bit = *shiftreg & 0xF; 2179 disp = (s16) * shiftreg >> 4; 2180 srcval = fetch_data_word(srcoffset + disp); 2181 mask = (u16) (0x1 << bit); 2182 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2183 store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 2184 } 2185 break; 2186 case 2: 2187 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2188 u32 srcval, mask; 2189 u32 *shiftreg; 2190 2191 srcoffset = decode_rm10_address(rl); 2192 DECODE_PRINTF(","); 2193 shiftreg = DECODE_RM_LONG_REGISTER(rh); 2194 TRACE_AND_STEP(); 2195 bit = *shiftreg & 0x1F; 2196 disp = (s16) * shiftreg >> 5; 2197 srcval = fetch_data_long(srcoffset + disp); 2198 mask = (0x1 << bit); 2199 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2200 store_data_long(srcoffset + disp, srcval ^ mask); 2201 } 2202 else { 2203 u16 srcval, mask; 2204 u16 *shiftreg; 2205 2206 srcoffset = decode_rm10_address(rl); 2207 DECODE_PRINTF(","); 2208 shiftreg = DECODE_RM_WORD_REGISTER(rh); 2209 TRACE_AND_STEP(); 2210 bit = *shiftreg & 0xF; 2211 disp = (s16) * shiftreg >> 4; 2212 srcval = fetch_data_word(srcoffset + disp); 2213 mask = (u16) (0x1 << bit); 2214 CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 2215 store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 2216 } 2217 break; 2218 case 3: /* register to register */ 2219 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2220 u32 *srcreg, *shiftreg; 2221 u32 mask; 2222 2223 srcreg = DECODE_RM_LONG_REGISTER(rl); 2224 DECODE_PRINTF(","); 2225 shiftreg = DECODE_RM_LONG_REGISTER(rh); 2226 TRACE_AND_STEP(); 2227 bit = *shiftreg & 0x1F; 2228 mask = (0x1 << bit); 2229 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 2230 *srcreg ^= mask; 2231 } 2232 else { 2233 u16 *srcreg, *shiftreg; 2234 u16 mask; 2235 2236 srcreg = DECODE_RM_WORD_REGISTER(rl); 2237 DECODE_PRINTF(","); 2238 shiftreg = DECODE_RM_WORD_REGISTER(rh); 2239 TRACE_AND_STEP(); 2240 bit = *shiftreg & 0xF; 2241 mask = (u16) (0x1 << bit); 2242 CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 2243 *srcreg ^= mask; 2244 } 2245 break; 2246 } 2247 DECODE_CLEAR_SEGOVR(); 2248 END_OF_INSTR(); 2249 } 2250 2251 /**************************************************************************** 2252 REMARKS: 2253 Handles opcode 0x0f,0xbc 2254 ****************************************************************************/ 2255 static void 2256 x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) 2257 { 2258 int mod, rl, rh; 2259 uint srcoffset; 2260 2261 START_OF_INSTR(); 2262 DECODE_PRINTF("BSF\t"); 2263 FETCH_DECODE_MODRM(mod, rh, rl); 2264 switch (mod) { 2265 case 0: 2266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2267 u32 srcval, *dstreg; 2268 2269 srcoffset = decode_rm00_address(rl); 2270 DECODE_PRINTF(","); 2271 dstreg = DECODE_RM_LONG_REGISTER(rh); 2272 TRACE_AND_STEP(); 2273 srcval = fetch_data_long(srcoffset); 2274 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2275 for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 2276 if ((srcval >> *dstreg) & 1) 2277 break; 2278 } 2279 else { 2280 u16 srcval, *dstreg; 2281 2282 srcoffset = decode_rm00_address(rl); 2283 DECODE_PRINTF(","); 2284 dstreg = DECODE_RM_WORD_REGISTER(rh); 2285 TRACE_AND_STEP(); 2286 srcval = fetch_data_word(srcoffset); 2287 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2288 for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 2289 if ((srcval >> *dstreg) & 1) 2290 break; 2291 } 2292 break; 2293 case 1: 2294 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2295 u32 srcval, *dstreg; 2296 2297 srcoffset = decode_rm01_address(rl); 2298 DECODE_PRINTF(","); 2299 dstreg = DECODE_RM_LONG_REGISTER(rh); 2300 TRACE_AND_STEP(); 2301 srcval = fetch_data_long(srcoffset); 2302 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2303 for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 2304 if ((srcval >> *dstreg) & 1) 2305 break; 2306 } 2307 else { 2308 u16 srcval, *dstreg; 2309 2310 srcoffset = decode_rm01_address(rl); 2311 DECODE_PRINTF(","); 2312 dstreg = DECODE_RM_WORD_REGISTER(rh); 2313 TRACE_AND_STEP(); 2314 srcval = fetch_data_word(srcoffset); 2315 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2316 for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 2317 if ((srcval >> *dstreg) & 1) 2318 break; 2319 } 2320 break; 2321 case 2: 2322 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2323 u32 srcval, *dstreg; 2324 2325 srcoffset = decode_rm10_address(rl); 2326 DECODE_PRINTF(","); 2327 dstreg = DECODE_RM_LONG_REGISTER(rh); 2328 TRACE_AND_STEP(); 2329 srcval = fetch_data_long(srcoffset); 2330 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2331 for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 2332 if ((srcval >> *dstreg) & 1) 2333 break; 2334 } 2335 else { 2336 u16 srcval, *dstreg; 2337 2338 srcoffset = decode_rm10_address(rl); 2339 DECODE_PRINTF(","); 2340 dstreg = DECODE_RM_WORD_REGISTER(rh); 2341 TRACE_AND_STEP(); 2342 srcval = fetch_data_word(srcoffset); 2343 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2344 for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 2345 if ((srcval >> *dstreg) & 1) 2346 break; 2347 } 2348 break; 2349 case 3: /* register to register */ 2350 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2351 u32 srcval, *dstreg; 2352 2353 srcval = *DECODE_RM_LONG_REGISTER(rl); 2354 DECODE_PRINTF(","); 2355 dstreg = DECODE_RM_LONG_REGISTER(rh); 2356 TRACE_AND_STEP(); 2357 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2358 for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 2359 if ((srcval >> *dstreg) & 1) 2360 break; 2361 } 2362 else { 2363 u16 srcval, *dstreg; 2364 2365 srcval = *DECODE_RM_WORD_REGISTER(rl); 2366 DECODE_PRINTF(","); 2367 dstreg = DECODE_RM_WORD_REGISTER(rh); 2368 TRACE_AND_STEP(); 2369 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2370 for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 2371 if ((srcval >> *dstreg) & 1) 2372 break; 2373 } 2374 break; 2375 } 2376 DECODE_CLEAR_SEGOVR(); 2377 END_OF_INSTR(); 2378 } 2379 2380 /**************************************************************************** 2381 REMARKS: 2382 Handles opcode 0x0f,0xbd 2383 ****************************************************************************/ 2384 static void 2385 x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) 2386 { 2387 int mod, rl, rh; 2388 uint srcoffset; 2389 2390 START_OF_INSTR(); 2391 DECODE_PRINTF("BSR\t"); 2392 FETCH_DECODE_MODRM(mod, rh, rl); 2393 switch (mod) { 2394 case 0: 2395 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2396 u32 srcval, *dstreg; 2397 2398 srcoffset = decode_rm00_address(rl); 2399 DECODE_PRINTF(","); 2400 dstreg = DECODE_RM_LONG_REGISTER(rh); 2401 TRACE_AND_STEP(); 2402 srcval = fetch_data_long(srcoffset); 2403 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2404 for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 2405 if ((srcval >> *dstreg) & 1) 2406 break; 2407 } 2408 else { 2409 u16 srcval, *dstreg; 2410 2411 srcoffset = decode_rm00_address(rl); 2412 DECODE_PRINTF(","); 2413 dstreg = DECODE_RM_WORD_REGISTER(rh); 2414 TRACE_AND_STEP(); 2415 srcval = fetch_data_word(srcoffset); 2416 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2417 for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 2418 if ((srcval >> *dstreg) & 1) 2419 break; 2420 } 2421 break; 2422 case 1: 2423 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2424 u32 srcval, *dstreg; 2425 2426 srcoffset = decode_rm01_address(rl); 2427 DECODE_PRINTF(","); 2428 dstreg = DECODE_RM_LONG_REGISTER(rh); 2429 TRACE_AND_STEP(); 2430 srcval = fetch_data_long(srcoffset); 2431 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2432 for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 2433 if ((srcval >> *dstreg) & 1) 2434 break; 2435 } 2436 else { 2437 u16 srcval, *dstreg; 2438 2439 srcoffset = decode_rm01_address(rl); 2440 DECODE_PRINTF(","); 2441 dstreg = DECODE_RM_WORD_REGISTER(rh); 2442 TRACE_AND_STEP(); 2443 srcval = fetch_data_word(srcoffset); 2444 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2445 for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 2446 if ((srcval >> *dstreg) & 1) 2447 break; 2448 } 2449 break; 2450 case 2: 2451 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2452 u32 srcval, *dstreg; 2453 2454 srcoffset = decode_rm10_address(rl); 2455 DECODE_PRINTF(","); 2456 dstreg = DECODE_RM_LONG_REGISTER(rh); 2457 TRACE_AND_STEP(); 2458 srcval = fetch_data_long(srcoffset); 2459 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2460 for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 2461 if ((srcval >> *dstreg) & 1) 2462 break; 2463 } 2464 else { 2465 u16 srcval, *dstreg; 2466 2467 srcoffset = decode_rm10_address(rl); 2468 DECODE_PRINTF(","); 2469 dstreg = DECODE_RM_WORD_REGISTER(rh); 2470 TRACE_AND_STEP(); 2471 srcval = fetch_data_word(srcoffset); 2472 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2473 for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 2474 if ((srcval >> *dstreg) & 1) 2475 break; 2476 } 2477 break; 2478 case 3: /* register to register */ 2479 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2480 u32 srcval, *dstreg; 2481 2482 srcval = *DECODE_RM_LONG_REGISTER(rl); 2483 DECODE_PRINTF(","); 2484 dstreg = DECODE_RM_LONG_REGISTER(rh); 2485 TRACE_AND_STEP(); 2486 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2487 for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 2488 if ((srcval >> *dstreg) & 1) 2489 break; 2490 } 2491 else { 2492 u16 srcval, *dstreg; 2493 2494 srcval = *DECODE_RM_WORD_REGISTER(rl); 2495 DECODE_PRINTF(","); 2496 dstreg = DECODE_RM_WORD_REGISTER(rh); 2497 TRACE_AND_STEP(); 2498 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 2499 for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 2500 if ((srcval >> *dstreg) & 1) 2501 break; 2502 } 2503 break; 2504 } 2505 DECODE_CLEAR_SEGOVR(); 2506 END_OF_INSTR(); 2507 } 2508 2509 /**************************************************************************** 2510 REMARKS: 2511 Handles opcode 0x0f,0xbe 2512 ****************************************************************************/ 2513 static void 2514 x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 2515 { 2516 int mod, rl, rh; 2517 uint srcoffset; 2518 2519 START_OF_INSTR(); 2520 DECODE_PRINTF("MOVSX\t"); 2521 FETCH_DECODE_MODRM(mod, rh, rl); 2522 switch (mod) { 2523 case 0: 2524 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2525 u32 *destreg; 2526 u32 srcval; 2527 2528 destreg = DECODE_RM_LONG_REGISTER(rh); 2529 DECODE_PRINTF(","); 2530 srcoffset = decode_rm00_address(rl); 2531 srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 2532 DECODE_PRINTF("\n"); 2533 TRACE_AND_STEP(); 2534 *destreg = srcval; 2535 } 2536 else { 2537 u16 *destreg; 2538 u16 srcval; 2539 2540 destreg = DECODE_RM_WORD_REGISTER(rh); 2541 DECODE_PRINTF(","); 2542 srcoffset = decode_rm00_address(rl); 2543 srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 2544 DECODE_PRINTF("\n"); 2545 TRACE_AND_STEP(); 2546 *destreg = srcval; 2547 } 2548 break; 2549 case 1: 2550 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2551 u32 *destreg; 2552 u32 srcval; 2553 2554 destreg = DECODE_RM_LONG_REGISTER(rh); 2555 DECODE_PRINTF(","); 2556 srcoffset = decode_rm01_address(rl); 2557 srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 2558 DECODE_PRINTF("\n"); 2559 TRACE_AND_STEP(); 2560 *destreg = srcval; 2561 } 2562 else { 2563 u16 *destreg; 2564 u16 srcval; 2565 2566 destreg = DECODE_RM_WORD_REGISTER(rh); 2567 DECODE_PRINTF(","); 2568 srcoffset = decode_rm01_address(rl); 2569 srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 2570 DECODE_PRINTF("\n"); 2571 TRACE_AND_STEP(); 2572 *destreg = srcval; 2573 } 2574 break; 2575 case 2: 2576 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2577 u32 *destreg; 2578 u32 srcval; 2579 2580 destreg = DECODE_RM_LONG_REGISTER(rh); 2581 DECODE_PRINTF(","); 2582 srcoffset = decode_rm10_address(rl); 2583 srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 2584 DECODE_PRINTF("\n"); 2585 TRACE_AND_STEP(); 2586 *destreg = srcval; 2587 } 2588 else { 2589 u16 *destreg; 2590 u16 srcval; 2591 2592 destreg = DECODE_RM_WORD_REGISTER(rh); 2593 DECODE_PRINTF(","); 2594 srcoffset = decode_rm10_address(rl); 2595 srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 2596 DECODE_PRINTF("\n"); 2597 TRACE_AND_STEP(); 2598 *destreg = srcval; 2599 } 2600 break; 2601 case 3: /* register to register */ 2602 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2603 u32 *destreg; 2604 u8 *srcreg; 2605 2606 destreg = DECODE_RM_LONG_REGISTER(rh); 2607 DECODE_PRINTF(","); 2608 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2609 DECODE_PRINTF("\n"); 2610 TRACE_AND_STEP(); 2611 *destreg = (s32) ((s8) * srcreg); 2612 } 2613 else { 2614 u16 *destreg; 2615 u8 *srcreg; 2616 2617 destreg = DECODE_RM_WORD_REGISTER(rh); 2618 DECODE_PRINTF(","); 2619 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2620 DECODE_PRINTF("\n"); 2621 TRACE_AND_STEP(); 2622 *destreg = (s16) ((s8) * srcreg); 2623 } 2624 break; 2625 } 2626 DECODE_CLEAR_SEGOVR(); 2627 END_OF_INSTR(); 2628 } 2629 2630 /**************************************************************************** 2631 REMARKS: 2632 Handles opcode 0x0f,0xbf 2633 ****************************************************************************/ 2634 static void 2635 x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2)) 2636 { 2637 int mod, rl, rh; 2638 uint srcoffset; 2639 u32 *destreg; 2640 u32 srcval; 2641 u16 *srcreg; 2642 2643 START_OF_INSTR(); 2644 DECODE_PRINTF("MOVSX\t"); 2645 FETCH_DECODE_MODRM(mod, rh, rl); 2646 switch (mod) { 2647 case 0: 2648 destreg = DECODE_RM_LONG_REGISTER(rh); 2649 DECODE_PRINTF(","); 2650 srcoffset = decode_rm00_address(rl); 2651 srcval = (s32) ((s16) fetch_data_word(srcoffset)); 2652 DECODE_PRINTF("\n"); 2653 TRACE_AND_STEP(); 2654 *destreg = srcval; 2655 break; 2656 case 1: 2657 destreg = DECODE_RM_LONG_REGISTER(rh); 2658 DECODE_PRINTF(","); 2659 srcoffset = decode_rm01_address(rl); 2660 srcval = (s32) ((s16) fetch_data_word(srcoffset)); 2661 DECODE_PRINTF("\n"); 2662 TRACE_AND_STEP(); 2663 *destreg = srcval; 2664 break; 2665 case 2: 2666 destreg = DECODE_RM_LONG_REGISTER(rh); 2667 DECODE_PRINTF(","); 2668 srcoffset = decode_rm10_address(rl); 2669 srcval = (s32) ((s16) fetch_data_word(srcoffset)); 2670 DECODE_PRINTF("\n"); 2671 TRACE_AND_STEP(); 2672 *destreg = srcval; 2673 break; 2674 case 3: /* register to register */ 2675 destreg = DECODE_RM_LONG_REGISTER(rh); 2676 DECODE_PRINTF(","); 2677 srcreg = DECODE_RM_WORD_REGISTER(rl); 2678 DECODE_PRINTF("\n"); 2679 TRACE_AND_STEP(); 2680 *destreg = (s32) ((s16) * srcreg); 2681 break; 2682 } 2683 DECODE_CLEAR_SEGOVR(); 2684 END_OF_INSTR(); 2685 } 2686 2687 /* Handles opcodes 0xc8-0xcf */ 2688 static void 2689 x86emuOp2_bswap(u8 X86EMU_UNUSED(op2)) 2690 { 2691 START_OF_INSTR(); 2692 DECODE_PRINTF("BSWAP\n"); 2693 TRACE_AND_STEP(); 2694 2695 switch (op2) { 2696 case 0xc8: 2697 M.x86.R_EAX = bswap_32(M.x86.R_EAX); 2698 break; 2699 case 0xc9: 2700 M.x86.R_ECX = bswap_32(M.x86.R_ECX); 2701 break; 2702 case 0xca: 2703 M.x86.R_EDX = bswap_32(M.x86.R_EDX); 2704 break; 2705 case 0xcb: 2706 M.x86.R_EBX = bswap_32(M.x86.R_EBX); 2707 break; 2708 case 0xcc: 2709 M.x86.R_ESP = bswap_32(M.x86.R_ESP); 2710 break; 2711 case 0xcd: 2712 M.x86.R_EBP = bswap_32(M.x86.R_EBP); 2713 break; 2714 case 0xce: 2715 M.x86.R_ESI = bswap_32(M.x86.R_ESI); 2716 break; 2717 case 0xcf: 2718 M.x86.R_EDI = bswap_32(M.x86.R_EDI); 2719 break; 2720 default: 2721 /* can't happen */ 2722 break; 2723 } 2724 2725 DECODE_CLEAR_SEGOVR(); 2726 END_OF_INSTR(); 2727 } 2728 2729 /*************************************************************************** 2730 * Double byte operation code table: 2731 **************************************************************************/ 2732 void (*x86emu_optab2[256]) (u8) = { 2733 /* 0x00 */ x86emuOp2_illegal_op, 2734 /* Group F (ring 0 PM) */ 2735 /* 0x01 */ x86emuOp2_illegal_op, 2736 /* Group G (ring 0 PM) */ 2737 /* 0x02 */ x86emuOp2_illegal_op, 2738 /* lar (ring 0 PM) */ 2739 /* 0x03 */ x86emuOp2_illegal_op, 2740 /* lsl (ring 0 PM) */ 2741 /* 0x04 */ x86emuOp2_illegal_op, 2742 /* 0x05 */ x86emuOp2_illegal_op, 2743 /* loadall (undocumented) */ 2744 /* 0x06 */ x86emuOp2_illegal_op, 2745 /* clts (ring 0 PM) */ 2746 /* 0x07 */ x86emuOp2_illegal_op, 2747 /* loadall (undocumented) */ 2748 /* 0x08 */ x86emuOp2_illegal_op, 2749 /* invd (ring 0 PM) */ 2750 /* 0x09 */ x86emuOp2_illegal_op, 2751 /* wbinvd (ring 0 PM) */ 2752 /* 0x0a */ x86emuOp2_illegal_op, 2753 /* 0x0b */ x86emuOp2_illegal_op, 2754 /* 0x0c */ x86emuOp2_illegal_op, 2755 /* 0x0d */ x86emuOp2_illegal_op, 2756 /* 0x0e */ x86emuOp2_illegal_op, 2757 /* 0x0f */ x86emuOp2_illegal_op, 2758 /* 0x10 */ x86emuOp2_illegal_op, 2759 /* 0x11 */ x86emuOp2_illegal_op, 2760 /* 0x12 */ x86emuOp2_illegal_op, 2761 /* 0x13 */ x86emuOp2_illegal_op, 2762 /* 0x14 */ x86emuOp2_illegal_op, 2763 /* 0x15 */ x86emuOp2_illegal_op, 2764 /* 0x16 */ x86emuOp2_illegal_op, 2765 /* 0x17 */ x86emuOp2_illegal_op, 2766 /* 0x18 */ x86emuOp2_illegal_op, 2767 /* 0x19 */ x86emuOp2_illegal_op, 2768 /* 0x1a */ x86emuOp2_illegal_op, 2769 /* 0x1b */ x86emuOp2_illegal_op, 2770 /* 0x1c */ x86emuOp2_illegal_op, 2771 /* 0x1d */ x86emuOp2_illegal_op, 2772 /* 0x1e */ x86emuOp2_illegal_op, 2773 /* 0x1f */ x86emuOp2_illegal_op, 2774 /* 0x20 */ x86emuOp2_illegal_op, 2775 /* mov reg32,creg (ring 0 PM) */ 2776 /* 0x21 */ x86emuOp2_illegal_op, 2777 /* mov reg32,dreg (ring 0 PM) */ 2778 /* 0x22 */ x86emuOp2_illegal_op, 2779 /* mov creg,reg32 (ring 0 PM) */ 2780 /* 0x23 */ x86emuOp2_illegal_op, 2781 /* mov dreg,reg32 (ring 0 PM) */ 2782 /* 0x24 */ x86emuOp2_illegal_op, 2783 /* mov reg32,treg (ring 0 PM) */ 2784 /* 0x25 */ x86emuOp2_illegal_op, 2785 /* 0x26 */ x86emuOp2_illegal_op, 2786 /* mov treg,reg32 (ring 0 PM) */ 2787 /* 0x27 */ x86emuOp2_illegal_op, 2788 /* 0x28 */ x86emuOp2_illegal_op, 2789 /* 0x29 */ x86emuOp2_illegal_op, 2790 /* 0x2a */ x86emuOp2_illegal_op, 2791 /* 0x2b */ x86emuOp2_illegal_op, 2792 /* 0x2c */ x86emuOp2_illegal_op, 2793 /* 0x2d */ x86emuOp2_illegal_op, 2794 /* 0x2e */ x86emuOp2_illegal_op, 2795 /* 0x2f */ x86emuOp2_illegal_op, 2796 /* 0x30 */ x86emuOp2_illegal_op, 2797 /* 0x31 */ x86emuOp2_rdtsc, 2798 /* 0x32 */ x86emuOp2_illegal_op, 2799 /* 0x33 */ x86emuOp2_illegal_op, 2800 /* 0x34 */ x86emuOp2_illegal_op, 2801 /* 0x35 */ x86emuOp2_illegal_op, 2802 /* 0x36 */ x86emuOp2_illegal_op, 2803 /* 0x37 */ x86emuOp2_illegal_op, 2804 /* 0x38 */ x86emuOp2_illegal_op, 2805 /* 0x39 */ x86emuOp2_illegal_op, 2806 /* 0x3a */ x86emuOp2_illegal_op, 2807 /* 0x3b */ x86emuOp2_illegal_op, 2808 /* 0x3c */ x86emuOp2_illegal_op, 2809 /* 0x3d */ x86emuOp2_illegal_op, 2810 /* 0x3e */ x86emuOp2_illegal_op, 2811 /* 0x3f */ x86emuOp2_illegal_op, 2812 /* 0x40 */ x86emuOp2_illegal_op, 2813 /* 0x41 */ x86emuOp2_illegal_op, 2814 /* 0x42 */ x86emuOp2_illegal_op, 2815 /* 0x43 */ x86emuOp2_illegal_op, 2816 /* 0x44 */ x86emuOp2_illegal_op, 2817 /* 0x45 */ x86emuOp2_illegal_op, 2818 /* 0x46 */ x86emuOp2_illegal_op, 2819 /* 0x47 */ x86emuOp2_illegal_op, 2820 /* 0x48 */ x86emuOp2_illegal_op, 2821 /* 0x49 */ x86emuOp2_illegal_op, 2822 /* 0x4a */ x86emuOp2_illegal_op, 2823 /* 0x4b */ x86emuOp2_illegal_op, 2824 /* 0x4c */ x86emuOp2_illegal_op, 2825 /* 0x4d */ x86emuOp2_illegal_op, 2826 /* 0x4e */ x86emuOp2_illegal_op, 2827 /* 0x4f */ x86emuOp2_illegal_op, 2828 /* 0x50 */ x86emuOp2_illegal_op, 2829 /* 0x51 */ x86emuOp2_illegal_op, 2830 /* 0x52 */ x86emuOp2_illegal_op, 2831 /* 0x53 */ x86emuOp2_illegal_op, 2832 /* 0x54 */ x86emuOp2_illegal_op, 2833 /* 0x55 */ x86emuOp2_illegal_op, 2834 /* 0x56 */ x86emuOp2_illegal_op, 2835 /* 0x57 */ x86emuOp2_illegal_op, 2836 /* 0x58 */ x86emuOp2_illegal_op, 2837 /* 0x59 */ x86emuOp2_illegal_op, 2838 /* 0x5a */ x86emuOp2_illegal_op, 2839 /* 0x5b */ x86emuOp2_illegal_op, 2840 /* 0x5c */ x86emuOp2_illegal_op, 2841 /* 0x5d */ x86emuOp2_illegal_op, 2842 /* 0x5e */ x86emuOp2_illegal_op, 2843 /* 0x5f */ x86emuOp2_illegal_op, 2844 /* 0x60 */ x86emuOp2_illegal_op, 2845 /* 0x61 */ x86emuOp2_illegal_op, 2846 /* 0x62 */ x86emuOp2_illegal_op, 2847 /* 0x63 */ x86emuOp2_illegal_op, 2848 /* 0x64 */ x86emuOp2_illegal_op, 2849 /* 0x65 */ x86emuOp2_illegal_op, 2850 /* 0x66 */ x86emuOp2_illegal_op, 2851 /* 0x67 */ x86emuOp2_illegal_op, 2852 /* 0x68 */ x86emuOp2_illegal_op, 2853 /* 0x69 */ x86emuOp2_illegal_op, 2854 /* 0x6a */ x86emuOp2_illegal_op, 2855 /* 0x6b */ x86emuOp2_illegal_op, 2856 /* 0x6c */ x86emuOp2_illegal_op, 2857 /* 0x6d */ x86emuOp2_illegal_op, 2858 /* 0x6e */ x86emuOp2_illegal_op, 2859 /* 0x6f */ x86emuOp2_illegal_op, 2860 /* 0x70 */ x86emuOp2_illegal_op, 2861 /* 0x71 */ x86emuOp2_illegal_op, 2862 /* 0x72 */ x86emuOp2_illegal_op, 2863 /* 0x73 */ x86emuOp2_illegal_op, 2864 /* 0x74 */ x86emuOp2_illegal_op, 2865 /* 0x75 */ x86emuOp2_illegal_op, 2866 /* 0x76 */ x86emuOp2_illegal_op, 2867 /* 0x77 */ x86emuOp2_illegal_op, 2868 /* 0x78 */ x86emuOp2_illegal_op, 2869 /* 0x79 */ x86emuOp2_illegal_op, 2870 /* 0x7a */ x86emuOp2_illegal_op, 2871 /* 0x7b */ x86emuOp2_illegal_op, 2872 /* 0x7c */ x86emuOp2_illegal_op, 2873 /* 0x7d */ x86emuOp2_illegal_op, 2874 /* 0x7e */ x86emuOp2_illegal_op, 2875 /* 0x7f */ x86emuOp2_illegal_op, 2876 /* 0x80 */ x86emuOp2_long_jump, 2877 /* 0x81 */ x86emuOp2_long_jump, 2878 /* 0x82 */ x86emuOp2_long_jump, 2879 /* 0x83 */ x86emuOp2_long_jump, 2880 /* 0x84 */ x86emuOp2_long_jump, 2881 /* 0x85 */ x86emuOp2_long_jump, 2882 /* 0x86 */ x86emuOp2_long_jump, 2883 /* 0x87 */ x86emuOp2_long_jump, 2884 /* 0x88 */ x86emuOp2_long_jump, 2885 /* 0x89 */ x86emuOp2_long_jump, 2886 /* 0x8a */ x86emuOp2_long_jump, 2887 /* 0x8b */ x86emuOp2_long_jump, 2888 /* 0x8c */ x86emuOp2_long_jump, 2889 /* 0x8d */ x86emuOp2_long_jump, 2890 /* 0x8e */ x86emuOp2_long_jump, 2891 /* 0x8f */ x86emuOp2_long_jump, 2892 /* 0x90 */ x86emuOp2_set_byte, 2893 /* 0x91 */ x86emuOp2_set_byte, 2894 /* 0x92 */ x86emuOp2_set_byte, 2895 /* 0x93 */ x86emuOp2_set_byte, 2896 /* 0x94 */ x86emuOp2_set_byte, 2897 /* 0x95 */ x86emuOp2_set_byte, 2898 /* 0x96 */ x86emuOp2_set_byte, 2899 /* 0x97 */ x86emuOp2_set_byte, 2900 /* 0x98 */ x86emuOp2_set_byte, 2901 /* 0x99 */ x86emuOp2_set_byte, 2902 /* 0x9a */ x86emuOp2_set_byte, 2903 /* 0x9b */ x86emuOp2_set_byte, 2904 /* 0x9c */ x86emuOp2_set_byte, 2905 /* 0x9d */ x86emuOp2_set_byte, 2906 /* 0x9e */ x86emuOp2_set_byte, 2907 /* 0x9f */ x86emuOp2_set_byte, 2908 /* 0xa0 */ x86emuOp2_push_FS, 2909 /* 0xa1 */ x86emuOp2_pop_FS, 2910 /* 0xa2 */ x86emuOp2_cpuid, 2911 /* 0xa3 */ x86emuOp2_bt_R, 2912 /* 0xa4 */ x86emuOp2_shld_IMM, 2913 /* 0xa5 */ x86emuOp2_shld_CL, 2914 /* 0xa6 */ x86emuOp2_illegal_op, 2915 /* 0xa7 */ x86emuOp2_illegal_op, 2916 /* 0xa8 */ x86emuOp2_push_GS, 2917 /* 0xa9 */ x86emuOp2_pop_GS, 2918 /* 0xaa */ x86emuOp2_illegal_op, 2919 /* 0xab */ x86emuOp2_bts_R, 2920 /* 0xac */ x86emuOp2_shrd_IMM, 2921 /* 0xad */ x86emuOp2_shrd_CL, 2922 /* 0xae */ x86emuOp2_illegal_op, 2923 /* 0xaf */ x86emuOp2_imul_R_RM, 2924 /* 0xb0 */ x86emuOp2_illegal_op, 2925 /* TODO: cmpxchg */ 2926 /* 0xb1 */ x86emuOp2_illegal_op, 2927 /* TODO: cmpxchg */ 2928 /* 0xb2 */ x86emuOp2_lss_R_IMM, 2929 /* 0xb3 */ x86emuOp2_btr_R, 2930 /* 0xb4 */ x86emuOp2_lfs_R_IMM, 2931 /* 0xb5 */ x86emuOp2_lgs_R_IMM, 2932 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM, 2933 /* 0xb7 */ x86emuOp2_movzx_word_R_RM, 2934 /* 0xb8 */ x86emuOp2_illegal_op, 2935 /* 0xb9 */ x86emuOp2_illegal_op, 2936 /* 0xba */ x86emuOp2_btX_I, 2937 /* 0xbb */ x86emuOp2_btc_R, 2938 /* 0xbc */ x86emuOp2_bsf, 2939 /* 0xbd */ x86emuOp2_bsr, 2940 /* 0xbe */ x86emuOp2_movsx_byte_R_RM, 2941 /* 0xbf */ x86emuOp2_movsx_word_R_RM, 2942 /* 0xc0 */ x86emuOp2_illegal_op, 2943 /* TODO: xadd */ 2944 /* 0xc1 */ x86emuOp2_illegal_op, 2945 /* TODO: xadd */ 2946 /* 0xc2 */ x86emuOp2_illegal_op, 2947 /* 0xc3 */ x86emuOp2_illegal_op, 2948 /* 0xc4 */ x86emuOp2_illegal_op, 2949 /* 0xc5 */ x86emuOp2_illegal_op, 2950 /* 0xc6 */ x86emuOp2_illegal_op, 2951 /* 0xc7 */ x86emuOp2_illegal_op, 2952 /* 0xc8 */ x86emuOp2_bswap, 2953 /* 0xc9 */ x86emuOp2_bswap, 2954 /* 0xca */ x86emuOp2_bswap, 2955 /* 0xcb */ x86emuOp2_bswap, 2956 /* 0xcc */ x86emuOp2_bswap, 2957 /* 0xcd */ x86emuOp2_bswap, 2958 /* 0xce */ x86emuOp2_bswap, 2959 /* 0xcf */ x86emuOp2_bswap, 2960 /* 0xd0 */ x86emuOp2_illegal_op, 2961 /* 0xd1 */ x86emuOp2_illegal_op, 2962 /* 0xd2 */ x86emuOp2_illegal_op, 2963 /* 0xd3 */ x86emuOp2_illegal_op, 2964 /* 0xd4 */ x86emuOp2_illegal_op, 2965 /* 0xd5 */ x86emuOp2_illegal_op, 2966 /* 0xd6 */ x86emuOp2_illegal_op, 2967 /* 0xd7 */ x86emuOp2_illegal_op, 2968 /* 0xd8 */ x86emuOp2_illegal_op, 2969 /* 0xd9 */ x86emuOp2_illegal_op, 2970 /* 0xda */ x86emuOp2_illegal_op, 2971 /* 0xdb */ x86emuOp2_illegal_op, 2972 /* 0xdc */ x86emuOp2_illegal_op, 2973 /* 0xdd */ x86emuOp2_illegal_op, 2974 /* 0xde */ x86emuOp2_illegal_op, 2975 /* 0xdf */ x86emuOp2_illegal_op, 2976 /* 0xe0 */ x86emuOp2_illegal_op, 2977 /* 0xe1 */ x86emuOp2_illegal_op, 2978 /* 0xe2 */ x86emuOp2_illegal_op, 2979 /* 0xe3 */ x86emuOp2_illegal_op, 2980 /* 0xe4 */ x86emuOp2_illegal_op, 2981 /* 0xe5 */ x86emuOp2_illegal_op, 2982 /* 0xe6 */ x86emuOp2_illegal_op, 2983 /* 0xe7 */ x86emuOp2_illegal_op, 2984 /* 0xe8 */ x86emuOp2_illegal_op, 2985 /* 0xe9 */ x86emuOp2_illegal_op, 2986 /* 0xea */ x86emuOp2_illegal_op, 2987 /* 0xeb */ x86emuOp2_illegal_op, 2988 /* 0xec */ x86emuOp2_illegal_op, 2989 /* 0xed */ x86emuOp2_illegal_op, 2990 /* 0xee */ x86emuOp2_illegal_op, 2991 /* 0xef */ x86emuOp2_illegal_op, 2992 /* 0xf0 */ x86emuOp2_illegal_op, 2993 /* 0xf1 */ x86emuOp2_illegal_op, 2994 /* 0xf2 */ x86emuOp2_illegal_op, 2995 /* 0xf3 */ x86emuOp2_illegal_op, 2996 /* 0xf4 */ x86emuOp2_illegal_op, 2997 /* 0xf5 */ x86emuOp2_illegal_op, 2998 /* 0xf6 */ x86emuOp2_illegal_op, 2999 /* 0xf7 */ x86emuOp2_illegal_op, 3000 /* 0xf8 */ x86emuOp2_illegal_op, 3001 /* 0xf9 */ x86emuOp2_illegal_op, 3002 /* 0xfa */ x86emuOp2_illegal_op, 3003 /* 0xfb */ x86emuOp2_illegal_op, 3004 /* 0xfc */ x86emuOp2_illegal_op, 3005 /* 0xfd */ x86emuOp2_illegal_op, 3006 /* 0xfe */ x86emuOp2_illegal_op, 3007 /* 0xff */ x86emuOp2_illegal_op, 3008 }; 3009