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