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