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