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 processor instructions. 37* 38* There are approximately 250 subroutines in here, which correspond 39* to the 256 byte-"opcodes" found on the 8086. The table which 40* dispatches this is found in the files optab.[ch]. 41* 42* Each opcode proc has a comment preceding it which gives its table 43* address. Several opcodes are missing (undefined) in the table. 44* 45* Each proc includes information for decoding (DECODE_PRINTF and 46* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc 47* functions (START_OF_INSTR, END_OF_INSTR). 48* 49* Many of the procedures are *VERY* similar in coding. This has 50* allowed for a very large amount of code to be generated in a fairly 51* short amount of time (i.e. cut, paste, and modify). The result is 52* that much of the code below could have been folded into subroutines 53* for a large reduction in size of this file. The downside would be 54* that there would be a penalty in execution speed. The file could 55* also have been *MUCH* larger by inlining certain functions which 56* were called. This could have resulted even faster execution. The 57* prime directive I used to decide whether to inline the code or to 58* modularize it, was basically: 1) no unnecessary subroutine calls, 59* 2) no routines more than about 200 lines in size, and 3) modularize 60* any code that I might not get right the first time. The fetch_* 61* subroutines fall into the latter category. The The decode_* fall 62* into the second category. The coding of the "switch(mod){ .... }" 63* in many of the subroutines below falls into the first category. 64* Especially, the coding of {add,and,or,sub,...}_{byte,word} 65* subroutines are an especially glaring case of the third guideline. 66* Since so much of the code is cloned from other modules (compare 67* opcode #00 to opcode #01), making the basic operations subroutine 68* calls is especially important; otherwise mistakes in coding an 69* "add" would represent a nightmare in maintenance. 70* 71****************************************************************************/ 72 73#include "x86emu/x86emui.h" 74 75/*----------------------------- Implementation ----------------------------*/ 76 77/**************************************************************************** 78PARAMETERS: 79op1 - Instruction op code 80 81REMARKS: 82Handles illegal opcodes. 83****************************************************************************/ 84static void 85x86emuOp_illegal_op(u8 op1) 86{ 87 START_OF_INSTR(); 88 if (M.x86.R_SP != 0) { 89 DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); 90 TRACE_REGS(); 91 DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", 92 M.x86.R_CS, M.x86.R_IP - 1, op1)); 93 HALT_SYS(); 94 } 95 else { 96 /* If we get here, it means the stack pointer is back to zero 97 * so we are just returning from an emulator service call 98 * so therte is no need to display an error message. We trap 99 * the emulator with an 0xF1 opcode to finish the service 100 * call. 101 */ 102 X86EMU_halt_sys(); 103 } 104 END_OF_INSTR(); 105} 106 107/**************************************************************************** 108REMARKS: 109Handles opcode 0x00 110****************************************************************************/ 111static void 112x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1)) 113{ 114 int mod, rl, rh; 115 uint destoffset; 116 u8 *destreg, *srcreg; 117 u8 destval; 118 119 START_OF_INSTR(); 120 DECODE_PRINTF("ADD\t"); 121 FETCH_DECODE_MODRM(mod, rh, rl); 122 switch (mod) { 123 case 0: 124 destoffset = decode_rm00_address(rl); 125 DECODE_PRINTF(","); 126 destval = fetch_data_byte(destoffset); 127 srcreg = DECODE_RM_BYTE_REGISTER(rh); 128 DECODE_PRINTF("\n"); 129 TRACE_AND_STEP(); 130 destval = add_byte(destval, *srcreg); 131 store_data_byte(destoffset, destval); 132 break; 133 case 1: 134 destoffset = decode_rm01_address(rl); 135 DECODE_PRINTF(","); 136 destval = fetch_data_byte(destoffset); 137 srcreg = DECODE_RM_BYTE_REGISTER(rh); 138 DECODE_PRINTF("\n"); 139 TRACE_AND_STEP(); 140 destval = add_byte(destval, *srcreg); 141 store_data_byte(destoffset, destval); 142 break; 143 case 2: 144 destoffset = decode_rm10_address(rl); 145 DECODE_PRINTF(","); 146 destval = fetch_data_byte(destoffset); 147 srcreg = DECODE_RM_BYTE_REGISTER(rh); 148 DECODE_PRINTF("\n"); 149 TRACE_AND_STEP(); 150 destval = add_byte(destval, *srcreg); 151 store_data_byte(destoffset, destval); 152 break; 153 case 3: /* register to register */ 154 destreg = DECODE_RM_BYTE_REGISTER(rl); 155 DECODE_PRINTF(","); 156 srcreg = DECODE_RM_BYTE_REGISTER(rh); 157 DECODE_PRINTF("\n"); 158 TRACE_AND_STEP(); 159 *destreg = add_byte(*destreg, *srcreg); 160 break; 161 } 162 DECODE_CLEAR_SEGOVR(); 163 END_OF_INSTR(); 164} 165 166/**************************************************************************** 167REMARKS: 168Handles opcode 0x01 169****************************************************************************/ 170static void 171x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1)) 172{ 173 int mod, rl, rh; 174 uint destoffset; 175 176 START_OF_INSTR(); 177 DECODE_PRINTF("ADD\t"); 178 FETCH_DECODE_MODRM(mod, rh, rl); 179 switch (mod) { 180 case 0: 181 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 182 u32 destval; 183 u32 *srcreg; 184 185 destoffset = decode_rm00_address(rl); 186 DECODE_PRINTF(","); 187 destval = fetch_data_long(destoffset); 188 srcreg = DECODE_RM_LONG_REGISTER(rh); 189 DECODE_PRINTF("\n"); 190 TRACE_AND_STEP(); 191 destval = add_long(destval, *srcreg); 192 store_data_long(destoffset, destval); 193 } 194 else { 195 u16 destval; 196 u16 *srcreg; 197 198 destoffset = decode_rm00_address(rl); 199 DECODE_PRINTF(","); 200 destval = fetch_data_word(destoffset); 201 srcreg = DECODE_RM_WORD_REGISTER(rh); 202 DECODE_PRINTF("\n"); 203 TRACE_AND_STEP(); 204 destval = add_word(destval, *srcreg); 205 store_data_word(destoffset, destval); 206 } 207 break; 208 case 1: 209 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 210 u32 destval; 211 u32 *srcreg; 212 213 destoffset = decode_rm01_address(rl); 214 DECODE_PRINTF(","); 215 destval = fetch_data_long(destoffset); 216 srcreg = DECODE_RM_LONG_REGISTER(rh); 217 DECODE_PRINTF("\n"); 218 TRACE_AND_STEP(); 219 destval = add_long(destval, *srcreg); 220 store_data_long(destoffset, destval); 221 } 222 else { 223 u16 destval; 224 u16 *srcreg; 225 226 destoffset = decode_rm01_address(rl); 227 DECODE_PRINTF(","); 228 destval = fetch_data_word(destoffset); 229 srcreg = DECODE_RM_WORD_REGISTER(rh); 230 DECODE_PRINTF("\n"); 231 TRACE_AND_STEP(); 232 destval = add_word(destval, *srcreg); 233 store_data_word(destoffset, destval); 234 } 235 break; 236 case 2: 237 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 238 u32 destval; 239 u32 *srcreg; 240 241 destoffset = decode_rm10_address(rl); 242 DECODE_PRINTF(","); 243 destval = fetch_data_long(destoffset); 244 srcreg = DECODE_RM_LONG_REGISTER(rh); 245 DECODE_PRINTF("\n"); 246 TRACE_AND_STEP(); 247 destval = add_long(destval, *srcreg); 248 store_data_long(destoffset, destval); 249 } 250 else { 251 u16 destval; 252 u16 *srcreg; 253 254 destoffset = decode_rm10_address(rl); 255 DECODE_PRINTF(","); 256 destval = fetch_data_word(destoffset); 257 srcreg = DECODE_RM_WORD_REGISTER(rh); 258 DECODE_PRINTF("\n"); 259 TRACE_AND_STEP(); 260 destval = add_word(destval, *srcreg); 261 store_data_word(destoffset, destval); 262 } 263 break; 264 case 3: /* register to register */ 265 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 266 u32 *destreg, *srcreg; 267 268 destreg = DECODE_RM_LONG_REGISTER(rl); 269 DECODE_PRINTF(","); 270 srcreg = DECODE_RM_LONG_REGISTER(rh); 271 DECODE_PRINTF("\n"); 272 TRACE_AND_STEP(); 273 *destreg = add_long(*destreg, *srcreg); 274 } 275 else { 276 u16 *destreg, *srcreg; 277 278 destreg = DECODE_RM_WORD_REGISTER(rl); 279 DECODE_PRINTF(","); 280 srcreg = DECODE_RM_WORD_REGISTER(rh); 281 DECODE_PRINTF("\n"); 282 TRACE_AND_STEP(); 283 *destreg = add_word(*destreg, *srcreg); 284 } 285 break; 286 } 287 DECODE_CLEAR_SEGOVR(); 288 END_OF_INSTR(); 289} 290 291/**************************************************************************** 292REMARKS: 293Handles opcode 0x02 294****************************************************************************/ 295static void 296x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1)) 297{ 298 int mod, rl, rh; 299 u8 *destreg, *srcreg; 300 uint srcoffset; 301 u8 srcval; 302 303 START_OF_INSTR(); 304 DECODE_PRINTF("ADD\t"); 305 FETCH_DECODE_MODRM(mod, rh, rl); 306 switch (mod) { 307 case 0: 308 destreg = DECODE_RM_BYTE_REGISTER(rh); 309 DECODE_PRINTF(","); 310 srcoffset = decode_rm00_address(rl); 311 srcval = fetch_data_byte(srcoffset); 312 DECODE_PRINTF("\n"); 313 TRACE_AND_STEP(); 314 *destreg = add_byte(*destreg, srcval); 315 break; 316 case 1: 317 destreg = DECODE_RM_BYTE_REGISTER(rh); 318 DECODE_PRINTF(","); 319 srcoffset = decode_rm01_address(rl); 320 srcval = fetch_data_byte(srcoffset); 321 DECODE_PRINTF("\n"); 322 TRACE_AND_STEP(); 323 *destreg = add_byte(*destreg, srcval); 324 break; 325 case 2: 326 destreg = DECODE_RM_BYTE_REGISTER(rh); 327 DECODE_PRINTF(","); 328 srcoffset = decode_rm10_address(rl); 329 srcval = fetch_data_byte(srcoffset); 330 DECODE_PRINTF("\n"); 331 TRACE_AND_STEP(); 332 *destreg = add_byte(*destreg, srcval); 333 break; 334 case 3: /* register to register */ 335 destreg = DECODE_RM_BYTE_REGISTER(rh); 336 DECODE_PRINTF(","); 337 srcreg = DECODE_RM_BYTE_REGISTER(rl); 338 DECODE_PRINTF("\n"); 339 TRACE_AND_STEP(); 340 *destreg = add_byte(*destreg, *srcreg); 341 break; 342 } 343 DECODE_CLEAR_SEGOVR(); 344 END_OF_INSTR(); 345} 346 347/**************************************************************************** 348REMARKS: 349Handles opcode 0x03 350****************************************************************************/ 351static void 352x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1)) 353{ 354 int mod, rl, rh; 355 uint srcoffset; 356 357 START_OF_INSTR(); 358 DECODE_PRINTF("ADD\t"); 359 FETCH_DECODE_MODRM(mod, rh, rl); 360 switch (mod) { 361 case 0: 362 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 363 u32 *destreg; 364 u32 srcval; 365 366 destreg = DECODE_RM_LONG_REGISTER(rh); 367 DECODE_PRINTF(","); 368 srcoffset = decode_rm00_address(rl); 369 srcval = fetch_data_long(srcoffset); 370 DECODE_PRINTF("\n"); 371 TRACE_AND_STEP(); 372 *destreg = add_long(*destreg, srcval); 373 } 374 else { 375 u16 *destreg; 376 u16 srcval; 377 378 destreg = DECODE_RM_WORD_REGISTER(rh); 379 DECODE_PRINTF(","); 380 srcoffset = decode_rm00_address(rl); 381 srcval = fetch_data_word(srcoffset); 382 DECODE_PRINTF("\n"); 383 TRACE_AND_STEP(); 384 *destreg = add_word(*destreg, srcval); 385 } 386 break; 387 case 1: 388 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 389 u32 *destreg; 390 u32 srcval; 391 392 destreg = DECODE_RM_LONG_REGISTER(rh); 393 DECODE_PRINTF(","); 394 srcoffset = decode_rm01_address(rl); 395 srcval = fetch_data_long(srcoffset); 396 DECODE_PRINTF("\n"); 397 TRACE_AND_STEP(); 398 *destreg = add_long(*destreg, srcval); 399 } 400 else { 401 u16 *destreg; 402 u16 srcval; 403 404 destreg = DECODE_RM_WORD_REGISTER(rh); 405 DECODE_PRINTF(","); 406 srcoffset = decode_rm01_address(rl); 407 srcval = fetch_data_word(srcoffset); 408 DECODE_PRINTF("\n"); 409 TRACE_AND_STEP(); 410 *destreg = add_word(*destreg, srcval); 411 } 412 break; 413 case 2: 414 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 415 u32 *destreg; 416 u32 srcval; 417 418 destreg = DECODE_RM_LONG_REGISTER(rh); 419 DECODE_PRINTF(","); 420 srcoffset = decode_rm10_address(rl); 421 srcval = fetch_data_long(srcoffset); 422 DECODE_PRINTF("\n"); 423 TRACE_AND_STEP(); 424 *destreg = add_long(*destreg, srcval); 425 } 426 else { 427 u16 *destreg; 428 u16 srcval; 429 430 destreg = DECODE_RM_WORD_REGISTER(rh); 431 DECODE_PRINTF(","); 432 srcoffset = decode_rm10_address(rl); 433 srcval = fetch_data_word(srcoffset); 434 DECODE_PRINTF("\n"); 435 TRACE_AND_STEP(); 436 *destreg = add_word(*destreg, srcval); 437 } 438 break; 439 case 3: /* register to register */ 440 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 441 u32 *destreg, *srcreg; 442 443 destreg = DECODE_RM_LONG_REGISTER(rh); 444 DECODE_PRINTF(","); 445 srcreg = DECODE_RM_LONG_REGISTER(rl); 446 DECODE_PRINTF("\n"); 447 TRACE_AND_STEP(); 448 *destreg = add_long(*destreg, *srcreg); 449 } 450 else { 451 u16 *destreg, *srcreg; 452 453 destreg = DECODE_RM_WORD_REGISTER(rh); 454 DECODE_PRINTF(","); 455 srcreg = DECODE_RM_WORD_REGISTER(rl); 456 DECODE_PRINTF("\n"); 457 TRACE_AND_STEP(); 458 *destreg = add_word(*destreg, *srcreg); 459 } 460 break; 461 } 462 DECODE_CLEAR_SEGOVR(); 463 END_OF_INSTR(); 464} 465 466/**************************************************************************** 467REMARKS: 468Handles opcode 0x04 469****************************************************************************/ 470static void 471x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 472{ 473 u8 srcval; 474 475 START_OF_INSTR(); 476 DECODE_PRINTF("ADD\tAL,"); 477 srcval = fetch_byte_imm(); 478 DECODE_PRINTF2("%x\n", srcval); 479 TRACE_AND_STEP(); 480 M.x86.R_AL = add_byte(M.x86.R_AL, srcval); 481 DECODE_CLEAR_SEGOVR(); 482 END_OF_INSTR(); 483} 484 485/**************************************************************************** 486REMARKS: 487Handles opcode 0x05 488****************************************************************************/ 489static void 490x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 491{ 492 u32 srcval; 493 494 START_OF_INSTR(); 495 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 496 DECODE_PRINTF("ADD\tEAX,"); 497 srcval = fetch_long_imm(); 498 } 499 else { 500 DECODE_PRINTF("ADD\tAX,"); 501 srcval = fetch_word_imm(); 502 } 503 DECODE_PRINTF2("%x\n", srcval); 504 TRACE_AND_STEP(); 505 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 506 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval); 507 } 508 else { 509 M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval); 510 } 511 DECODE_CLEAR_SEGOVR(); 512 END_OF_INSTR(); 513} 514 515/**************************************************************************** 516REMARKS: 517Handles opcode 0x06 518****************************************************************************/ 519static void 520x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 521{ 522 START_OF_INSTR(); 523 DECODE_PRINTF("PUSH\tES\n"); 524 TRACE_AND_STEP(); 525 push_word(M.x86.R_ES); 526 DECODE_CLEAR_SEGOVR(); 527 END_OF_INSTR(); 528} 529 530/**************************************************************************** 531REMARKS: 532Handles opcode 0x07 533****************************************************************************/ 534static void 535x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 536{ 537 START_OF_INSTR(); 538 DECODE_PRINTF("POP\tES\n"); 539 TRACE_AND_STEP(); 540 M.x86.R_ES = pop_word(); 541 DECODE_CLEAR_SEGOVR(); 542 END_OF_INSTR(); 543} 544 545/**************************************************************************** 546REMARKS: 547Handles opcode 0x08 548****************************************************************************/ 549static void 550x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1)) 551{ 552 int mod, rl, rh; 553 u8 *destreg, *srcreg; 554 uint destoffset; 555 u8 destval; 556 557 START_OF_INSTR(); 558 DECODE_PRINTF("OR\t"); 559 FETCH_DECODE_MODRM(mod, rh, rl); 560 switch (mod) { 561 case 0: 562 destoffset = decode_rm00_address(rl); 563 DECODE_PRINTF(","); 564 destval = fetch_data_byte(destoffset); 565 srcreg = DECODE_RM_BYTE_REGISTER(rh); 566 DECODE_PRINTF("\n"); 567 TRACE_AND_STEP(); 568 destval = or_byte(destval, *srcreg); 569 store_data_byte(destoffset, destval); 570 break; 571 case 1: 572 destoffset = decode_rm01_address(rl); 573 DECODE_PRINTF(","); 574 destval = fetch_data_byte(destoffset); 575 srcreg = DECODE_RM_BYTE_REGISTER(rh); 576 DECODE_PRINTF("\n"); 577 TRACE_AND_STEP(); 578 destval = or_byte(destval, *srcreg); 579 store_data_byte(destoffset, destval); 580 break; 581 case 2: 582 destoffset = decode_rm10_address(rl); 583 DECODE_PRINTF(","); 584 destval = fetch_data_byte(destoffset); 585 srcreg = DECODE_RM_BYTE_REGISTER(rh); 586 DECODE_PRINTF("\n"); 587 TRACE_AND_STEP(); 588 destval = or_byte(destval, *srcreg); 589 store_data_byte(destoffset, destval); 590 break; 591 case 3: /* register to register */ 592 destreg = DECODE_RM_BYTE_REGISTER(rl); 593 DECODE_PRINTF(","); 594 srcreg = DECODE_RM_BYTE_REGISTER(rh); 595 DECODE_PRINTF("\n"); 596 TRACE_AND_STEP(); 597 *destreg = or_byte(*destreg, *srcreg); 598 break; 599 } 600 DECODE_CLEAR_SEGOVR(); 601 END_OF_INSTR(); 602} 603 604/**************************************************************************** 605REMARKS: 606Handles opcode 0x09 607****************************************************************************/ 608static void 609x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1)) 610{ 611 int mod, rl, rh; 612 uint destoffset; 613 614 START_OF_INSTR(); 615 DECODE_PRINTF("OR\t"); 616 FETCH_DECODE_MODRM(mod, rh, rl); 617 switch (mod) { 618 case 0: 619 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 620 u32 destval; 621 u32 *srcreg; 622 623 destoffset = decode_rm00_address(rl); 624 DECODE_PRINTF(","); 625 destval = fetch_data_long(destoffset); 626 srcreg = DECODE_RM_LONG_REGISTER(rh); 627 DECODE_PRINTF("\n"); 628 TRACE_AND_STEP(); 629 destval = or_long(destval, *srcreg); 630 store_data_long(destoffset, destval); 631 } 632 else { 633 u16 destval; 634 u16 *srcreg; 635 636 destoffset = decode_rm00_address(rl); 637 DECODE_PRINTF(","); 638 destval = fetch_data_word(destoffset); 639 srcreg = DECODE_RM_WORD_REGISTER(rh); 640 DECODE_PRINTF("\n"); 641 TRACE_AND_STEP(); 642 destval = or_word(destval, *srcreg); 643 store_data_word(destoffset, destval); 644 } 645 break; 646 case 1: 647 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 648 u32 destval; 649 u32 *srcreg; 650 651 destoffset = decode_rm01_address(rl); 652 DECODE_PRINTF(","); 653 destval = fetch_data_long(destoffset); 654 srcreg = DECODE_RM_LONG_REGISTER(rh); 655 DECODE_PRINTF("\n"); 656 TRACE_AND_STEP(); 657 destval = or_long(destval, *srcreg); 658 store_data_long(destoffset, destval); 659 } 660 else { 661 u16 destval; 662 u16 *srcreg; 663 664 destoffset = decode_rm01_address(rl); 665 DECODE_PRINTF(","); 666 destval = fetch_data_word(destoffset); 667 srcreg = DECODE_RM_WORD_REGISTER(rh); 668 DECODE_PRINTF("\n"); 669 TRACE_AND_STEP(); 670 destval = or_word(destval, *srcreg); 671 store_data_word(destoffset, destval); 672 } 673 break; 674 case 2: 675 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 676 u32 destval; 677 u32 *srcreg; 678 679 destoffset = decode_rm10_address(rl); 680 DECODE_PRINTF(","); 681 destval = fetch_data_long(destoffset); 682 srcreg = DECODE_RM_LONG_REGISTER(rh); 683 DECODE_PRINTF("\n"); 684 TRACE_AND_STEP(); 685 destval = or_long(destval, *srcreg); 686 store_data_long(destoffset, destval); 687 } 688 else { 689 u16 destval; 690 u16 *srcreg; 691 692 destoffset = decode_rm10_address(rl); 693 DECODE_PRINTF(","); 694 destval = fetch_data_word(destoffset); 695 srcreg = DECODE_RM_WORD_REGISTER(rh); 696 DECODE_PRINTF("\n"); 697 TRACE_AND_STEP(); 698 destval = or_word(destval, *srcreg); 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, *srcreg; 705 706 destreg = DECODE_RM_LONG_REGISTER(rl); 707 DECODE_PRINTF(","); 708 srcreg = DECODE_RM_LONG_REGISTER(rh); 709 DECODE_PRINTF("\n"); 710 TRACE_AND_STEP(); 711 *destreg = or_long(*destreg, *srcreg); 712 } 713 else { 714 u16 *destreg, *srcreg; 715 716 destreg = DECODE_RM_WORD_REGISTER(rl); 717 DECODE_PRINTF(","); 718 srcreg = DECODE_RM_WORD_REGISTER(rh); 719 DECODE_PRINTF("\n"); 720 TRACE_AND_STEP(); 721 *destreg = or_word(*destreg, *srcreg); 722 } 723 break; 724 } 725 DECODE_CLEAR_SEGOVR(); 726 END_OF_INSTR(); 727} 728 729/**************************************************************************** 730REMARKS: 731Handles opcode 0x0a 732****************************************************************************/ 733static void 734x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1)) 735{ 736 int mod, rl, rh; 737 u8 *destreg, *srcreg; 738 uint srcoffset; 739 u8 srcval; 740 741 START_OF_INSTR(); 742 DECODE_PRINTF("OR\t"); 743 FETCH_DECODE_MODRM(mod, rh, rl); 744 switch (mod) { 745 case 0: 746 destreg = DECODE_RM_BYTE_REGISTER(rh); 747 DECODE_PRINTF(","); 748 srcoffset = decode_rm00_address(rl); 749 srcval = fetch_data_byte(srcoffset); 750 DECODE_PRINTF("\n"); 751 TRACE_AND_STEP(); 752 *destreg = or_byte(*destreg, srcval); 753 break; 754 case 1: 755 destreg = DECODE_RM_BYTE_REGISTER(rh); 756 DECODE_PRINTF(","); 757 srcoffset = decode_rm01_address(rl); 758 srcval = fetch_data_byte(srcoffset); 759 DECODE_PRINTF("\n"); 760 TRACE_AND_STEP(); 761 *destreg = or_byte(*destreg, srcval); 762 break; 763 case 2: 764 destreg = DECODE_RM_BYTE_REGISTER(rh); 765 DECODE_PRINTF(","); 766 srcoffset = decode_rm10_address(rl); 767 srcval = fetch_data_byte(srcoffset); 768 DECODE_PRINTF("\n"); 769 TRACE_AND_STEP(); 770 *destreg = or_byte(*destreg, srcval); 771 break; 772 case 3: /* register to register */ 773 destreg = DECODE_RM_BYTE_REGISTER(rh); 774 DECODE_PRINTF(","); 775 srcreg = DECODE_RM_BYTE_REGISTER(rl); 776 DECODE_PRINTF("\n"); 777 TRACE_AND_STEP(); 778 *destreg = or_byte(*destreg, *srcreg); 779 break; 780 } 781 DECODE_CLEAR_SEGOVR(); 782 END_OF_INSTR(); 783} 784 785/**************************************************************************** 786REMARKS: 787Handles opcode 0x0b 788****************************************************************************/ 789static void 790x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1)) 791{ 792 int mod, rl, rh; 793 uint srcoffset; 794 795 START_OF_INSTR(); 796 DECODE_PRINTF("OR\t"); 797 FETCH_DECODE_MODRM(mod, rh, rl); 798 switch (mod) { 799 case 0: 800 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 801 u32 *destreg; 802 u32 srcval; 803 804 destreg = DECODE_RM_LONG_REGISTER(rh); 805 DECODE_PRINTF(","); 806 srcoffset = decode_rm00_address(rl); 807 srcval = fetch_data_long(srcoffset); 808 DECODE_PRINTF("\n"); 809 TRACE_AND_STEP(); 810 *destreg = or_long(*destreg, srcval); 811 } 812 else { 813 u16 *destreg; 814 u16 srcval; 815 816 destreg = DECODE_RM_WORD_REGISTER(rh); 817 DECODE_PRINTF(","); 818 srcoffset = decode_rm00_address(rl); 819 srcval = fetch_data_word(srcoffset); 820 DECODE_PRINTF("\n"); 821 TRACE_AND_STEP(); 822 *destreg = or_word(*destreg, srcval); 823 } 824 break; 825 case 1: 826 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 827 u32 *destreg; 828 u32 srcval; 829 830 destreg = DECODE_RM_LONG_REGISTER(rh); 831 DECODE_PRINTF(","); 832 srcoffset = decode_rm01_address(rl); 833 srcval = fetch_data_long(srcoffset); 834 DECODE_PRINTF("\n"); 835 TRACE_AND_STEP(); 836 *destreg = or_long(*destreg, srcval); 837 } 838 else { 839 u16 *destreg; 840 u16 srcval; 841 842 destreg = DECODE_RM_WORD_REGISTER(rh); 843 DECODE_PRINTF(","); 844 srcoffset = decode_rm01_address(rl); 845 srcval = fetch_data_word(srcoffset); 846 DECODE_PRINTF("\n"); 847 TRACE_AND_STEP(); 848 *destreg = or_word(*destreg, srcval); 849 } 850 break; 851 case 2: 852 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 853 u32 *destreg; 854 u32 srcval; 855 856 destreg = DECODE_RM_LONG_REGISTER(rh); 857 DECODE_PRINTF(","); 858 srcoffset = decode_rm10_address(rl); 859 srcval = fetch_data_long(srcoffset); 860 DECODE_PRINTF("\n"); 861 TRACE_AND_STEP(); 862 *destreg = or_long(*destreg, srcval); 863 } 864 else { 865 u16 *destreg; 866 u16 srcval; 867 868 destreg = DECODE_RM_WORD_REGISTER(rh); 869 DECODE_PRINTF(","); 870 srcoffset = decode_rm10_address(rl); 871 srcval = fetch_data_word(srcoffset); 872 DECODE_PRINTF("\n"); 873 TRACE_AND_STEP(); 874 *destreg = or_word(*destreg, srcval); 875 } 876 break; 877 case 3: /* register to register */ 878 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 879 u32 *destreg, *srcreg; 880 881 destreg = DECODE_RM_LONG_REGISTER(rh); 882 DECODE_PRINTF(","); 883 srcreg = DECODE_RM_LONG_REGISTER(rl); 884 DECODE_PRINTF("\n"); 885 TRACE_AND_STEP(); 886 *destreg = or_long(*destreg, *srcreg); 887 } 888 else { 889 u16 *destreg, *srcreg; 890 891 destreg = DECODE_RM_WORD_REGISTER(rh); 892 DECODE_PRINTF(","); 893 srcreg = DECODE_RM_WORD_REGISTER(rl); 894 DECODE_PRINTF("\n"); 895 TRACE_AND_STEP(); 896 *destreg = or_word(*destreg, *srcreg); 897 } 898 break; 899 } 900 DECODE_CLEAR_SEGOVR(); 901 END_OF_INSTR(); 902} 903 904/**************************************************************************** 905REMARKS: 906Handles opcode 0x0c 907****************************************************************************/ 908static void 909x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 910{ 911 u8 srcval; 912 913 START_OF_INSTR(); 914 DECODE_PRINTF("OR\tAL,"); 915 srcval = fetch_byte_imm(); 916 DECODE_PRINTF2("%x\n", srcval); 917 TRACE_AND_STEP(); 918 M.x86.R_AL = or_byte(M.x86.R_AL, srcval); 919 DECODE_CLEAR_SEGOVR(); 920 END_OF_INSTR(); 921} 922 923/**************************************************************************** 924REMARKS: 925Handles opcode 0x0d 926****************************************************************************/ 927static void 928x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 929{ 930 u32 srcval; 931 932 START_OF_INSTR(); 933 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 934 DECODE_PRINTF("OR\tEAX,"); 935 srcval = fetch_long_imm(); 936 } 937 else { 938 DECODE_PRINTF("OR\tAX,"); 939 srcval = fetch_word_imm(); 940 } 941 DECODE_PRINTF2("%x\n", srcval); 942 TRACE_AND_STEP(); 943 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 944 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval); 945 } 946 else { 947 M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval); 948 } 949 DECODE_CLEAR_SEGOVR(); 950 END_OF_INSTR(); 951} 952 953/**************************************************************************** 954REMARKS: 955Handles opcode 0x0e 956****************************************************************************/ 957static void 958x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 959{ 960 START_OF_INSTR(); 961 DECODE_PRINTF("PUSH\tCS\n"); 962 TRACE_AND_STEP(); 963 push_word(M.x86.R_CS); 964 DECODE_CLEAR_SEGOVR(); 965 END_OF_INSTR(); 966} 967 968/**************************************************************************** 969REMARKS: 970Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 971****************************************************************************/ 972static void 973x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 974{ 975 u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++)); 976 977 INC_DECODED_INST_LEN(1); 978 (*x86emu_optab2[op2]) (op2); 979} 980 981/**************************************************************************** 982REMARKS: 983Handles opcode 0x10 984****************************************************************************/ 985static void 986x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1)) 987{ 988 int mod, rl, rh; 989 u8 *destreg, *srcreg; 990 uint destoffset; 991 u8 destval; 992 993 START_OF_INSTR(); 994 DECODE_PRINTF("ADC\t"); 995 FETCH_DECODE_MODRM(mod, rh, rl); 996 switch (mod) { 997 case 0: 998 destoffset = decode_rm00_address(rl); 999 DECODE_PRINTF(","); 1000 destval = fetch_data_byte(destoffset); 1001 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1002 DECODE_PRINTF("\n"); 1003 TRACE_AND_STEP(); 1004 destval = adc_byte(destval, *srcreg); 1005 store_data_byte(destoffset, destval); 1006 break; 1007 case 1: 1008 destoffset = decode_rm01_address(rl); 1009 DECODE_PRINTF(","); 1010 destval = fetch_data_byte(destoffset); 1011 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1012 DECODE_PRINTF("\n"); 1013 TRACE_AND_STEP(); 1014 destval = adc_byte(destval, *srcreg); 1015 store_data_byte(destoffset, destval); 1016 break; 1017 case 2: 1018 destoffset = decode_rm10_address(rl); 1019 DECODE_PRINTF(","); 1020 destval = fetch_data_byte(destoffset); 1021 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1022 DECODE_PRINTF("\n"); 1023 TRACE_AND_STEP(); 1024 destval = adc_byte(destval, *srcreg); 1025 store_data_byte(destoffset, destval); 1026 break; 1027 case 3: /* register to register */ 1028 destreg = DECODE_RM_BYTE_REGISTER(rl); 1029 DECODE_PRINTF(","); 1030 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1031 DECODE_PRINTF("\n"); 1032 TRACE_AND_STEP(); 1033 *destreg = adc_byte(*destreg, *srcreg); 1034 break; 1035 } 1036 DECODE_CLEAR_SEGOVR(); 1037 END_OF_INSTR(); 1038} 1039 1040/**************************************************************************** 1041REMARKS: 1042Handles opcode 0x11 1043****************************************************************************/ 1044static void 1045x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1)) 1046{ 1047 int mod, rl, rh; 1048 uint destoffset; 1049 1050 START_OF_INSTR(); 1051 DECODE_PRINTF("ADC\t"); 1052 FETCH_DECODE_MODRM(mod, rh, rl); 1053 switch (mod) { 1054 case 0: 1055 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1056 u32 destval; 1057 u32 *srcreg; 1058 1059 destoffset = decode_rm00_address(rl); 1060 DECODE_PRINTF(","); 1061 destval = fetch_data_long(destoffset); 1062 srcreg = DECODE_RM_LONG_REGISTER(rh); 1063 DECODE_PRINTF("\n"); 1064 TRACE_AND_STEP(); 1065 destval = adc_long(destval, *srcreg); 1066 store_data_long(destoffset, destval); 1067 } 1068 else { 1069 u16 destval; 1070 u16 *srcreg; 1071 1072 destoffset = decode_rm00_address(rl); 1073 DECODE_PRINTF(","); 1074 destval = fetch_data_word(destoffset); 1075 srcreg = DECODE_RM_WORD_REGISTER(rh); 1076 DECODE_PRINTF("\n"); 1077 TRACE_AND_STEP(); 1078 destval = adc_word(destval, *srcreg); 1079 store_data_word(destoffset, destval); 1080 } 1081 break; 1082 case 1: 1083 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1084 u32 destval; 1085 u32 *srcreg; 1086 1087 destoffset = decode_rm01_address(rl); 1088 DECODE_PRINTF(","); 1089 destval = fetch_data_long(destoffset); 1090 srcreg = DECODE_RM_LONG_REGISTER(rh); 1091 DECODE_PRINTF("\n"); 1092 TRACE_AND_STEP(); 1093 destval = adc_long(destval, *srcreg); 1094 store_data_long(destoffset, destval); 1095 } 1096 else { 1097 u16 destval; 1098 u16 *srcreg; 1099 1100 destoffset = decode_rm01_address(rl); 1101 DECODE_PRINTF(","); 1102 destval = fetch_data_word(destoffset); 1103 srcreg = DECODE_RM_WORD_REGISTER(rh); 1104 DECODE_PRINTF("\n"); 1105 TRACE_AND_STEP(); 1106 destval = adc_word(destval, *srcreg); 1107 store_data_word(destoffset, destval); 1108 } 1109 break; 1110 case 2: 1111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1112 u32 destval; 1113 u32 *srcreg; 1114 1115 destoffset = decode_rm10_address(rl); 1116 DECODE_PRINTF(","); 1117 destval = fetch_data_long(destoffset); 1118 srcreg = DECODE_RM_LONG_REGISTER(rh); 1119 DECODE_PRINTF("\n"); 1120 TRACE_AND_STEP(); 1121 destval = adc_long(destval, *srcreg); 1122 store_data_long(destoffset, destval); 1123 } 1124 else { 1125 u16 destval; 1126 u16 *srcreg; 1127 1128 destoffset = decode_rm10_address(rl); 1129 DECODE_PRINTF(","); 1130 destval = fetch_data_word(destoffset); 1131 srcreg = DECODE_RM_WORD_REGISTER(rh); 1132 DECODE_PRINTF("\n"); 1133 TRACE_AND_STEP(); 1134 destval = adc_word(destval, *srcreg); 1135 store_data_word(destoffset, destval); 1136 } 1137 break; 1138 case 3: /* register to register */ 1139 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1140 u32 *destreg, *srcreg; 1141 1142 destreg = DECODE_RM_LONG_REGISTER(rl); 1143 DECODE_PRINTF(","); 1144 srcreg = DECODE_RM_LONG_REGISTER(rh); 1145 DECODE_PRINTF("\n"); 1146 TRACE_AND_STEP(); 1147 *destreg = adc_long(*destreg, *srcreg); 1148 } 1149 else { 1150 u16 *destreg, *srcreg; 1151 1152 destreg = DECODE_RM_WORD_REGISTER(rl); 1153 DECODE_PRINTF(","); 1154 srcreg = DECODE_RM_WORD_REGISTER(rh); 1155 DECODE_PRINTF("\n"); 1156 TRACE_AND_STEP(); 1157 *destreg = adc_word(*destreg, *srcreg); 1158 } 1159 break; 1160 } 1161 DECODE_CLEAR_SEGOVR(); 1162 END_OF_INSTR(); 1163} 1164 1165/**************************************************************************** 1166REMARKS: 1167Handles opcode 0x12 1168****************************************************************************/ 1169static void 1170x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1171{ 1172 int mod, rl, rh; 1173 u8 *destreg, *srcreg; 1174 uint srcoffset; 1175 u8 srcval; 1176 1177 START_OF_INSTR(); 1178 DECODE_PRINTF("ADC\t"); 1179 FETCH_DECODE_MODRM(mod, rh, rl); 1180 switch (mod) { 1181 case 0: 1182 destreg = DECODE_RM_BYTE_REGISTER(rh); 1183 DECODE_PRINTF(","); 1184 srcoffset = decode_rm00_address(rl); 1185 srcval = fetch_data_byte(srcoffset); 1186 DECODE_PRINTF("\n"); 1187 TRACE_AND_STEP(); 1188 *destreg = adc_byte(*destreg, srcval); 1189 break; 1190 case 1: 1191 destreg = DECODE_RM_BYTE_REGISTER(rh); 1192 DECODE_PRINTF(","); 1193 srcoffset = decode_rm01_address(rl); 1194 srcval = fetch_data_byte(srcoffset); 1195 DECODE_PRINTF("\n"); 1196 TRACE_AND_STEP(); 1197 *destreg = adc_byte(*destreg, srcval); 1198 break; 1199 case 2: 1200 destreg = DECODE_RM_BYTE_REGISTER(rh); 1201 DECODE_PRINTF(","); 1202 srcoffset = decode_rm10_address(rl); 1203 srcval = fetch_data_byte(srcoffset); 1204 DECODE_PRINTF("\n"); 1205 TRACE_AND_STEP(); 1206 *destreg = adc_byte(*destreg, srcval); 1207 break; 1208 case 3: /* register to register */ 1209 destreg = DECODE_RM_BYTE_REGISTER(rh); 1210 DECODE_PRINTF(","); 1211 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1212 DECODE_PRINTF("\n"); 1213 TRACE_AND_STEP(); 1214 *destreg = adc_byte(*destreg, *srcreg); 1215 break; 1216 } 1217 DECODE_CLEAR_SEGOVR(); 1218 END_OF_INSTR(); 1219} 1220 1221/**************************************************************************** 1222REMARKS: 1223Handles opcode 0x13 1224****************************************************************************/ 1225static void 1226x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1)) 1227{ 1228 int mod, rl, rh; 1229 uint srcoffset; 1230 1231 START_OF_INSTR(); 1232 DECODE_PRINTF("ADC\t"); 1233 FETCH_DECODE_MODRM(mod, rh, rl); 1234 switch (mod) { 1235 case 0: 1236 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1237 u32 *destreg; 1238 u32 srcval; 1239 1240 destreg = DECODE_RM_LONG_REGISTER(rh); 1241 DECODE_PRINTF(","); 1242 srcoffset = decode_rm00_address(rl); 1243 srcval = fetch_data_long(srcoffset); 1244 DECODE_PRINTF("\n"); 1245 TRACE_AND_STEP(); 1246 *destreg = adc_long(*destreg, srcval); 1247 } 1248 else { 1249 u16 *destreg; 1250 u16 srcval; 1251 1252 destreg = DECODE_RM_WORD_REGISTER(rh); 1253 DECODE_PRINTF(","); 1254 srcoffset = decode_rm00_address(rl); 1255 srcval = fetch_data_word(srcoffset); 1256 DECODE_PRINTF("\n"); 1257 TRACE_AND_STEP(); 1258 *destreg = adc_word(*destreg, srcval); 1259 } 1260 break; 1261 case 1: 1262 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1263 u32 *destreg; 1264 u32 srcval; 1265 1266 destreg = DECODE_RM_LONG_REGISTER(rh); 1267 DECODE_PRINTF(","); 1268 srcoffset = decode_rm01_address(rl); 1269 srcval = fetch_data_long(srcoffset); 1270 DECODE_PRINTF("\n"); 1271 TRACE_AND_STEP(); 1272 *destreg = adc_long(*destreg, srcval); 1273 } 1274 else { 1275 u16 *destreg; 1276 u16 srcval; 1277 1278 destreg = DECODE_RM_WORD_REGISTER(rh); 1279 DECODE_PRINTF(","); 1280 srcoffset = decode_rm01_address(rl); 1281 srcval = fetch_data_word(srcoffset); 1282 DECODE_PRINTF("\n"); 1283 TRACE_AND_STEP(); 1284 *destreg = adc_word(*destreg, srcval); 1285 } 1286 break; 1287 case 2: 1288 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1289 u32 *destreg; 1290 u32 srcval; 1291 1292 destreg = DECODE_RM_LONG_REGISTER(rh); 1293 DECODE_PRINTF(","); 1294 srcoffset = decode_rm10_address(rl); 1295 srcval = fetch_data_long(srcoffset); 1296 DECODE_PRINTF("\n"); 1297 TRACE_AND_STEP(); 1298 *destreg = adc_long(*destreg, srcval); 1299 } 1300 else { 1301 u16 *destreg; 1302 u16 srcval; 1303 1304 destreg = DECODE_RM_WORD_REGISTER(rh); 1305 DECODE_PRINTF(","); 1306 srcoffset = decode_rm10_address(rl); 1307 srcval = fetch_data_word(srcoffset); 1308 DECODE_PRINTF("\n"); 1309 TRACE_AND_STEP(); 1310 *destreg = adc_word(*destreg, srcval); 1311 } 1312 break; 1313 case 3: /* register to register */ 1314 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1315 u32 *destreg, *srcreg; 1316 1317 destreg = DECODE_RM_LONG_REGISTER(rh); 1318 DECODE_PRINTF(","); 1319 srcreg = DECODE_RM_LONG_REGISTER(rl); 1320 DECODE_PRINTF("\n"); 1321 TRACE_AND_STEP(); 1322 *destreg = adc_long(*destreg, *srcreg); 1323 } 1324 else { 1325 u16 *destreg, *srcreg; 1326 1327 destreg = DECODE_RM_WORD_REGISTER(rh); 1328 DECODE_PRINTF(","); 1329 srcreg = DECODE_RM_WORD_REGISTER(rl); 1330 DECODE_PRINTF("\n"); 1331 TRACE_AND_STEP(); 1332 *destreg = adc_word(*destreg, *srcreg); 1333 } 1334 break; 1335 } 1336 DECODE_CLEAR_SEGOVR(); 1337 END_OF_INSTR(); 1338} 1339 1340/**************************************************************************** 1341REMARKS: 1342Handles opcode 0x14 1343****************************************************************************/ 1344static void 1345x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1346{ 1347 u8 srcval; 1348 1349 START_OF_INSTR(); 1350 DECODE_PRINTF("ADC\tAL,"); 1351 srcval = fetch_byte_imm(); 1352 DECODE_PRINTF2("%x\n", srcval); 1353 TRACE_AND_STEP(); 1354 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval); 1355 DECODE_CLEAR_SEGOVR(); 1356 END_OF_INSTR(); 1357} 1358 1359/**************************************************************************** 1360REMARKS: 1361Handles opcode 0x15 1362****************************************************************************/ 1363static void 1364x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1365{ 1366 u32 srcval; 1367 1368 START_OF_INSTR(); 1369 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1370 DECODE_PRINTF("ADC\tEAX,"); 1371 srcval = fetch_long_imm(); 1372 } 1373 else { 1374 DECODE_PRINTF("ADC\tAX,"); 1375 srcval = fetch_word_imm(); 1376 } 1377 DECODE_PRINTF2("%x\n", srcval); 1378 TRACE_AND_STEP(); 1379 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1380 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval); 1381 } 1382 else { 1383 M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval); 1384 } 1385 DECODE_CLEAR_SEGOVR(); 1386 END_OF_INSTR(); 1387} 1388 1389/**************************************************************************** 1390REMARKS: 1391Handles opcode 0x16 1392****************************************************************************/ 1393static void 1394x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 1395{ 1396 START_OF_INSTR(); 1397 DECODE_PRINTF("PUSH\tSS\n"); 1398 TRACE_AND_STEP(); 1399 push_word(M.x86.R_SS); 1400 DECODE_CLEAR_SEGOVR(); 1401 END_OF_INSTR(); 1402} 1403 1404/**************************************************************************** 1405REMARKS: 1406Handles opcode 0x17 1407****************************************************************************/ 1408static void 1409x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 1410{ 1411 START_OF_INSTR(); 1412 DECODE_PRINTF("POP\tSS\n"); 1413 TRACE_AND_STEP(); 1414 M.x86.R_SS = pop_word(); 1415 DECODE_CLEAR_SEGOVR(); 1416 END_OF_INSTR(); 1417} 1418 1419/**************************************************************************** 1420REMARKS: 1421Handles opcode 0x18 1422****************************************************************************/ 1423static void 1424x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1425{ 1426 int mod, rl, rh; 1427 u8 *destreg, *srcreg; 1428 uint destoffset; 1429 u8 destval; 1430 1431 START_OF_INSTR(); 1432 DECODE_PRINTF("SBB\t"); 1433 FETCH_DECODE_MODRM(mod, rh, rl); 1434 switch (mod) { 1435 case 0: 1436 destoffset = decode_rm00_address(rl); 1437 DECODE_PRINTF(","); 1438 destval = fetch_data_byte(destoffset); 1439 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1440 DECODE_PRINTF("\n"); 1441 TRACE_AND_STEP(); 1442 destval = sbb_byte(destval, *srcreg); 1443 store_data_byte(destoffset, destval); 1444 break; 1445 case 1: 1446 destoffset = decode_rm01_address(rl); 1447 DECODE_PRINTF(","); 1448 destval = fetch_data_byte(destoffset); 1449 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1450 DECODE_PRINTF("\n"); 1451 TRACE_AND_STEP(); 1452 destval = sbb_byte(destval, *srcreg); 1453 store_data_byte(destoffset, destval); 1454 break; 1455 case 2: 1456 destoffset = decode_rm10_address(rl); 1457 DECODE_PRINTF(","); 1458 destval = fetch_data_byte(destoffset); 1459 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1460 DECODE_PRINTF("\n"); 1461 TRACE_AND_STEP(); 1462 destval = sbb_byte(destval, *srcreg); 1463 store_data_byte(destoffset, destval); 1464 break; 1465 case 3: /* register to register */ 1466 destreg = DECODE_RM_BYTE_REGISTER(rl); 1467 DECODE_PRINTF(","); 1468 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1469 DECODE_PRINTF("\n"); 1470 TRACE_AND_STEP(); 1471 *destreg = sbb_byte(*destreg, *srcreg); 1472 break; 1473 } 1474 DECODE_CLEAR_SEGOVR(); 1475 END_OF_INSTR(); 1476} 1477 1478/**************************************************************************** 1479REMARKS: 1480Handles opcode 0x19 1481****************************************************************************/ 1482static void 1483x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1)) 1484{ 1485 int mod, rl, rh; 1486 uint destoffset; 1487 1488 START_OF_INSTR(); 1489 DECODE_PRINTF("SBB\t"); 1490 FETCH_DECODE_MODRM(mod, rh, rl); 1491 switch (mod) { 1492 case 0: 1493 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1494 u32 destval; 1495 u32 *srcreg; 1496 1497 destoffset = decode_rm00_address(rl); 1498 DECODE_PRINTF(","); 1499 destval = fetch_data_long(destoffset); 1500 srcreg = DECODE_RM_LONG_REGISTER(rh); 1501 DECODE_PRINTF("\n"); 1502 TRACE_AND_STEP(); 1503 destval = sbb_long(destval, *srcreg); 1504 store_data_long(destoffset, destval); 1505 } 1506 else { 1507 u16 destval; 1508 u16 *srcreg; 1509 1510 destoffset = decode_rm00_address(rl); 1511 DECODE_PRINTF(","); 1512 destval = fetch_data_word(destoffset); 1513 srcreg = DECODE_RM_WORD_REGISTER(rh); 1514 DECODE_PRINTF("\n"); 1515 TRACE_AND_STEP(); 1516 destval = sbb_word(destval, *srcreg); 1517 store_data_word(destoffset, destval); 1518 } 1519 break; 1520 case 1: 1521 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1522 u32 destval; 1523 u32 *srcreg; 1524 1525 destoffset = decode_rm01_address(rl); 1526 DECODE_PRINTF(","); 1527 destval = fetch_data_long(destoffset); 1528 srcreg = DECODE_RM_LONG_REGISTER(rh); 1529 DECODE_PRINTF("\n"); 1530 TRACE_AND_STEP(); 1531 destval = sbb_long(destval, *srcreg); 1532 store_data_long(destoffset, destval); 1533 } 1534 else { 1535 u16 destval; 1536 u16 *srcreg; 1537 1538 destoffset = decode_rm01_address(rl); 1539 DECODE_PRINTF(","); 1540 destval = fetch_data_word(destoffset); 1541 srcreg = DECODE_RM_WORD_REGISTER(rh); 1542 DECODE_PRINTF("\n"); 1543 TRACE_AND_STEP(); 1544 destval = sbb_word(destval, *srcreg); 1545 store_data_word(destoffset, destval); 1546 } 1547 break; 1548 case 2: 1549 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1550 u32 destval; 1551 u32 *srcreg; 1552 1553 destoffset = decode_rm10_address(rl); 1554 DECODE_PRINTF(","); 1555 destval = fetch_data_long(destoffset); 1556 srcreg = DECODE_RM_LONG_REGISTER(rh); 1557 DECODE_PRINTF("\n"); 1558 TRACE_AND_STEP(); 1559 destval = sbb_long(destval, *srcreg); 1560 store_data_long(destoffset, destval); 1561 } 1562 else { 1563 u16 destval; 1564 u16 *srcreg; 1565 1566 destoffset = decode_rm10_address(rl); 1567 DECODE_PRINTF(","); 1568 destval = fetch_data_word(destoffset); 1569 srcreg = DECODE_RM_WORD_REGISTER(rh); 1570 DECODE_PRINTF("\n"); 1571 TRACE_AND_STEP(); 1572 destval = sbb_word(destval, *srcreg); 1573 store_data_word(destoffset, destval); 1574 } 1575 break; 1576 case 3: /* register to register */ 1577 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1578 u32 *destreg, *srcreg; 1579 1580 destreg = DECODE_RM_LONG_REGISTER(rl); 1581 DECODE_PRINTF(","); 1582 srcreg = DECODE_RM_LONG_REGISTER(rh); 1583 DECODE_PRINTF("\n"); 1584 TRACE_AND_STEP(); 1585 *destreg = sbb_long(*destreg, *srcreg); 1586 } 1587 else { 1588 u16 *destreg, *srcreg; 1589 1590 destreg = DECODE_RM_WORD_REGISTER(rl); 1591 DECODE_PRINTF(","); 1592 srcreg = DECODE_RM_WORD_REGISTER(rh); 1593 DECODE_PRINTF("\n"); 1594 TRACE_AND_STEP(); 1595 *destreg = sbb_word(*destreg, *srcreg); 1596 } 1597 break; 1598 } 1599 DECODE_CLEAR_SEGOVR(); 1600 END_OF_INSTR(); 1601} 1602 1603/**************************************************************************** 1604REMARKS: 1605Handles opcode 0x1a 1606****************************************************************************/ 1607static void 1608x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1609{ 1610 int mod, rl, rh; 1611 u8 *destreg, *srcreg; 1612 uint srcoffset; 1613 u8 srcval; 1614 1615 START_OF_INSTR(); 1616 DECODE_PRINTF("SBB\t"); 1617 FETCH_DECODE_MODRM(mod, rh, rl); 1618 switch (mod) { 1619 case 0: 1620 destreg = DECODE_RM_BYTE_REGISTER(rh); 1621 DECODE_PRINTF(","); 1622 srcoffset = decode_rm00_address(rl); 1623 srcval = fetch_data_byte(srcoffset); 1624 DECODE_PRINTF("\n"); 1625 TRACE_AND_STEP(); 1626 *destreg = sbb_byte(*destreg, srcval); 1627 break; 1628 case 1: 1629 destreg = DECODE_RM_BYTE_REGISTER(rh); 1630 DECODE_PRINTF(","); 1631 srcoffset = decode_rm01_address(rl); 1632 srcval = fetch_data_byte(srcoffset); 1633 DECODE_PRINTF("\n"); 1634 TRACE_AND_STEP(); 1635 *destreg = sbb_byte(*destreg, srcval); 1636 break; 1637 case 2: 1638 destreg = DECODE_RM_BYTE_REGISTER(rh); 1639 DECODE_PRINTF(","); 1640 srcoffset = decode_rm10_address(rl); 1641 srcval = fetch_data_byte(srcoffset); 1642 DECODE_PRINTF("\n"); 1643 TRACE_AND_STEP(); 1644 *destreg = sbb_byte(*destreg, srcval); 1645 break; 1646 case 3: /* register to register */ 1647 destreg = DECODE_RM_BYTE_REGISTER(rh); 1648 DECODE_PRINTF(","); 1649 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1650 DECODE_PRINTF("\n"); 1651 TRACE_AND_STEP(); 1652 *destreg = sbb_byte(*destreg, *srcreg); 1653 break; 1654 } 1655 DECODE_CLEAR_SEGOVR(); 1656 END_OF_INSTR(); 1657} 1658 1659/**************************************************************************** 1660REMARKS: 1661Handles opcode 0x1b 1662****************************************************************************/ 1663static void 1664x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1)) 1665{ 1666 int mod, rl, rh; 1667 uint srcoffset; 1668 1669 START_OF_INSTR(); 1670 DECODE_PRINTF("SBB\t"); 1671 FETCH_DECODE_MODRM(mod, rh, rl); 1672 switch (mod) { 1673 case 0: 1674 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1675 u32 *destreg; 1676 u32 srcval; 1677 1678 destreg = DECODE_RM_LONG_REGISTER(rh); 1679 DECODE_PRINTF(","); 1680 srcoffset = decode_rm00_address(rl); 1681 srcval = fetch_data_long(srcoffset); 1682 DECODE_PRINTF("\n"); 1683 TRACE_AND_STEP(); 1684 *destreg = sbb_long(*destreg, srcval); 1685 } 1686 else { 1687 u16 *destreg; 1688 u16 srcval; 1689 1690 destreg = DECODE_RM_WORD_REGISTER(rh); 1691 DECODE_PRINTF(","); 1692 srcoffset = decode_rm00_address(rl); 1693 srcval = fetch_data_word(srcoffset); 1694 DECODE_PRINTF("\n"); 1695 TRACE_AND_STEP(); 1696 *destreg = sbb_word(*destreg, srcval); 1697 } 1698 break; 1699 case 1: 1700 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1701 u32 *destreg; 1702 u32 srcval; 1703 1704 destreg = DECODE_RM_LONG_REGISTER(rh); 1705 DECODE_PRINTF(","); 1706 srcoffset = decode_rm01_address(rl); 1707 srcval = fetch_data_long(srcoffset); 1708 DECODE_PRINTF("\n"); 1709 TRACE_AND_STEP(); 1710 *destreg = sbb_long(*destreg, srcval); 1711 } 1712 else { 1713 u16 *destreg; 1714 u16 srcval; 1715 1716 destreg = DECODE_RM_WORD_REGISTER(rh); 1717 DECODE_PRINTF(","); 1718 srcoffset = decode_rm01_address(rl); 1719 srcval = fetch_data_word(srcoffset); 1720 DECODE_PRINTF("\n"); 1721 TRACE_AND_STEP(); 1722 *destreg = sbb_word(*destreg, srcval); 1723 } 1724 break; 1725 case 2: 1726 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1727 u32 *destreg; 1728 u32 srcval; 1729 1730 destreg = DECODE_RM_LONG_REGISTER(rh); 1731 DECODE_PRINTF(","); 1732 srcoffset = decode_rm10_address(rl); 1733 srcval = fetch_data_long(srcoffset); 1734 DECODE_PRINTF("\n"); 1735 TRACE_AND_STEP(); 1736 *destreg = sbb_long(*destreg, srcval); 1737 } 1738 else { 1739 u16 *destreg; 1740 u16 srcval; 1741 1742 destreg = DECODE_RM_WORD_REGISTER(rh); 1743 DECODE_PRINTF(","); 1744 srcoffset = decode_rm10_address(rl); 1745 srcval = fetch_data_word(srcoffset); 1746 DECODE_PRINTF("\n"); 1747 TRACE_AND_STEP(); 1748 *destreg = sbb_word(*destreg, srcval); 1749 } 1750 break; 1751 case 3: /* register to register */ 1752 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1753 u32 *destreg, *srcreg; 1754 1755 destreg = DECODE_RM_LONG_REGISTER(rh); 1756 DECODE_PRINTF(","); 1757 srcreg = DECODE_RM_LONG_REGISTER(rl); 1758 DECODE_PRINTF("\n"); 1759 TRACE_AND_STEP(); 1760 *destreg = sbb_long(*destreg, *srcreg); 1761 } 1762 else { 1763 u16 *destreg, *srcreg; 1764 1765 destreg = DECODE_RM_WORD_REGISTER(rh); 1766 DECODE_PRINTF(","); 1767 srcreg = DECODE_RM_WORD_REGISTER(rl); 1768 DECODE_PRINTF("\n"); 1769 TRACE_AND_STEP(); 1770 *destreg = sbb_word(*destreg, *srcreg); 1771 } 1772 break; 1773 } 1774 DECODE_CLEAR_SEGOVR(); 1775 END_OF_INSTR(); 1776} 1777 1778/**************************************************************************** 1779REMARKS: 1780Handles opcode 0x1c 1781****************************************************************************/ 1782static void 1783x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1784{ 1785 u8 srcval; 1786 1787 START_OF_INSTR(); 1788 DECODE_PRINTF("SBB\tAL,"); 1789 srcval = fetch_byte_imm(); 1790 DECODE_PRINTF2("%x\n", srcval); 1791 TRACE_AND_STEP(); 1792 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval); 1793 DECODE_CLEAR_SEGOVR(); 1794 END_OF_INSTR(); 1795} 1796 1797/**************************************************************************** 1798REMARKS: 1799Handles opcode 0x1d 1800****************************************************************************/ 1801static void 1802x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1803{ 1804 u32 srcval; 1805 1806 START_OF_INSTR(); 1807 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1808 DECODE_PRINTF("SBB\tEAX,"); 1809 srcval = fetch_long_imm(); 1810 } 1811 else { 1812 DECODE_PRINTF("SBB\tAX,"); 1813 srcval = fetch_word_imm(); 1814 } 1815 DECODE_PRINTF2("%x\n", srcval); 1816 TRACE_AND_STEP(); 1817 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1818 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval); 1819 } 1820 else { 1821 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval); 1822 } 1823 DECODE_CLEAR_SEGOVR(); 1824 END_OF_INSTR(); 1825} 1826 1827/**************************************************************************** 1828REMARKS: 1829Handles opcode 0x1e 1830****************************************************************************/ 1831static void 1832x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 1833{ 1834 START_OF_INSTR(); 1835 DECODE_PRINTF("PUSH\tDS\n"); 1836 TRACE_AND_STEP(); 1837 push_word(M.x86.R_DS); 1838 DECODE_CLEAR_SEGOVR(); 1839 END_OF_INSTR(); 1840} 1841 1842/**************************************************************************** 1843REMARKS: 1844Handles opcode 0x1f 1845****************************************************************************/ 1846static void 1847x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 1848{ 1849 START_OF_INSTR(); 1850 DECODE_PRINTF("POP\tDS\n"); 1851 TRACE_AND_STEP(); 1852 M.x86.R_DS = pop_word(); 1853 DECODE_CLEAR_SEGOVR(); 1854 END_OF_INSTR(); 1855} 1856 1857/**************************************************************************** 1858REMARKS: 1859Handles opcode 0x20 1860****************************************************************************/ 1861static void 1862x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1863{ 1864 int mod, rl, rh; 1865 u8 *destreg, *srcreg; 1866 uint destoffset; 1867 u8 destval; 1868 1869 START_OF_INSTR(); 1870 DECODE_PRINTF("AND\t"); 1871 FETCH_DECODE_MODRM(mod, rh, rl); 1872 1873 switch (mod) { 1874 case 0: 1875 destoffset = decode_rm00_address(rl); 1876 DECODE_PRINTF(","); 1877 destval = fetch_data_byte(destoffset); 1878 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1879 DECODE_PRINTF("\n"); 1880 TRACE_AND_STEP(); 1881 destval = and_byte(destval, *srcreg); 1882 store_data_byte(destoffset, destval); 1883 break; 1884 1885 case 1: 1886 destoffset = decode_rm01_address(rl); 1887 DECODE_PRINTF(","); 1888 destval = fetch_data_byte(destoffset); 1889 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1890 DECODE_PRINTF("\n"); 1891 TRACE_AND_STEP(); 1892 destval = and_byte(destval, *srcreg); 1893 store_data_byte(destoffset, destval); 1894 break; 1895 1896 case 2: 1897 destoffset = decode_rm10_address(rl); 1898 DECODE_PRINTF(","); 1899 destval = fetch_data_byte(destoffset); 1900 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1901 DECODE_PRINTF("\n"); 1902 TRACE_AND_STEP(); 1903 destval = and_byte(destval, *srcreg); 1904 store_data_byte(destoffset, destval); 1905 break; 1906 1907 case 3: /* register to register */ 1908 destreg = DECODE_RM_BYTE_REGISTER(rl); 1909 DECODE_PRINTF(","); 1910 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1911 DECODE_PRINTF("\n"); 1912 TRACE_AND_STEP(); 1913 *destreg = and_byte(*destreg, *srcreg); 1914 break; 1915 } 1916 DECODE_CLEAR_SEGOVR(); 1917 END_OF_INSTR(); 1918} 1919 1920/**************************************************************************** 1921REMARKS: 1922Handles opcode 0x21 1923****************************************************************************/ 1924static void 1925x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1)) 1926{ 1927 int mod, rl, rh; 1928 uint destoffset; 1929 1930 START_OF_INSTR(); 1931 DECODE_PRINTF("AND\t"); 1932 FETCH_DECODE_MODRM(mod, rh, rl); 1933 switch (mod) { 1934 case 0: 1935 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1936 u32 destval; 1937 u32 *srcreg; 1938 1939 destoffset = decode_rm00_address(rl); 1940 DECODE_PRINTF(","); 1941 destval = fetch_data_long(destoffset); 1942 srcreg = DECODE_RM_LONG_REGISTER(rh); 1943 DECODE_PRINTF("\n"); 1944 TRACE_AND_STEP(); 1945 destval = and_long(destval, *srcreg); 1946 store_data_long(destoffset, destval); 1947 } 1948 else { 1949 u16 destval; 1950 u16 *srcreg; 1951 1952 destoffset = decode_rm00_address(rl); 1953 DECODE_PRINTF(","); 1954 destval = fetch_data_word(destoffset); 1955 srcreg = DECODE_RM_WORD_REGISTER(rh); 1956 DECODE_PRINTF("\n"); 1957 TRACE_AND_STEP(); 1958 destval = and_word(destval, *srcreg); 1959 store_data_word(destoffset, destval); 1960 } 1961 break; 1962 case 1: 1963 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1964 u32 destval; 1965 u32 *srcreg; 1966 1967 destoffset = decode_rm01_address(rl); 1968 DECODE_PRINTF(","); 1969 destval = fetch_data_long(destoffset); 1970 srcreg = DECODE_RM_LONG_REGISTER(rh); 1971 DECODE_PRINTF("\n"); 1972 TRACE_AND_STEP(); 1973 destval = and_long(destval, *srcreg); 1974 store_data_long(destoffset, destval); 1975 } 1976 else { 1977 u16 destval; 1978 u16 *srcreg; 1979 1980 destoffset = decode_rm01_address(rl); 1981 DECODE_PRINTF(","); 1982 destval = fetch_data_word(destoffset); 1983 srcreg = DECODE_RM_WORD_REGISTER(rh); 1984 DECODE_PRINTF("\n"); 1985 TRACE_AND_STEP(); 1986 destval = and_word(destval, *srcreg); 1987 store_data_word(destoffset, destval); 1988 } 1989 break; 1990 case 2: 1991 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1992 u32 destval; 1993 u32 *srcreg; 1994 1995 destoffset = decode_rm10_address(rl); 1996 DECODE_PRINTF(","); 1997 destval = fetch_data_long(destoffset); 1998 srcreg = DECODE_RM_LONG_REGISTER(rh); 1999 DECODE_PRINTF("\n"); 2000 TRACE_AND_STEP(); 2001 destval = and_long(destval, *srcreg); 2002 store_data_long(destoffset, destval); 2003 } 2004 else { 2005 u16 destval; 2006 u16 *srcreg; 2007 2008 destoffset = decode_rm10_address(rl); 2009 DECODE_PRINTF(","); 2010 destval = fetch_data_word(destoffset); 2011 srcreg = DECODE_RM_WORD_REGISTER(rh); 2012 DECODE_PRINTF("\n"); 2013 TRACE_AND_STEP(); 2014 destval = and_word(destval, *srcreg); 2015 store_data_word(destoffset, destval); 2016 } 2017 break; 2018 case 3: /* register to register */ 2019 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2020 u32 *destreg, *srcreg; 2021 2022 destreg = DECODE_RM_LONG_REGISTER(rl); 2023 DECODE_PRINTF(","); 2024 srcreg = DECODE_RM_LONG_REGISTER(rh); 2025 DECODE_PRINTF("\n"); 2026 TRACE_AND_STEP(); 2027 *destreg = and_long(*destreg, *srcreg); 2028 } 2029 else { 2030 u16 *destreg, *srcreg; 2031 2032 destreg = DECODE_RM_WORD_REGISTER(rl); 2033 DECODE_PRINTF(","); 2034 srcreg = DECODE_RM_WORD_REGISTER(rh); 2035 DECODE_PRINTF("\n"); 2036 TRACE_AND_STEP(); 2037 *destreg = and_word(*destreg, *srcreg); 2038 } 2039 break; 2040 } 2041 DECODE_CLEAR_SEGOVR(); 2042 END_OF_INSTR(); 2043} 2044 2045/**************************************************************************** 2046REMARKS: 2047Handles opcode 0x22 2048****************************************************************************/ 2049static void 2050x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2051{ 2052 int mod, rl, rh; 2053 u8 *destreg, *srcreg; 2054 uint srcoffset; 2055 u8 srcval; 2056 2057 START_OF_INSTR(); 2058 DECODE_PRINTF("AND\t"); 2059 FETCH_DECODE_MODRM(mod, rh, rl); 2060 switch (mod) { 2061 case 0: 2062 destreg = DECODE_RM_BYTE_REGISTER(rh); 2063 DECODE_PRINTF(","); 2064 srcoffset = decode_rm00_address(rl); 2065 srcval = fetch_data_byte(srcoffset); 2066 DECODE_PRINTF("\n"); 2067 TRACE_AND_STEP(); 2068 *destreg = and_byte(*destreg, srcval); 2069 break; 2070 case 1: 2071 destreg = DECODE_RM_BYTE_REGISTER(rh); 2072 DECODE_PRINTF(","); 2073 srcoffset = decode_rm01_address(rl); 2074 srcval = fetch_data_byte(srcoffset); 2075 DECODE_PRINTF("\n"); 2076 TRACE_AND_STEP(); 2077 *destreg = and_byte(*destreg, srcval); 2078 break; 2079 case 2: 2080 destreg = DECODE_RM_BYTE_REGISTER(rh); 2081 DECODE_PRINTF(","); 2082 srcoffset = decode_rm10_address(rl); 2083 srcval = fetch_data_byte(srcoffset); 2084 DECODE_PRINTF("\n"); 2085 TRACE_AND_STEP(); 2086 *destreg = and_byte(*destreg, srcval); 2087 break; 2088 case 3: /* register to register */ 2089 destreg = DECODE_RM_BYTE_REGISTER(rh); 2090 DECODE_PRINTF(","); 2091 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2092 DECODE_PRINTF("\n"); 2093 TRACE_AND_STEP(); 2094 *destreg = and_byte(*destreg, *srcreg); 2095 break; 2096 } 2097 DECODE_CLEAR_SEGOVR(); 2098 END_OF_INSTR(); 2099} 2100 2101/**************************************************************************** 2102REMARKS: 2103Handles opcode 0x23 2104****************************************************************************/ 2105static void 2106x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1)) 2107{ 2108 int mod, rl, rh; 2109 uint srcoffset; 2110 2111 START_OF_INSTR(); 2112 DECODE_PRINTF("AND\t"); 2113 FETCH_DECODE_MODRM(mod, rh, rl); 2114 switch (mod) { 2115 case 0: 2116 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2117 u32 *destreg; 2118 u32 srcval; 2119 2120 destreg = DECODE_RM_LONG_REGISTER(rh); 2121 DECODE_PRINTF(","); 2122 srcoffset = decode_rm00_address(rl); 2123 srcval = fetch_data_long(srcoffset); 2124 DECODE_PRINTF("\n"); 2125 TRACE_AND_STEP(); 2126 *destreg = and_long(*destreg, srcval); 2127 } 2128 else { 2129 u16 *destreg; 2130 u16 srcval; 2131 2132 destreg = DECODE_RM_WORD_REGISTER(rh); 2133 DECODE_PRINTF(","); 2134 srcoffset = decode_rm00_address(rl); 2135 srcval = fetch_data_word(srcoffset); 2136 DECODE_PRINTF("\n"); 2137 TRACE_AND_STEP(); 2138 *destreg = and_word(*destreg, srcval); 2139 } 2140 break; 2141 case 1: 2142 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2143 u32 *destreg; 2144 u32 srcval; 2145 2146 destreg = DECODE_RM_LONG_REGISTER(rh); 2147 DECODE_PRINTF(","); 2148 srcoffset = decode_rm01_address(rl); 2149 srcval = fetch_data_long(srcoffset); 2150 DECODE_PRINTF("\n"); 2151 TRACE_AND_STEP(); 2152 *destreg = and_long(*destreg, srcval); 2153 break; 2154 } 2155 else { 2156 u16 *destreg; 2157 u16 srcval; 2158 2159 destreg = DECODE_RM_WORD_REGISTER(rh); 2160 DECODE_PRINTF(","); 2161 srcoffset = decode_rm01_address(rl); 2162 srcval = fetch_data_word(srcoffset); 2163 DECODE_PRINTF("\n"); 2164 TRACE_AND_STEP(); 2165 *destreg = and_word(*destreg, srcval); 2166 break; 2167 } 2168 case 2: 2169 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2170 u32 *destreg; 2171 u32 srcval; 2172 2173 destreg = DECODE_RM_LONG_REGISTER(rh); 2174 DECODE_PRINTF(","); 2175 srcoffset = decode_rm10_address(rl); 2176 srcval = fetch_data_long(srcoffset); 2177 DECODE_PRINTF("\n"); 2178 TRACE_AND_STEP(); 2179 *destreg = and_long(*destreg, srcval); 2180 } 2181 else { 2182 u16 *destreg; 2183 u16 srcval; 2184 2185 destreg = DECODE_RM_WORD_REGISTER(rh); 2186 DECODE_PRINTF(","); 2187 srcoffset = decode_rm10_address(rl); 2188 srcval = fetch_data_word(srcoffset); 2189 DECODE_PRINTF("\n"); 2190 TRACE_AND_STEP(); 2191 *destreg = and_word(*destreg, srcval); 2192 } 2193 break; 2194 case 3: /* register to register */ 2195 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2196 u32 *destreg, *srcreg; 2197 2198 destreg = DECODE_RM_LONG_REGISTER(rh); 2199 DECODE_PRINTF(","); 2200 srcreg = DECODE_RM_LONG_REGISTER(rl); 2201 DECODE_PRINTF("\n"); 2202 TRACE_AND_STEP(); 2203 *destreg = and_long(*destreg, *srcreg); 2204 } 2205 else { 2206 u16 *destreg, *srcreg; 2207 2208 destreg = DECODE_RM_WORD_REGISTER(rh); 2209 DECODE_PRINTF(","); 2210 srcreg = DECODE_RM_WORD_REGISTER(rl); 2211 DECODE_PRINTF("\n"); 2212 TRACE_AND_STEP(); 2213 *destreg = and_word(*destreg, *srcreg); 2214 } 2215 break; 2216 } 2217 DECODE_CLEAR_SEGOVR(); 2218 END_OF_INSTR(); 2219} 2220 2221/**************************************************************************** 2222REMARKS: 2223Handles opcode 0x24 2224****************************************************************************/ 2225static void 2226x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2227{ 2228 u8 srcval; 2229 2230 START_OF_INSTR(); 2231 DECODE_PRINTF("AND\tAL,"); 2232 srcval = fetch_byte_imm(); 2233 DECODE_PRINTF2("%x\n", srcval); 2234 TRACE_AND_STEP(); 2235 M.x86.R_AL = and_byte(M.x86.R_AL, srcval); 2236 DECODE_CLEAR_SEGOVR(); 2237 END_OF_INSTR(); 2238} 2239 2240/**************************************************************************** 2241REMARKS: 2242Handles opcode 0x25 2243****************************************************************************/ 2244static void 2245x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2246{ 2247 u32 srcval; 2248 2249 START_OF_INSTR(); 2250 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2251 DECODE_PRINTF("AND\tEAX,"); 2252 srcval = fetch_long_imm(); 2253 } 2254 else { 2255 DECODE_PRINTF("AND\tAX,"); 2256 srcval = fetch_word_imm(); 2257 } 2258 DECODE_PRINTF2("%x\n", srcval); 2259 TRACE_AND_STEP(); 2260 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2261 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval); 2262 } 2263 else { 2264 M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval); 2265 } 2266 DECODE_CLEAR_SEGOVR(); 2267 END_OF_INSTR(); 2268} 2269 2270/**************************************************************************** 2271REMARKS: 2272Handles opcode 0x26 2273****************************************************************************/ 2274static void 2275x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 2276{ 2277 START_OF_INSTR(); 2278 DECODE_PRINTF("ES:\n"); 2279 TRACE_AND_STEP(); 2280 M.x86.mode |= SYSMODE_SEGOVR_ES; 2281 /* 2282 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 2283 * opcode subroutines we do not want to do this. 2284 */ 2285 END_OF_INSTR(); 2286} 2287 2288/**************************************************************************** 2289REMARKS: 2290Handles opcode 0x27 2291****************************************************************************/ 2292static void 2293x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 2294{ 2295 START_OF_INSTR(); 2296 DECODE_PRINTF("DAA\n"); 2297 TRACE_AND_STEP(); 2298 M.x86.R_AL = daa_byte(M.x86.R_AL); 2299 DECODE_CLEAR_SEGOVR(); 2300 END_OF_INSTR(); 2301} 2302 2303/**************************************************************************** 2304REMARKS: 2305Handles opcode 0x28 2306****************************************************************************/ 2307static void 2308x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2309{ 2310 int mod, rl, rh; 2311 u8 *destreg, *srcreg; 2312 uint destoffset; 2313 u8 destval; 2314 2315 START_OF_INSTR(); 2316 DECODE_PRINTF("SUB\t"); 2317 FETCH_DECODE_MODRM(mod, rh, rl); 2318 switch (mod) { 2319 case 0: 2320 destoffset = decode_rm00_address(rl); 2321 DECODE_PRINTF(","); 2322 destval = fetch_data_byte(destoffset); 2323 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2324 DECODE_PRINTF("\n"); 2325 TRACE_AND_STEP(); 2326 destval = sub_byte(destval, *srcreg); 2327 store_data_byte(destoffset, destval); 2328 break; 2329 case 1: 2330 destoffset = decode_rm01_address(rl); 2331 DECODE_PRINTF(","); 2332 destval = fetch_data_byte(destoffset); 2333 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2334 DECODE_PRINTF("\n"); 2335 TRACE_AND_STEP(); 2336 destval = sub_byte(destval, *srcreg); 2337 store_data_byte(destoffset, destval); 2338 break; 2339 case 2: 2340 destoffset = decode_rm10_address(rl); 2341 DECODE_PRINTF(","); 2342 destval = fetch_data_byte(destoffset); 2343 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2344 DECODE_PRINTF("\n"); 2345 TRACE_AND_STEP(); 2346 destval = sub_byte(destval, *srcreg); 2347 store_data_byte(destoffset, destval); 2348 break; 2349 case 3: /* register to register */ 2350 destreg = DECODE_RM_BYTE_REGISTER(rl); 2351 DECODE_PRINTF(","); 2352 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2353 DECODE_PRINTF("\n"); 2354 TRACE_AND_STEP(); 2355 *destreg = sub_byte(*destreg, *srcreg); 2356 break; 2357 } 2358 DECODE_CLEAR_SEGOVR(); 2359 END_OF_INSTR(); 2360} 2361 2362/**************************************************************************** 2363REMARKS: 2364Handles opcode 0x29 2365****************************************************************************/ 2366static void 2367x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1)) 2368{ 2369 int mod, rl, rh; 2370 uint destoffset; 2371 2372 START_OF_INSTR(); 2373 DECODE_PRINTF("SUB\t"); 2374 FETCH_DECODE_MODRM(mod, rh, rl); 2375 switch (mod) { 2376 case 0: 2377 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2378 u32 destval; 2379 u32 *srcreg; 2380 2381 destoffset = decode_rm00_address(rl); 2382 DECODE_PRINTF(","); 2383 destval = fetch_data_long(destoffset); 2384 srcreg = DECODE_RM_LONG_REGISTER(rh); 2385 DECODE_PRINTF("\n"); 2386 TRACE_AND_STEP(); 2387 destval = sub_long(destval, *srcreg); 2388 store_data_long(destoffset, destval); 2389 } 2390 else { 2391 u16 destval; 2392 u16 *srcreg; 2393 2394 destoffset = decode_rm00_address(rl); 2395 DECODE_PRINTF(","); 2396 destval = fetch_data_word(destoffset); 2397 srcreg = DECODE_RM_WORD_REGISTER(rh); 2398 DECODE_PRINTF("\n"); 2399 TRACE_AND_STEP(); 2400 destval = sub_word(destval, *srcreg); 2401 store_data_word(destoffset, destval); 2402 } 2403 break; 2404 case 1: 2405 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2406 u32 destval; 2407 u32 *srcreg; 2408 2409 destoffset = decode_rm01_address(rl); 2410 DECODE_PRINTF(","); 2411 destval = fetch_data_long(destoffset); 2412 srcreg = DECODE_RM_LONG_REGISTER(rh); 2413 DECODE_PRINTF("\n"); 2414 TRACE_AND_STEP(); 2415 destval = sub_long(destval, *srcreg); 2416 store_data_long(destoffset, destval); 2417 } 2418 else { 2419 u16 destval; 2420 u16 *srcreg; 2421 2422 destoffset = decode_rm01_address(rl); 2423 DECODE_PRINTF(","); 2424 destval = fetch_data_word(destoffset); 2425 srcreg = DECODE_RM_WORD_REGISTER(rh); 2426 DECODE_PRINTF("\n"); 2427 TRACE_AND_STEP(); 2428 destval = sub_word(destval, *srcreg); 2429 store_data_word(destoffset, destval); 2430 } 2431 break; 2432 case 2: 2433 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2434 u32 destval; 2435 u32 *srcreg; 2436 2437 destoffset = decode_rm10_address(rl); 2438 DECODE_PRINTF(","); 2439 destval = fetch_data_long(destoffset); 2440 srcreg = DECODE_RM_LONG_REGISTER(rh); 2441 DECODE_PRINTF("\n"); 2442 TRACE_AND_STEP(); 2443 destval = sub_long(destval, *srcreg); 2444 store_data_long(destoffset, destval); 2445 } 2446 else { 2447 u16 destval; 2448 u16 *srcreg; 2449 2450 destoffset = decode_rm10_address(rl); 2451 DECODE_PRINTF(","); 2452 destval = fetch_data_word(destoffset); 2453 srcreg = DECODE_RM_WORD_REGISTER(rh); 2454 DECODE_PRINTF("\n"); 2455 TRACE_AND_STEP(); 2456 destval = sub_word(destval, *srcreg); 2457 store_data_word(destoffset, destval); 2458 } 2459 break; 2460 case 3: /* register to register */ 2461 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2462 u32 *destreg, *srcreg; 2463 2464 destreg = DECODE_RM_LONG_REGISTER(rl); 2465 DECODE_PRINTF(","); 2466 srcreg = DECODE_RM_LONG_REGISTER(rh); 2467 DECODE_PRINTF("\n"); 2468 TRACE_AND_STEP(); 2469 *destreg = sub_long(*destreg, *srcreg); 2470 } 2471 else { 2472 u16 *destreg, *srcreg; 2473 2474 destreg = DECODE_RM_WORD_REGISTER(rl); 2475 DECODE_PRINTF(","); 2476 srcreg = DECODE_RM_WORD_REGISTER(rh); 2477 DECODE_PRINTF("\n"); 2478 TRACE_AND_STEP(); 2479 *destreg = sub_word(*destreg, *srcreg); 2480 } 2481 break; 2482 } 2483 DECODE_CLEAR_SEGOVR(); 2484 END_OF_INSTR(); 2485} 2486 2487/**************************************************************************** 2488REMARKS: 2489Handles opcode 0x2a 2490****************************************************************************/ 2491static void 2492x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2493{ 2494 int mod, rl, rh; 2495 u8 *destreg, *srcreg; 2496 uint srcoffset; 2497 u8 srcval; 2498 2499 START_OF_INSTR(); 2500 DECODE_PRINTF("SUB\t"); 2501 FETCH_DECODE_MODRM(mod, rh, rl); 2502 switch (mod) { 2503 case 0: 2504 destreg = DECODE_RM_BYTE_REGISTER(rh); 2505 DECODE_PRINTF(","); 2506 srcoffset = decode_rm00_address(rl); 2507 srcval = fetch_data_byte(srcoffset); 2508 DECODE_PRINTF("\n"); 2509 TRACE_AND_STEP(); 2510 *destreg = sub_byte(*destreg, srcval); 2511 break; 2512 case 1: 2513 destreg = DECODE_RM_BYTE_REGISTER(rh); 2514 DECODE_PRINTF(","); 2515 srcoffset = decode_rm01_address(rl); 2516 srcval = fetch_data_byte(srcoffset); 2517 DECODE_PRINTF("\n"); 2518 TRACE_AND_STEP(); 2519 *destreg = sub_byte(*destreg, srcval); 2520 break; 2521 case 2: 2522 destreg = DECODE_RM_BYTE_REGISTER(rh); 2523 DECODE_PRINTF(","); 2524 srcoffset = decode_rm10_address(rl); 2525 srcval = fetch_data_byte(srcoffset); 2526 DECODE_PRINTF("\n"); 2527 TRACE_AND_STEP(); 2528 *destreg = sub_byte(*destreg, srcval); 2529 break; 2530 case 3: /* register to register */ 2531 destreg = DECODE_RM_BYTE_REGISTER(rh); 2532 DECODE_PRINTF(","); 2533 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2534 DECODE_PRINTF("\n"); 2535 TRACE_AND_STEP(); 2536 *destreg = sub_byte(*destreg, *srcreg); 2537 break; 2538 } 2539 DECODE_CLEAR_SEGOVR(); 2540 END_OF_INSTR(); 2541} 2542 2543/**************************************************************************** 2544REMARKS: 2545Handles opcode 0x2b 2546****************************************************************************/ 2547static void 2548x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1)) 2549{ 2550 int mod, rl, rh; 2551 uint srcoffset; 2552 2553 START_OF_INSTR(); 2554 DECODE_PRINTF("SUB\t"); 2555 FETCH_DECODE_MODRM(mod, rh, rl); 2556 switch (mod) { 2557 case 0: 2558 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2559 u32 *destreg; 2560 u32 srcval; 2561 2562 destreg = DECODE_RM_LONG_REGISTER(rh); 2563 DECODE_PRINTF(","); 2564 srcoffset = decode_rm00_address(rl); 2565 srcval = fetch_data_long(srcoffset); 2566 DECODE_PRINTF("\n"); 2567 TRACE_AND_STEP(); 2568 *destreg = sub_long(*destreg, srcval); 2569 } 2570 else { 2571 u16 *destreg; 2572 u16 srcval; 2573 2574 destreg = DECODE_RM_WORD_REGISTER(rh); 2575 DECODE_PRINTF(","); 2576 srcoffset = decode_rm00_address(rl); 2577 srcval = fetch_data_word(srcoffset); 2578 DECODE_PRINTF("\n"); 2579 TRACE_AND_STEP(); 2580 *destreg = sub_word(*destreg, srcval); 2581 } 2582 break; 2583 case 1: 2584 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2585 u32 *destreg; 2586 u32 srcval; 2587 2588 destreg = DECODE_RM_LONG_REGISTER(rh); 2589 DECODE_PRINTF(","); 2590 srcoffset = decode_rm01_address(rl); 2591 srcval = fetch_data_long(srcoffset); 2592 DECODE_PRINTF("\n"); 2593 TRACE_AND_STEP(); 2594 *destreg = sub_long(*destreg, srcval); 2595 } 2596 else { 2597 u16 *destreg; 2598 u16 srcval; 2599 2600 destreg = DECODE_RM_WORD_REGISTER(rh); 2601 DECODE_PRINTF(","); 2602 srcoffset = decode_rm01_address(rl); 2603 srcval = fetch_data_word(srcoffset); 2604 DECODE_PRINTF("\n"); 2605 TRACE_AND_STEP(); 2606 *destreg = sub_word(*destreg, srcval); 2607 } 2608 break; 2609 case 2: 2610 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2611 u32 *destreg; 2612 u32 srcval; 2613 2614 destreg = DECODE_RM_LONG_REGISTER(rh); 2615 DECODE_PRINTF(","); 2616 srcoffset = decode_rm10_address(rl); 2617 srcval = fetch_data_long(srcoffset); 2618 DECODE_PRINTF("\n"); 2619 TRACE_AND_STEP(); 2620 *destreg = sub_long(*destreg, srcval); 2621 } 2622 else { 2623 u16 *destreg; 2624 u16 srcval; 2625 2626 destreg = DECODE_RM_WORD_REGISTER(rh); 2627 DECODE_PRINTF(","); 2628 srcoffset = decode_rm10_address(rl); 2629 srcval = fetch_data_word(srcoffset); 2630 DECODE_PRINTF("\n"); 2631 TRACE_AND_STEP(); 2632 *destreg = sub_word(*destreg, srcval); 2633 } 2634 break; 2635 case 3: /* register to register */ 2636 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2637 u32 *destreg, *srcreg; 2638 2639 destreg = DECODE_RM_LONG_REGISTER(rh); 2640 DECODE_PRINTF(","); 2641 srcreg = DECODE_RM_LONG_REGISTER(rl); 2642 DECODE_PRINTF("\n"); 2643 TRACE_AND_STEP(); 2644 *destreg = sub_long(*destreg, *srcreg); 2645 } 2646 else { 2647 u16 *destreg, *srcreg; 2648 2649 destreg = DECODE_RM_WORD_REGISTER(rh); 2650 DECODE_PRINTF(","); 2651 srcreg = DECODE_RM_WORD_REGISTER(rl); 2652 DECODE_PRINTF("\n"); 2653 TRACE_AND_STEP(); 2654 *destreg = sub_word(*destreg, *srcreg); 2655 } 2656 break; 2657 } 2658 DECODE_CLEAR_SEGOVR(); 2659 END_OF_INSTR(); 2660} 2661 2662/**************************************************************************** 2663REMARKS: 2664Handles opcode 0x2c 2665****************************************************************************/ 2666static void 2667x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2668{ 2669 u8 srcval; 2670 2671 START_OF_INSTR(); 2672 DECODE_PRINTF("SUB\tAL,"); 2673 srcval = fetch_byte_imm(); 2674 DECODE_PRINTF2("%x\n", srcval); 2675 TRACE_AND_STEP(); 2676 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval); 2677 DECODE_CLEAR_SEGOVR(); 2678 END_OF_INSTR(); 2679} 2680 2681/**************************************************************************** 2682REMARKS: 2683Handles opcode 0x2d 2684****************************************************************************/ 2685static void 2686x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2687{ 2688 u32 srcval; 2689 2690 START_OF_INSTR(); 2691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2692 DECODE_PRINTF("SUB\tEAX,"); 2693 srcval = fetch_long_imm(); 2694 } 2695 else { 2696 DECODE_PRINTF("SUB\tAX,"); 2697 srcval = fetch_word_imm(); 2698 } 2699 DECODE_PRINTF2("%x\n", srcval); 2700 TRACE_AND_STEP(); 2701 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2702 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval); 2703 } 2704 else { 2705 M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval); 2706 } 2707 DECODE_CLEAR_SEGOVR(); 2708 END_OF_INSTR(); 2709} 2710 2711/**************************************************************************** 2712REMARKS: 2713Handles opcode 0x2e 2714****************************************************************************/ 2715static void 2716x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 2717{ 2718 START_OF_INSTR(); 2719 DECODE_PRINTF("CS:\n"); 2720 TRACE_AND_STEP(); 2721 M.x86.mode |= SYSMODE_SEGOVR_CS; 2722 /* note no DECODE_CLEAR_SEGOVR here. */ 2723 END_OF_INSTR(); 2724} 2725 2726/**************************************************************************** 2727REMARKS: 2728Handles opcode 0x2f 2729****************************************************************************/ 2730static void 2731x86emuOp_das(u8 X86EMU_UNUSED(op1)) 2732{ 2733 START_OF_INSTR(); 2734 DECODE_PRINTF("DAS\n"); 2735 TRACE_AND_STEP(); 2736 M.x86.R_AL = das_byte(M.x86.R_AL); 2737 DECODE_CLEAR_SEGOVR(); 2738 END_OF_INSTR(); 2739} 2740 2741/**************************************************************************** 2742REMARKS: 2743Handles opcode 0x30 2744****************************************************************************/ 2745static void 2746x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2747{ 2748 int mod, rl, rh; 2749 u8 *destreg, *srcreg; 2750 uint destoffset; 2751 u8 destval; 2752 2753 START_OF_INSTR(); 2754 DECODE_PRINTF("XOR\t"); 2755 FETCH_DECODE_MODRM(mod, rh, rl); 2756 switch (mod) { 2757 case 0: 2758 destoffset = decode_rm00_address(rl); 2759 DECODE_PRINTF(","); 2760 destval = fetch_data_byte(destoffset); 2761 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2762 DECODE_PRINTF("\n"); 2763 TRACE_AND_STEP(); 2764 destval = xor_byte(destval, *srcreg); 2765 store_data_byte(destoffset, destval); 2766 break; 2767 case 1: 2768 destoffset = decode_rm01_address(rl); 2769 DECODE_PRINTF(","); 2770 destval = fetch_data_byte(destoffset); 2771 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2772 DECODE_PRINTF("\n"); 2773 TRACE_AND_STEP(); 2774 destval = xor_byte(destval, *srcreg); 2775 store_data_byte(destoffset, destval); 2776 break; 2777 case 2: 2778 destoffset = decode_rm10_address(rl); 2779 DECODE_PRINTF(","); 2780 destval = fetch_data_byte(destoffset); 2781 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2782 DECODE_PRINTF("\n"); 2783 TRACE_AND_STEP(); 2784 destval = xor_byte(destval, *srcreg); 2785 store_data_byte(destoffset, destval); 2786 break; 2787 case 3: /* register to register */ 2788 destreg = DECODE_RM_BYTE_REGISTER(rl); 2789 DECODE_PRINTF(","); 2790 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2791 DECODE_PRINTF("\n"); 2792 TRACE_AND_STEP(); 2793 *destreg = xor_byte(*destreg, *srcreg); 2794 break; 2795 } 2796 DECODE_CLEAR_SEGOVR(); 2797 END_OF_INSTR(); 2798} 2799 2800/**************************************************************************** 2801REMARKS: 2802Handles opcode 0x31 2803****************************************************************************/ 2804static void 2805x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1)) 2806{ 2807 int mod, rl, rh; 2808 uint destoffset; 2809 2810 START_OF_INSTR(); 2811 DECODE_PRINTF("XOR\t"); 2812 FETCH_DECODE_MODRM(mod, rh, rl); 2813 switch (mod) { 2814 case 0: 2815 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2816 u32 destval; 2817 u32 *srcreg; 2818 2819 destoffset = decode_rm00_address(rl); 2820 DECODE_PRINTF(","); 2821 destval = fetch_data_long(destoffset); 2822 srcreg = DECODE_RM_LONG_REGISTER(rh); 2823 DECODE_PRINTF("\n"); 2824 TRACE_AND_STEP(); 2825 destval = xor_long(destval, *srcreg); 2826 store_data_long(destoffset, destval); 2827 } 2828 else { 2829 u16 destval; 2830 u16 *srcreg; 2831 2832 destoffset = decode_rm00_address(rl); 2833 DECODE_PRINTF(","); 2834 destval = fetch_data_word(destoffset); 2835 srcreg = DECODE_RM_WORD_REGISTER(rh); 2836 DECODE_PRINTF("\n"); 2837 TRACE_AND_STEP(); 2838 destval = xor_word(destval, *srcreg); 2839 store_data_word(destoffset, destval); 2840 } 2841 break; 2842 case 1: 2843 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2844 u32 destval; 2845 u32 *srcreg; 2846 2847 destoffset = decode_rm01_address(rl); 2848 DECODE_PRINTF(","); 2849 destval = fetch_data_long(destoffset); 2850 srcreg = DECODE_RM_LONG_REGISTER(rh); 2851 DECODE_PRINTF("\n"); 2852 TRACE_AND_STEP(); 2853 destval = xor_long(destval, *srcreg); 2854 store_data_long(destoffset, destval); 2855 } 2856 else { 2857 u16 destval; 2858 u16 *srcreg; 2859 2860 destoffset = decode_rm01_address(rl); 2861 DECODE_PRINTF(","); 2862 destval = fetch_data_word(destoffset); 2863 srcreg = DECODE_RM_WORD_REGISTER(rh); 2864 DECODE_PRINTF("\n"); 2865 TRACE_AND_STEP(); 2866 destval = xor_word(destval, *srcreg); 2867 store_data_word(destoffset, destval); 2868 } 2869 break; 2870 case 2: 2871 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2872 u32 destval; 2873 u32 *srcreg; 2874 2875 destoffset = decode_rm10_address(rl); 2876 DECODE_PRINTF(","); 2877 destval = fetch_data_long(destoffset); 2878 srcreg = DECODE_RM_LONG_REGISTER(rh); 2879 DECODE_PRINTF("\n"); 2880 TRACE_AND_STEP(); 2881 destval = xor_long(destval, *srcreg); 2882 store_data_long(destoffset, destval); 2883 } 2884 else { 2885 u16 destval; 2886 u16 *srcreg; 2887 2888 destoffset = decode_rm10_address(rl); 2889 DECODE_PRINTF(","); 2890 destval = fetch_data_word(destoffset); 2891 srcreg = DECODE_RM_WORD_REGISTER(rh); 2892 DECODE_PRINTF("\n"); 2893 TRACE_AND_STEP(); 2894 destval = xor_word(destval, *srcreg); 2895 store_data_word(destoffset, destval); 2896 } 2897 break; 2898 case 3: /* register to register */ 2899 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2900 u32 *destreg, *srcreg; 2901 2902 destreg = DECODE_RM_LONG_REGISTER(rl); 2903 DECODE_PRINTF(","); 2904 srcreg = DECODE_RM_LONG_REGISTER(rh); 2905 DECODE_PRINTF("\n"); 2906 TRACE_AND_STEP(); 2907 *destreg = xor_long(*destreg, *srcreg); 2908 } 2909 else { 2910 u16 *destreg, *srcreg; 2911 2912 destreg = DECODE_RM_WORD_REGISTER(rl); 2913 DECODE_PRINTF(","); 2914 srcreg = DECODE_RM_WORD_REGISTER(rh); 2915 DECODE_PRINTF("\n"); 2916 TRACE_AND_STEP(); 2917 *destreg = xor_word(*destreg, *srcreg); 2918 } 2919 break; 2920 } 2921 DECODE_CLEAR_SEGOVR(); 2922 END_OF_INSTR(); 2923} 2924 2925/**************************************************************************** 2926REMARKS: 2927Handles opcode 0x32 2928****************************************************************************/ 2929static void 2930x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2931{ 2932 int mod, rl, rh; 2933 u8 *destreg, *srcreg; 2934 uint srcoffset; 2935 u8 srcval; 2936 2937 START_OF_INSTR(); 2938 DECODE_PRINTF("XOR\t"); 2939 FETCH_DECODE_MODRM(mod, rh, rl); 2940 switch (mod) { 2941 case 0: 2942 destreg = DECODE_RM_BYTE_REGISTER(rh); 2943 DECODE_PRINTF(","); 2944 srcoffset = decode_rm00_address(rl); 2945 srcval = fetch_data_byte(srcoffset); 2946 DECODE_PRINTF("\n"); 2947 TRACE_AND_STEP(); 2948 *destreg = xor_byte(*destreg, srcval); 2949 break; 2950 case 1: 2951 destreg = DECODE_RM_BYTE_REGISTER(rh); 2952 DECODE_PRINTF(","); 2953 srcoffset = decode_rm01_address(rl); 2954 srcval = fetch_data_byte(srcoffset); 2955 DECODE_PRINTF("\n"); 2956 TRACE_AND_STEP(); 2957 *destreg = xor_byte(*destreg, srcval); 2958 break; 2959 case 2: 2960 destreg = DECODE_RM_BYTE_REGISTER(rh); 2961 DECODE_PRINTF(","); 2962 srcoffset = decode_rm10_address(rl); 2963 srcval = fetch_data_byte(srcoffset); 2964 DECODE_PRINTF("\n"); 2965 TRACE_AND_STEP(); 2966 *destreg = xor_byte(*destreg, srcval); 2967 break; 2968 case 3: /* register to register */ 2969 destreg = DECODE_RM_BYTE_REGISTER(rh); 2970 DECODE_PRINTF(","); 2971 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2972 DECODE_PRINTF("\n"); 2973 TRACE_AND_STEP(); 2974 *destreg = xor_byte(*destreg, *srcreg); 2975 break; 2976 } 2977 DECODE_CLEAR_SEGOVR(); 2978 END_OF_INSTR(); 2979} 2980 2981/**************************************************************************** 2982REMARKS: 2983Handles opcode 0x33 2984****************************************************************************/ 2985static void 2986x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1)) 2987{ 2988 int mod, rl, rh; 2989 uint srcoffset; 2990 2991 START_OF_INSTR(); 2992 DECODE_PRINTF("XOR\t"); 2993 FETCH_DECODE_MODRM(mod, rh, rl); 2994 switch (mod) { 2995 case 0: 2996 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2997 u32 *destreg; 2998 u32 srcval; 2999 3000 destreg = DECODE_RM_LONG_REGISTER(rh); 3001 DECODE_PRINTF(","); 3002 srcoffset = decode_rm00_address(rl); 3003 srcval = fetch_data_long(srcoffset); 3004 DECODE_PRINTF("\n"); 3005 TRACE_AND_STEP(); 3006 *destreg = xor_long(*destreg, srcval); 3007 } 3008 else { 3009 u16 *destreg; 3010 u16 srcval; 3011 3012 destreg = DECODE_RM_WORD_REGISTER(rh); 3013 DECODE_PRINTF(","); 3014 srcoffset = decode_rm00_address(rl); 3015 srcval = fetch_data_word(srcoffset); 3016 DECODE_PRINTF("\n"); 3017 TRACE_AND_STEP(); 3018 *destreg = xor_word(*destreg, srcval); 3019 } 3020 break; 3021 case 1: 3022 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3023 u32 *destreg; 3024 u32 srcval; 3025 3026 destreg = DECODE_RM_LONG_REGISTER(rh); 3027 DECODE_PRINTF(","); 3028 srcoffset = decode_rm01_address(rl); 3029 srcval = fetch_data_long(srcoffset); 3030 DECODE_PRINTF("\n"); 3031 TRACE_AND_STEP(); 3032 *destreg = xor_long(*destreg, srcval); 3033 } 3034 else { 3035 u16 *destreg; 3036 u16 srcval; 3037 3038 destreg = DECODE_RM_WORD_REGISTER(rh); 3039 DECODE_PRINTF(","); 3040 srcoffset = decode_rm01_address(rl); 3041 srcval = fetch_data_word(srcoffset); 3042 DECODE_PRINTF("\n"); 3043 TRACE_AND_STEP(); 3044 *destreg = xor_word(*destreg, srcval); 3045 } 3046 break; 3047 case 2: 3048 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3049 u32 *destreg; 3050 u32 srcval; 3051 3052 destreg = DECODE_RM_LONG_REGISTER(rh); 3053 DECODE_PRINTF(","); 3054 srcoffset = decode_rm10_address(rl); 3055 srcval = fetch_data_long(srcoffset); 3056 DECODE_PRINTF("\n"); 3057 TRACE_AND_STEP(); 3058 *destreg = xor_long(*destreg, srcval); 3059 } 3060 else { 3061 u16 *destreg; 3062 u16 srcval; 3063 3064 destreg = DECODE_RM_WORD_REGISTER(rh); 3065 DECODE_PRINTF(","); 3066 srcoffset = decode_rm10_address(rl); 3067 srcval = fetch_data_word(srcoffset); 3068 DECODE_PRINTF("\n"); 3069 TRACE_AND_STEP(); 3070 *destreg = xor_word(*destreg, srcval); 3071 } 3072 break; 3073 case 3: /* register to register */ 3074 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3075 u32 *destreg, *srcreg; 3076 3077 destreg = DECODE_RM_LONG_REGISTER(rh); 3078 DECODE_PRINTF(","); 3079 srcreg = DECODE_RM_LONG_REGISTER(rl); 3080 DECODE_PRINTF("\n"); 3081 TRACE_AND_STEP(); 3082 *destreg = xor_long(*destreg, *srcreg); 3083 } 3084 else { 3085 u16 *destreg, *srcreg; 3086 3087 destreg = DECODE_RM_WORD_REGISTER(rh); 3088 DECODE_PRINTF(","); 3089 srcreg = DECODE_RM_WORD_REGISTER(rl); 3090 DECODE_PRINTF("\n"); 3091 TRACE_AND_STEP(); 3092 *destreg = xor_word(*destreg, *srcreg); 3093 } 3094 break; 3095 } 3096 DECODE_CLEAR_SEGOVR(); 3097 END_OF_INSTR(); 3098} 3099 3100/**************************************************************************** 3101REMARKS: 3102Handles opcode 0x34 3103****************************************************************************/ 3104static void 3105x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 3106{ 3107 u8 srcval; 3108 3109 START_OF_INSTR(); 3110 DECODE_PRINTF("XOR\tAL,"); 3111 srcval = fetch_byte_imm(); 3112 DECODE_PRINTF2("%x\n", srcval); 3113 TRACE_AND_STEP(); 3114 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval); 3115 DECODE_CLEAR_SEGOVR(); 3116 END_OF_INSTR(); 3117} 3118 3119/**************************************************************************** 3120REMARKS: 3121Handles opcode 0x35 3122****************************************************************************/ 3123static void 3124x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3125{ 3126 u32 srcval; 3127 3128 START_OF_INSTR(); 3129 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3130 DECODE_PRINTF("XOR\tEAX,"); 3131 srcval = fetch_long_imm(); 3132 } 3133 else { 3134 DECODE_PRINTF("XOR\tAX,"); 3135 srcval = fetch_word_imm(); 3136 } 3137 DECODE_PRINTF2("%x\n", srcval); 3138 TRACE_AND_STEP(); 3139 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3140 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval); 3141 } 3142 else { 3143 M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval); 3144 } 3145 DECODE_CLEAR_SEGOVR(); 3146 END_OF_INSTR(); 3147} 3148 3149/**************************************************************************** 3150REMARKS: 3151Handles opcode 0x36 3152****************************************************************************/ 3153static void 3154x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 3155{ 3156 START_OF_INSTR(); 3157 DECODE_PRINTF("SS:\n"); 3158 TRACE_AND_STEP(); 3159 M.x86.mode |= SYSMODE_SEGOVR_SS; 3160 /* no DECODE_CLEAR_SEGOVR ! */ 3161 END_OF_INSTR(); 3162} 3163 3164/**************************************************************************** 3165REMARKS: 3166Handles opcode 0x37 3167****************************************************************************/ 3168static void 3169x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 3170{ 3171 START_OF_INSTR(); 3172 DECODE_PRINTF("AAA\n"); 3173 TRACE_AND_STEP(); 3174 M.x86.R_AX = aaa_word(M.x86.R_AX); 3175 DECODE_CLEAR_SEGOVR(); 3176 END_OF_INSTR(); 3177} 3178 3179/**************************************************************************** 3180REMARKS: 3181Handles opcode 0x38 3182****************************************************************************/ 3183static void 3184x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1)) 3185{ 3186 int mod, rl, rh; 3187 uint destoffset; 3188 u8 *destreg, *srcreg; 3189 u8 destval; 3190 3191 START_OF_INSTR(); 3192 DECODE_PRINTF("CMP\t"); 3193 FETCH_DECODE_MODRM(mod, rh, rl); 3194 switch (mod) { 3195 case 0: 3196 destoffset = decode_rm00_address(rl); 3197 DECODE_PRINTF(","); 3198 destval = fetch_data_byte(destoffset); 3199 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3200 DECODE_PRINTF("\n"); 3201 TRACE_AND_STEP(); 3202 cmp_byte(destval, *srcreg); 3203 break; 3204 case 1: 3205 destoffset = decode_rm01_address(rl); 3206 DECODE_PRINTF(","); 3207 destval = fetch_data_byte(destoffset); 3208 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3209 DECODE_PRINTF("\n"); 3210 TRACE_AND_STEP(); 3211 cmp_byte(destval, *srcreg); 3212 break; 3213 case 2: 3214 destoffset = decode_rm10_address(rl); 3215 DECODE_PRINTF(","); 3216 destval = fetch_data_byte(destoffset); 3217 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3218 DECODE_PRINTF("\n"); 3219 TRACE_AND_STEP(); 3220 cmp_byte(destval, *srcreg); 3221 break; 3222 case 3: /* register to register */ 3223 destreg = DECODE_RM_BYTE_REGISTER(rl); 3224 DECODE_PRINTF(","); 3225 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3226 DECODE_PRINTF("\n"); 3227 TRACE_AND_STEP(); 3228 cmp_byte(*destreg, *srcreg); 3229 break; 3230 } 3231 DECODE_CLEAR_SEGOVR(); 3232 END_OF_INSTR(); 3233} 3234 3235/**************************************************************************** 3236REMARKS: 3237Handles opcode 0x39 3238****************************************************************************/ 3239static void 3240x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1)) 3241{ 3242 int mod, rl, rh; 3243 uint destoffset; 3244 3245 START_OF_INSTR(); 3246 DECODE_PRINTF("CMP\t"); 3247 FETCH_DECODE_MODRM(mod, rh, rl); 3248 switch (mod) { 3249 case 0: 3250 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3251 u32 destval; 3252 u32 *srcreg; 3253 3254 destoffset = decode_rm00_address(rl); 3255 DECODE_PRINTF(","); 3256 destval = fetch_data_long(destoffset); 3257 srcreg = DECODE_RM_LONG_REGISTER(rh); 3258 DECODE_PRINTF("\n"); 3259 TRACE_AND_STEP(); 3260 cmp_long(destval, *srcreg); 3261 } 3262 else { 3263 u16 destval; 3264 u16 *srcreg; 3265 3266 destoffset = decode_rm00_address(rl); 3267 DECODE_PRINTF(","); 3268 destval = fetch_data_word(destoffset); 3269 srcreg = DECODE_RM_WORD_REGISTER(rh); 3270 DECODE_PRINTF("\n"); 3271 TRACE_AND_STEP(); 3272 cmp_word(destval, *srcreg); 3273 } 3274 break; 3275 case 1: 3276 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3277 u32 destval; 3278 u32 *srcreg; 3279 3280 destoffset = decode_rm01_address(rl); 3281 DECODE_PRINTF(","); 3282 destval = fetch_data_long(destoffset); 3283 srcreg = DECODE_RM_LONG_REGISTER(rh); 3284 DECODE_PRINTF("\n"); 3285 TRACE_AND_STEP(); 3286 cmp_long(destval, *srcreg); 3287 } 3288 else { 3289 u16 destval; 3290 u16 *srcreg; 3291 3292 destoffset = decode_rm01_address(rl); 3293 DECODE_PRINTF(","); 3294 destval = fetch_data_word(destoffset); 3295 srcreg = DECODE_RM_WORD_REGISTER(rh); 3296 DECODE_PRINTF("\n"); 3297 TRACE_AND_STEP(); 3298 cmp_word(destval, *srcreg); 3299 } 3300 break; 3301 case 2: 3302 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3303 u32 destval; 3304 u32 *srcreg; 3305 3306 destoffset = decode_rm10_address(rl); 3307 DECODE_PRINTF(","); 3308 destval = fetch_data_long(destoffset); 3309 srcreg = DECODE_RM_LONG_REGISTER(rh); 3310 DECODE_PRINTF("\n"); 3311 TRACE_AND_STEP(); 3312 cmp_long(destval, *srcreg); 3313 } 3314 else { 3315 u16 destval; 3316 u16 *srcreg; 3317 3318 destoffset = decode_rm10_address(rl); 3319 DECODE_PRINTF(","); 3320 destval = fetch_data_word(destoffset); 3321 srcreg = DECODE_RM_WORD_REGISTER(rh); 3322 DECODE_PRINTF("\n"); 3323 TRACE_AND_STEP(); 3324 cmp_word(destval, *srcreg); 3325 } 3326 break; 3327 case 3: /* register to register */ 3328 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3329 u32 *destreg, *srcreg; 3330 3331 destreg = DECODE_RM_LONG_REGISTER(rl); 3332 DECODE_PRINTF(","); 3333 srcreg = DECODE_RM_LONG_REGISTER(rh); 3334 DECODE_PRINTF("\n"); 3335 TRACE_AND_STEP(); 3336 cmp_long(*destreg, *srcreg); 3337 } 3338 else { 3339 u16 *destreg, *srcreg; 3340 3341 destreg = DECODE_RM_WORD_REGISTER(rl); 3342 DECODE_PRINTF(","); 3343 srcreg = DECODE_RM_WORD_REGISTER(rh); 3344 DECODE_PRINTF("\n"); 3345 TRACE_AND_STEP(); 3346 cmp_word(*destreg, *srcreg); 3347 } 3348 break; 3349 } 3350 DECODE_CLEAR_SEGOVR(); 3351 END_OF_INSTR(); 3352} 3353 3354/**************************************************************************** 3355REMARKS: 3356Handles opcode 0x3a 3357****************************************************************************/ 3358static void 3359x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1)) 3360{ 3361 int mod, rl, rh; 3362 u8 *destreg, *srcreg; 3363 uint srcoffset; 3364 u8 srcval; 3365 3366 START_OF_INSTR(); 3367 DECODE_PRINTF("CMP\t"); 3368 FETCH_DECODE_MODRM(mod, rh, rl); 3369 switch (mod) { 3370 case 0: 3371 destreg = DECODE_RM_BYTE_REGISTER(rh); 3372 DECODE_PRINTF(","); 3373 srcoffset = decode_rm00_address(rl); 3374 srcval = fetch_data_byte(srcoffset); 3375 DECODE_PRINTF("\n"); 3376 TRACE_AND_STEP(); 3377 cmp_byte(*destreg, srcval); 3378 break; 3379 case 1: 3380 destreg = DECODE_RM_BYTE_REGISTER(rh); 3381 DECODE_PRINTF(","); 3382 srcoffset = decode_rm01_address(rl); 3383 srcval = fetch_data_byte(srcoffset); 3384 DECODE_PRINTF("\n"); 3385 TRACE_AND_STEP(); 3386 cmp_byte(*destreg, srcval); 3387 break; 3388 case 2: 3389 destreg = DECODE_RM_BYTE_REGISTER(rh); 3390 DECODE_PRINTF(","); 3391 srcoffset = decode_rm10_address(rl); 3392 srcval = fetch_data_byte(srcoffset); 3393 DECODE_PRINTF("\n"); 3394 TRACE_AND_STEP(); 3395 cmp_byte(*destreg, srcval); 3396 break; 3397 case 3: /* register to register */ 3398 destreg = DECODE_RM_BYTE_REGISTER(rh); 3399 DECODE_PRINTF(","); 3400 srcreg = DECODE_RM_BYTE_REGISTER(rl); 3401 DECODE_PRINTF("\n"); 3402 TRACE_AND_STEP(); 3403 cmp_byte(*destreg, *srcreg); 3404 break; 3405 } 3406 DECODE_CLEAR_SEGOVR(); 3407 END_OF_INSTR(); 3408} 3409 3410/**************************************************************************** 3411REMARKS: 3412Handles opcode 0x3b 3413****************************************************************************/ 3414static void 3415x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1)) 3416{ 3417 int mod, rl, rh; 3418 uint srcoffset; 3419 3420 START_OF_INSTR(); 3421 DECODE_PRINTF("CMP\t"); 3422 FETCH_DECODE_MODRM(mod, rh, rl); 3423 switch (mod) { 3424 case 0: 3425 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3426 u32 *destreg; 3427 u32 srcval; 3428 3429 destreg = DECODE_RM_LONG_REGISTER(rh); 3430 DECODE_PRINTF(","); 3431 srcoffset = decode_rm00_address(rl); 3432 srcval = fetch_data_long(srcoffset); 3433 DECODE_PRINTF("\n"); 3434 TRACE_AND_STEP(); 3435 cmp_long(*destreg, srcval); 3436 } 3437 else { 3438 u16 *destreg; 3439 u16 srcval; 3440 3441 destreg = DECODE_RM_WORD_REGISTER(rh); 3442 DECODE_PRINTF(","); 3443 srcoffset = decode_rm00_address(rl); 3444 srcval = fetch_data_word(srcoffset); 3445 DECODE_PRINTF("\n"); 3446 TRACE_AND_STEP(); 3447 cmp_word(*destreg, srcval); 3448 } 3449 break; 3450 case 1: 3451 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3452 u32 *destreg; 3453 u32 srcval; 3454 3455 destreg = DECODE_RM_LONG_REGISTER(rh); 3456 DECODE_PRINTF(","); 3457 srcoffset = decode_rm01_address(rl); 3458 srcval = fetch_data_long(srcoffset); 3459 DECODE_PRINTF("\n"); 3460 TRACE_AND_STEP(); 3461 cmp_long(*destreg, srcval); 3462 } 3463 else { 3464 u16 *destreg; 3465 u16 srcval; 3466 3467 destreg = DECODE_RM_WORD_REGISTER(rh); 3468 DECODE_PRINTF(","); 3469 srcoffset = decode_rm01_address(rl); 3470 srcval = fetch_data_word(srcoffset); 3471 DECODE_PRINTF("\n"); 3472 TRACE_AND_STEP(); 3473 cmp_word(*destreg, srcval); 3474 } 3475 break; 3476 case 2: 3477 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3478 u32 *destreg; 3479 u32 srcval; 3480 3481 destreg = DECODE_RM_LONG_REGISTER(rh); 3482 DECODE_PRINTF(","); 3483 srcoffset = decode_rm10_address(rl); 3484 srcval = fetch_data_long(srcoffset); 3485 DECODE_PRINTF("\n"); 3486 TRACE_AND_STEP(); 3487 cmp_long(*destreg, srcval); 3488 } 3489 else { 3490 u16 *destreg; 3491 u16 srcval; 3492 3493 destreg = DECODE_RM_WORD_REGISTER(rh); 3494 DECODE_PRINTF(","); 3495 srcoffset = decode_rm10_address(rl); 3496 srcval = fetch_data_word(srcoffset); 3497 DECODE_PRINTF("\n"); 3498 TRACE_AND_STEP(); 3499 cmp_word(*destreg, srcval); 3500 } 3501 break; 3502 case 3: /* register to register */ 3503 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3504 u32 *destreg, *srcreg; 3505 3506 destreg = DECODE_RM_LONG_REGISTER(rh); 3507 DECODE_PRINTF(","); 3508 srcreg = DECODE_RM_LONG_REGISTER(rl); 3509 DECODE_PRINTF("\n"); 3510 TRACE_AND_STEP(); 3511 cmp_long(*destreg, *srcreg); 3512 } 3513 else { 3514 u16 *destreg, *srcreg; 3515 3516 destreg = DECODE_RM_WORD_REGISTER(rh); 3517 DECODE_PRINTF(","); 3518 srcreg = DECODE_RM_WORD_REGISTER(rl); 3519 DECODE_PRINTF("\n"); 3520 TRACE_AND_STEP(); 3521 cmp_word(*destreg, *srcreg); 3522 } 3523 break; 3524 } 3525 DECODE_CLEAR_SEGOVR(); 3526 END_OF_INSTR(); 3527} 3528 3529/**************************************************************************** 3530REMARKS: 3531Handles opcode 0x3c 3532****************************************************************************/ 3533static void 3534x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 3535{ 3536 u8 srcval; 3537 3538 START_OF_INSTR(); 3539 DECODE_PRINTF("CMP\tAL,"); 3540 srcval = fetch_byte_imm(); 3541 DECODE_PRINTF2("%x\n", srcval); 3542 TRACE_AND_STEP(); 3543 cmp_byte(M.x86.R_AL, srcval); 3544 DECODE_CLEAR_SEGOVR(); 3545 END_OF_INSTR(); 3546} 3547 3548/**************************************************************************** 3549REMARKS: 3550Handles opcode 0x3d 3551****************************************************************************/ 3552static void 3553x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3554{ 3555 u32 srcval; 3556 3557 START_OF_INSTR(); 3558 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3559 DECODE_PRINTF("CMP\tEAX,"); 3560 srcval = fetch_long_imm(); 3561 } 3562 else { 3563 DECODE_PRINTF("CMP\tAX,"); 3564 srcval = fetch_word_imm(); 3565 } 3566 DECODE_PRINTF2("%x\n", srcval); 3567 TRACE_AND_STEP(); 3568 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3569 cmp_long(M.x86.R_EAX, srcval); 3570 } 3571 else { 3572 cmp_word(M.x86.R_AX, (u16) srcval); 3573 } 3574 DECODE_CLEAR_SEGOVR(); 3575 END_OF_INSTR(); 3576} 3577 3578/**************************************************************************** 3579REMARKS: 3580Handles opcode 0x3e 3581****************************************************************************/ 3582static void 3583x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 3584{ 3585 START_OF_INSTR(); 3586 DECODE_PRINTF("DS:\n"); 3587 TRACE_AND_STEP(); 3588 M.x86.mode |= SYSMODE_SEGOVR_DS; 3589 /* NO DECODE_CLEAR_SEGOVR! */ 3590 END_OF_INSTR(); 3591} 3592 3593/**************************************************************************** 3594REMARKS: 3595Handles opcode 0x3f 3596****************************************************************************/ 3597static void 3598x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 3599{ 3600 START_OF_INSTR(); 3601 DECODE_PRINTF("AAS\n"); 3602 TRACE_AND_STEP(); 3603 M.x86.R_AX = aas_word(M.x86.R_AX); 3604 DECODE_CLEAR_SEGOVR(); 3605 END_OF_INSTR(); 3606} 3607 3608/**************************************************************************** 3609REMARKS: 3610Handles opcode 0x40 3611****************************************************************************/ 3612static void 3613x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1)) 3614{ 3615 START_OF_INSTR(); 3616 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3617 DECODE_PRINTF("INC\tEAX\n"); 3618 } 3619 else { 3620 DECODE_PRINTF("INC\tAX\n"); 3621 } 3622 TRACE_AND_STEP(); 3623 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3624 M.x86.R_EAX = inc_long(M.x86.R_EAX); 3625 } 3626 else { 3627 M.x86.R_AX = inc_word(M.x86.R_AX); 3628 } 3629 DECODE_CLEAR_SEGOVR(); 3630 END_OF_INSTR(); 3631} 3632 3633/**************************************************************************** 3634REMARKS: 3635Handles opcode 0x41 3636****************************************************************************/ 3637static void 3638x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1)) 3639{ 3640 START_OF_INSTR(); 3641 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3642 DECODE_PRINTF("INC\tECX\n"); 3643 } 3644 else { 3645 DECODE_PRINTF("INC\tCX\n"); 3646 } 3647 TRACE_AND_STEP(); 3648 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3649 M.x86.R_ECX = inc_long(M.x86.R_ECX); 3650 } 3651 else { 3652 M.x86.R_CX = inc_word(M.x86.R_CX); 3653 } 3654 DECODE_CLEAR_SEGOVR(); 3655 END_OF_INSTR(); 3656} 3657 3658/**************************************************************************** 3659REMARKS: 3660Handles opcode 0x42 3661****************************************************************************/ 3662static void 3663x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1)) 3664{ 3665 START_OF_INSTR(); 3666 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3667 DECODE_PRINTF("INC\tEDX\n"); 3668 } 3669 else { 3670 DECODE_PRINTF("INC\tDX\n"); 3671 } 3672 TRACE_AND_STEP(); 3673 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3674 M.x86.R_EDX = inc_long(M.x86.R_EDX); 3675 } 3676 else { 3677 M.x86.R_DX = inc_word(M.x86.R_DX); 3678 } 3679 DECODE_CLEAR_SEGOVR(); 3680 END_OF_INSTR(); 3681} 3682 3683/**************************************************************************** 3684REMARKS: 3685Handles opcode 0x43 3686****************************************************************************/ 3687static void 3688x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1)) 3689{ 3690 START_OF_INSTR(); 3691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3692 DECODE_PRINTF("INC\tEBX\n"); 3693 } 3694 else { 3695 DECODE_PRINTF("INC\tBX\n"); 3696 } 3697 TRACE_AND_STEP(); 3698 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3699 M.x86.R_EBX = inc_long(M.x86.R_EBX); 3700 } 3701 else { 3702 M.x86.R_BX = inc_word(M.x86.R_BX); 3703 } 3704 DECODE_CLEAR_SEGOVR(); 3705 END_OF_INSTR(); 3706} 3707 3708/**************************************************************************** 3709REMARKS: 3710Handles opcode 0x44 3711****************************************************************************/ 3712static void 3713x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1)) 3714{ 3715 START_OF_INSTR(); 3716 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3717 DECODE_PRINTF("INC\tESP\n"); 3718 } 3719 else { 3720 DECODE_PRINTF("INC\tSP\n"); 3721 } 3722 TRACE_AND_STEP(); 3723 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3724 M.x86.R_ESP = inc_long(M.x86.R_ESP); 3725 } 3726 else { 3727 M.x86.R_SP = inc_word(M.x86.R_SP); 3728 } 3729 DECODE_CLEAR_SEGOVR(); 3730 END_OF_INSTR(); 3731} 3732 3733/**************************************************************************** 3734REMARKS: 3735Handles opcode 0x45 3736****************************************************************************/ 3737static void 3738x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1)) 3739{ 3740 START_OF_INSTR(); 3741 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3742 DECODE_PRINTF("INC\tEBP\n"); 3743 } 3744 else { 3745 DECODE_PRINTF("INC\tBP\n"); 3746 } 3747 TRACE_AND_STEP(); 3748 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3749 M.x86.R_EBP = inc_long(M.x86.R_EBP); 3750 } 3751 else { 3752 M.x86.R_BP = inc_word(M.x86.R_BP); 3753 } 3754 DECODE_CLEAR_SEGOVR(); 3755 END_OF_INSTR(); 3756} 3757 3758/**************************************************************************** 3759REMARKS: 3760Handles opcode 0x46 3761****************************************************************************/ 3762static void 3763x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1)) 3764{ 3765 START_OF_INSTR(); 3766 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3767 DECODE_PRINTF("INC\tESI\n"); 3768 } 3769 else { 3770 DECODE_PRINTF("INC\tSI\n"); 3771 } 3772 TRACE_AND_STEP(); 3773 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3774 M.x86.R_ESI = inc_long(M.x86.R_ESI); 3775 } 3776 else { 3777 M.x86.R_SI = inc_word(M.x86.R_SI); 3778 } 3779 DECODE_CLEAR_SEGOVR(); 3780 END_OF_INSTR(); 3781} 3782 3783/**************************************************************************** 3784REMARKS: 3785Handles opcode 0x47 3786****************************************************************************/ 3787static void 3788x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1)) 3789{ 3790 START_OF_INSTR(); 3791 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3792 DECODE_PRINTF("INC\tEDI\n"); 3793 } 3794 else { 3795 DECODE_PRINTF("INC\tDI\n"); 3796 } 3797 TRACE_AND_STEP(); 3798 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3799 M.x86.R_EDI = inc_long(M.x86.R_EDI); 3800 } 3801 else { 3802 M.x86.R_DI = inc_word(M.x86.R_DI); 3803 } 3804 DECODE_CLEAR_SEGOVR(); 3805 END_OF_INSTR(); 3806} 3807 3808/**************************************************************************** 3809REMARKS: 3810Handles opcode 0x48 3811****************************************************************************/ 3812static void 3813x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1)) 3814{ 3815 START_OF_INSTR(); 3816 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3817 DECODE_PRINTF("DEC\tEAX\n"); 3818 } 3819 else { 3820 DECODE_PRINTF("DEC\tAX\n"); 3821 } 3822 TRACE_AND_STEP(); 3823 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3824 M.x86.R_EAX = dec_long(M.x86.R_EAX); 3825 } 3826 else { 3827 M.x86.R_AX = dec_word(M.x86.R_AX); 3828 } 3829 DECODE_CLEAR_SEGOVR(); 3830 END_OF_INSTR(); 3831} 3832 3833/**************************************************************************** 3834REMARKS: 3835Handles opcode 0x49 3836****************************************************************************/ 3837static void 3838x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1)) 3839{ 3840 START_OF_INSTR(); 3841 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3842 DECODE_PRINTF("DEC\tECX\n"); 3843 } 3844 else { 3845 DECODE_PRINTF("DEC\tCX\n"); 3846 } 3847 TRACE_AND_STEP(); 3848 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3849 M.x86.R_ECX = dec_long(M.x86.R_ECX); 3850 } 3851 else { 3852 M.x86.R_CX = dec_word(M.x86.R_CX); 3853 } 3854 DECODE_CLEAR_SEGOVR(); 3855 END_OF_INSTR(); 3856} 3857 3858/**************************************************************************** 3859REMARKS: 3860Handles opcode 0x4a 3861****************************************************************************/ 3862static void 3863x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1)) 3864{ 3865 START_OF_INSTR(); 3866 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3867 DECODE_PRINTF("DEC\tEDX\n"); 3868 } 3869 else { 3870 DECODE_PRINTF("DEC\tDX\n"); 3871 } 3872 TRACE_AND_STEP(); 3873 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3874 M.x86.R_EDX = dec_long(M.x86.R_EDX); 3875 } 3876 else { 3877 M.x86.R_DX = dec_word(M.x86.R_DX); 3878 } 3879 DECODE_CLEAR_SEGOVR(); 3880 END_OF_INSTR(); 3881} 3882 3883/**************************************************************************** 3884REMARKS: 3885Handles opcode 0x4b 3886****************************************************************************/ 3887static void 3888x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1)) 3889{ 3890 START_OF_INSTR(); 3891 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3892 DECODE_PRINTF("DEC\tEBX\n"); 3893 } 3894 else { 3895 DECODE_PRINTF("DEC\tBX\n"); 3896 } 3897 TRACE_AND_STEP(); 3898 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3899 M.x86.R_EBX = dec_long(M.x86.R_EBX); 3900 } 3901 else { 3902 M.x86.R_BX = dec_word(M.x86.R_BX); 3903 } 3904 DECODE_CLEAR_SEGOVR(); 3905 END_OF_INSTR(); 3906} 3907 3908/**************************************************************************** 3909REMARKS: 3910Handles opcode 0x4c 3911****************************************************************************/ 3912static void 3913x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1)) 3914{ 3915 START_OF_INSTR(); 3916 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3917 DECODE_PRINTF("DEC\tESP\n"); 3918 } 3919 else { 3920 DECODE_PRINTF("DEC\tSP\n"); 3921 } 3922 TRACE_AND_STEP(); 3923 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3924 M.x86.R_ESP = dec_long(M.x86.R_ESP); 3925 } 3926 else { 3927 M.x86.R_SP = dec_word(M.x86.R_SP); 3928 } 3929 DECODE_CLEAR_SEGOVR(); 3930 END_OF_INSTR(); 3931} 3932 3933/**************************************************************************** 3934REMARKS: 3935Handles opcode 0x4d 3936****************************************************************************/ 3937static void 3938x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1)) 3939{ 3940 START_OF_INSTR(); 3941 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3942 DECODE_PRINTF("DEC\tEBP\n"); 3943 } 3944 else { 3945 DECODE_PRINTF("DEC\tBP\n"); 3946 } 3947 TRACE_AND_STEP(); 3948 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3949 M.x86.R_EBP = dec_long(M.x86.R_EBP); 3950 } 3951 else { 3952 M.x86.R_BP = dec_word(M.x86.R_BP); 3953 } 3954 DECODE_CLEAR_SEGOVR(); 3955 END_OF_INSTR(); 3956} 3957 3958/**************************************************************************** 3959REMARKS: 3960Handles opcode 0x4e 3961****************************************************************************/ 3962static void 3963x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1)) 3964{ 3965 START_OF_INSTR(); 3966 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3967 DECODE_PRINTF("DEC\tESI\n"); 3968 } 3969 else { 3970 DECODE_PRINTF("DEC\tSI\n"); 3971 } 3972 TRACE_AND_STEP(); 3973 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3974 M.x86.R_ESI = dec_long(M.x86.R_ESI); 3975 } 3976 else { 3977 M.x86.R_SI = dec_word(M.x86.R_SI); 3978 } 3979 DECODE_CLEAR_SEGOVR(); 3980 END_OF_INSTR(); 3981} 3982 3983/**************************************************************************** 3984REMARKS: 3985Handles opcode 0x4f 3986****************************************************************************/ 3987static void 3988x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1)) 3989{ 3990 START_OF_INSTR(); 3991 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3992 DECODE_PRINTF("DEC\tEDI\n"); 3993 } 3994 else { 3995 DECODE_PRINTF("DEC\tDI\n"); 3996 } 3997 TRACE_AND_STEP(); 3998 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3999 M.x86.R_EDI = dec_long(M.x86.R_EDI); 4000 } 4001 else { 4002 M.x86.R_DI = dec_word(M.x86.R_DI); 4003 } 4004 DECODE_CLEAR_SEGOVR(); 4005 END_OF_INSTR(); 4006} 4007 4008/**************************************************************************** 4009REMARKS: 4010Handles opcode 0x50 4011****************************************************************************/ 4012static void 4013x86emuOp_push_AX(u8 X86EMU_UNUSED(op1)) 4014{ 4015 START_OF_INSTR(); 4016 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4017 DECODE_PRINTF("PUSH\tEAX\n"); 4018 } 4019 else { 4020 DECODE_PRINTF("PUSH\tAX\n"); 4021 } 4022 TRACE_AND_STEP(); 4023 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4024 push_long(M.x86.R_EAX); 4025 } 4026 else { 4027 push_word(M.x86.R_AX); 4028 } 4029 DECODE_CLEAR_SEGOVR(); 4030 END_OF_INSTR(); 4031} 4032 4033/**************************************************************************** 4034REMARKS: 4035Handles opcode 0x51 4036****************************************************************************/ 4037static void 4038x86emuOp_push_CX(u8 X86EMU_UNUSED(op1)) 4039{ 4040 START_OF_INSTR(); 4041 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4042 DECODE_PRINTF("PUSH\tECX\n"); 4043 } 4044 else { 4045 DECODE_PRINTF("PUSH\tCX\n"); 4046 } 4047 TRACE_AND_STEP(); 4048 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4049 push_long(M.x86.R_ECX); 4050 } 4051 else { 4052 push_word(M.x86.R_CX); 4053 } 4054 DECODE_CLEAR_SEGOVR(); 4055 END_OF_INSTR(); 4056} 4057 4058/**************************************************************************** 4059REMARKS: 4060Handles opcode 0x52 4061****************************************************************************/ 4062static void 4063x86emuOp_push_DX(u8 X86EMU_UNUSED(op1)) 4064{ 4065 START_OF_INSTR(); 4066 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4067 DECODE_PRINTF("PUSH\tEDX\n"); 4068 } 4069 else { 4070 DECODE_PRINTF("PUSH\tDX\n"); 4071 } 4072 TRACE_AND_STEP(); 4073 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4074 push_long(M.x86.R_EDX); 4075 } 4076 else { 4077 push_word(M.x86.R_DX); 4078 } 4079 DECODE_CLEAR_SEGOVR(); 4080 END_OF_INSTR(); 4081} 4082 4083/**************************************************************************** 4084REMARKS: 4085Handles opcode 0x53 4086****************************************************************************/ 4087static void 4088x86emuOp_push_BX(u8 X86EMU_UNUSED(op1)) 4089{ 4090 START_OF_INSTR(); 4091 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4092 DECODE_PRINTF("PUSH\tEBX\n"); 4093 } 4094 else { 4095 DECODE_PRINTF("PUSH\tBX\n"); 4096 } 4097 TRACE_AND_STEP(); 4098 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4099 push_long(M.x86.R_EBX); 4100 } 4101 else { 4102 push_word(M.x86.R_BX); 4103 } 4104 DECODE_CLEAR_SEGOVR(); 4105 END_OF_INSTR(); 4106} 4107 4108/**************************************************************************** 4109REMARKS: 4110Handles opcode 0x54 4111****************************************************************************/ 4112static void 4113x86emuOp_push_SP(u8 X86EMU_UNUSED(op1)) 4114{ 4115 START_OF_INSTR(); 4116 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4117 DECODE_PRINTF("PUSH\tESP\n"); 4118 } 4119 else { 4120 DECODE_PRINTF("PUSH\tSP\n"); 4121 } 4122 TRACE_AND_STEP(); 4123 /* Always push (E)SP, since we are emulating an i386 and above 4124 * processor. This is necessary as some BIOS'es use this to check 4125 * what type of processor is in the system. 4126 */ 4127 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4128 push_long(M.x86.R_ESP); 4129 } 4130 else { 4131 push_word((u16) (M.x86.R_SP)); 4132 } 4133 DECODE_CLEAR_SEGOVR(); 4134 END_OF_INSTR(); 4135} 4136 4137/**************************************************************************** 4138REMARKS: 4139Handles opcode 0x55 4140****************************************************************************/ 4141static void 4142x86emuOp_push_BP(u8 X86EMU_UNUSED(op1)) 4143{ 4144 START_OF_INSTR(); 4145 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4146 DECODE_PRINTF("PUSH\tEBP\n"); 4147 } 4148 else { 4149 DECODE_PRINTF("PUSH\tBP\n"); 4150 } 4151 TRACE_AND_STEP(); 4152 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4153 push_long(M.x86.R_EBP); 4154 } 4155 else { 4156 push_word(M.x86.R_BP); 4157 } 4158 DECODE_CLEAR_SEGOVR(); 4159 END_OF_INSTR(); 4160} 4161 4162/**************************************************************************** 4163REMARKS: 4164Handles opcode 0x56 4165****************************************************************************/ 4166static void 4167x86emuOp_push_SI(u8 X86EMU_UNUSED(op1)) 4168{ 4169 START_OF_INSTR(); 4170 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4171 DECODE_PRINTF("PUSH\tESI\n"); 4172 } 4173 else { 4174 DECODE_PRINTF("PUSH\tSI\n"); 4175 } 4176 TRACE_AND_STEP(); 4177 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4178 push_long(M.x86.R_ESI); 4179 } 4180 else { 4181 push_word(M.x86.R_SI); 4182 } 4183 DECODE_CLEAR_SEGOVR(); 4184 END_OF_INSTR(); 4185} 4186 4187/**************************************************************************** 4188REMARKS: 4189Handles opcode 0x57 4190****************************************************************************/ 4191static void 4192x86emuOp_push_DI(u8 X86EMU_UNUSED(op1)) 4193{ 4194 START_OF_INSTR(); 4195 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4196 DECODE_PRINTF("PUSH\tEDI\n"); 4197 } 4198 else { 4199 DECODE_PRINTF("PUSH\tDI\n"); 4200 } 4201 TRACE_AND_STEP(); 4202 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4203 push_long(M.x86.R_EDI); 4204 } 4205 else { 4206 push_word(M.x86.R_DI); 4207 } 4208 DECODE_CLEAR_SEGOVR(); 4209 END_OF_INSTR(); 4210} 4211 4212/**************************************************************************** 4213REMARKS: 4214Handles opcode 0x58 4215****************************************************************************/ 4216static void 4217x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1)) 4218{ 4219 START_OF_INSTR(); 4220 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4221 DECODE_PRINTF("POP\tEAX\n"); 4222 } 4223 else { 4224 DECODE_PRINTF("POP\tAX\n"); 4225 } 4226 TRACE_AND_STEP(); 4227 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4228 M.x86.R_EAX = pop_long(); 4229 } 4230 else { 4231 M.x86.R_AX = pop_word(); 4232 } 4233 DECODE_CLEAR_SEGOVR(); 4234 END_OF_INSTR(); 4235} 4236 4237/**************************************************************************** 4238REMARKS: 4239Handles opcode 0x59 4240****************************************************************************/ 4241static void 4242x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1)) 4243{ 4244 START_OF_INSTR(); 4245 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4246 DECODE_PRINTF("POP\tECX\n"); 4247 } 4248 else { 4249 DECODE_PRINTF("POP\tCX\n"); 4250 } 4251 TRACE_AND_STEP(); 4252 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4253 M.x86.R_ECX = pop_long(); 4254 } 4255 else { 4256 M.x86.R_CX = pop_word(); 4257 } 4258 DECODE_CLEAR_SEGOVR(); 4259 END_OF_INSTR(); 4260} 4261 4262/**************************************************************************** 4263REMARKS: 4264Handles opcode 0x5a 4265****************************************************************************/ 4266static void 4267x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1)) 4268{ 4269 START_OF_INSTR(); 4270 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4271 DECODE_PRINTF("POP\tEDX\n"); 4272 } 4273 else { 4274 DECODE_PRINTF("POP\tDX\n"); 4275 } 4276 TRACE_AND_STEP(); 4277 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4278 M.x86.R_EDX = pop_long(); 4279 } 4280 else { 4281 M.x86.R_DX = pop_word(); 4282 } 4283 DECODE_CLEAR_SEGOVR(); 4284 END_OF_INSTR(); 4285} 4286 4287/**************************************************************************** 4288REMARKS: 4289Handles opcode 0x5b 4290****************************************************************************/ 4291static void 4292x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1)) 4293{ 4294 START_OF_INSTR(); 4295 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4296 DECODE_PRINTF("POP\tEBX\n"); 4297 } 4298 else { 4299 DECODE_PRINTF("POP\tBX\n"); 4300 } 4301 TRACE_AND_STEP(); 4302 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4303 M.x86.R_EBX = pop_long(); 4304 } 4305 else { 4306 M.x86.R_BX = pop_word(); 4307 } 4308 DECODE_CLEAR_SEGOVR(); 4309 END_OF_INSTR(); 4310} 4311 4312/**************************************************************************** 4313REMARKS: 4314Handles opcode 0x5c 4315****************************************************************************/ 4316static void 4317x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1)) 4318{ 4319 START_OF_INSTR(); 4320 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4321 DECODE_PRINTF("POP\tESP\n"); 4322 } 4323 else { 4324 DECODE_PRINTF("POP\tSP\n"); 4325 } 4326 TRACE_AND_STEP(); 4327 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4328 M.x86.R_ESP = pop_long(); 4329 } 4330 else { 4331 M.x86.R_SP = pop_word(); 4332 } 4333 DECODE_CLEAR_SEGOVR(); 4334 END_OF_INSTR(); 4335} 4336 4337/**************************************************************************** 4338REMARKS: 4339Handles opcode 0x5d 4340****************************************************************************/ 4341static void 4342x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1)) 4343{ 4344 START_OF_INSTR(); 4345 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4346 DECODE_PRINTF("POP\tEBP\n"); 4347 } 4348 else { 4349 DECODE_PRINTF("POP\tBP\n"); 4350 } 4351 TRACE_AND_STEP(); 4352 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4353 M.x86.R_EBP = pop_long(); 4354 } 4355 else { 4356 M.x86.R_BP = pop_word(); 4357 } 4358 DECODE_CLEAR_SEGOVR(); 4359 END_OF_INSTR(); 4360} 4361 4362/**************************************************************************** 4363REMARKS: 4364Handles opcode 0x5e 4365****************************************************************************/ 4366static void 4367x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1)) 4368{ 4369 START_OF_INSTR(); 4370 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4371 DECODE_PRINTF("POP\tESI\n"); 4372 } 4373 else { 4374 DECODE_PRINTF("POP\tSI\n"); 4375 } 4376 TRACE_AND_STEP(); 4377 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4378 M.x86.R_ESI = pop_long(); 4379 } 4380 else { 4381 M.x86.R_SI = pop_word(); 4382 } 4383 DECODE_CLEAR_SEGOVR(); 4384 END_OF_INSTR(); 4385} 4386 4387/**************************************************************************** 4388REMARKS: 4389Handles opcode 0x5f 4390****************************************************************************/ 4391static void 4392x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1)) 4393{ 4394 START_OF_INSTR(); 4395 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4396 DECODE_PRINTF("POP\tEDI\n"); 4397 } 4398 else { 4399 DECODE_PRINTF("POP\tDI\n"); 4400 } 4401 TRACE_AND_STEP(); 4402 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4403 M.x86.R_EDI = pop_long(); 4404 } 4405 else { 4406 M.x86.R_DI = pop_word(); 4407 } 4408 DECODE_CLEAR_SEGOVR(); 4409 END_OF_INSTR(); 4410} 4411 4412/**************************************************************************** 4413REMARKS: 4414Handles opcode 0x60 4415****************************************************************************/ 4416static void 4417x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 4418{ 4419 START_OF_INSTR(); 4420 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4421 DECODE_PRINTF("PUSHAD\n"); 4422 } 4423 else { 4424 DECODE_PRINTF("PUSHA\n"); 4425 } 4426 TRACE_AND_STEP(); 4427 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4428 u32 old_sp = M.x86.R_ESP; 4429 4430 push_long(M.x86.R_EAX); 4431 push_long(M.x86.R_ECX); 4432 push_long(M.x86.R_EDX); 4433 push_long(M.x86.R_EBX); 4434 push_long(old_sp); 4435 push_long(M.x86.R_EBP); 4436 push_long(M.x86.R_ESI); 4437 push_long(M.x86.R_EDI); 4438 } 4439 else { 4440 u16 old_sp = M.x86.R_SP; 4441 4442 push_word(M.x86.R_AX); 4443 push_word(M.x86.R_CX); 4444 push_word(M.x86.R_DX); 4445 push_word(M.x86.R_BX); 4446 push_word(old_sp); 4447 push_word(M.x86.R_BP); 4448 push_word(M.x86.R_SI); 4449 push_word(M.x86.R_DI); 4450 } 4451 DECODE_CLEAR_SEGOVR(); 4452 END_OF_INSTR(); 4453} 4454 4455/**************************************************************************** 4456REMARKS: 4457Handles opcode 0x61 4458****************************************************************************/ 4459static void 4460x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 4461{ 4462 START_OF_INSTR(); 4463 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4464 DECODE_PRINTF("POPAD\n"); 4465 } 4466 else { 4467 DECODE_PRINTF("POPA\n"); 4468 } 4469 TRACE_AND_STEP(); 4470 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4471 M.x86.R_EDI = pop_long(); 4472 M.x86.R_ESI = pop_long(); 4473 M.x86.R_EBP = pop_long(); 4474 M.x86.R_ESP += 4; /* skip ESP */ 4475 M.x86.R_EBX = pop_long(); 4476 M.x86.R_EDX = pop_long(); 4477 M.x86.R_ECX = pop_long(); 4478 M.x86.R_EAX = pop_long(); 4479 } 4480 else { 4481 M.x86.R_DI = pop_word(); 4482 M.x86.R_SI = pop_word(); 4483 M.x86.R_BP = pop_word(); 4484 M.x86.R_SP += 2; /* skip SP */ 4485 M.x86.R_BX = pop_word(); 4486 M.x86.R_DX = pop_word(); 4487 M.x86.R_CX = pop_word(); 4488 M.x86.R_AX = pop_word(); 4489 } 4490 DECODE_CLEAR_SEGOVR(); 4491 END_OF_INSTR(); 4492} 4493 4494/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4495/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4496 4497/**************************************************************************** 4498REMARKS: 4499Handles opcode 0x64 4500****************************************************************************/ 4501static void 4502x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 4503{ 4504 START_OF_INSTR(); 4505 DECODE_PRINTF("FS:\n"); 4506 TRACE_AND_STEP(); 4507 M.x86.mode |= SYSMODE_SEGOVR_FS; 4508 /* 4509 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4510 * opcode subroutines we do not want to do this. 4511 */ 4512 END_OF_INSTR(); 4513} 4514 4515/**************************************************************************** 4516REMARKS: 4517Handles opcode 0x65 4518****************************************************************************/ 4519static void 4520x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 4521{ 4522 START_OF_INSTR(); 4523 DECODE_PRINTF("GS:\n"); 4524 TRACE_AND_STEP(); 4525 M.x86.mode |= SYSMODE_SEGOVR_GS; 4526 /* 4527 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4528 * opcode subroutines we do not want to do this. 4529 */ 4530 END_OF_INSTR(); 4531} 4532 4533/**************************************************************************** 4534REMARKS: 4535Handles opcode 0x66 - prefix for 32-bit register 4536****************************************************************************/ 4537static void 4538x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 4539{ 4540 START_OF_INSTR(); 4541 DECODE_PRINTF("DATA:\n"); 4542 TRACE_AND_STEP(); 4543 M.x86.mode |= SYSMODE_PREFIX_DATA; 4544 /* note no DECODE_CLEAR_SEGOVR here. */ 4545 END_OF_INSTR(); 4546} 4547 4548/**************************************************************************** 4549REMARKS: 4550Handles opcode 0x67 - prefix for 32-bit address 4551****************************************************************************/ 4552static void 4553x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 4554{ 4555 START_OF_INSTR(); 4556 DECODE_PRINTF("ADDR:\n"); 4557 TRACE_AND_STEP(); 4558 M.x86.mode |= SYSMODE_PREFIX_ADDR; 4559 /* note no DECODE_CLEAR_SEGOVR here. */ 4560 END_OF_INSTR(); 4561} 4562 4563/**************************************************************************** 4564REMARKS: 4565Handles opcode 0x68 4566****************************************************************************/ 4567static void 4568x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 4569{ 4570 u32 imm; 4571 4572 START_OF_INSTR(); 4573 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4574 imm = fetch_long_imm(); 4575 } 4576 else { 4577 imm = fetch_word_imm(); 4578 } 4579 DECODE_PRINTF2("PUSH\t%x\n", imm); 4580 TRACE_AND_STEP(); 4581 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4582 push_long(imm); 4583 } 4584 else { 4585 push_word((u16) imm); 4586 } 4587 DECODE_CLEAR_SEGOVR(); 4588 END_OF_INSTR(); 4589} 4590 4591/**************************************************************************** 4592REMARKS: 4593Handles opcode 0x69 4594****************************************************************************/ 4595static void 4596x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 4597{ 4598 int mod, rl, rh; 4599 uint srcoffset; 4600 4601 START_OF_INSTR(); 4602 DECODE_PRINTF("IMUL\t"); 4603 FETCH_DECODE_MODRM(mod, rh, rl); 4604 switch (mod) { 4605 case 0: 4606 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4607 u32 *destreg; 4608 u32 srcval; 4609 u32 res_lo, res_hi; 4610 s32 imm; 4611 4612 destreg = DECODE_RM_LONG_REGISTER(rh); 4613 DECODE_PRINTF(","); 4614 srcoffset = decode_rm00_address(rl); 4615 srcval = fetch_data_long(srcoffset); 4616 imm = fetch_long_imm(); 4617 DECODE_PRINTF2(",%d\n", (s32) imm); 4618 TRACE_AND_STEP(); 4619 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4620 if (res_hi != 0) { 4621 SET_FLAG(F_CF); 4622 SET_FLAG(F_OF); 4623 } 4624 else { 4625 CLEAR_FLAG(F_CF); 4626 CLEAR_FLAG(F_OF); 4627 } 4628 *destreg = (u32) res_lo; 4629 } 4630 else { 4631 u16 *destreg; 4632 u16 srcval; 4633 u32 res; 4634 s16 imm; 4635 4636 destreg = DECODE_RM_WORD_REGISTER(rh); 4637 DECODE_PRINTF(","); 4638 srcoffset = decode_rm00_address(rl); 4639 srcval = fetch_data_word(srcoffset); 4640 imm = fetch_word_imm(); 4641 DECODE_PRINTF2(",%d\n", (s32) imm); 4642 TRACE_AND_STEP(); 4643 res = (s16) srcval *(s16) imm; 4644 4645 if (res > 0xFFFF) { 4646 SET_FLAG(F_CF); 4647 SET_FLAG(F_OF); 4648 } 4649 else { 4650 CLEAR_FLAG(F_CF); 4651 CLEAR_FLAG(F_OF); 4652 } 4653 *destreg = (u16) res; 4654 } 4655 break; 4656 case 1: 4657 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4658 u32 *destreg; 4659 u32 srcval; 4660 u32 res_lo, res_hi; 4661 s32 imm; 4662 4663 destreg = DECODE_RM_LONG_REGISTER(rh); 4664 DECODE_PRINTF(","); 4665 srcoffset = decode_rm01_address(rl); 4666 srcval = fetch_data_long(srcoffset); 4667 imm = fetch_long_imm(); 4668 DECODE_PRINTF2(",%d\n", (s32) imm); 4669 TRACE_AND_STEP(); 4670 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4671 if (res_hi != 0) { 4672 SET_FLAG(F_CF); 4673 SET_FLAG(F_OF); 4674 } 4675 else { 4676 CLEAR_FLAG(F_CF); 4677 CLEAR_FLAG(F_OF); 4678 } 4679 *destreg = (u32) res_lo; 4680 } 4681 else { 4682 u16 *destreg; 4683 u16 srcval; 4684 u32 res; 4685 s16 imm; 4686 4687 destreg = DECODE_RM_WORD_REGISTER(rh); 4688 DECODE_PRINTF(","); 4689 srcoffset = decode_rm01_address(rl); 4690 srcval = fetch_data_word(srcoffset); 4691 imm = fetch_word_imm(); 4692 DECODE_PRINTF2(",%d\n", (s32) imm); 4693 TRACE_AND_STEP(); 4694 res = (s16) srcval *(s16) imm; 4695 4696 if (res > 0xFFFF) { 4697 SET_FLAG(F_CF); 4698 SET_FLAG(F_OF); 4699 } 4700 else { 4701 CLEAR_FLAG(F_CF); 4702 CLEAR_FLAG(F_OF); 4703 } 4704 *destreg = (u16) res; 4705 } 4706 break; 4707 case 2: 4708 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4709 u32 *destreg; 4710 u32 srcval; 4711 u32 res_lo, res_hi; 4712 s32 imm; 4713 4714 destreg = DECODE_RM_LONG_REGISTER(rh); 4715 DECODE_PRINTF(","); 4716 srcoffset = decode_rm10_address(rl); 4717 srcval = fetch_data_long(srcoffset); 4718 imm = fetch_long_imm(); 4719 DECODE_PRINTF2(",%d\n", (s32) imm); 4720 TRACE_AND_STEP(); 4721 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4722 if (res_hi != 0) { 4723 SET_FLAG(F_CF); 4724 SET_FLAG(F_OF); 4725 } 4726 else { 4727 CLEAR_FLAG(F_CF); 4728 CLEAR_FLAG(F_OF); 4729 } 4730 *destreg = (u32) res_lo; 4731 } 4732 else { 4733 u16 *destreg; 4734 u16 srcval; 4735 u32 res; 4736 s16 imm; 4737 4738 destreg = DECODE_RM_WORD_REGISTER(rh); 4739 DECODE_PRINTF(","); 4740 srcoffset = decode_rm10_address(rl); 4741 srcval = fetch_data_word(srcoffset); 4742 imm = fetch_word_imm(); 4743 DECODE_PRINTF2(",%d\n", (s32) imm); 4744 TRACE_AND_STEP(); 4745 res = (s16) srcval *(s16) imm; 4746 4747 if (res > 0xFFFF) { 4748 SET_FLAG(F_CF); 4749 SET_FLAG(F_OF); 4750 } 4751 else { 4752 CLEAR_FLAG(F_CF); 4753 CLEAR_FLAG(F_OF); 4754 } 4755 *destreg = (u16) res; 4756 } 4757 break; 4758 case 3: /* register to register */ 4759 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4760 u32 *destreg, *srcreg; 4761 u32 res_lo, res_hi; 4762 s32 imm; 4763 4764 destreg = DECODE_RM_LONG_REGISTER(rh); 4765 DECODE_PRINTF(","); 4766 srcreg = DECODE_RM_LONG_REGISTER(rl); 4767 imm = fetch_long_imm(); 4768 DECODE_PRINTF2(",%d\n", (s32) imm); 4769 TRACE_AND_STEP(); 4770 imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm); 4771 if (res_hi != 0) { 4772 SET_FLAG(F_CF); 4773 SET_FLAG(F_OF); 4774 } 4775 else { 4776 CLEAR_FLAG(F_CF); 4777 CLEAR_FLAG(F_OF); 4778 } 4779 *destreg = (u32) res_lo; 4780 } 4781 else { 4782 u16 *destreg, *srcreg; 4783 u32 res; 4784 s16 imm; 4785 4786 destreg = DECODE_RM_WORD_REGISTER(rh); 4787 DECODE_PRINTF(","); 4788 srcreg = DECODE_RM_WORD_REGISTER(rl); 4789 imm = fetch_word_imm(); 4790 DECODE_PRINTF2(",%d\n", (s32) imm); 4791 res = (s16) * srcreg * (s16) imm; 4792 if (res > 0xFFFF) { 4793 SET_FLAG(F_CF); 4794 SET_FLAG(F_OF); 4795 } 4796 else { 4797 CLEAR_FLAG(F_CF); 4798 CLEAR_FLAG(F_OF); 4799 } 4800 *destreg = (u16) res; 4801 } 4802 break; 4803 } 4804 DECODE_CLEAR_SEGOVR(); 4805 END_OF_INSTR(); 4806} 4807 4808/**************************************************************************** 4809REMARKS: 4810Handles opcode 0x6a 4811****************************************************************************/ 4812static void 4813x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 4814{ 4815 s16 imm; 4816 4817 START_OF_INSTR(); 4818 imm = (s8) fetch_byte_imm(); 4819 DECODE_PRINTF2("PUSH\t%d\n", imm); 4820 TRACE_AND_STEP(); 4821 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4822 push_long((s32) imm); 4823 } 4824 else { 4825 push_word(imm); 4826 } 4827 DECODE_CLEAR_SEGOVR(); 4828 END_OF_INSTR(); 4829} 4830 4831/**************************************************************************** 4832REMARKS: 4833Handles opcode 0x6b 4834****************************************************************************/ 4835static void 4836x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 4837{ 4838 int mod, rl, rh; 4839 uint srcoffset; 4840 s8 imm; 4841 4842 START_OF_INSTR(); 4843 DECODE_PRINTF("IMUL\t"); 4844 FETCH_DECODE_MODRM(mod, rh, rl); 4845 switch (mod) { 4846 case 0: 4847 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4848 u32 *destreg; 4849 u32 srcval; 4850 u32 res_lo, res_hi; 4851 4852 destreg = DECODE_RM_LONG_REGISTER(rh); 4853 DECODE_PRINTF(","); 4854 srcoffset = decode_rm00_address(rl); 4855 srcval = fetch_data_long(srcoffset); 4856 imm = fetch_byte_imm(); 4857 DECODE_PRINTF2(",%d\n", (s32) imm); 4858 TRACE_AND_STEP(); 4859 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4860 if (res_hi != 0) { 4861 SET_FLAG(F_CF); 4862 SET_FLAG(F_OF); 4863 } 4864 else { 4865 CLEAR_FLAG(F_CF); 4866 CLEAR_FLAG(F_OF); 4867 } 4868 *destreg = (u32) res_lo; 4869 } 4870 else { 4871 u16 *destreg; 4872 u16 srcval; 4873 u32 res; 4874 4875 destreg = DECODE_RM_WORD_REGISTER(rh); 4876 DECODE_PRINTF(","); 4877 srcoffset = decode_rm00_address(rl); 4878 srcval = fetch_data_word(srcoffset); 4879 imm = fetch_byte_imm(); 4880 DECODE_PRINTF2(",%d\n", (s32) imm); 4881 TRACE_AND_STEP(); 4882 res = (s16) srcval *(s16) imm; 4883 4884 if (res > 0xFFFF) { 4885 SET_FLAG(F_CF); 4886 SET_FLAG(F_OF); 4887 } 4888 else { 4889 CLEAR_FLAG(F_CF); 4890 CLEAR_FLAG(F_OF); 4891 } 4892 *destreg = (u16) res; 4893 } 4894 break; 4895 case 1: 4896 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4897 u32 *destreg; 4898 u32 srcval; 4899 u32 res_lo, res_hi; 4900 4901 destreg = DECODE_RM_LONG_REGISTER(rh); 4902 DECODE_PRINTF(","); 4903 srcoffset = decode_rm01_address(rl); 4904 srcval = fetch_data_long(srcoffset); 4905 imm = fetch_byte_imm(); 4906 DECODE_PRINTF2(",%d\n", (s32) imm); 4907 TRACE_AND_STEP(); 4908 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4909 if (res_hi != 0) { 4910 SET_FLAG(F_CF); 4911 SET_FLAG(F_OF); 4912 } 4913 else { 4914 CLEAR_FLAG(F_CF); 4915 CLEAR_FLAG(F_OF); 4916 } 4917 *destreg = (u32) res_lo; 4918 } 4919 else { 4920 u16 *destreg; 4921 u16 srcval; 4922 u32 res; 4923 4924 destreg = DECODE_RM_WORD_REGISTER(rh); 4925 DECODE_PRINTF(","); 4926 srcoffset = decode_rm01_address(rl); 4927 srcval = fetch_data_word(srcoffset); 4928 imm = fetch_byte_imm(); 4929 DECODE_PRINTF2(",%d\n", (s32) imm); 4930 TRACE_AND_STEP(); 4931 res = (s16) srcval *(s16) imm; 4932 4933 if (res > 0xFFFF) { 4934 SET_FLAG(F_CF); 4935 SET_FLAG(F_OF); 4936 } 4937 else { 4938 CLEAR_FLAG(F_CF); 4939 CLEAR_FLAG(F_OF); 4940 } 4941 *destreg = (u16) res; 4942 } 4943 break; 4944 case 2: 4945 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4946 u32 *destreg; 4947 u32 srcval; 4948 u32 res_lo, res_hi; 4949 4950 destreg = DECODE_RM_LONG_REGISTER(rh); 4951 DECODE_PRINTF(","); 4952 srcoffset = decode_rm10_address(rl); 4953 srcval = fetch_data_long(srcoffset); 4954 imm = fetch_byte_imm(); 4955 DECODE_PRINTF2(",%d\n", (s32) imm); 4956 TRACE_AND_STEP(); 4957 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm); 4958 if (res_hi != 0) { 4959 SET_FLAG(F_CF); 4960 SET_FLAG(F_OF); 4961 } 4962 else { 4963 CLEAR_FLAG(F_CF); 4964 CLEAR_FLAG(F_OF); 4965 } 4966 *destreg = (u32) res_lo; 4967 } 4968 else { 4969 u16 *destreg; 4970 u16 srcval; 4971 u32 res; 4972 4973 destreg = DECODE_RM_WORD_REGISTER(rh); 4974 DECODE_PRINTF(","); 4975 srcoffset = decode_rm10_address(rl); 4976 srcval = fetch_data_word(srcoffset); 4977 imm = fetch_byte_imm(); 4978 DECODE_PRINTF2(",%d\n", (s32) imm); 4979 TRACE_AND_STEP(); 4980 res = (s16) srcval *(s16) imm; 4981 4982 if (res > 0xFFFF) { 4983 SET_FLAG(F_CF); 4984 SET_FLAG(F_OF); 4985 } 4986 else { 4987 CLEAR_FLAG(F_CF); 4988 CLEAR_FLAG(F_OF); 4989 } 4990 *destreg = (u16) res; 4991 } 4992 break; 4993 case 3: /* register to register */ 4994 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4995 u32 *destreg, *srcreg; 4996 u32 res_lo, res_hi; 4997 4998 destreg = DECODE_RM_LONG_REGISTER(rh); 4999 DECODE_PRINTF(","); 5000 srcreg = DECODE_RM_LONG_REGISTER(rl); 5001 imm = fetch_byte_imm(); 5002 DECODE_PRINTF2(",%d\n", (s32) imm); 5003 TRACE_AND_STEP(); 5004 imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm); 5005 if (res_hi != 0) { 5006 SET_FLAG(F_CF); 5007 SET_FLAG(F_OF); 5008 } 5009 else { 5010 CLEAR_FLAG(F_CF); 5011 CLEAR_FLAG(F_OF); 5012 } 5013 *destreg = (u32) res_lo; 5014 } 5015 else { 5016 u16 *destreg, *srcreg; 5017 u32 res; 5018 5019 destreg = DECODE_RM_WORD_REGISTER(rh); 5020 DECODE_PRINTF(","); 5021 srcreg = DECODE_RM_WORD_REGISTER(rl); 5022 imm = fetch_byte_imm(); 5023 DECODE_PRINTF2(",%d\n", (s32) imm); 5024 res = (s16) * srcreg * (s16) imm; 5025 if (res > 0xFFFF) { 5026 SET_FLAG(F_CF); 5027 SET_FLAG(F_OF); 5028 } 5029 else { 5030 CLEAR_FLAG(F_CF); 5031 CLEAR_FLAG(F_OF); 5032 } 5033 *destreg = (u16) res; 5034 } 5035 break; 5036 } 5037 DECODE_CLEAR_SEGOVR(); 5038 END_OF_INSTR(); 5039} 5040 5041/**************************************************************************** 5042REMARKS: 5043Handles opcode 0x6c 5044****************************************************************************/ 5045static void 5046x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 5047{ 5048 START_OF_INSTR(); 5049 DECODE_PRINTF("INSB\n"); 5050 ins(1); 5051 TRACE_AND_STEP(); 5052 DECODE_CLEAR_SEGOVR(); 5053 END_OF_INSTR(); 5054} 5055 5056/**************************************************************************** 5057REMARKS: 5058Handles opcode 0x6d 5059****************************************************************************/ 5060static void 5061x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 5062{ 5063 START_OF_INSTR(); 5064 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5065 DECODE_PRINTF("INSD\n"); 5066 ins(4); 5067 } 5068 else { 5069 DECODE_PRINTF("INSW\n"); 5070 ins(2); 5071 } 5072 TRACE_AND_STEP(); 5073 DECODE_CLEAR_SEGOVR(); 5074 END_OF_INSTR(); 5075} 5076 5077/**************************************************************************** 5078REMARKS: 5079Handles opcode 0x6e 5080****************************************************************************/ 5081static void 5082x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 5083{ 5084 START_OF_INSTR(); 5085 DECODE_PRINTF("OUTSB\n"); 5086 outs(1); 5087 TRACE_AND_STEP(); 5088 DECODE_CLEAR_SEGOVR(); 5089 END_OF_INSTR(); 5090} 5091 5092/**************************************************************************** 5093REMARKS: 5094Handles opcode 0x6f 5095****************************************************************************/ 5096static void 5097x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 5098{ 5099 START_OF_INSTR(); 5100 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5101 DECODE_PRINTF("OUTSD\n"); 5102 outs(4); 5103 } 5104 else { 5105 DECODE_PRINTF("OUTSW\n"); 5106 outs(2); 5107 } 5108 TRACE_AND_STEP(); 5109 DECODE_CLEAR_SEGOVR(); 5110 END_OF_INSTR(); 5111} 5112 5113/**************************************************************************** 5114REMARKS: 5115Handles opcode 0x70 5116****************************************************************************/ 5117static void 5118x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1)) 5119{ 5120 s8 offset; 5121 u16 target; 5122 5123 /* jump to byte offset if overflow flag is set */ 5124 START_OF_INSTR(); 5125 DECODE_PRINTF("JO\t"); 5126 offset = (s8) fetch_byte_imm(); 5127 target = (u16) (M.x86.R_IP + (s16) offset); 5128 DECODE_PRINTF2("%x\n", target); 5129 TRACE_AND_STEP(); 5130 if (ACCESS_FLAG(F_OF)) 5131 M.x86.R_IP = target; 5132 DECODE_CLEAR_SEGOVR(); 5133 END_OF_INSTR(); 5134} 5135 5136/**************************************************************************** 5137REMARKS: 5138Handles opcode 0x71 5139****************************************************************************/ 5140static void 5141x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1)) 5142{ 5143 s8 offset; 5144 u16 target; 5145 5146 /* jump to byte offset if overflow is not set */ 5147 START_OF_INSTR(); 5148 DECODE_PRINTF("JNO\t"); 5149 offset = (s8) fetch_byte_imm(); 5150 target = (u16) (M.x86.R_IP + (s16) offset); 5151 DECODE_PRINTF2("%x\n", target); 5152 TRACE_AND_STEP(); 5153 if (!ACCESS_FLAG(F_OF)) 5154 M.x86.R_IP = target; 5155 DECODE_CLEAR_SEGOVR(); 5156 END_OF_INSTR(); 5157} 5158 5159/**************************************************************************** 5160REMARKS: 5161Handles opcode 0x72 5162****************************************************************************/ 5163static void 5164x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1)) 5165{ 5166 s8 offset; 5167 u16 target; 5168 5169 /* jump to byte offset if carry flag is set. */ 5170 START_OF_INSTR(); 5171 DECODE_PRINTF("JB\t"); 5172 offset = (s8) fetch_byte_imm(); 5173 target = (u16) (M.x86.R_IP + (s16) offset); 5174 DECODE_PRINTF2("%x\n", target); 5175 TRACE_AND_STEP(); 5176 if (ACCESS_FLAG(F_CF)) 5177 M.x86.R_IP = target; 5178 DECODE_CLEAR_SEGOVR(); 5179 END_OF_INSTR(); 5180} 5181 5182/**************************************************************************** 5183REMARKS: 5184Handles opcode 0x73 5185****************************************************************************/ 5186static void 5187x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1)) 5188{ 5189 s8 offset; 5190 u16 target; 5191 5192 /* jump to byte offset if carry flag is clear. */ 5193 START_OF_INSTR(); 5194 DECODE_PRINTF("JNB\t"); 5195 offset = (s8) fetch_byte_imm(); 5196 target = (u16) (M.x86.R_IP + (s16) offset); 5197 DECODE_PRINTF2("%x\n", target); 5198 TRACE_AND_STEP(); 5199 if (!ACCESS_FLAG(F_CF)) 5200 M.x86.R_IP = target; 5201 DECODE_CLEAR_SEGOVR(); 5202 END_OF_INSTR(); 5203} 5204 5205/**************************************************************************** 5206REMARKS: 5207Handles opcode 0x74 5208****************************************************************************/ 5209static void 5210x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1)) 5211{ 5212 s8 offset; 5213 u16 target; 5214 5215 /* jump to byte offset if zero flag is set. */ 5216 START_OF_INSTR(); 5217 DECODE_PRINTF("JZ\t"); 5218 offset = (s8) fetch_byte_imm(); 5219 target = (u16) (M.x86.R_IP + (s16) offset); 5220 DECODE_PRINTF2("%x\n", target); 5221 TRACE_AND_STEP(); 5222 if (ACCESS_FLAG(F_ZF)) 5223 M.x86.R_IP = target; 5224 DECODE_CLEAR_SEGOVR(); 5225 END_OF_INSTR(); 5226} 5227 5228/**************************************************************************** 5229REMARKS: 5230Handles opcode 0x75 5231****************************************************************************/ 5232static void 5233x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1)) 5234{ 5235 s8 offset; 5236 u16 target; 5237 5238 /* jump to byte offset if zero flag is clear. */ 5239 START_OF_INSTR(); 5240 DECODE_PRINTF("JNZ\t"); 5241 offset = (s8) fetch_byte_imm(); 5242 target = (u16) (M.x86.R_IP + (s16) offset); 5243 DECODE_PRINTF2("%x\n", target); 5244 TRACE_AND_STEP(); 5245 if (!ACCESS_FLAG(F_ZF)) 5246 M.x86.R_IP = target; 5247 DECODE_CLEAR_SEGOVR(); 5248 END_OF_INSTR(); 5249} 5250 5251/**************************************************************************** 5252REMARKS: 5253Handles opcode 0x76 5254****************************************************************************/ 5255static void 5256x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1)) 5257{ 5258 s8 offset; 5259 u16 target; 5260 5261 /* jump to byte offset if carry flag is set or if the zero 5262 flag is set. */ 5263 START_OF_INSTR(); 5264 DECODE_PRINTF("JBE\t"); 5265 offset = (s8) fetch_byte_imm(); 5266 target = (u16) (M.x86.R_IP + (s16) offset); 5267 DECODE_PRINTF2("%x\n", target); 5268 TRACE_AND_STEP(); 5269 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) 5270 M.x86.R_IP = target; 5271 DECODE_CLEAR_SEGOVR(); 5272 END_OF_INSTR(); 5273} 5274 5275/**************************************************************************** 5276REMARKS: 5277Handles opcode 0x77 5278****************************************************************************/ 5279static void 5280x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1)) 5281{ 5282 s8 offset; 5283 u16 target; 5284 5285 /* jump to byte offset if carry flag is clear and if the zero 5286 flag is clear */ 5287 START_OF_INSTR(); 5288 DECODE_PRINTF("JNBE\t"); 5289 offset = (s8) fetch_byte_imm(); 5290 target = (u16) (M.x86.R_IP + (s16) offset); 5291 DECODE_PRINTF2("%x\n", target); 5292 TRACE_AND_STEP(); 5293 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))) 5294 M.x86.R_IP = target; 5295 DECODE_CLEAR_SEGOVR(); 5296 END_OF_INSTR(); 5297} 5298 5299/**************************************************************************** 5300REMARKS: 5301Handles opcode 0x78 5302****************************************************************************/ 5303static void 5304x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1)) 5305{ 5306 s8 offset; 5307 u16 target; 5308 5309 /* jump to byte offset if sign flag is set */ 5310 START_OF_INSTR(); 5311 DECODE_PRINTF("JS\t"); 5312 offset = (s8) fetch_byte_imm(); 5313 target = (u16) (M.x86.R_IP + (s16) offset); 5314 DECODE_PRINTF2("%x\n", target); 5315 TRACE_AND_STEP(); 5316 if (ACCESS_FLAG(F_SF)) 5317 M.x86.R_IP = target; 5318 DECODE_CLEAR_SEGOVR(); 5319 END_OF_INSTR(); 5320} 5321 5322/**************************************************************************** 5323REMARKS: 5324Handles opcode 0x79 5325****************************************************************************/ 5326static void 5327x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1)) 5328{ 5329 s8 offset; 5330 u16 target; 5331 5332 /* jump to byte offset if sign flag is clear */ 5333 START_OF_INSTR(); 5334 DECODE_PRINTF("JNS\t"); 5335 offset = (s8) fetch_byte_imm(); 5336 target = (u16) (M.x86.R_IP + (s16) offset); 5337 DECODE_PRINTF2("%x\n", target); 5338 TRACE_AND_STEP(); 5339 if (!ACCESS_FLAG(F_SF)) 5340 M.x86.R_IP = target; 5341 DECODE_CLEAR_SEGOVR(); 5342 END_OF_INSTR(); 5343} 5344 5345/**************************************************************************** 5346REMARKS: 5347Handles opcode 0x7a 5348****************************************************************************/ 5349static void 5350x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1)) 5351{ 5352 s8 offset; 5353 u16 target; 5354 5355 /* jump to byte offset if parity flag is set (even parity) */ 5356 START_OF_INSTR(); 5357 DECODE_PRINTF("JP\t"); 5358 offset = (s8) fetch_byte_imm(); 5359 target = (u16) (M.x86.R_IP + (s16) offset); 5360 DECODE_PRINTF2("%x\n", target); 5361 TRACE_AND_STEP(); 5362 if (ACCESS_FLAG(F_PF)) 5363 M.x86.R_IP = target; 5364 DECODE_CLEAR_SEGOVR(); 5365 END_OF_INSTR(); 5366} 5367 5368/**************************************************************************** 5369REMARKS: 5370Handles opcode 0x7b 5371****************************************************************************/ 5372static void 5373x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1)) 5374{ 5375 s8 offset; 5376 u16 target; 5377 5378 /* jump to byte offset if parity flag is clear (odd parity) */ 5379 START_OF_INSTR(); 5380 DECODE_PRINTF("JNP\t"); 5381 offset = (s8) fetch_byte_imm(); 5382 target = (u16) (M.x86.R_IP + (s16) offset); 5383 DECODE_PRINTF2("%x\n", target); 5384 TRACE_AND_STEP(); 5385 if (!ACCESS_FLAG(F_PF)) 5386 M.x86.R_IP = target; 5387 DECODE_CLEAR_SEGOVR(); 5388 END_OF_INSTR(); 5389} 5390 5391/**************************************************************************** 5392REMARKS: 5393Handles opcode 0x7c 5394****************************************************************************/ 5395static void 5396x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1)) 5397{ 5398 s8 offset; 5399 u16 target; 5400 int sf, of; 5401 5402 /* jump to byte offset if sign flag not equal to overflow flag. */ 5403 START_OF_INSTR(); 5404 DECODE_PRINTF("JL\t"); 5405 offset = (s8) fetch_byte_imm(); 5406 target = (u16) (M.x86.R_IP + (s16) offset); 5407 DECODE_PRINTF2("%x\n", target); 5408 TRACE_AND_STEP(); 5409 sf = ACCESS_FLAG(F_SF) != 0; 5410 of = ACCESS_FLAG(F_OF) != 0; 5411 if (sf ^ of) 5412 M.x86.R_IP = target; 5413 DECODE_CLEAR_SEGOVR(); 5414 END_OF_INSTR(); 5415} 5416 5417/**************************************************************************** 5418REMARKS: 5419Handles opcode 0x7d 5420****************************************************************************/ 5421static void 5422x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1)) 5423{ 5424 s8 offset; 5425 u16 target; 5426 int sf, of; 5427 5428 /* jump to byte offset if sign flag not equal to overflow flag. */ 5429 START_OF_INSTR(); 5430 DECODE_PRINTF("JNL\t"); 5431 offset = (s8) fetch_byte_imm(); 5432 target = (u16) (M.x86.R_IP + (s16) offset); 5433 DECODE_PRINTF2("%x\n", target); 5434 TRACE_AND_STEP(); 5435 sf = ACCESS_FLAG(F_SF) != 0; 5436 of = ACCESS_FLAG(F_OF) != 0; 5437 /* note: inverse of above, but using == instead of xor. */ 5438 if (sf == of) 5439 M.x86.R_IP = target; 5440 DECODE_CLEAR_SEGOVR(); 5441 END_OF_INSTR(); 5442} 5443 5444/**************************************************************************** 5445REMARKS: 5446Handles opcode 0x7e 5447****************************************************************************/ 5448static void 5449x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1)) 5450{ 5451 s8 offset; 5452 u16 target; 5453 int sf, of; 5454 5455 /* jump to byte offset if sign flag not equal to overflow flag 5456 or the zero flag is set */ 5457 START_OF_INSTR(); 5458 DECODE_PRINTF("JLE\t"); 5459 offset = (s8) fetch_byte_imm(); 5460 target = (u16) (M.x86.R_IP + (s16) offset); 5461 DECODE_PRINTF2("%x\n", target); 5462 TRACE_AND_STEP(); 5463 sf = ACCESS_FLAG(F_SF) != 0; 5464 of = ACCESS_FLAG(F_OF) != 0; 5465 if ((sf ^ of) || ACCESS_FLAG(F_ZF)) 5466 M.x86.R_IP = target; 5467 DECODE_CLEAR_SEGOVR(); 5468 END_OF_INSTR(); 5469} 5470 5471/**************************************************************************** 5472REMARKS: 5473Handles opcode 0x7f 5474****************************************************************************/ 5475static void 5476x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1)) 5477{ 5478 s8 offset; 5479 u16 target; 5480 int sf, of; 5481 5482 /* jump to byte offset if sign flag equal to overflow flag. 5483 and the zero flag is clear */ 5484 START_OF_INSTR(); 5485 DECODE_PRINTF("JNLE\t"); 5486 offset = (s8) fetch_byte_imm(); 5487 target = (u16) (M.x86.R_IP + (s16) offset); 5488 DECODE_PRINTF2("%x\n", target); 5489 TRACE_AND_STEP(); 5490 sf = ACCESS_FLAG(F_SF) != 0; 5491 of = ACCESS_FLAG(F_OF) != 0; 5492 if ((sf == of) && !ACCESS_FLAG(F_ZF)) 5493 M.x86.R_IP = target; 5494 DECODE_CLEAR_SEGOVR(); 5495 END_OF_INSTR(); 5496} 5497 5498static u8(*opc80_byte_operation[]) (u8 d, u8 s) = { 5499 add_byte, /* 00 */ 5500 or_byte, /* 01 */ 5501 adc_byte, /* 02 */ 5502 sbb_byte, /* 03 */ 5503 and_byte, /* 04 */ 5504 sub_byte, /* 05 */ 5505 xor_byte, /* 06 */ 5506 cmp_byte, /* 07 */ 5507}; 5508 5509/**************************************************************************** 5510REMARKS: 5511Handles opcode 0x80 5512****************************************************************************/ 5513static void 5514x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5515{ 5516 int mod, rl, rh; 5517 u8 *destreg; 5518 uint destoffset; 5519 u8 imm; 5520 u8 destval; 5521 5522 /* 5523 * Weirdo special case instruction format. Part of the opcode 5524 * held below in "RH". Doubly nested case would result, except 5525 * that the decoded instruction 5526 */ 5527 START_OF_INSTR(); 5528 FETCH_DECODE_MODRM(mod, rh, rl); 5529#ifdef DEBUG 5530 if (DEBUG_DECODE()) { 5531 /* XXX DECODE_PRINTF may be changed to something more 5532 general, so that it is important to leave the strings 5533 in the same format, even though the result is that the 5534 above test is done twice. */ 5535 5536 switch (rh) { 5537 case 0: 5538 DECODE_PRINTF("ADD\t"); 5539 break; 5540 case 1: 5541 DECODE_PRINTF("OR\t"); 5542 break; 5543 case 2: 5544 DECODE_PRINTF("ADC\t"); 5545 break; 5546 case 3: 5547 DECODE_PRINTF("SBB\t"); 5548 break; 5549 case 4: 5550 DECODE_PRINTF("AND\t"); 5551 break; 5552 case 5: 5553 DECODE_PRINTF("SUB\t"); 5554 break; 5555 case 6: 5556 DECODE_PRINTF("XOR\t"); 5557 break; 5558 case 7: 5559 DECODE_PRINTF("CMP\t"); 5560 break; 5561 } 5562 } 5563#endif 5564 /* know operation, decode the mod byte to find the addressing 5565 mode. */ 5566 switch (mod) { 5567 case 0: 5568 DECODE_PRINTF("BYTE PTR "); 5569 destoffset = decode_rm00_address(rl); 5570 DECODE_PRINTF(","); 5571 destval = fetch_data_byte(destoffset); 5572 imm = fetch_byte_imm(); 5573 DECODE_PRINTF2("%x\n", imm); 5574 TRACE_AND_STEP(); 5575 destval = (*opc80_byte_operation[rh]) (destval, imm); 5576 if (rh != 7) 5577 store_data_byte(destoffset, destval); 5578 break; 5579 case 1: 5580 DECODE_PRINTF("BYTE PTR "); 5581 destoffset = decode_rm01_address(rl); 5582 DECODE_PRINTF(","); 5583 destval = fetch_data_byte(destoffset); 5584 imm = fetch_byte_imm(); 5585 DECODE_PRINTF2("%x\n", imm); 5586 TRACE_AND_STEP(); 5587 destval = (*opc80_byte_operation[rh]) (destval, imm); 5588 if (rh != 7) 5589 store_data_byte(destoffset, destval); 5590 break; 5591 case 2: 5592 DECODE_PRINTF("BYTE PTR "); 5593 destoffset = decode_rm10_address(rl); 5594 DECODE_PRINTF(","); 5595 destval = fetch_data_byte(destoffset); 5596 imm = fetch_byte_imm(); 5597 DECODE_PRINTF2("%x\n", imm); 5598 TRACE_AND_STEP(); 5599 destval = (*opc80_byte_operation[rh]) (destval, imm); 5600 if (rh != 7) 5601 store_data_byte(destoffset, destval); 5602 break; 5603 case 3: /* register to register */ 5604 destreg = DECODE_RM_BYTE_REGISTER(rl); 5605 DECODE_PRINTF(","); 5606 imm = fetch_byte_imm(); 5607 DECODE_PRINTF2("%x\n", imm); 5608 TRACE_AND_STEP(); 5609 destval = (*opc80_byte_operation[rh]) (*destreg, imm); 5610 if (rh != 7) 5611 *destreg = destval; 5612 break; 5613 } 5614 DECODE_CLEAR_SEGOVR(); 5615 END_OF_INSTR(); 5616} 5617 5618static u16(*opc81_word_operation[]) (u16 d, u16 s) = { 5619 add_word, /*00 */ 5620 or_word, /*01 */ 5621 adc_word, /*02 */ 5622 sbb_word, /*03 */ 5623 and_word, /*04 */ 5624 sub_word, /*05 */ 5625 xor_word, /*06 */ 5626 cmp_word, /*07 */ 5627}; 5628 5629static u32(*opc81_long_operation[]) (u32 d, u32 s) = { 5630 add_long, /*00 */ 5631 or_long, /*01 */ 5632 adc_long, /*02 */ 5633 sbb_long, /*03 */ 5634 and_long, /*04 */ 5635 sub_long, /*05 */ 5636 xor_long, /*06 */ 5637 cmp_long, /*07 */ 5638}; 5639 5640/**************************************************************************** 5641REMARKS: 5642Handles opcode 0x81 5643****************************************************************************/ 5644static void 5645x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5646{ 5647 int mod, rl, rh; 5648 uint destoffset; 5649 5650 /* 5651 * Weirdo special case instruction format. Part of the opcode 5652 * held below in "RH". Doubly nested case would result, except 5653 * that the decoded instruction 5654 */ 5655 START_OF_INSTR(); 5656 FETCH_DECODE_MODRM(mod, rh, rl); 5657#ifdef DEBUG 5658 if (DEBUG_DECODE()) { 5659 /* XXX DECODE_PRINTF may be changed to something more 5660 general, so that it is important to leave the strings 5661 in the same format, even though the result is that the 5662 above test is done twice. */ 5663 5664 switch (rh) { 5665 case 0: 5666 DECODE_PRINTF("ADD\t"); 5667 break; 5668 case 1: 5669 DECODE_PRINTF("OR\t"); 5670 break; 5671 case 2: 5672 DECODE_PRINTF("ADC\t"); 5673 break; 5674 case 3: 5675 DECODE_PRINTF("SBB\t"); 5676 break; 5677 case 4: 5678 DECODE_PRINTF("AND\t"); 5679 break; 5680 case 5: 5681 DECODE_PRINTF("SUB\t"); 5682 break; 5683 case 6: 5684 DECODE_PRINTF("XOR\t"); 5685 break; 5686 case 7: 5687 DECODE_PRINTF("CMP\t"); 5688 break; 5689 } 5690 } 5691#endif 5692 /* 5693 * Know operation, decode the mod byte to find the addressing 5694 * mode. 5695 */ 5696 switch (mod) { 5697 case 0: 5698 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5699 u32 destval, imm; 5700 5701 DECODE_PRINTF("DWORD PTR "); 5702 destoffset = decode_rm00_address(rl); 5703 DECODE_PRINTF(","); 5704 destval = fetch_data_long(destoffset); 5705 imm = fetch_long_imm(); 5706 DECODE_PRINTF2("%x\n", imm); 5707 TRACE_AND_STEP(); 5708 destval = (*opc81_long_operation[rh]) (destval, imm); 5709 if (rh != 7) 5710 store_data_long(destoffset, destval); 5711 } 5712 else { 5713 u16 destval, imm; 5714 5715 DECODE_PRINTF("WORD PTR "); 5716 destoffset = decode_rm00_address(rl); 5717 DECODE_PRINTF(","); 5718 destval = fetch_data_word(destoffset); 5719 imm = fetch_word_imm(); 5720 DECODE_PRINTF2("%x\n", imm); 5721 TRACE_AND_STEP(); 5722 destval = (*opc81_word_operation[rh]) (destval, imm); 5723 if (rh != 7) 5724 store_data_word(destoffset, destval); 5725 } 5726 break; 5727 case 1: 5728 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5729 u32 destval, imm; 5730 5731 DECODE_PRINTF("DWORD PTR "); 5732 destoffset = decode_rm01_address(rl); 5733 DECODE_PRINTF(","); 5734 destval = fetch_data_long(destoffset); 5735 imm = fetch_long_imm(); 5736 DECODE_PRINTF2("%x\n", imm); 5737 TRACE_AND_STEP(); 5738 destval = (*opc81_long_operation[rh]) (destval, imm); 5739 if (rh != 7) 5740 store_data_long(destoffset, destval); 5741 } 5742 else { 5743 u16 destval, imm; 5744 5745 DECODE_PRINTF("WORD PTR "); 5746 destoffset = decode_rm01_address(rl); 5747 DECODE_PRINTF(","); 5748 destval = fetch_data_word(destoffset); 5749 imm = fetch_word_imm(); 5750 DECODE_PRINTF2("%x\n", imm); 5751 TRACE_AND_STEP(); 5752 destval = (*opc81_word_operation[rh]) (destval, imm); 5753 if (rh != 7) 5754 store_data_word(destoffset, destval); 5755 } 5756 break; 5757 case 2: 5758 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5759 u32 destval, imm; 5760 5761 DECODE_PRINTF("DWORD PTR "); 5762 destoffset = decode_rm10_address(rl); 5763 DECODE_PRINTF(","); 5764 destval = fetch_data_long(destoffset); 5765 imm = fetch_long_imm(); 5766 DECODE_PRINTF2("%x\n", imm); 5767 TRACE_AND_STEP(); 5768 destval = (*opc81_long_operation[rh]) (destval, imm); 5769 if (rh != 7) 5770 store_data_long(destoffset, destval); 5771 } 5772 else { 5773 u16 destval, imm; 5774 5775 DECODE_PRINTF("WORD PTR "); 5776 destoffset = decode_rm10_address(rl); 5777 DECODE_PRINTF(","); 5778 destval = fetch_data_word(destoffset); 5779 imm = fetch_word_imm(); 5780 DECODE_PRINTF2("%x\n", imm); 5781 TRACE_AND_STEP(); 5782 destval = (*opc81_word_operation[rh]) (destval, imm); 5783 if (rh != 7) 5784 store_data_word(destoffset, destval); 5785 } 5786 break; 5787 case 3: /* register to register */ 5788 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5789 u32 *destreg; 5790 u32 destval, imm; 5791 5792 destreg = DECODE_RM_LONG_REGISTER(rl); 5793 DECODE_PRINTF(","); 5794 imm = fetch_long_imm(); 5795 DECODE_PRINTF2("%x\n", imm); 5796 TRACE_AND_STEP(); 5797 destval = (*opc81_long_operation[rh]) (*destreg, imm); 5798 if (rh != 7) 5799 *destreg = destval; 5800 } 5801 else { 5802 u16 *destreg; 5803 u16 destval, imm; 5804 5805 destreg = DECODE_RM_WORD_REGISTER(rl); 5806 DECODE_PRINTF(","); 5807 imm = fetch_word_imm(); 5808 DECODE_PRINTF2("%x\n", imm); 5809 TRACE_AND_STEP(); 5810 destval = (*opc81_word_operation[rh]) (*destreg, imm); 5811 if (rh != 7) 5812 *destreg = destval; 5813 } 5814 break; 5815 } 5816 DECODE_CLEAR_SEGOVR(); 5817 END_OF_INSTR(); 5818} 5819 5820static u8(*opc82_byte_operation[]) (u8 s, u8 d) = { 5821 add_byte, /*00 */ 5822 or_byte, /*01 *//*YYY UNUSED ???? */ 5823 adc_byte, /*02 */ 5824 sbb_byte, /*03 */ 5825 and_byte, /*04 *//*YYY UNUSED ???? */ 5826 sub_byte, /*05 */ 5827 xor_byte, /*06 *//*YYY UNUSED ???? */ 5828 cmp_byte, /*07 */ 5829}; 5830 5831/**************************************************************************** 5832REMARKS: 5833Handles opcode 0x82 5834****************************************************************************/ 5835static void 5836x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5837{ 5838 int mod, rl, rh; 5839 u8 *destreg; 5840 uint destoffset; 5841 u8 imm; 5842 u8 destval; 5843 5844 /* 5845 * Weirdo special case instruction format. Part of the opcode 5846 * held below in "RH". Doubly nested case would result, except 5847 * that the decoded instruction Similar to opcode 81, except that 5848 * the immediate byte is sign extended to a word length. 5849 */ 5850 START_OF_INSTR(); 5851 FETCH_DECODE_MODRM(mod, rh, rl); 5852#ifdef DEBUG 5853 if (DEBUG_DECODE()) { 5854 /* XXX DECODE_PRINTF may be changed to something more 5855 general, so that it is important to leave the strings 5856 in the same format, even though the result is that the 5857 above test is done twice. */ 5858 switch (rh) { 5859 case 0: 5860 DECODE_PRINTF("ADD\t"); 5861 break; 5862 case 1: 5863 DECODE_PRINTF("OR\t"); 5864 break; 5865 case 2: 5866 DECODE_PRINTF("ADC\t"); 5867 break; 5868 case 3: 5869 DECODE_PRINTF("SBB\t"); 5870 break; 5871 case 4: 5872 DECODE_PRINTF("AND\t"); 5873 break; 5874 case 5: 5875 DECODE_PRINTF("SUB\t"); 5876 break; 5877 case 6: 5878 DECODE_PRINTF("XOR\t"); 5879 break; 5880 case 7: 5881 DECODE_PRINTF("CMP\t"); 5882 break; 5883 } 5884 } 5885#endif 5886 /* know operation, decode the mod byte to find the addressing 5887 mode. */ 5888 switch (mod) { 5889 case 0: 5890 DECODE_PRINTF("BYTE PTR "); 5891 destoffset = decode_rm00_address(rl); 5892 destval = fetch_data_byte(destoffset); 5893 imm = fetch_byte_imm(); 5894 DECODE_PRINTF2(",%x\n", imm); 5895 TRACE_AND_STEP(); 5896 destval = (*opc82_byte_operation[rh]) (destval, imm); 5897 if (rh != 7) 5898 store_data_byte(destoffset, destval); 5899 break; 5900 case 1: 5901 DECODE_PRINTF("BYTE PTR "); 5902 destoffset = decode_rm01_address(rl); 5903 destval = fetch_data_byte(destoffset); 5904 imm = fetch_byte_imm(); 5905 DECODE_PRINTF2(",%x\n", imm); 5906 TRACE_AND_STEP(); 5907 destval = (*opc82_byte_operation[rh]) (destval, imm); 5908 if (rh != 7) 5909 store_data_byte(destoffset, destval); 5910 break; 5911 case 2: 5912 DECODE_PRINTF("BYTE PTR "); 5913 destoffset = decode_rm10_address(rl); 5914 destval = fetch_data_byte(destoffset); 5915 imm = fetch_byte_imm(); 5916 DECODE_PRINTF2(",%x\n", imm); 5917 TRACE_AND_STEP(); 5918 destval = (*opc82_byte_operation[rh]) (destval, imm); 5919 if (rh != 7) 5920 store_data_byte(destoffset, destval); 5921 break; 5922 case 3: /* register to register */ 5923 destreg = DECODE_RM_BYTE_REGISTER(rl); 5924 imm = fetch_byte_imm(); 5925 DECODE_PRINTF2(",%x\n", imm); 5926 TRACE_AND_STEP(); 5927 destval = (*opc82_byte_operation[rh]) (*destreg, imm); 5928 if (rh != 7) 5929 *destreg = destval; 5930 break; 5931 } 5932 DECODE_CLEAR_SEGOVR(); 5933 END_OF_INSTR(); 5934} 5935 5936static u16(*opc83_word_operation[]) (u16 s, u16 d) = { 5937 add_word, /*00 */ 5938 or_word, /*01 *//*YYY UNUSED ???? */ 5939 adc_word, /*02 */ 5940 sbb_word, /*03 */ 5941 and_word, /*04 *//*YYY UNUSED ???? */ 5942 sub_word, /*05 */ 5943 xor_word, /*06 *//*YYY UNUSED ???? */ 5944 cmp_word, /*07 */ 5945}; 5946 5947static u32(*opc83_long_operation[]) (u32 s, u32 d) = { 5948 add_long, /*00 */ 5949 or_long, /*01 *//*YYY UNUSED ???? */ 5950 adc_long, /*02 */ 5951 sbb_long, /*03 */ 5952 and_long, /*04 *//*YYY UNUSED ???? */ 5953 sub_long, /*05 */ 5954 xor_long, /*06 *//*YYY UNUSED ???? */ 5955 cmp_long, /*07 */ 5956}; 5957 5958/**************************************************************************** 5959REMARKS: 5960Handles opcode 0x83 5961****************************************************************************/ 5962static void 5963x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5964{ 5965 int mod, rl, rh; 5966 uint destoffset; 5967 5968 /* 5969 * Weirdo special case instruction format. Part of the opcode 5970 * held below in "RH". Doubly nested case would result, except 5971 * that the decoded instruction Similar to opcode 81, except that 5972 * the immediate byte is sign extended to a word length. 5973 */ 5974 START_OF_INSTR(); 5975 FETCH_DECODE_MODRM(mod, rh, rl); 5976#ifdef DEBUG 5977 if (DEBUG_DECODE()) { 5978 /* XXX DECODE_PRINTF may be changed to something more 5979 general, so that it is important to leave the strings 5980 in the same format, even though the result is that the 5981 above test is done twice. */ 5982 switch (rh) { 5983 case 0: 5984 DECODE_PRINTF("ADD\t"); 5985 break; 5986 case 1: 5987 DECODE_PRINTF("OR\t"); 5988 break; 5989 case 2: 5990 DECODE_PRINTF("ADC\t"); 5991 break; 5992 case 3: 5993 DECODE_PRINTF("SBB\t"); 5994 break; 5995 case 4: 5996 DECODE_PRINTF("AND\t"); 5997 break; 5998 case 5: 5999 DECODE_PRINTF("SUB\t"); 6000 break; 6001 case 6: 6002 DECODE_PRINTF("XOR\t"); 6003 break; 6004 case 7: 6005 DECODE_PRINTF("CMP\t"); 6006 break; 6007 } 6008 } 6009#endif 6010 /* know operation, decode the mod byte to find the addressing 6011 mode. */ 6012 switch (mod) { 6013 case 0: 6014 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6015 u32 destval, imm; 6016 6017 DECODE_PRINTF("DWORD PTR "); 6018 destoffset = decode_rm00_address(rl); 6019 destval = fetch_data_long(destoffset); 6020 imm = (s8) fetch_byte_imm(); 6021 DECODE_PRINTF2(",%x\n", imm); 6022 TRACE_AND_STEP(); 6023 destval = (*opc83_long_operation[rh]) (destval, imm); 6024 if (rh != 7) 6025 store_data_long(destoffset, destval); 6026 } 6027 else { 6028 u16 destval, imm; 6029 6030 DECODE_PRINTF("WORD PTR "); 6031 destoffset = decode_rm00_address(rl); 6032 destval = fetch_data_word(destoffset); 6033 imm = (s8) fetch_byte_imm(); 6034 DECODE_PRINTF2(",%x\n", imm); 6035 TRACE_AND_STEP(); 6036 destval = (*opc83_word_operation[rh]) (destval, imm); 6037 if (rh != 7) 6038 store_data_word(destoffset, destval); 6039 } 6040 break; 6041 case 1: 6042 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6043 u32 destval, imm; 6044 6045 DECODE_PRINTF("DWORD PTR "); 6046 destoffset = decode_rm01_address(rl); 6047 destval = fetch_data_long(destoffset); 6048 imm = (s8) fetch_byte_imm(); 6049 DECODE_PRINTF2(",%x\n", imm); 6050 TRACE_AND_STEP(); 6051 destval = (*opc83_long_operation[rh]) (destval, imm); 6052 if (rh != 7) 6053 store_data_long(destoffset, destval); 6054 } 6055 else { 6056 u16 destval, imm; 6057 6058 DECODE_PRINTF("WORD PTR "); 6059 destoffset = decode_rm01_address(rl); 6060 destval = fetch_data_word(destoffset); 6061 imm = (s8) fetch_byte_imm(); 6062 DECODE_PRINTF2(",%x\n", imm); 6063 TRACE_AND_STEP(); 6064 destval = (*opc83_word_operation[rh]) (destval, imm); 6065 if (rh != 7) 6066 store_data_word(destoffset, destval); 6067 } 6068 break; 6069 case 2: 6070 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6071 u32 destval, imm; 6072 6073 DECODE_PRINTF("DWORD PTR "); 6074 destoffset = decode_rm10_address(rl); 6075 destval = fetch_data_long(destoffset); 6076 imm = (s8) fetch_byte_imm(); 6077 DECODE_PRINTF2(",%x\n", imm); 6078 TRACE_AND_STEP(); 6079 destval = (*opc83_long_operation[rh]) (destval, imm); 6080 if (rh != 7) 6081 store_data_long(destoffset, destval); 6082 } 6083 else { 6084 u16 destval, imm; 6085 6086 DECODE_PRINTF("WORD PTR "); 6087 destoffset = decode_rm10_address(rl); 6088 destval = fetch_data_word(destoffset); 6089 imm = (s8) fetch_byte_imm(); 6090 DECODE_PRINTF2(",%x\n", imm); 6091 TRACE_AND_STEP(); 6092 destval = (*opc83_word_operation[rh]) (destval, imm); 6093 if (rh != 7) 6094 store_data_word(destoffset, destval); 6095 } 6096 break; 6097 case 3: /* register to register */ 6098 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6099 u32 *destreg; 6100 u32 destval, imm; 6101 6102 destreg = DECODE_RM_LONG_REGISTER(rl); 6103 imm = (s8) fetch_byte_imm(); 6104 DECODE_PRINTF2(",%x\n", imm); 6105 TRACE_AND_STEP(); 6106 destval = (*opc83_long_operation[rh]) (*destreg, imm); 6107 if (rh != 7) 6108 *destreg = destval; 6109 } 6110 else { 6111 u16 *destreg; 6112 u16 destval, imm; 6113 6114 destreg = DECODE_RM_WORD_REGISTER(rl); 6115 imm = (s8) fetch_byte_imm(); 6116 DECODE_PRINTF2(",%x\n", imm); 6117 TRACE_AND_STEP(); 6118 destval = (*opc83_word_operation[rh]) (*destreg, imm); 6119 if (rh != 7) 6120 *destreg = destval; 6121 } 6122 break; 6123 } 6124 DECODE_CLEAR_SEGOVR(); 6125 END_OF_INSTR(); 6126} 6127 6128/**************************************************************************** 6129REMARKS: 6130Handles opcode 0x84 6131****************************************************************************/ 6132static void 6133x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6134{ 6135 int mod, rl, rh; 6136 u8 *destreg, *srcreg; 6137 uint destoffset; 6138 u8 destval; 6139 6140 START_OF_INSTR(); 6141 DECODE_PRINTF("TEST\t"); 6142 FETCH_DECODE_MODRM(mod, rh, rl); 6143 switch (mod) { 6144 case 0: 6145 destoffset = decode_rm00_address(rl); 6146 DECODE_PRINTF(","); 6147 destval = fetch_data_byte(destoffset); 6148 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6149 DECODE_PRINTF("\n"); 6150 TRACE_AND_STEP(); 6151 test_byte(destval, *srcreg); 6152 break; 6153 case 1: 6154 destoffset = decode_rm01_address(rl); 6155 DECODE_PRINTF(","); 6156 destval = fetch_data_byte(destoffset); 6157 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6158 DECODE_PRINTF("\n"); 6159 TRACE_AND_STEP(); 6160 test_byte(destval, *srcreg); 6161 break; 6162 case 2: 6163 destoffset = decode_rm10_address(rl); 6164 DECODE_PRINTF(","); 6165 destval = fetch_data_byte(destoffset); 6166 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6167 DECODE_PRINTF("\n"); 6168 TRACE_AND_STEP(); 6169 test_byte(destval, *srcreg); 6170 break; 6171 case 3: /* register to register */ 6172 destreg = DECODE_RM_BYTE_REGISTER(rl); 6173 DECODE_PRINTF(","); 6174 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6175 DECODE_PRINTF("\n"); 6176 TRACE_AND_STEP(); 6177 test_byte(*destreg, *srcreg); 6178 break; 6179 } 6180 DECODE_CLEAR_SEGOVR(); 6181 END_OF_INSTR(); 6182} 6183 6184/**************************************************************************** 6185REMARKS: 6186Handles opcode 0x85 6187****************************************************************************/ 6188static void 6189x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 6190{ 6191 int mod, rl, rh; 6192 uint destoffset; 6193 6194 START_OF_INSTR(); 6195 DECODE_PRINTF("TEST\t"); 6196 FETCH_DECODE_MODRM(mod, rh, rl); 6197 switch (mod) { 6198 case 0: 6199 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6200 u32 destval; 6201 u32 *srcreg; 6202 6203 destoffset = decode_rm00_address(rl); 6204 DECODE_PRINTF(","); 6205 destval = fetch_data_long(destoffset); 6206 srcreg = DECODE_RM_LONG_REGISTER(rh); 6207 DECODE_PRINTF("\n"); 6208 TRACE_AND_STEP(); 6209 test_long(destval, *srcreg); 6210 } 6211 else { 6212 u16 destval; 6213 u16 *srcreg; 6214 6215 destoffset = decode_rm00_address(rl); 6216 DECODE_PRINTF(","); 6217 destval = fetch_data_word(destoffset); 6218 srcreg = DECODE_RM_WORD_REGISTER(rh); 6219 DECODE_PRINTF("\n"); 6220 TRACE_AND_STEP(); 6221 test_word(destval, *srcreg); 6222 } 6223 break; 6224 case 1: 6225 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6226 u32 destval; 6227 u32 *srcreg; 6228 6229 destoffset = decode_rm01_address(rl); 6230 DECODE_PRINTF(","); 6231 destval = fetch_data_long(destoffset); 6232 srcreg = DECODE_RM_LONG_REGISTER(rh); 6233 DECODE_PRINTF("\n"); 6234 TRACE_AND_STEP(); 6235 test_long(destval, *srcreg); 6236 } 6237 else { 6238 u16 destval; 6239 u16 *srcreg; 6240 6241 destoffset = decode_rm01_address(rl); 6242 DECODE_PRINTF(","); 6243 destval = fetch_data_word(destoffset); 6244 srcreg = DECODE_RM_WORD_REGISTER(rh); 6245 DECODE_PRINTF("\n"); 6246 TRACE_AND_STEP(); 6247 test_word(destval, *srcreg); 6248 } 6249 break; 6250 case 2: 6251 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6252 u32 destval; 6253 u32 *srcreg; 6254 6255 destoffset = decode_rm10_address(rl); 6256 DECODE_PRINTF(","); 6257 destval = fetch_data_long(destoffset); 6258 srcreg = DECODE_RM_LONG_REGISTER(rh); 6259 DECODE_PRINTF("\n"); 6260 TRACE_AND_STEP(); 6261 test_long(destval, *srcreg); 6262 } 6263 else { 6264 u16 destval; 6265 u16 *srcreg; 6266 6267 destoffset = decode_rm10_address(rl); 6268 DECODE_PRINTF(","); 6269 destval = fetch_data_word(destoffset); 6270 srcreg = DECODE_RM_WORD_REGISTER(rh); 6271 DECODE_PRINTF("\n"); 6272 TRACE_AND_STEP(); 6273 test_word(destval, *srcreg); 6274 } 6275 break; 6276 case 3: /* register to register */ 6277 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6278 u32 *destreg, *srcreg; 6279 6280 destreg = DECODE_RM_LONG_REGISTER(rl); 6281 DECODE_PRINTF(","); 6282 srcreg = DECODE_RM_LONG_REGISTER(rh); 6283 DECODE_PRINTF("\n"); 6284 TRACE_AND_STEP(); 6285 test_long(*destreg, *srcreg); 6286 } 6287 else { 6288 u16 *destreg, *srcreg; 6289 6290 destreg = DECODE_RM_WORD_REGISTER(rl); 6291 DECODE_PRINTF(","); 6292 srcreg = DECODE_RM_WORD_REGISTER(rh); 6293 DECODE_PRINTF("\n"); 6294 TRACE_AND_STEP(); 6295 test_word(*destreg, *srcreg); 6296 } 6297 break; 6298 } 6299 DECODE_CLEAR_SEGOVR(); 6300 END_OF_INSTR(); 6301} 6302 6303/**************************************************************************** 6304REMARKS: 6305Handles opcode 0x86 6306****************************************************************************/ 6307static void 6308x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6309{ 6310 int mod, rl, rh; 6311 u8 *destreg, *srcreg; 6312 uint destoffset; 6313 u8 destval; 6314 u8 tmp; 6315 6316 START_OF_INSTR(); 6317 DECODE_PRINTF("XCHG\t"); 6318 FETCH_DECODE_MODRM(mod, rh, rl); 6319 switch (mod) { 6320 case 0: 6321 destoffset = decode_rm00_address(rl); 6322 DECODE_PRINTF(","); 6323 destval = fetch_data_byte(destoffset); 6324 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6325 DECODE_PRINTF("\n"); 6326 TRACE_AND_STEP(); 6327 tmp = *srcreg; 6328 *srcreg = destval; 6329 destval = tmp; 6330 store_data_byte(destoffset, destval); 6331 break; 6332 case 1: 6333 destoffset = decode_rm01_address(rl); 6334 DECODE_PRINTF(","); 6335 destval = fetch_data_byte(destoffset); 6336 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6337 DECODE_PRINTF("\n"); 6338 TRACE_AND_STEP(); 6339 tmp = *srcreg; 6340 *srcreg = destval; 6341 destval = tmp; 6342 store_data_byte(destoffset, destval); 6343 break; 6344 case 2: 6345 destoffset = decode_rm10_address(rl); 6346 DECODE_PRINTF(","); 6347 destval = fetch_data_byte(destoffset); 6348 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6349 DECODE_PRINTF("\n"); 6350 TRACE_AND_STEP(); 6351 tmp = *srcreg; 6352 *srcreg = destval; 6353 destval = tmp; 6354 store_data_byte(destoffset, destval); 6355 break; 6356 case 3: /* register to register */ 6357 destreg = DECODE_RM_BYTE_REGISTER(rl); 6358 DECODE_PRINTF(","); 6359 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6360 DECODE_PRINTF("\n"); 6361 TRACE_AND_STEP(); 6362 tmp = *srcreg; 6363 *srcreg = *destreg; 6364 *destreg = tmp; 6365 break; 6366 } 6367 DECODE_CLEAR_SEGOVR(); 6368 END_OF_INSTR(); 6369} 6370 6371/**************************************************************************** 6372REMARKS: 6373Handles opcode 0x87 6374****************************************************************************/ 6375static void 6376x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 6377{ 6378 int mod, rl, rh; 6379 uint destoffset; 6380 6381 START_OF_INSTR(); 6382 DECODE_PRINTF("XCHG\t"); 6383 FETCH_DECODE_MODRM(mod, rh, rl); 6384 switch (mod) { 6385 case 0: 6386 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6387 u32 *srcreg; 6388 u32 destval, tmp; 6389 6390 destoffset = decode_rm00_address(rl); 6391 DECODE_PRINTF(","); 6392 destval = fetch_data_long(destoffset); 6393 srcreg = DECODE_RM_LONG_REGISTER(rh); 6394 DECODE_PRINTF("\n"); 6395 TRACE_AND_STEP(); 6396 tmp = *srcreg; 6397 *srcreg = destval; 6398 destval = tmp; 6399 store_data_long(destoffset, destval); 6400 } 6401 else { 6402 u16 *srcreg; 6403 u16 destval, tmp; 6404 6405 destoffset = decode_rm00_address(rl); 6406 DECODE_PRINTF(","); 6407 destval = fetch_data_word(destoffset); 6408 srcreg = DECODE_RM_WORD_REGISTER(rh); 6409 DECODE_PRINTF("\n"); 6410 TRACE_AND_STEP(); 6411 tmp = *srcreg; 6412 *srcreg = destval; 6413 destval = tmp; 6414 store_data_word(destoffset, destval); 6415 } 6416 break; 6417 case 1: 6418 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6419 u32 *srcreg; 6420 u32 destval, tmp; 6421 6422 destoffset = decode_rm01_address(rl); 6423 DECODE_PRINTF(","); 6424 destval = fetch_data_long(destoffset); 6425 srcreg = DECODE_RM_LONG_REGISTER(rh); 6426 DECODE_PRINTF("\n"); 6427 TRACE_AND_STEP(); 6428 tmp = *srcreg; 6429 *srcreg = destval; 6430 destval = tmp; 6431 store_data_long(destoffset, destval); 6432 } 6433 else { 6434 u16 *srcreg; 6435 u16 destval, tmp; 6436 6437 destoffset = decode_rm01_address(rl); 6438 DECODE_PRINTF(","); 6439 destval = fetch_data_word(destoffset); 6440 srcreg = DECODE_RM_WORD_REGISTER(rh); 6441 DECODE_PRINTF("\n"); 6442 TRACE_AND_STEP(); 6443 tmp = *srcreg; 6444 *srcreg = destval; 6445 destval = tmp; 6446 store_data_word(destoffset, destval); 6447 } 6448 break; 6449 case 2: 6450 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6451 u32 *srcreg; 6452 u32 destval, tmp; 6453 6454 destoffset = decode_rm10_address(rl); 6455 DECODE_PRINTF(","); 6456 destval = fetch_data_long(destoffset); 6457 srcreg = DECODE_RM_LONG_REGISTER(rh); 6458 DECODE_PRINTF("\n"); 6459 TRACE_AND_STEP(); 6460 tmp = *srcreg; 6461 *srcreg = destval; 6462 destval = tmp; 6463 store_data_long(destoffset, destval); 6464 } 6465 else { 6466 u16 *srcreg; 6467 u16 destval, tmp; 6468 6469 destoffset = decode_rm10_address(rl); 6470 DECODE_PRINTF(","); 6471 destval = fetch_data_word(destoffset); 6472 srcreg = DECODE_RM_WORD_REGISTER(rh); 6473 DECODE_PRINTF("\n"); 6474 TRACE_AND_STEP(); 6475 tmp = *srcreg; 6476 *srcreg = destval; 6477 destval = tmp; 6478 store_data_word(destoffset, destval); 6479 } 6480 break; 6481 case 3: /* register to register */ 6482 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6483 u32 *destreg, *srcreg; 6484 u32 tmp; 6485 6486 destreg = DECODE_RM_LONG_REGISTER(rl); 6487 DECODE_PRINTF(","); 6488 srcreg = DECODE_RM_LONG_REGISTER(rh); 6489 DECODE_PRINTF("\n"); 6490 TRACE_AND_STEP(); 6491 tmp = *srcreg; 6492 *srcreg = *destreg; 6493 *destreg = tmp; 6494 } 6495 else { 6496 u16 *destreg, *srcreg; 6497 u16 tmp; 6498 6499 destreg = DECODE_RM_WORD_REGISTER(rl); 6500 DECODE_PRINTF(","); 6501 srcreg = DECODE_RM_WORD_REGISTER(rh); 6502 DECODE_PRINTF("\n"); 6503 TRACE_AND_STEP(); 6504 tmp = *srcreg; 6505 *srcreg = *destreg; 6506 *destreg = tmp; 6507 } 6508 break; 6509 } 6510 DECODE_CLEAR_SEGOVR(); 6511 END_OF_INSTR(); 6512} 6513 6514/**************************************************************************** 6515REMARKS: 6516Handles opcode 0x88 6517****************************************************************************/ 6518static void 6519x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6520{ 6521 int mod, rl, rh; 6522 u8 *destreg, *srcreg; 6523 uint destoffset; 6524 6525 START_OF_INSTR(); 6526 DECODE_PRINTF("MOV\t"); 6527 FETCH_DECODE_MODRM(mod, rh, rl); 6528 switch (mod) { 6529 case 0: 6530 destoffset = decode_rm00_address(rl); 6531 DECODE_PRINTF(","); 6532 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6533 DECODE_PRINTF("\n"); 6534 TRACE_AND_STEP(); 6535 store_data_byte(destoffset, *srcreg); 6536 break; 6537 case 1: 6538 destoffset = decode_rm01_address(rl); 6539 DECODE_PRINTF(","); 6540 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6541 DECODE_PRINTF("\n"); 6542 TRACE_AND_STEP(); 6543 store_data_byte(destoffset, *srcreg); 6544 break; 6545 case 2: 6546 destoffset = decode_rm10_address(rl); 6547 DECODE_PRINTF(","); 6548 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6549 DECODE_PRINTF("\n"); 6550 TRACE_AND_STEP(); 6551 store_data_byte(destoffset, *srcreg); 6552 break; 6553 case 3: /* register to register */ 6554 destreg = DECODE_RM_BYTE_REGISTER(rl); 6555 DECODE_PRINTF(","); 6556 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6557 DECODE_PRINTF("\n"); 6558 TRACE_AND_STEP(); 6559 *destreg = *srcreg; 6560 break; 6561 } 6562 DECODE_CLEAR_SEGOVR(); 6563 END_OF_INSTR(); 6564} 6565 6566/**************************************************************************** 6567REMARKS: 6568Handles opcode 0x89 6569****************************************************************************/ 6570static void 6571x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 6572{ 6573 int mod, rl, rh; 6574 u32 destoffset; 6575 6576 START_OF_INSTR(); 6577 DECODE_PRINTF("MOV\t"); 6578 FETCH_DECODE_MODRM(mod, rh, rl); 6579 switch (mod) { 6580 case 0: 6581 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6582 u32 *srcreg; 6583 6584 destoffset = decode_rm00_address(rl); 6585 DECODE_PRINTF(","); 6586 srcreg = DECODE_RM_LONG_REGISTER(rh); 6587 DECODE_PRINTF("\n"); 6588 TRACE_AND_STEP(); 6589 store_data_long(destoffset, *srcreg); 6590 } 6591 else { 6592 u16 *srcreg; 6593 6594 destoffset = decode_rm00_address(rl); 6595 DECODE_PRINTF(","); 6596 srcreg = DECODE_RM_WORD_REGISTER(rh); 6597 DECODE_PRINTF("\n"); 6598 TRACE_AND_STEP(); 6599 store_data_word(destoffset, *srcreg); 6600 } 6601 break; 6602 case 1: 6603 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6604 u32 *srcreg; 6605 6606 destoffset = decode_rm01_address(rl); 6607 DECODE_PRINTF(","); 6608 srcreg = DECODE_RM_LONG_REGISTER(rh); 6609 DECODE_PRINTF("\n"); 6610 TRACE_AND_STEP(); 6611 store_data_long(destoffset, *srcreg); 6612 } 6613 else { 6614 u16 *srcreg; 6615 6616 destoffset = decode_rm01_address(rl); 6617 DECODE_PRINTF(","); 6618 srcreg = DECODE_RM_WORD_REGISTER(rh); 6619 DECODE_PRINTF("\n"); 6620 TRACE_AND_STEP(); 6621 store_data_word(destoffset, *srcreg); 6622 } 6623 break; 6624 case 2: 6625 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6626 u32 *srcreg; 6627 6628 destoffset = decode_rm10_address(rl); 6629 DECODE_PRINTF(","); 6630 srcreg = DECODE_RM_LONG_REGISTER(rh); 6631 DECODE_PRINTF("\n"); 6632 TRACE_AND_STEP(); 6633 store_data_long(destoffset, *srcreg); 6634 } 6635 else { 6636 u16 *srcreg; 6637 6638 destoffset = decode_rm10_address(rl); 6639 DECODE_PRINTF(","); 6640 srcreg = DECODE_RM_WORD_REGISTER(rh); 6641 DECODE_PRINTF("\n"); 6642 TRACE_AND_STEP(); 6643 store_data_word(destoffset, *srcreg); 6644 } 6645 break; 6646 case 3: /* register to register */ 6647 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6648 u32 *destreg, *srcreg; 6649 6650 destreg = DECODE_RM_LONG_REGISTER(rl); 6651 DECODE_PRINTF(","); 6652 srcreg = DECODE_RM_LONG_REGISTER(rh); 6653 DECODE_PRINTF("\n"); 6654 TRACE_AND_STEP(); 6655 *destreg = *srcreg; 6656 } 6657 else { 6658 u16 *destreg, *srcreg; 6659 6660 destreg = DECODE_RM_WORD_REGISTER(rl); 6661 DECODE_PRINTF(","); 6662 srcreg = DECODE_RM_WORD_REGISTER(rh); 6663 DECODE_PRINTF("\n"); 6664 TRACE_AND_STEP(); 6665 *destreg = *srcreg; 6666 } 6667 break; 6668 } 6669 DECODE_CLEAR_SEGOVR(); 6670 END_OF_INSTR(); 6671} 6672 6673/**************************************************************************** 6674REMARKS: 6675Handles opcode 0x8a 6676****************************************************************************/ 6677static void 6678x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 6679{ 6680 int mod, rl, rh; 6681 u8 *destreg, *srcreg; 6682 uint srcoffset; 6683 u8 srcval; 6684 6685 START_OF_INSTR(); 6686 DECODE_PRINTF("MOV\t"); 6687 FETCH_DECODE_MODRM(mod, rh, rl); 6688 switch (mod) { 6689 case 0: 6690 destreg = DECODE_RM_BYTE_REGISTER(rh); 6691 DECODE_PRINTF(","); 6692 srcoffset = decode_rm00_address(rl); 6693 srcval = fetch_data_byte(srcoffset); 6694 DECODE_PRINTF("\n"); 6695 TRACE_AND_STEP(); 6696 *destreg = srcval; 6697 break; 6698 case 1: 6699 destreg = DECODE_RM_BYTE_REGISTER(rh); 6700 DECODE_PRINTF(","); 6701 srcoffset = decode_rm01_address(rl); 6702 srcval = fetch_data_byte(srcoffset); 6703 DECODE_PRINTF("\n"); 6704 TRACE_AND_STEP(); 6705 *destreg = srcval; 6706 break; 6707 case 2: 6708 destreg = DECODE_RM_BYTE_REGISTER(rh); 6709 DECODE_PRINTF(","); 6710 srcoffset = decode_rm10_address(rl); 6711 srcval = fetch_data_byte(srcoffset); 6712 DECODE_PRINTF("\n"); 6713 TRACE_AND_STEP(); 6714 *destreg = srcval; 6715 break; 6716 case 3: /* register to register */ 6717 destreg = DECODE_RM_BYTE_REGISTER(rh); 6718 DECODE_PRINTF(","); 6719 srcreg = DECODE_RM_BYTE_REGISTER(rl); 6720 DECODE_PRINTF("\n"); 6721 TRACE_AND_STEP(); 6722 *destreg = *srcreg; 6723 break; 6724 } 6725 DECODE_CLEAR_SEGOVR(); 6726 END_OF_INSTR(); 6727} 6728 6729/**************************************************************************** 6730REMARKS: 6731Handles opcode 0x8b 6732****************************************************************************/ 6733static void 6734x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 6735{ 6736 int mod, rl, rh; 6737 uint srcoffset; 6738 6739 START_OF_INSTR(); 6740 DECODE_PRINTF("MOV\t"); 6741 FETCH_DECODE_MODRM(mod, rh, rl); 6742 switch (mod) { 6743 case 0: 6744 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6745 u32 *destreg; 6746 u32 srcval; 6747 6748 destreg = DECODE_RM_LONG_REGISTER(rh); 6749 DECODE_PRINTF(","); 6750 srcoffset = decode_rm00_address(rl); 6751 srcval = fetch_data_long(srcoffset); 6752 DECODE_PRINTF("\n"); 6753 TRACE_AND_STEP(); 6754 *destreg = srcval; 6755 } 6756 else { 6757 u16 *destreg; 6758 u16 srcval; 6759 6760 destreg = DECODE_RM_WORD_REGISTER(rh); 6761 DECODE_PRINTF(","); 6762 srcoffset = decode_rm00_address(rl); 6763 srcval = fetch_data_word(srcoffset); 6764 DECODE_PRINTF("\n"); 6765 TRACE_AND_STEP(); 6766 *destreg = srcval; 6767 } 6768 break; 6769 case 1: 6770 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6771 u32 *destreg; 6772 u32 srcval; 6773 6774 destreg = DECODE_RM_LONG_REGISTER(rh); 6775 DECODE_PRINTF(","); 6776 srcoffset = decode_rm01_address(rl); 6777 srcval = fetch_data_long(srcoffset); 6778 DECODE_PRINTF("\n"); 6779 TRACE_AND_STEP(); 6780 *destreg = srcval; 6781 } 6782 else { 6783 u16 *destreg; 6784 u16 srcval; 6785 6786 destreg = DECODE_RM_WORD_REGISTER(rh); 6787 DECODE_PRINTF(","); 6788 srcoffset = decode_rm01_address(rl); 6789 srcval = fetch_data_word(srcoffset); 6790 DECODE_PRINTF("\n"); 6791 TRACE_AND_STEP(); 6792 *destreg = srcval; 6793 } 6794 break; 6795 case 2: 6796 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6797 u32 *destreg; 6798 u32 srcval; 6799 6800 destreg = DECODE_RM_LONG_REGISTER(rh); 6801 DECODE_PRINTF(","); 6802 srcoffset = decode_rm10_address(rl); 6803 srcval = fetch_data_long(srcoffset); 6804 DECODE_PRINTF("\n"); 6805 TRACE_AND_STEP(); 6806 *destreg = srcval; 6807 } 6808 else { 6809 u16 *destreg; 6810 u16 srcval; 6811 6812 destreg = DECODE_RM_WORD_REGISTER(rh); 6813 DECODE_PRINTF(","); 6814 srcoffset = decode_rm10_address(rl); 6815 srcval = fetch_data_word(srcoffset); 6816 DECODE_PRINTF("\n"); 6817 TRACE_AND_STEP(); 6818 *destreg = srcval; 6819 } 6820 break; 6821 case 3: /* register to register */ 6822 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6823 u32 *destreg, *srcreg; 6824 6825 destreg = DECODE_RM_LONG_REGISTER(rh); 6826 DECODE_PRINTF(","); 6827 srcreg = DECODE_RM_LONG_REGISTER(rl); 6828 DECODE_PRINTF("\n"); 6829 TRACE_AND_STEP(); 6830 *destreg = *srcreg; 6831 } 6832 else { 6833 u16 *destreg, *srcreg; 6834 6835 destreg = DECODE_RM_WORD_REGISTER(rh); 6836 DECODE_PRINTF(","); 6837 srcreg = DECODE_RM_WORD_REGISTER(rl); 6838 DECODE_PRINTF("\n"); 6839 TRACE_AND_STEP(); 6840 *destreg = *srcreg; 6841 } 6842 break; 6843 } 6844 DECODE_CLEAR_SEGOVR(); 6845 END_OF_INSTR(); 6846} 6847 6848/**************************************************************************** 6849REMARKS: 6850Handles opcode 0x8c 6851****************************************************************************/ 6852static void 6853x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 6854{ 6855 int mod, rl, rh; 6856 u16 *destreg, *srcreg; 6857 uint destoffset; 6858 u16 destval; 6859 6860 START_OF_INSTR(); 6861 DECODE_PRINTF("MOV\t"); 6862 FETCH_DECODE_MODRM(mod, rh, rl); 6863 switch (mod) { 6864 case 0: 6865 destoffset = decode_rm00_address(rl); 6866 DECODE_PRINTF(","); 6867 srcreg = decode_rm_seg_register(rh); 6868 DECODE_PRINTF("\n"); 6869 TRACE_AND_STEP(); 6870 destval = *srcreg; 6871 store_data_word(destoffset, destval); 6872 break; 6873 case 1: 6874 destoffset = decode_rm01_address(rl); 6875 DECODE_PRINTF(","); 6876 srcreg = decode_rm_seg_register(rh); 6877 DECODE_PRINTF("\n"); 6878 TRACE_AND_STEP(); 6879 destval = *srcreg; 6880 store_data_word(destoffset, destval); 6881 break; 6882 case 2: 6883 destoffset = decode_rm10_address(rl); 6884 DECODE_PRINTF(","); 6885 srcreg = decode_rm_seg_register(rh); 6886 DECODE_PRINTF("\n"); 6887 TRACE_AND_STEP(); 6888 destval = *srcreg; 6889 store_data_word(destoffset, destval); 6890 break; 6891 case 3: /* register to register */ 6892 destreg = DECODE_RM_WORD_REGISTER(rl); 6893 DECODE_PRINTF(","); 6894 srcreg = decode_rm_seg_register(rh); 6895 DECODE_PRINTF("\n"); 6896 TRACE_AND_STEP(); 6897 *destreg = *srcreg; 6898 break; 6899 } 6900 DECODE_CLEAR_SEGOVR(); 6901 END_OF_INSTR(); 6902} 6903 6904/**************************************************************************** 6905REMARKS: 6906Handles opcode 0x8d 6907****************************************************************************/ 6908static void 6909x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 6910{ 6911 int mod, rl, rh; 6912 uint destoffset; 6913 6914 START_OF_INSTR(); 6915 DECODE_PRINTF("LEA\t"); 6916 FETCH_DECODE_MODRM(mod, rh, rl); 6917 switch (mod) { 6918 case 0: 6919 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6920 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6921 6922 DECODE_PRINTF(","); 6923 destoffset = decode_rm00_address(rl); 6924 DECODE_PRINTF("\n"); 6925 TRACE_AND_STEP(); 6926 *srcreg = (u32) destoffset; 6927 } 6928 else { 6929 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6930 6931 DECODE_PRINTF(","); 6932 destoffset = decode_rm00_address(rl); 6933 DECODE_PRINTF("\n"); 6934 TRACE_AND_STEP(); 6935 *srcreg = (u16) destoffset; 6936 } 6937 break; 6938 case 1: 6939 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6940 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6941 6942 DECODE_PRINTF(","); 6943 destoffset = decode_rm01_address(rl); 6944 DECODE_PRINTF("\n"); 6945 TRACE_AND_STEP(); 6946 *srcreg = (u32) destoffset; 6947 } 6948 else { 6949 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6950 6951 DECODE_PRINTF(","); 6952 destoffset = decode_rm01_address(rl); 6953 DECODE_PRINTF("\n"); 6954 TRACE_AND_STEP(); 6955 *srcreg = (u16) destoffset; 6956 } 6957 break; 6958 case 2: 6959 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6960 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6961 6962 DECODE_PRINTF(","); 6963 destoffset = decode_rm10_address(rl); 6964 DECODE_PRINTF("\n"); 6965 TRACE_AND_STEP(); 6966 *srcreg = (u32) destoffset; 6967 } 6968 else { 6969 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6970 6971 DECODE_PRINTF(","); 6972 destoffset = decode_rm10_address(rl); 6973 DECODE_PRINTF("\n"); 6974 TRACE_AND_STEP(); 6975 *srcreg = (u16) destoffset; 6976 } 6977 break; 6978 case 3: /* register to register */ 6979 /* undefined. Do nothing. */ 6980 break; 6981 } 6982 DECODE_CLEAR_SEGOVR(); 6983 END_OF_INSTR(); 6984} 6985 6986/**************************************************************************** 6987REMARKS: 6988Handles opcode 0x8e 6989****************************************************************************/ 6990static void 6991x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 6992{ 6993 int mod, rl, rh; 6994 u16 *destreg, *srcreg; 6995 uint srcoffset; 6996 u16 srcval; 6997 6998 START_OF_INSTR(); 6999 DECODE_PRINTF("MOV\t"); 7000 FETCH_DECODE_MODRM(mod, rh, rl); 7001 switch (mod) { 7002 case 0: 7003 destreg = decode_rm_seg_register(rh); 7004 DECODE_PRINTF(","); 7005 srcoffset = decode_rm00_address(rl); 7006 srcval = fetch_data_word(srcoffset); 7007 DECODE_PRINTF("\n"); 7008 TRACE_AND_STEP(); 7009 *destreg = srcval; 7010 break; 7011 case 1: 7012 destreg = decode_rm_seg_register(rh); 7013 DECODE_PRINTF(","); 7014 srcoffset = decode_rm01_address(rl); 7015 srcval = fetch_data_word(srcoffset); 7016 DECODE_PRINTF("\n"); 7017 TRACE_AND_STEP(); 7018 *destreg = srcval; 7019 break; 7020 case 2: 7021 destreg = decode_rm_seg_register(rh); 7022 DECODE_PRINTF(","); 7023 srcoffset = decode_rm10_address(rl); 7024 srcval = fetch_data_word(srcoffset); 7025 DECODE_PRINTF("\n"); 7026 TRACE_AND_STEP(); 7027 *destreg = srcval; 7028 break; 7029 case 3: /* register to register */ 7030 destreg = decode_rm_seg_register(rh); 7031 DECODE_PRINTF(","); 7032 srcreg = DECODE_RM_WORD_REGISTER(rl); 7033 DECODE_PRINTF("\n"); 7034 TRACE_AND_STEP(); 7035 *destreg = *srcreg; 7036 break; 7037 } 7038 /* 7039 * Clean up, and reset all the R_xSP pointers to the correct 7040 * locations. This is about 3x too much overhead (doing all the 7041 * segreg ptrs when only one is needed, but this instruction 7042 * *cannot* be that common, and this isn't too much work anyway. 7043 */ 7044 DECODE_CLEAR_SEGOVR(); 7045 END_OF_INSTR(); 7046} 7047 7048/**************************************************************************** 7049REMARKS: 7050Handles opcode 0x8f 7051****************************************************************************/ 7052static void 7053x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 7054{ 7055 int mod, rl, rh; 7056 uint destoffset; 7057 7058 START_OF_INSTR(); 7059 DECODE_PRINTF("POP\t"); 7060 FETCH_DECODE_MODRM(mod, rh, rl); 7061 if (rh != 0) { 7062 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 7063 HALT_SYS(); 7064 } 7065 switch (mod) { 7066 case 0: 7067 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7068 u32 destval; 7069 7070 destoffset = decode_rm00_address(rl); 7071 DECODE_PRINTF("\n"); 7072 TRACE_AND_STEP(); 7073 destval = pop_long(); 7074 store_data_long(destoffset, destval); 7075 } 7076 else { 7077 u16 destval; 7078 7079 destoffset = decode_rm00_address(rl); 7080 DECODE_PRINTF("\n"); 7081 TRACE_AND_STEP(); 7082 destval = pop_word(); 7083 store_data_word(destoffset, destval); 7084 } 7085 break; 7086 case 1: 7087 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7088 u32 destval; 7089 7090 destoffset = decode_rm01_address(rl); 7091 DECODE_PRINTF("\n"); 7092 TRACE_AND_STEP(); 7093 destval = pop_long(); 7094 store_data_long(destoffset, destval); 7095 } 7096 else { 7097 u16 destval; 7098 7099 destoffset = decode_rm01_address(rl); 7100 DECODE_PRINTF("\n"); 7101 TRACE_AND_STEP(); 7102 destval = pop_word(); 7103 store_data_word(destoffset, destval); 7104 } 7105 break; 7106 case 2: 7107 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7108 u32 destval; 7109 7110 destoffset = decode_rm10_address(rl); 7111 DECODE_PRINTF("\n"); 7112 TRACE_AND_STEP(); 7113 destval = pop_long(); 7114 store_data_long(destoffset, destval); 7115 } 7116 else { 7117 u16 destval; 7118 7119 destoffset = decode_rm10_address(rl); 7120 DECODE_PRINTF("\n"); 7121 TRACE_AND_STEP(); 7122 destval = pop_word(); 7123 store_data_word(destoffset, destval); 7124 } 7125 break; 7126 case 3: /* register to register */ 7127 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7128 u32 *destreg; 7129 7130 destreg = DECODE_RM_LONG_REGISTER(rl); 7131 DECODE_PRINTF("\n"); 7132 TRACE_AND_STEP(); 7133 *destreg = pop_long(); 7134 } 7135 else { 7136 u16 *destreg; 7137 7138 destreg = DECODE_RM_WORD_REGISTER(rl); 7139 DECODE_PRINTF("\n"); 7140 TRACE_AND_STEP(); 7141 *destreg = pop_word(); 7142 } 7143 break; 7144 } 7145 DECODE_CLEAR_SEGOVR(); 7146 END_OF_INSTR(); 7147} 7148 7149/**************************************************************************** 7150REMARKS: 7151Handles opcode 0x90 7152****************************************************************************/ 7153static void 7154x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 7155{ 7156 START_OF_INSTR(); 7157 DECODE_PRINTF("NOP\n"); 7158 TRACE_AND_STEP(); 7159 DECODE_CLEAR_SEGOVR(); 7160 END_OF_INSTR(); 7161} 7162 7163/**************************************************************************** 7164REMARKS: 7165Handles opcode 0x91 7166****************************************************************************/ 7167static void 7168x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1)) 7169{ 7170 u32 tmp; 7171 7172 START_OF_INSTR(); 7173 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7174 DECODE_PRINTF("XCHG\tEAX,ECX\n"); 7175 } 7176 else { 7177 DECODE_PRINTF("XCHG\tAX,CX\n"); 7178 } 7179 TRACE_AND_STEP(); 7180 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7181 tmp = M.x86.R_EAX; 7182 M.x86.R_EAX = M.x86.R_ECX; 7183 M.x86.R_ECX = tmp; 7184 } 7185 else { 7186 tmp = M.x86.R_AX; 7187 M.x86.R_AX = M.x86.R_CX; 7188 M.x86.R_CX = (u16) tmp; 7189 } 7190 DECODE_CLEAR_SEGOVR(); 7191 END_OF_INSTR(); 7192} 7193 7194/**************************************************************************** 7195REMARKS: 7196Handles opcode 0x92 7197****************************************************************************/ 7198static void 7199x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1)) 7200{ 7201 u32 tmp; 7202 7203 START_OF_INSTR(); 7204 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7205 DECODE_PRINTF("XCHG\tEAX,EDX\n"); 7206 } 7207 else { 7208 DECODE_PRINTF("XCHG\tAX,DX\n"); 7209 } 7210 TRACE_AND_STEP(); 7211 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7212 tmp = M.x86.R_EAX; 7213 M.x86.R_EAX = M.x86.R_EDX; 7214 M.x86.R_EDX = tmp; 7215 } 7216 else { 7217 tmp = M.x86.R_AX; 7218 M.x86.R_AX = M.x86.R_DX; 7219 M.x86.R_DX = (u16) tmp; 7220 } 7221 DECODE_CLEAR_SEGOVR(); 7222 END_OF_INSTR(); 7223} 7224 7225/**************************************************************************** 7226REMARKS: 7227Handles opcode 0x93 7228****************************************************************************/ 7229static void 7230x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1)) 7231{ 7232 u32 tmp; 7233 7234 START_OF_INSTR(); 7235 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7236 DECODE_PRINTF("XCHG\tEAX,EBX\n"); 7237 } 7238 else { 7239 DECODE_PRINTF("XCHG\tAX,BX\n"); 7240 } 7241 TRACE_AND_STEP(); 7242 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7243 tmp = M.x86.R_EAX; 7244 M.x86.R_EAX = M.x86.R_EBX; 7245 M.x86.R_EBX = tmp; 7246 } 7247 else { 7248 tmp = M.x86.R_AX; 7249 M.x86.R_AX = M.x86.R_BX; 7250 M.x86.R_BX = (u16) tmp; 7251 } 7252 DECODE_CLEAR_SEGOVR(); 7253 END_OF_INSTR(); 7254} 7255 7256/**************************************************************************** 7257REMARKS: 7258Handles opcode 0x94 7259****************************************************************************/ 7260static void 7261x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1)) 7262{ 7263 u32 tmp; 7264 7265 START_OF_INSTR(); 7266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7267 DECODE_PRINTF("XCHG\tEAX,ESP\n"); 7268 } 7269 else { 7270 DECODE_PRINTF("XCHG\tAX,SP\n"); 7271 } 7272 TRACE_AND_STEP(); 7273 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7274 tmp = M.x86.R_EAX; 7275 M.x86.R_EAX = M.x86.R_ESP; 7276 M.x86.R_ESP = tmp; 7277 } 7278 else { 7279 tmp = M.x86.R_AX; 7280 M.x86.R_AX = M.x86.R_SP; 7281 M.x86.R_SP = (u16) tmp; 7282 } 7283 DECODE_CLEAR_SEGOVR(); 7284 END_OF_INSTR(); 7285} 7286 7287/**************************************************************************** 7288REMARKS: 7289Handles opcode 0x95 7290****************************************************************************/ 7291static void 7292x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1)) 7293{ 7294 u32 tmp; 7295 7296 START_OF_INSTR(); 7297 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7298 DECODE_PRINTF("XCHG\tEAX,EBP\n"); 7299 } 7300 else { 7301 DECODE_PRINTF("XCHG\tAX,BP\n"); 7302 } 7303 TRACE_AND_STEP(); 7304 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7305 tmp = M.x86.R_EAX; 7306 M.x86.R_EAX = M.x86.R_EBP; 7307 M.x86.R_EBP = tmp; 7308 } 7309 else { 7310 tmp = M.x86.R_AX; 7311 M.x86.R_AX = M.x86.R_BP; 7312 M.x86.R_BP = (u16) tmp; 7313 } 7314 DECODE_CLEAR_SEGOVR(); 7315 END_OF_INSTR(); 7316} 7317 7318/**************************************************************************** 7319REMARKS: 7320Handles opcode 0x96 7321****************************************************************************/ 7322static void 7323x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1)) 7324{ 7325 u32 tmp; 7326 7327 START_OF_INSTR(); 7328 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7329 DECODE_PRINTF("XCHG\tEAX,ESI\n"); 7330 } 7331 else { 7332 DECODE_PRINTF("XCHG\tAX,SI\n"); 7333 } 7334 TRACE_AND_STEP(); 7335 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7336 tmp = M.x86.R_EAX; 7337 M.x86.R_EAX = M.x86.R_ESI; 7338 M.x86.R_ESI = tmp; 7339 } 7340 else { 7341 tmp = M.x86.R_AX; 7342 M.x86.R_AX = M.x86.R_SI; 7343 M.x86.R_SI = (u16) tmp; 7344 } 7345 DECODE_CLEAR_SEGOVR(); 7346 END_OF_INSTR(); 7347} 7348 7349/**************************************************************************** 7350REMARKS: 7351Handles opcode 0x97 7352****************************************************************************/ 7353static void 7354x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1)) 7355{ 7356 u32 tmp; 7357 7358 START_OF_INSTR(); 7359 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7360 DECODE_PRINTF("XCHG\tEAX,EDI\n"); 7361 } 7362 else { 7363 DECODE_PRINTF("XCHG\tAX,DI\n"); 7364 } 7365 TRACE_AND_STEP(); 7366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7367 tmp = M.x86.R_EAX; 7368 M.x86.R_EAX = M.x86.R_EDI; 7369 M.x86.R_EDI = tmp; 7370 } 7371 else { 7372 tmp = M.x86.R_AX; 7373 M.x86.R_AX = M.x86.R_DI; 7374 M.x86.R_DI = (u16) tmp; 7375 } 7376 DECODE_CLEAR_SEGOVR(); 7377 END_OF_INSTR(); 7378} 7379 7380/**************************************************************************** 7381REMARKS: 7382Handles opcode 0x98 7383****************************************************************************/ 7384static void 7385x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 7386{ 7387 START_OF_INSTR(); 7388 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7389 DECODE_PRINTF("CWDE\n"); 7390 } 7391 else { 7392 DECODE_PRINTF("CBW\n"); 7393 } 7394 TRACE_AND_STEP(); 7395 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7396 if (M.x86.R_AX & 0x8000) { 7397 M.x86.R_EAX |= 0xffff0000; 7398 } 7399 else { 7400 M.x86.R_EAX &= 0x0000ffff; 7401 } 7402 } 7403 else { 7404 if (M.x86.R_AL & 0x80) { 7405 M.x86.R_AH = 0xff; 7406 } 7407 else { 7408 M.x86.R_AH = 0x0; 7409 } 7410 } 7411 DECODE_CLEAR_SEGOVR(); 7412 END_OF_INSTR(); 7413} 7414 7415/**************************************************************************** 7416REMARKS: 7417Handles opcode 0x99 7418****************************************************************************/ 7419static void 7420x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 7421{ 7422 START_OF_INSTR(); 7423 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7424 DECODE_PRINTF("CDQ\n"); 7425 } 7426 else { 7427 DECODE_PRINTF("CWD\n"); 7428 } 7429 DECODE_PRINTF("CWD\n"); 7430 TRACE_AND_STEP(); 7431 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7432 if (M.x86.R_EAX & 0x80000000) { 7433 M.x86.R_EDX = 0xffffffff; 7434 } 7435 else { 7436 M.x86.R_EDX = 0x0; 7437 } 7438 } 7439 else { 7440 if (M.x86.R_AX & 0x8000) { 7441 M.x86.R_DX = 0xffff; 7442 } 7443 else { 7444 M.x86.R_DX = 0x0; 7445 } 7446 } 7447 DECODE_CLEAR_SEGOVR(); 7448 END_OF_INSTR(); 7449} 7450 7451/**************************************************************************** 7452REMARKS: 7453Handles opcode 0x9a 7454****************************************************************************/ 7455static void 7456x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 7457{ 7458 u32 farseg, faroff; 7459 7460 START_OF_INSTR(); 7461 DECODE_PRINTF("CALL\t"); 7462 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7463 faroff = fetch_long_imm(); 7464 farseg = fetch_word_imm(); 7465 } 7466 else { 7467 faroff = fetch_word_imm(); 7468 farseg = fetch_word_imm(); 7469 } 7470 DECODE_PRINTF2("%04x:", farseg); 7471 DECODE_PRINTF2("%04x\n", faroff); 7472 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 7473 7474 /* XXX 7475 * 7476 * Hooked interrupt vectors calling into our "BIOS" will cause 7477 * problems unless all intersegment stuff is checked for BIOS 7478 * access. Check needed here. For moment, let it alone. 7479 */ 7480 TRACE_AND_STEP(); 7481 push_word(M.x86.R_CS); 7482 M.x86.R_CS = farseg; 7483 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7484 push_long(M.x86.R_EIP); 7485 } 7486 else { 7487 push_word(M.x86.R_IP); 7488 } 7489 M.x86.R_EIP = faroff & 0xffff; 7490 DECODE_CLEAR_SEGOVR(); 7491 END_OF_INSTR(); 7492} 7493 7494/**************************************************************************** 7495REMARKS: 7496Handles opcode 0x9b 7497****************************************************************************/ 7498static void 7499x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 7500{ 7501 START_OF_INSTR(); 7502 DECODE_PRINTF("WAIT"); 7503 TRACE_AND_STEP(); 7504 /* NADA. */ 7505 DECODE_CLEAR_SEGOVR(); 7506 END_OF_INSTR(); 7507} 7508 7509/**************************************************************************** 7510REMARKS: 7511Handles opcode 0x9c 7512****************************************************************************/ 7513static void 7514x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 7515{ 7516 u32 flags; 7517 7518 START_OF_INSTR(); 7519 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7520 DECODE_PRINTF("PUSHFD\n"); 7521 } 7522 else { 7523 DECODE_PRINTF("PUSHF\n"); 7524 } 7525 TRACE_AND_STEP(); 7526 7527 /* clear out *all* bits not representing flags, and turn on real bits */ 7528 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 7529 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7530 push_long(flags); 7531 } 7532 else { 7533 push_word((u16) flags); 7534 } 7535 DECODE_CLEAR_SEGOVR(); 7536 END_OF_INSTR(); 7537} 7538 7539/**************************************************************************** 7540REMARKS: 7541Handles opcode 0x9d 7542****************************************************************************/ 7543static void 7544x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 7545{ 7546 START_OF_INSTR(); 7547 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7548 DECODE_PRINTF("POPFD\n"); 7549 } 7550 else { 7551 DECODE_PRINTF("POPF\n"); 7552 } 7553 TRACE_AND_STEP(); 7554 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7555 M.x86.R_EFLG = pop_long(); 7556 } 7557 else { 7558 M.x86.R_FLG = pop_word(); 7559 } 7560 DECODE_CLEAR_SEGOVR(); 7561 END_OF_INSTR(); 7562} 7563 7564/**************************************************************************** 7565REMARKS: 7566Handles opcode 0x9e 7567****************************************************************************/ 7568static void 7569x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 7570{ 7571 START_OF_INSTR(); 7572 DECODE_PRINTF("SAHF\n"); 7573 TRACE_AND_STEP(); 7574 /* clear the lower bits of the flag register */ 7575 M.x86.R_FLG &= 0xffffff00; 7576 /* or in the AH register into the flags register */ 7577 M.x86.R_FLG |= M.x86.R_AH; 7578 DECODE_CLEAR_SEGOVR(); 7579 END_OF_INSTR(); 7580} 7581 7582/**************************************************************************** 7583REMARKS: 7584Handles opcode 0x9f 7585****************************************************************************/ 7586static void 7587x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 7588{ 7589 START_OF_INSTR(); 7590 DECODE_PRINTF("LAHF\n"); 7591 TRACE_AND_STEP(); 7592 M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff); 7593 /* Undocumented TC++ behavior??? Nope. It's documented, but 7594 you have to look real hard to notice it. */ 7595 M.x86.R_AH |= 0x2; 7596 DECODE_CLEAR_SEGOVR(); 7597 END_OF_INSTR(); 7598} 7599 7600/**************************************************************************** 7601REMARKS: 7602Handles opcode 0xa0 7603****************************************************************************/ 7604static void 7605x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 7606{ 7607 u16 offset; 7608 7609 START_OF_INSTR(); 7610 DECODE_PRINTF("MOV\tAL,"); 7611 offset = fetch_word_imm(); 7612 DECODE_PRINTF2("[%04x]\n", offset); 7613 TRACE_AND_STEP(); 7614 M.x86.R_AL = fetch_data_byte(offset); 7615 DECODE_CLEAR_SEGOVR(); 7616 END_OF_INSTR(); 7617} 7618 7619/**************************************************************************** 7620REMARKS: 7621Handles opcode 0xa1 7622****************************************************************************/ 7623static void 7624x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 7625{ 7626 u16 offset; 7627 7628 START_OF_INSTR(); 7629 offset = fetch_word_imm(); 7630 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7631 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 7632 } 7633 else { 7634 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 7635 } 7636 TRACE_AND_STEP(); 7637 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7638 M.x86.R_EAX = fetch_data_long(offset); 7639 } 7640 else { 7641 M.x86.R_AX = fetch_data_word(offset); 7642 } 7643 DECODE_CLEAR_SEGOVR(); 7644 END_OF_INSTR(); 7645} 7646 7647/**************************************************************************** 7648REMARKS: 7649Handles opcode 0xa2 7650****************************************************************************/ 7651static void 7652x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 7653{ 7654 u16 offset; 7655 7656 START_OF_INSTR(); 7657 DECODE_PRINTF("MOV\t"); 7658 offset = fetch_word_imm(); 7659 DECODE_PRINTF2("[%04x],AL\n", offset); 7660 TRACE_AND_STEP(); 7661 store_data_byte(offset, M.x86.R_AL); 7662 DECODE_CLEAR_SEGOVR(); 7663 END_OF_INSTR(); 7664} 7665 7666/**************************************************************************** 7667REMARKS: 7668Handles opcode 0xa3 7669****************************************************************************/ 7670static void 7671x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 7672{ 7673 u16 offset; 7674 7675 START_OF_INSTR(); 7676 offset = fetch_word_imm(); 7677 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7678 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 7679 } 7680 else { 7681 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 7682 } 7683 TRACE_AND_STEP(); 7684 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7685 store_data_long(offset, M.x86.R_EAX); 7686 } 7687 else { 7688 store_data_word(offset, M.x86.R_AX); 7689 } 7690 DECODE_CLEAR_SEGOVR(); 7691 END_OF_INSTR(); 7692} 7693 7694/**************************************************************************** 7695REMARKS: 7696Handles opcode 0xa4 7697****************************************************************************/ 7698static void 7699x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 7700{ 7701 u8 val; 7702 u32 count; 7703 int inc; 7704 7705 START_OF_INSTR(); 7706 DECODE_PRINTF("MOVS\tBYTE\n"); 7707 if (ACCESS_FLAG(F_DF)) /* down */ 7708 inc = -1; 7709 else 7710 inc = 1; 7711 TRACE_AND_STEP(); 7712 count = 1; 7713 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7714 /* don't care whether REPE or REPNE */ 7715 /* move them until CX is ZERO. */ 7716 count = M.x86.R_CX; 7717 M.x86.R_CX = 0; 7718 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7719 } 7720 while (count--) { 7721 val = fetch_data_byte(M.x86.R_SI); 7722 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 7723 M.x86.R_SI += inc; 7724 M.x86.R_DI += inc; 7725 } 7726 DECODE_CLEAR_SEGOVR(); 7727 END_OF_INSTR(); 7728} 7729 7730/**************************************************************************** 7731REMARKS: 7732Handles opcode 0xa5 7733****************************************************************************/ 7734static void 7735x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 7736{ 7737 u32 val; 7738 int inc; 7739 u32 count; 7740 7741 START_OF_INSTR(); 7742 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7743 DECODE_PRINTF("MOVS\tDWORD\n"); 7744 if (ACCESS_FLAG(F_DF)) /* down */ 7745 inc = -4; 7746 else 7747 inc = 4; 7748 } 7749 else { 7750 DECODE_PRINTF("MOVS\tWORD\n"); 7751 if (ACCESS_FLAG(F_DF)) /* down */ 7752 inc = -2; 7753 else 7754 inc = 2; 7755 } 7756 TRACE_AND_STEP(); 7757 count = 1; 7758 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7759 /* don't care whether REPE or REPNE */ 7760 /* move them until CX is ZERO. */ 7761 count = M.x86.R_CX; 7762 M.x86.R_CX = 0; 7763 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7764 } 7765 while (count--) { 7766 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7767 val = fetch_data_long(M.x86.R_SI); 7768 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 7769 } 7770 else { 7771 val = fetch_data_word(M.x86.R_SI); 7772 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val); 7773 } 7774 M.x86.R_SI += inc; 7775 M.x86.R_DI += inc; 7776 } 7777 DECODE_CLEAR_SEGOVR(); 7778 END_OF_INSTR(); 7779} 7780 7781/**************************************************************************** 7782REMARKS: 7783Handles opcode 0xa6 7784****************************************************************************/ 7785static void 7786x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 7787{ 7788 s8 val1, val2; 7789 int inc; 7790 7791 START_OF_INSTR(); 7792 DECODE_PRINTF("CMPS\tBYTE\n"); 7793 TRACE_AND_STEP(); 7794 if (ACCESS_FLAG(F_DF)) /* down */ 7795 inc = -1; 7796 else 7797 inc = 1; 7798 7799 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7800 /* REPE */ 7801 /* move them until CX is ZERO. */ 7802 while (M.x86.R_CX != 0) { 7803 val1 = fetch_data_byte(M.x86.R_SI); 7804 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7805 cmp_byte(val1, val2); 7806 M.x86.R_CX -= 1; 7807 M.x86.R_SI += inc; 7808 M.x86.R_DI += inc; 7809 if (ACCESS_FLAG(F_ZF) == 0) 7810 break; 7811 } 7812 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7813 } 7814 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7815 /* REPNE */ 7816 /* move them until CX is ZERO. */ 7817 while (M.x86.R_CX != 0) { 7818 val1 = fetch_data_byte(M.x86.R_SI); 7819 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7820 cmp_byte(val1, val2); 7821 M.x86.R_CX -= 1; 7822 M.x86.R_SI += inc; 7823 M.x86.R_DI += inc; 7824 if (ACCESS_FLAG(F_ZF)) 7825 break; /* zero flag set means equal */ 7826 } 7827 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7828 } 7829 else { 7830 val1 = fetch_data_byte(M.x86.R_SI); 7831 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7832 cmp_byte(val1, val2); 7833 M.x86.R_SI += inc; 7834 M.x86.R_DI += inc; 7835 } 7836 DECODE_CLEAR_SEGOVR(); 7837 END_OF_INSTR(); 7838} 7839 7840/**************************************************************************** 7841REMARKS: 7842Handles opcode 0xa7 7843****************************************************************************/ 7844static void 7845x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 7846{ 7847 u32 val1, val2; 7848 int inc; 7849 7850 START_OF_INSTR(); 7851 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7852 DECODE_PRINTF("CMPS\tDWORD\n"); 7853 if (ACCESS_FLAG(F_DF)) /* down */ 7854 inc = -4; 7855 else 7856 inc = 4; 7857 } 7858 else { 7859 DECODE_PRINTF("CMPS\tWORD\n"); 7860 if (ACCESS_FLAG(F_DF)) /* down */ 7861 inc = -2; 7862 else 7863 inc = 2; 7864 } 7865 TRACE_AND_STEP(); 7866 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7867 /* REPE */ 7868 /* move them until CX is ZERO. */ 7869 while (M.x86.R_CX != 0) { 7870 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7871 val1 = fetch_data_long(M.x86.R_SI); 7872 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7873 cmp_long(val1, val2); 7874 } 7875 else { 7876 val1 = fetch_data_word(M.x86.R_SI); 7877 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7878 cmp_word((u16) val1, (u16) val2); 7879 } 7880 M.x86.R_CX -= 1; 7881 M.x86.R_SI += inc; 7882 M.x86.R_DI += inc; 7883 if (ACCESS_FLAG(F_ZF) == 0) 7884 break; 7885 } 7886 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7887 } 7888 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7889 /* REPNE */ 7890 /* move them until CX is ZERO. */ 7891 while (M.x86.R_CX != 0) { 7892 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7893 val1 = fetch_data_long(M.x86.R_SI); 7894 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7895 cmp_long(val1, val2); 7896 } 7897 else { 7898 val1 = fetch_data_word(M.x86.R_SI); 7899 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7900 cmp_word((u16) val1, (u16) val2); 7901 } 7902 M.x86.R_CX -= 1; 7903 M.x86.R_SI += inc; 7904 M.x86.R_DI += inc; 7905 if (ACCESS_FLAG(F_ZF)) 7906 break; /* zero flag set means equal */ 7907 } 7908 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7909 } 7910 else { 7911 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7912 val1 = fetch_data_long(M.x86.R_SI); 7913 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7914 cmp_long(val1, val2); 7915 } 7916 else { 7917 val1 = fetch_data_word(M.x86.R_SI); 7918 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7919 cmp_word((u16) val1, (u16) val2); 7920 } 7921 M.x86.R_SI += inc; 7922 M.x86.R_DI += inc; 7923 } 7924 DECODE_CLEAR_SEGOVR(); 7925 END_OF_INSTR(); 7926} 7927 7928/**************************************************************************** 7929REMARKS: 7930Handles opcode 0xa8 7931****************************************************************************/ 7932static void 7933x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 7934{ 7935 int imm; 7936 7937 START_OF_INSTR(); 7938 DECODE_PRINTF("TEST\tAL,"); 7939 imm = fetch_byte_imm(); 7940 DECODE_PRINTF2("%04x\n", imm); 7941 TRACE_AND_STEP(); 7942 test_byte(M.x86.R_AL, (u8) imm); 7943 DECODE_CLEAR_SEGOVR(); 7944 END_OF_INSTR(); 7945} 7946 7947/**************************************************************************** 7948REMARKS: 7949Handles opcode 0xa9 7950****************************************************************************/ 7951static void 7952x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 7953{ 7954 u32 srcval; 7955 7956 START_OF_INSTR(); 7957 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7958 DECODE_PRINTF("TEST\tEAX,"); 7959 srcval = fetch_long_imm(); 7960 } 7961 else { 7962 DECODE_PRINTF("TEST\tAX,"); 7963 srcval = fetch_word_imm(); 7964 } 7965 DECODE_PRINTF2("%x\n", srcval); 7966 TRACE_AND_STEP(); 7967 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7968 test_long(M.x86.R_EAX, srcval); 7969 } 7970 else { 7971 test_word(M.x86.R_AX, (u16) srcval); 7972 } 7973 DECODE_CLEAR_SEGOVR(); 7974 END_OF_INSTR(); 7975} 7976 7977/**************************************************************************** 7978REMARKS: 7979Handles opcode 0xaa 7980****************************************************************************/ 7981static void 7982x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 7983{ 7984 int inc; 7985 7986 START_OF_INSTR(); 7987 DECODE_PRINTF("STOS\tBYTE\n"); 7988 if (ACCESS_FLAG(F_DF)) /* down */ 7989 inc = -1; 7990 else 7991 inc = 1; 7992 TRACE_AND_STEP(); 7993 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7994 /* don't care whether REPE or REPNE */ 7995 /* move them until CX is ZERO. */ 7996 while (M.x86.R_CX != 0) { 7997 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7998 M.x86.R_CX -= 1; 7999 M.x86.R_DI += inc; 8000 } 8001 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 8002 } 8003 else { 8004 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 8005 M.x86.R_DI += inc; 8006 } 8007 DECODE_CLEAR_SEGOVR(); 8008 END_OF_INSTR(); 8009} 8010 8011/**************************************************************************** 8012REMARKS: 8013Handles opcode 0xab 8014****************************************************************************/ 8015static void 8016x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 8017{ 8018 int inc; 8019 u32 count; 8020 8021 START_OF_INSTR(); 8022 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8023 DECODE_PRINTF("STOS\tDWORD\n"); 8024 if (ACCESS_FLAG(F_DF)) /* down */ 8025 inc = -4; 8026 else 8027 inc = 4; 8028 } 8029 else { 8030 DECODE_PRINTF("STOS\tWORD\n"); 8031 if (ACCESS_FLAG(F_DF)) /* down */ 8032 inc = -2; 8033 else 8034 inc = 2; 8035 } 8036 TRACE_AND_STEP(); 8037 count = 1; 8038 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 8039 /* don't care whether REPE or REPNE */ 8040 /* move them until CX is ZERO. */ 8041 count = M.x86.R_CX; 8042 M.x86.R_CX = 0; 8043 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 8044 } 8045 while (count--) { 8046 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8047 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 8048 } 8049 else { 8050 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 8051 } 8052 M.x86.R_DI += inc; 8053 } 8054 DECODE_CLEAR_SEGOVR(); 8055 END_OF_INSTR(); 8056} 8057 8058/**************************************************************************** 8059REMARKS: 8060Handles opcode 0xac 8061****************************************************************************/ 8062static void 8063x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 8064{ 8065 int inc; 8066 8067 START_OF_INSTR(); 8068 DECODE_PRINTF("LODS\tBYTE\n"); 8069 TRACE_AND_STEP(); 8070 if (ACCESS_FLAG(F_DF)) /* down */ 8071 inc = -1; 8072 else 8073 inc = 1; 8074 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 8075 /* don't care whether REPE or REPNE */ 8076 /* move them until CX is ZERO. */ 8077 while (M.x86.R_CX != 0) { 8078 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 8079 M.x86.R_CX -= 1; 8080 M.x86.R_SI += inc; 8081 } 8082 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 8083 } 8084 else { 8085 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 8086 M.x86.R_SI += inc; 8087 } 8088 DECODE_CLEAR_SEGOVR(); 8089 END_OF_INSTR(); 8090} 8091 8092/**************************************************************************** 8093REMARKS: 8094Handles opcode 0xad 8095****************************************************************************/ 8096static void 8097x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 8098{ 8099 int inc; 8100 u32 count; 8101 8102 START_OF_INSTR(); 8103 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8104 DECODE_PRINTF("LODS\tDWORD\n"); 8105 if (ACCESS_FLAG(F_DF)) /* down */ 8106 inc = -4; 8107 else 8108 inc = 4; 8109 } 8110 else { 8111 DECODE_PRINTF("LODS\tWORD\n"); 8112 if (ACCESS_FLAG(F_DF)) /* down */ 8113 inc = -2; 8114 else 8115 inc = 2; 8116 } 8117 TRACE_AND_STEP(); 8118 count = 1; 8119 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 8120 /* don't care whether REPE or REPNE */ 8121 /* move them until CX is ZERO. */ 8122 count = M.x86.R_CX; 8123 M.x86.R_CX = 0; 8124 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 8125 } 8126 while (count--) { 8127 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8128 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 8129 } 8130 else { 8131 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 8132 } 8133 M.x86.R_SI += inc; 8134 } 8135 DECODE_CLEAR_SEGOVR(); 8136 END_OF_INSTR(); 8137} 8138 8139/**************************************************************************** 8140REMARKS: 8141Handles opcode 0xae 8142****************************************************************************/ 8143static void 8144x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 8145{ 8146 s8 val2; 8147 int inc; 8148 8149 START_OF_INSTR(); 8150 DECODE_PRINTF("SCAS\tBYTE\n"); 8151 TRACE_AND_STEP(); 8152 if (ACCESS_FLAG(F_DF)) /* down */ 8153 inc = -1; 8154 else 8155 inc = 1; 8156 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 8157 /* REPE */ 8158 /* move them until CX is ZERO. */ 8159 while (M.x86.R_CX != 0) { 8160 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 8161 cmp_byte(M.x86.R_AL, val2); 8162 M.x86.R_CX -= 1; 8163 M.x86.R_DI += inc; 8164 if (ACCESS_FLAG(F_ZF) == 0) 8165 break; 8166 } 8167 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 8168 } 8169 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 8170 /* REPNE */ 8171 /* move them until CX is ZERO. */ 8172 while (M.x86.R_CX != 0) { 8173 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 8174 cmp_byte(M.x86.R_AL, val2); 8175 M.x86.R_CX -= 1; 8176 M.x86.R_DI += inc; 8177 if (ACCESS_FLAG(F_ZF)) 8178 break; /* zero flag set means equal */ 8179 } 8180 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 8181 } 8182 else { 8183 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 8184 cmp_byte(M.x86.R_AL, val2); 8185 M.x86.R_DI += inc; 8186 } 8187 DECODE_CLEAR_SEGOVR(); 8188 END_OF_INSTR(); 8189} 8190 8191/**************************************************************************** 8192REMARKS: 8193Handles opcode 0xaf 8194****************************************************************************/ 8195static void 8196x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 8197{ 8198 int inc; 8199 u32 val; 8200 8201 START_OF_INSTR(); 8202 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8203 DECODE_PRINTF("SCAS\tDWORD\n"); 8204 if (ACCESS_FLAG(F_DF)) /* down */ 8205 inc = -4; 8206 else 8207 inc = 4; 8208 } 8209 else { 8210 DECODE_PRINTF("SCAS\tWORD\n"); 8211 if (ACCESS_FLAG(F_DF)) /* down */ 8212 inc = -2; 8213 else 8214 inc = 2; 8215 } 8216 TRACE_AND_STEP(); 8217 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 8218 /* REPE */ 8219 /* move them until CX is ZERO. */ 8220 while (M.x86.R_CX != 0) { 8221 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8222 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 8223 cmp_long(M.x86.R_EAX, val); 8224 } 8225 else { 8226 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 8227 cmp_word(M.x86.R_AX, (u16) val); 8228 } 8229 M.x86.R_CX -= 1; 8230 M.x86.R_DI += inc; 8231 if (ACCESS_FLAG(F_ZF) == 0) 8232 break; 8233 } 8234 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 8235 } 8236 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 8237 /* REPNE */ 8238 /* move them until CX is ZERO. */ 8239 while (M.x86.R_CX != 0) { 8240 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8241 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 8242 cmp_long(M.x86.R_EAX, val); 8243 } 8244 else { 8245 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 8246 cmp_word(M.x86.R_AX, (u16) val); 8247 } 8248 M.x86.R_CX -= 1; 8249 M.x86.R_DI += inc; 8250 if (ACCESS_FLAG(F_ZF)) 8251 break; /* zero flag set means equal */ 8252 } 8253 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 8254 } 8255 else { 8256 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8257 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 8258 cmp_long(M.x86.R_EAX, val); 8259 } 8260 else { 8261 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 8262 cmp_word(M.x86.R_AX, (u16) val); 8263 } 8264 M.x86.R_DI += inc; 8265 } 8266 DECODE_CLEAR_SEGOVR(); 8267 END_OF_INSTR(); 8268} 8269 8270/**************************************************************************** 8271REMARKS: 8272Handles opcode 0xb0 8273****************************************************************************/ 8274static void 8275x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 8276{ 8277 u8 imm; 8278 8279 START_OF_INSTR(); 8280 DECODE_PRINTF("MOV\tAL,"); 8281 imm = fetch_byte_imm(); 8282 DECODE_PRINTF2("%x\n", imm); 8283 TRACE_AND_STEP(); 8284 M.x86.R_AL = imm; 8285 DECODE_CLEAR_SEGOVR(); 8286 END_OF_INSTR(); 8287} 8288 8289/**************************************************************************** 8290REMARKS: 8291Handles opcode 0xb1 8292****************************************************************************/ 8293static void 8294x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) 8295{ 8296 u8 imm; 8297 8298 START_OF_INSTR(); 8299 DECODE_PRINTF("MOV\tCL,"); 8300 imm = fetch_byte_imm(); 8301 DECODE_PRINTF2("%x\n", imm); 8302 TRACE_AND_STEP(); 8303 M.x86.R_CL = imm; 8304 DECODE_CLEAR_SEGOVR(); 8305 END_OF_INSTR(); 8306} 8307 8308/**************************************************************************** 8309REMARKS: 8310Handles opcode 0xb2 8311****************************************************************************/ 8312static void 8313x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) 8314{ 8315 u8 imm; 8316 8317 START_OF_INSTR(); 8318 DECODE_PRINTF("MOV\tDL,"); 8319 imm = fetch_byte_imm(); 8320 DECODE_PRINTF2("%x\n", imm); 8321 TRACE_AND_STEP(); 8322 M.x86.R_DL = imm; 8323 DECODE_CLEAR_SEGOVR(); 8324 END_OF_INSTR(); 8325} 8326 8327/**************************************************************************** 8328REMARKS: 8329Handles opcode 0xb3 8330****************************************************************************/ 8331static void 8332x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) 8333{ 8334 u8 imm; 8335 8336 START_OF_INSTR(); 8337 DECODE_PRINTF("MOV\tBL,"); 8338 imm = fetch_byte_imm(); 8339 DECODE_PRINTF2("%x\n", imm); 8340 TRACE_AND_STEP(); 8341 M.x86.R_BL = imm; 8342 DECODE_CLEAR_SEGOVR(); 8343 END_OF_INSTR(); 8344} 8345 8346/**************************************************************************** 8347REMARKS: 8348Handles opcode 0xb4 8349****************************************************************************/ 8350static void 8351x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) 8352{ 8353 u8 imm; 8354 8355 START_OF_INSTR(); 8356 DECODE_PRINTF("MOV\tAH,"); 8357 imm = fetch_byte_imm(); 8358 DECODE_PRINTF2("%x\n", imm); 8359 TRACE_AND_STEP(); 8360 M.x86.R_AH = imm; 8361 DECODE_CLEAR_SEGOVR(); 8362 END_OF_INSTR(); 8363} 8364 8365/**************************************************************************** 8366REMARKS: 8367Handles opcode 0xb5 8368****************************************************************************/ 8369static void 8370x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) 8371{ 8372 u8 imm; 8373 8374 START_OF_INSTR(); 8375 DECODE_PRINTF("MOV\tCH,"); 8376 imm = fetch_byte_imm(); 8377 DECODE_PRINTF2("%x\n", imm); 8378 TRACE_AND_STEP(); 8379 M.x86.R_CH = imm; 8380 DECODE_CLEAR_SEGOVR(); 8381 END_OF_INSTR(); 8382} 8383 8384/**************************************************************************** 8385REMARKS: 8386Handles opcode 0xb6 8387****************************************************************************/ 8388static void 8389x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) 8390{ 8391 u8 imm; 8392 8393 START_OF_INSTR(); 8394 DECODE_PRINTF("MOV\tDH,"); 8395 imm = fetch_byte_imm(); 8396 DECODE_PRINTF2("%x\n", imm); 8397 TRACE_AND_STEP(); 8398 M.x86.R_DH = imm; 8399 DECODE_CLEAR_SEGOVR(); 8400 END_OF_INSTR(); 8401} 8402 8403/**************************************************************************** 8404REMARKS: 8405Handles opcode 0xb7 8406****************************************************************************/ 8407static void 8408x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) 8409{ 8410 u8 imm; 8411 8412 START_OF_INSTR(); 8413 DECODE_PRINTF("MOV\tBH,"); 8414 imm = fetch_byte_imm(); 8415 DECODE_PRINTF2("%x\n", imm); 8416 TRACE_AND_STEP(); 8417 M.x86.R_BH = imm; 8418 DECODE_CLEAR_SEGOVR(); 8419 END_OF_INSTR(); 8420} 8421 8422/**************************************************************************** 8423REMARKS: 8424Handles opcode 0xb8 8425****************************************************************************/ 8426static void 8427x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 8428{ 8429 u32 srcval; 8430 8431 START_OF_INSTR(); 8432 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8433 DECODE_PRINTF("MOV\tEAX,"); 8434 srcval = fetch_long_imm(); 8435 } 8436 else { 8437 DECODE_PRINTF("MOV\tAX,"); 8438 srcval = fetch_word_imm(); 8439 } 8440 DECODE_PRINTF2("%x\n", srcval); 8441 TRACE_AND_STEP(); 8442 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8443 M.x86.R_EAX = srcval; 8444 } 8445 else { 8446 M.x86.R_AX = (u16) srcval; 8447 } 8448 DECODE_CLEAR_SEGOVR(); 8449 END_OF_INSTR(); 8450} 8451 8452/**************************************************************************** 8453REMARKS: 8454Handles opcode 0xb9 8455****************************************************************************/ 8456static void 8457x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) 8458{ 8459 u32 srcval; 8460 8461 START_OF_INSTR(); 8462 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8463 DECODE_PRINTF("MOV\tECX,"); 8464 srcval = fetch_long_imm(); 8465 } 8466 else { 8467 DECODE_PRINTF("MOV\tCX,"); 8468 srcval = fetch_word_imm(); 8469 } 8470 DECODE_PRINTF2("%x\n", srcval); 8471 TRACE_AND_STEP(); 8472 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8473 M.x86.R_ECX = srcval; 8474 } 8475 else { 8476 M.x86.R_CX = (u16) srcval; 8477 } 8478 DECODE_CLEAR_SEGOVR(); 8479 END_OF_INSTR(); 8480} 8481 8482/**************************************************************************** 8483REMARKS: 8484Handles opcode 0xba 8485****************************************************************************/ 8486static void 8487x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) 8488{ 8489 u32 srcval; 8490 8491 START_OF_INSTR(); 8492 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8493 DECODE_PRINTF("MOV\tEDX,"); 8494 srcval = fetch_long_imm(); 8495 } 8496 else { 8497 DECODE_PRINTF("MOV\tDX,"); 8498 srcval = fetch_word_imm(); 8499 } 8500 DECODE_PRINTF2("%x\n", srcval); 8501 TRACE_AND_STEP(); 8502 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8503 M.x86.R_EDX = srcval; 8504 } 8505 else { 8506 M.x86.R_DX = (u16) srcval; 8507 } 8508 DECODE_CLEAR_SEGOVR(); 8509 END_OF_INSTR(); 8510} 8511 8512/**************************************************************************** 8513REMARKS: 8514Handles opcode 0xbb 8515****************************************************************************/ 8516static void 8517x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) 8518{ 8519 u32 srcval; 8520 8521 START_OF_INSTR(); 8522 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8523 DECODE_PRINTF("MOV\tEBX,"); 8524 srcval = fetch_long_imm(); 8525 } 8526 else { 8527 DECODE_PRINTF("MOV\tBX,"); 8528 srcval = fetch_word_imm(); 8529 } 8530 DECODE_PRINTF2("%x\n", srcval); 8531 TRACE_AND_STEP(); 8532 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8533 M.x86.R_EBX = srcval; 8534 } 8535 else { 8536 M.x86.R_BX = (u16) srcval; 8537 } 8538 DECODE_CLEAR_SEGOVR(); 8539 END_OF_INSTR(); 8540} 8541 8542/**************************************************************************** 8543REMARKS: 8544Handles opcode 0xbc 8545****************************************************************************/ 8546static void 8547x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) 8548{ 8549 u32 srcval; 8550 8551 START_OF_INSTR(); 8552 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8553 DECODE_PRINTF("MOV\tESP,"); 8554 srcval = fetch_long_imm(); 8555 } 8556 else { 8557 DECODE_PRINTF("MOV\tSP,"); 8558 srcval = fetch_word_imm(); 8559 } 8560 DECODE_PRINTF2("%x\n", srcval); 8561 TRACE_AND_STEP(); 8562 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8563 M.x86.R_ESP = srcval; 8564 } 8565 else { 8566 M.x86.R_SP = (u16) srcval; 8567 } 8568 DECODE_CLEAR_SEGOVR(); 8569 END_OF_INSTR(); 8570} 8571 8572/**************************************************************************** 8573REMARKS: 8574Handles opcode 0xbd 8575****************************************************************************/ 8576static void 8577x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) 8578{ 8579 u32 srcval; 8580 8581 START_OF_INSTR(); 8582 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8583 DECODE_PRINTF("MOV\tEBP,"); 8584 srcval = fetch_long_imm(); 8585 } 8586 else { 8587 DECODE_PRINTF("MOV\tBP,"); 8588 srcval = fetch_word_imm(); 8589 } 8590 DECODE_PRINTF2("%x\n", srcval); 8591 TRACE_AND_STEP(); 8592 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8593 M.x86.R_EBP = srcval; 8594 } 8595 else { 8596 M.x86.R_BP = (u16) srcval; 8597 } 8598 DECODE_CLEAR_SEGOVR(); 8599 END_OF_INSTR(); 8600} 8601 8602/**************************************************************************** 8603REMARKS: 8604Handles opcode 0xbe 8605****************************************************************************/ 8606static void 8607x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) 8608{ 8609 u32 srcval; 8610 8611 START_OF_INSTR(); 8612 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8613 DECODE_PRINTF("MOV\tESI,"); 8614 srcval = fetch_long_imm(); 8615 } 8616 else { 8617 DECODE_PRINTF("MOV\tSI,"); 8618 srcval = fetch_word_imm(); 8619 } 8620 DECODE_PRINTF2("%x\n", srcval); 8621 TRACE_AND_STEP(); 8622 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8623 M.x86.R_ESI = srcval; 8624 } 8625 else { 8626 M.x86.R_SI = (u16) srcval; 8627 } 8628 DECODE_CLEAR_SEGOVR(); 8629 END_OF_INSTR(); 8630} 8631 8632/**************************************************************************** 8633REMARKS: 8634Handles opcode 0xbf 8635****************************************************************************/ 8636static void 8637x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) 8638{ 8639 u32 srcval; 8640 8641 START_OF_INSTR(); 8642 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8643 DECODE_PRINTF("MOV\tEDI,"); 8644 srcval = fetch_long_imm(); 8645 } 8646 else { 8647 DECODE_PRINTF("MOV\tDI,"); 8648 srcval = fetch_word_imm(); 8649 } 8650 DECODE_PRINTF2("%x\n", srcval); 8651 TRACE_AND_STEP(); 8652 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8653 M.x86.R_EDI = srcval; 8654 } 8655 else { 8656 M.x86.R_DI = (u16) srcval; 8657 } 8658 DECODE_CLEAR_SEGOVR(); 8659 END_OF_INSTR(); 8660} 8661 8662/* used by opcodes c0, d0, and d2. */ 8663static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = { 8664 rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte, /* sal_byte === shl_byte by definition */ 8665sar_byte,}; 8666 8667/**************************************************************************** 8668REMARKS: 8669Handles opcode 0xc0 8670****************************************************************************/ 8671static void 8672x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 8673{ 8674 int mod, rl, rh; 8675 u8 *destreg; 8676 uint destoffset; 8677 u8 destval; 8678 u8 amt; 8679 8680 /* 8681 * Yet another weirdo special case instruction format. Part of 8682 * the opcode held below in "RH". Doubly nested case would 8683 * result, except that the decoded instruction 8684 */ 8685 START_OF_INSTR(); 8686 FETCH_DECODE_MODRM(mod, rh, rl); 8687#ifdef DEBUG 8688 if (DEBUG_DECODE()) { 8689 /* XXX DECODE_PRINTF may be changed to something more 8690 general, so that it is important to leave the strings 8691 in the same format, even though the result is that the 8692 above test is done twice. */ 8693 8694 switch (rh) { 8695 case 0: 8696 DECODE_PRINTF("ROL\t"); 8697 break; 8698 case 1: 8699 DECODE_PRINTF("ROR\t"); 8700 break; 8701 case 2: 8702 DECODE_PRINTF("RCL\t"); 8703 break; 8704 case 3: 8705 DECODE_PRINTF("RCR\t"); 8706 break; 8707 case 4: 8708 DECODE_PRINTF("SHL\t"); 8709 break; 8710 case 5: 8711 DECODE_PRINTF("SHR\t"); 8712 break; 8713 case 6: 8714 DECODE_PRINTF("SAL\t"); 8715 break; 8716 case 7: 8717 DECODE_PRINTF("SAR\t"); 8718 break; 8719 } 8720 } 8721#endif 8722 /* know operation, decode the mod byte to find the addressing 8723 mode. */ 8724 switch (mod) { 8725 case 0: 8726 DECODE_PRINTF("BYTE PTR "); 8727 destoffset = decode_rm00_address(rl); 8728 amt = fetch_byte_imm(); 8729 DECODE_PRINTF2(",%x\n", amt); 8730 destval = fetch_data_byte(destoffset); 8731 TRACE_AND_STEP(); 8732 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8733 store_data_byte(destoffset, destval); 8734 break; 8735 case 1: 8736 DECODE_PRINTF("BYTE PTR "); 8737 destoffset = decode_rm01_address(rl); 8738 amt = fetch_byte_imm(); 8739 DECODE_PRINTF2(",%x\n", amt); 8740 destval = fetch_data_byte(destoffset); 8741 TRACE_AND_STEP(); 8742 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8743 store_data_byte(destoffset, destval); 8744 break; 8745 case 2: 8746 DECODE_PRINTF("BYTE PTR "); 8747 destoffset = decode_rm10_address(rl); 8748 amt = fetch_byte_imm(); 8749 DECODE_PRINTF2(",%x\n", amt); 8750 destval = fetch_data_byte(destoffset); 8751 TRACE_AND_STEP(); 8752 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8753 store_data_byte(destoffset, destval); 8754 break; 8755 case 3: /* register to register */ 8756 destreg = DECODE_RM_BYTE_REGISTER(rl); 8757 amt = fetch_byte_imm(); 8758 DECODE_PRINTF2(",%x\n", amt); 8759 TRACE_AND_STEP(); 8760 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 8761 *destreg = destval; 8762 break; 8763 } 8764 DECODE_CLEAR_SEGOVR(); 8765 END_OF_INSTR(); 8766} 8767 8768/* used by opcodes c1, d1, and d3. */ 8769static u16(*opcD1_word_operation[]) (u16 s, u8 d) = { 8770 rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word, /* sal_byte === shl_byte by definition */ 8771sar_word,}; 8772 8773/* used by opcodes c1, d1, and d3. */ 8774static u32(*opcD1_long_operation[]) (u32 s, u8 d) = { 8775 rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long, /* sal_byte === shl_byte by definition */ 8776sar_long,}; 8777 8778/**************************************************************************** 8779REMARKS: 8780Handles opcode 0xc1 8781****************************************************************************/ 8782static void 8783x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 8784{ 8785 int mod, rl, rh; 8786 uint destoffset; 8787 u8 amt; 8788 8789 /* 8790 * Yet another weirdo special case instruction format. Part of 8791 * the opcode held below in "RH". Doubly nested case would 8792 * result, except that the decoded instruction 8793 */ 8794 START_OF_INSTR(); 8795 FETCH_DECODE_MODRM(mod, rh, rl); 8796#ifdef DEBUG 8797 if (DEBUG_DECODE()) { 8798 /* XXX DECODE_PRINTF may be changed to something more 8799 general, so that it is important to leave the strings 8800 in the same format, even though the result is that the 8801 above test is done twice. */ 8802 8803 switch (rh) { 8804 case 0: 8805 DECODE_PRINTF("ROL\t"); 8806 break; 8807 case 1: 8808 DECODE_PRINTF("ROR\t"); 8809 break; 8810 case 2: 8811 DECODE_PRINTF("RCL\t"); 8812 break; 8813 case 3: 8814 DECODE_PRINTF("RCR\t"); 8815 break; 8816 case 4: 8817 DECODE_PRINTF("SHL\t"); 8818 break; 8819 case 5: 8820 DECODE_PRINTF("SHR\t"); 8821 break; 8822 case 6: 8823 DECODE_PRINTF("SAL\t"); 8824 break; 8825 case 7: 8826 DECODE_PRINTF("SAR\t"); 8827 break; 8828 } 8829 } 8830#endif 8831 /* know operation, decode the mod byte to find the addressing 8832 mode. */ 8833 switch (mod) { 8834 case 0: 8835 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8836 u32 destval; 8837 8838 DECODE_PRINTF("DWORD PTR "); 8839 destoffset = decode_rm00_address(rl); 8840 amt = fetch_byte_imm(); 8841 DECODE_PRINTF2(",%x\n", amt); 8842 destval = fetch_data_long(destoffset); 8843 TRACE_AND_STEP(); 8844 destval = (*opcD1_long_operation[rh]) (destval, amt); 8845 store_data_long(destoffset, destval); 8846 } 8847 else { 8848 u16 destval; 8849 8850 DECODE_PRINTF("WORD PTR "); 8851 destoffset = decode_rm00_address(rl); 8852 amt = fetch_byte_imm(); 8853 DECODE_PRINTF2(",%x\n", amt); 8854 destval = fetch_data_word(destoffset); 8855 TRACE_AND_STEP(); 8856 destval = (*opcD1_word_operation[rh]) (destval, amt); 8857 store_data_word(destoffset, destval); 8858 } 8859 break; 8860 case 1: 8861 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8862 u32 destval; 8863 8864 DECODE_PRINTF("DWORD PTR "); 8865 destoffset = decode_rm01_address(rl); 8866 amt = fetch_byte_imm(); 8867 DECODE_PRINTF2(",%x\n", amt); 8868 destval = fetch_data_long(destoffset); 8869 TRACE_AND_STEP(); 8870 destval = (*opcD1_long_operation[rh]) (destval, amt); 8871 store_data_long(destoffset, destval); 8872 } 8873 else { 8874 u16 destval; 8875 8876 DECODE_PRINTF("WORD PTR "); 8877 destoffset = decode_rm01_address(rl); 8878 amt = fetch_byte_imm(); 8879 DECODE_PRINTF2(",%x\n", amt); 8880 destval = fetch_data_word(destoffset); 8881 TRACE_AND_STEP(); 8882 destval = (*opcD1_word_operation[rh]) (destval, amt); 8883 store_data_word(destoffset, destval); 8884 } 8885 break; 8886 case 2: 8887 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8888 u32 destval; 8889 8890 DECODE_PRINTF("DWORD PTR "); 8891 destoffset = decode_rm10_address(rl); 8892 amt = fetch_byte_imm(); 8893 DECODE_PRINTF2(",%x\n", amt); 8894 destval = fetch_data_long(destoffset); 8895 TRACE_AND_STEP(); 8896 destval = (*opcD1_long_operation[rh]) (destval, amt); 8897 store_data_long(destoffset, destval); 8898 } 8899 else { 8900 u16 destval; 8901 8902 DECODE_PRINTF("WORD PTR "); 8903 destoffset = decode_rm10_address(rl); 8904 amt = fetch_byte_imm(); 8905 DECODE_PRINTF2(",%x\n", amt); 8906 destval = fetch_data_word(destoffset); 8907 TRACE_AND_STEP(); 8908 destval = (*opcD1_word_operation[rh]) (destval, amt); 8909 store_data_word(destoffset, destval); 8910 } 8911 break; 8912 case 3: /* register to register */ 8913 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8914 u32 *destreg; 8915 8916 destreg = DECODE_RM_LONG_REGISTER(rl); 8917 amt = fetch_byte_imm(); 8918 DECODE_PRINTF2(",%x\n", amt); 8919 TRACE_AND_STEP(); 8920 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 8921 } 8922 else { 8923 u16 *destreg; 8924 8925 destreg = DECODE_RM_WORD_REGISTER(rl); 8926 amt = fetch_byte_imm(); 8927 DECODE_PRINTF2(",%x\n", amt); 8928 TRACE_AND_STEP(); 8929 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 8930 } 8931 break; 8932 } 8933 DECODE_CLEAR_SEGOVR(); 8934 END_OF_INSTR(); 8935} 8936 8937/**************************************************************************** 8938REMARKS: 8939Handles opcode 0xc2 8940****************************************************************************/ 8941static void 8942x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 8943{ 8944 u16 imm; 8945 8946 START_OF_INSTR(); 8947 DECODE_PRINTF("RET\t"); 8948 imm = fetch_word_imm(); 8949 DECODE_PRINTF2("%x\n", imm); 8950 RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip); 8951 TRACE_AND_STEP(); 8952 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8953 M.x86.R_EIP = pop_long(); 8954 } else { 8955 M.x86.R_IP = pop_word(); 8956 } 8957 M.x86.R_SP += imm; 8958 DECODE_CLEAR_SEGOVR(); 8959 END_OF_INSTR(); 8960} 8961 8962/**************************************************************************** 8963REMARKS: 8964Handles opcode 0xc3 8965****************************************************************************/ 8966static void 8967x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 8968{ 8969 START_OF_INSTR(); 8970 DECODE_PRINTF("RET\n"); 8971 RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip); 8972 TRACE_AND_STEP(); 8973 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8974 M.x86.R_EIP = pop_long(); 8975 } else { 8976 M.x86.R_IP = pop_word(); 8977 } 8978 DECODE_CLEAR_SEGOVR(); 8979 END_OF_INSTR(); 8980} 8981 8982/**************************************************************************** 8983REMARKS: 8984Handles opcode 0xc4 8985****************************************************************************/ 8986static void 8987x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 8988{ 8989 int mod, rh, rl; 8990 u16 *dstreg; 8991 uint srcoffset; 8992 8993 START_OF_INSTR(); 8994 DECODE_PRINTF("LES\t"); 8995 FETCH_DECODE_MODRM(mod, rh, rl); 8996 switch (mod) { 8997 case 0: 8998 dstreg = DECODE_RM_WORD_REGISTER(rh); 8999 DECODE_PRINTF(","); 9000 srcoffset = decode_rm00_address(rl); 9001 DECODE_PRINTF("\n"); 9002 TRACE_AND_STEP(); 9003 *dstreg = fetch_data_word(srcoffset); 9004 M.x86.R_ES = fetch_data_word(srcoffset + 2); 9005 break; 9006 case 1: 9007 dstreg = DECODE_RM_WORD_REGISTER(rh); 9008 DECODE_PRINTF(","); 9009 srcoffset = decode_rm01_address(rl); 9010 DECODE_PRINTF("\n"); 9011 TRACE_AND_STEP(); 9012 *dstreg = fetch_data_word(srcoffset); 9013 M.x86.R_ES = fetch_data_word(srcoffset + 2); 9014 break; 9015 case 2: 9016 dstreg = DECODE_RM_WORD_REGISTER(rh); 9017 DECODE_PRINTF(","); 9018 srcoffset = decode_rm10_address(rl); 9019 DECODE_PRINTF("\n"); 9020 TRACE_AND_STEP(); 9021 *dstreg = fetch_data_word(srcoffset); 9022 M.x86.R_ES = fetch_data_word(srcoffset + 2); 9023 break; 9024 case 3: /* register to register */ 9025 /* UNDEFINED! */ 9026 TRACE_AND_STEP(); 9027 } 9028 DECODE_CLEAR_SEGOVR(); 9029 END_OF_INSTR(); 9030} 9031 9032/**************************************************************************** 9033REMARKS: 9034Handles opcode 0xc5 9035****************************************************************************/ 9036static void 9037x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 9038{ 9039 int mod, rh, rl; 9040 u16 *dstreg; 9041 uint srcoffset; 9042 9043 START_OF_INSTR(); 9044 DECODE_PRINTF("LDS\t"); 9045 FETCH_DECODE_MODRM(mod, rh, rl); 9046 switch (mod) { 9047 case 0: 9048 dstreg = DECODE_RM_WORD_REGISTER(rh); 9049 DECODE_PRINTF(","); 9050 srcoffset = decode_rm00_address(rl); 9051 DECODE_PRINTF("\n"); 9052 TRACE_AND_STEP(); 9053 *dstreg = fetch_data_word(srcoffset); 9054 M.x86.R_DS = fetch_data_word(srcoffset + 2); 9055 break; 9056 case 1: 9057 dstreg = DECODE_RM_WORD_REGISTER(rh); 9058 DECODE_PRINTF(","); 9059 srcoffset = decode_rm01_address(rl); 9060 DECODE_PRINTF("\n"); 9061 TRACE_AND_STEP(); 9062 *dstreg = fetch_data_word(srcoffset); 9063 M.x86.R_DS = fetch_data_word(srcoffset + 2); 9064 break; 9065 case 2: 9066 dstreg = DECODE_RM_WORD_REGISTER(rh); 9067 DECODE_PRINTF(","); 9068 srcoffset = decode_rm10_address(rl); 9069 DECODE_PRINTF("\n"); 9070 TRACE_AND_STEP(); 9071 *dstreg = fetch_data_word(srcoffset); 9072 M.x86.R_DS = fetch_data_word(srcoffset + 2); 9073 break; 9074 case 3: /* register to register */ 9075 /* UNDEFINED! */ 9076 TRACE_AND_STEP(); 9077 } 9078 DECODE_CLEAR_SEGOVR(); 9079 END_OF_INSTR(); 9080} 9081 9082/**************************************************************************** 9083REMARKS: 9084Handles opcode 0xc6 9085****************************************************************************/ 9086static void 9087x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 9088{ 9089 int mod, rl, rh; 9090 u8 *destreg; 9091 uint destoffset; 9092 u8 imm; 9093 9094 START_OF_INSTR(); 9095 DECODE_PRINTF("MOV\t"); 9096 FETCH_DECODE_MODRM(mod, rh, rl); 9097 if (rh != 0) { 9098 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 9099 HALT_SYS(); 9100 } 9101 switch (mod) { 9102 case 0: 9103 DECODE_PRINTF("BYTE PTR "); 9104 destoffset = decode_rm00_address(rl); 9105 imm = fetch_byte_imm(); 9106 DECODE_PRINTF2(",%2x\n", imm); 9107 TRACE_AND_STEP(); 9108 store_data_byte(destoffset, imm); 9109 break; 9110 case 1: 9111 DECODE_PRINTF("BYTE PTR "); 9112 destoffset = decode_rm01_address(rl); 9113 imm = fetch_byte_imm(); 9114 DECODE_PRINTF2(",%2x\n", imm); 9115 TRACE_AND_STEP(); 9116 store_data_byte(destoffset, imm); 9117 break; 9118 case 2: 9119 DECODE_PRINTF("BYTE PTR "); 9120 destoffset = decode_rm10_address(rl); 9121 imm = fetch_byte_imm(); 9122 DECODE_PRINTF2(",%2x\n", imm); 9123 TRACE_AND_STEP(); 9124 store_data_byte(destoffset, imm); 9125 break; 9126 case 3: /* register to register */ 9127 destreg = DECODE_RM_BYTE_REGISTER(rl); 9128 imm = fetch_byte_imm(); 9129 DECODE_PRINTF2(",%2x\n", imm); 9130 TRACE_AND_STEP(); 9131 *destreg = imm; 9132 break; 9133 } 9134 DECODE_CLEAR_SEGOVR(); 9135 END_OF_INSTR(); 9136} 9137 9138/**************************************************************************** 9139REMARKS: 9140Handles opcode 0xc7 9141****************************************************************************/ 9142static void 9143x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 9144{ 9145 int mod, rl, rh; 9146 uint destoffset; 9147 9148 START_OF_INSTR(); 9149 DECODE_PRINTF("MOV\t"); 9150 FETCH_DECODE_MODRM(mod, rh, rl); 9151 if (rh != 0) { 9152 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 9153 HALT_SYS(); 9154 } 9155 switch (mod) { 9156 case 0: 9157 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9158 u32 imm; 9159 9160 DECODE_PRINTF("DWORD PTR "); 9161 destoffset = decode_rm00_address(rl); 9162 imm = fetch_long_imm(); 9163 DECODE_PRINTF2(",%x\n", imm); 9164 TRACE_AND_STEP(); 9165 store_data_long(destoffset, imm); 9166 } 9167 else { 9168 u16 imm; 9169 9170 DECODE_PRINTF("WORD PTR "); 9171 destoffset = decode_rm00_address(rl); 9172 imm = fetch_word_imm(); 9173 DECODE_PRINTF2(",%x\n", imm); 9174 TRACE_AND_STEP(); 9175 store_data_word(destoffset, imm); 9176 } 9177 break; 9178 case 1: 9179 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9180 u32 imm; 9181 9182 DECODE_PRINTF("DWORD PTR "); 9183 destoffset = decode_rm01_address(rl); 9184 imm = fetch_long_imm(); 9185 DECODE_PRINTF2(",%x\n", imm); 9186 TRACE_AND_STEP(); 9187 store_data_long(destoffset, imm); 9188 } 9189 else { 9190 u16 imm; 9191 9192 DECODE_PRINTF("WORD PTR "); 9193 destoffset = decode_rm01_address(rl); 9194 imm = fetch_word_imm(); 9195 DECODE_PRINTF2(",%x\n", imm); 9196 TRACE_AND_STEP(); 9197 store_data_word(destoffset, imm); 9198 } 9199 break; 9200 case 2: 9201 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9202 u32 imm; 9203 9204 DECODE_PRINTF("DWORD PTR "); 9205 destoffset = decode_rm10_address(rl); 9206 imm = fetch_long_imm(); 9207 DECODE_PRINTF2(",%x\n", imm); 9208 TRACE_AND_STEP(); 9209 store_data_long(destoffset, imm); 9210 } 9211 else { 9212 u16 imm; 9213 9214 DECODE_PRINTF("WORD PTR "); 9215 destoffset = decode_rm10_address(rl); 9216 imm = fetch_word_imm(); 9217 DECODE_PRINTF2(",%x\n", imm); 9218 TRACE_AND_STEP(); 9219 store_data_word(destoffset, imm); 9220 } 9221 break; 9222 case 3: /* register to register */ 9223 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9224 u32 *destreg; 9225 u32 imm; 9226 9227 destreg = DECODE_RM_LONG_REGISTER(rl); 9228 imm = fetch_long_imm(); 9229 DECODE_PRINTF2(",%x\n", imm); 9230 TRACE_AND_STEP(); 9231 *destreg = imm; 9232 } 9233 else { 9234 u16 *destreg; 9235 u16 imm; 9236 9237 destreg = DECODE_RM_WORD_REGISTER(rl); 9238 imm = fetch_word_imm(); 9239 DECODE_PRINTF2(",%x\n", imm); 9240 TRACE_AND_STEP(); 9241 *destreg = imm; 9242 } 9243 break; 9244 } 9245 DECODE_CLEAR_SEGOVR(); 9246 END_OF_INSTR(); 9247} 9248 9249/**************************************************************************** 9250REMARKS: 9251Handles opcode 0xc8 9252****************************************************************************/ 9253static void 9254x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 9255{ 9256 u16 local, frame_pointer; 9257 u8 nesting; 9258 int i; 9259 9260 START_OF_INSTR(); 9261 local = fetch_word_imm(); 9262 nesting = fetch_byte_imm(); 9263 DECODE_PRINTF2("ENTER %x\n", local); 9264 DECODE_PRINTF2(",%x\n", nesting); 9265 TRACE_AND_STEP(); 9266 push_word(M.x86.R_BP); 9267 frame_pointer = M.x86.R_SP; 9268 if (nesting > 0) { 9269 for (i = 1; i < nesting; i++) { 9270 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9271 M.x86.R_BP -= 4; 9272 push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP)); 9273 } else { 9274 M.x86.R_BP -= 2; 9275 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 9276 } 9277 } 9278 push_word(frame_pointer); 9279 } 9280 M.x86.R_BP = frame_pointer; 9281 M.x86.R_SP = (u16) (M.x86.R_SP - local); 9282 DECODE_CLEAR_SEGOVR(); 9283 END_OF_INSTR(); 9284} 9285 9286/**************************************************************************** 9287REMARKS: 9288Handles opcode 0xc9 9289****************************************************************************/ 9290static void 9291x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 9292{ 9293 START_OF_INSTR(); 9294 DECODE_PRINTF("LEAVE\n"); 9295 TRACE_AND_STEP(); 9296 M.x86.R_SP = M.x86.R_BP; 9297 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9298 M.x86.R_EBP = pop_long(); 9299 } else { 9300 M.x86.R_BP = pop_word(); 9301 } 9302 DECODE_CLEAR_SEGOVR(); 9303 END_OF_INSTR(); 9304} 9305 9306/**************************************************************************** 9307REMARKS: 9308Handles opcode 0xca 9309****************************************************************************/ 9310static void 9311x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 9312{ 9313 u16 imm; 9314 9315 START_OF_INSTR(); 9316 DECODE_PRINTF("RETF\t"); 9317 imm = fetch_word_imm(); 9318 DECODE_PRINTF2("%x\n", imm); 9319 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip); 9320 TRACE_AND_STEP(); 9321 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9322 M.x86.R_EIP = pop_long(); 9323 M.x86.R_CS = pop_long() & 0xffff; 9324 } else { 9325 M.x86.R_IP = pop_word(); 9326 M.x86.R_CS = pop_word(); 9327 } 9328 M.x86.R_SP += imm; 9329 DECODE_CLEAR_SEGOVR(); 9330 END_OF_INSTR(); 9331} 9332 9333/**************************************************************************** 9334REMARKS: 9335Handles opcode 0xcb 9336****************************************************************************/ 9337static void 9338x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 9339{ 9340 START_OF_INSTR(); 9341 DECODE_PRINTF("RETF\n"); 9342 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip); 9343 TRACE_AND_STEP(); 9344 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9345 M.x86.R_EIP = pop_long(); 9346 M.x86.R_CS = pop_long() & 0xffff; 9347 } else { 9348 M.x86.R_IP = pop_word(); 9349 M.x86.R_CS = pop_word(); 9350 } 9351 DECODE_CLEAR_SEGOVR(); 9352 END_OF_INSTR(); 9353} 9354 9355/**************************************************************************** 9356REMARKS: 9357Handles opcode 0xcc 9358****************************************************************************/ 9359static void 9360x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 9361{ 9362 START_OF_INSTR(); 9363 DECODE_PRINTF("INT 3\n"); 9364 TRACE_AND_STEP(); 9365 if (_X86EMU_intrTab[3]) { 9366 (*_X86EMU_intrTab[3]) (3); 9367 } 9368 else { 9369 push_word((u16) M.x86.R_FLG); 9370 CLEAR_FLAG(F_IF); 9371 CLEAR_FLAG(F_TF); 9372 push_word(M.x86.R_CS); 9373 M.x86.R_CS = mem_access_word(3 * 4 + 2); 9374 push_word(M.x86.R_IP); 9375 M.x86.R_IP = mem_access_word(3 * 4); 9376 } 9377 DECODE_CLEAR_SEGOVR(); 9378 END_OF_INSTR(); 9379} 9380 9381/**************************************************************************** 9382REMARKS: 9383Handles opcode 0xcd 9384****************************************************************************/ 9385static void 9386x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 9387{ 9388 u8 intnum; 9389 9390 START_OF_INSTR(); 9391 DECODE_PRINTF("INT\t"); 9392 intnum = fetch_byte_imm(); 9393 DECODE_PRINTF2("%x\n", intnum); 9394 TRACE_AND_STEP(); 9395 if (_X86EMU_intrTab[intnum]) { 9396 (*_X86EMU_intrTab[intnum]) (intnum); 9397 } 9398 else { 9399 push_word((u16) M.x86.R_FLG); 9400 CLEAR_FLAG(F_IF); 9401 CLEAR_FLAG(F_TF); 9402 push_word(M.x86.R_CS); 9403 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 9404 push_word(M.x86.R_IP); 9405 M.x86.R_IP = mem_access_word(intnum * 4); 9406 } 9407 DECODE_CLEAR_SEGOVR(); 9408 END_OF_INSTR(); 9409} 9410 9411/**************************************************************************** 9412REMARKS: 9413Handles opcode 0xce 9414****************************************************************************/ 9415static void 9416x86emuOp_into(u8 X86EMU_UNUSED(op1)) 9417{ 9418 START_OF_INSTR(); 9419 DECODE_PRINTF("INTO\n"); 9420 TRACE_AND_STEP(); 9421 if (ACCESS_FLAG(F_OF)) { 9422 if (_X86EMU_intrTab[4]) { 9423 (*_X86EMU_intrTab[4]) (4); 9424 } 9425 else { 9426 push_word((u16) M.x86.R_FLG); 9427 CLEAR_FLAG(F_IF); 9428 CLEAR_FLAG(F_TF); 9429 push_word(M.x86.R_CS); 9430 M.x86.R_CS = mem_access_word(4 * 4 + 2); 9431 push_word(M.x86.R_IP); 9432 M.x86.R_IP = mem_access_word(4 * 4); 9433 } 9434 } 9435 DECODE_CLEAR_SEGOVR(); 9436 END_OF_INSTR(); 9437} 9438 9439/**************************************************************************** 9440REMARKS: 9441Handles opcode 0xcf 9442****************************************************************************/ 9443static void 9444x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 9445{ 9446 START_OF_INSTR(); 9447 DECODE_PRINTF("IRET\n"); 9448 9449 TRACE_AND_STEP(); 9450 9451 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9452 M.x86.R_EIP = pop_long(); 9453 M.x86.R_CS = pop_long() & 0xffff; 9454 M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000); 9455 } else { 9456 M.x86.R_IP = pop_word(); 9457 M.x86.R_CS = pop_word(); 9458 M.x86.R_FLG = pop_word(); 9459 } 9460 DECODE_CLEAR_SEGOVR(); 9461 END_OF_INSTR(); 9462} 9463 9464/**************************************************************************** 9465REMARKS: 9466Handles opcode 0xd0 9467****************************************************************************/ 9468static void 9469x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 9470{ 9471 int mod, rl, rh; 9472 u8 *destreg; 9473 uint destoffset; 9474 u8 destval; 9475 9476 /* 9477 * Yet another weirdo special case instruction format. Part of 9478 * the opcode held below in "RH". Doubly nested case would 9479 * result, except that the decoded instruction 9480 */ 9481 START_OF_INSTR(); 9482 FETCH_DECODE_MODRM(mod, rh, rl); 9483#ifdef DEBUG 9484 if (DEBUG_DECODE()) { 9485 /* XXX DECODE_PRINTF may be changed to something more 9486 general, so that it is important to leave the strings 9487 in the same format, even though the result is that the 9488 above test is done twice. */ 9489 switch (rh) { 9490 case 0: 9491 DECODE_PRINTF("ROL\t"); 9492 break; 9493 case 1: 9494 DECODE_PRINTF("ROR\t"); 9495 break; 9496 case 2: 9497 DECODE_PRINTF("RCL\t"); 9498 break; 9499 case 3: 9500 DECODE_PRINTF("RCR\t"); 9501 break; 9502 case 4: 9503 DECODE_PRINTF("SHL\t"); 9504 break; 9505 case 5: 9506 DECODE_PRINTF("SHR\t"); 9507 break; 9508 case 6: 9509 DECODE_PRINTF("SAL\t"); 9510 break; 9511 case 7: 9512 DECODE_PRINTF("SAR\t"); 9513 break; 9514 } 9515 } 9516#endif 9517 /* know operation, decode the mod byte to find the addressing 9518 mode. */ 9519 switch (mod) { 9520 case 0: 9521 DECODE_PRINTF("BYTE PTR "); 9522 destoffset = decode_rm00_address(rl); 9523 DECODE_PRINTF(",1\n"); 9524 destval = fetch_data_byte(destoffset); 9525 TRACE_AND_STEP(); 9526 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9527 store_data_byte(destoffset, destval); 9528 break; 9529 case 1: 9530 DECODE_PRINTF("BYTE PTR "); 9531 destoffset = decode_rm01_address(rl); 9532 DECODE_PRINTF(",1\n"); 9533 destval = fetch_data_byte(destoffset); 9534 TRACE_AND_STEP(); 9535 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9536 store_data_byte(destoffset, destval); 9537 break; 9538 case 2: 9539 DECODE_PRINTF("BYTE PTR "); 9540 destoffset = decode_rm10_address(rl); 9541 DECODE_PRINTF(",1\n"); 9542 destval = fetch_data_byte(destoffset); 9543 TRACE_AND_STEP(); 9544 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9545 store_data_byte(destoffset, destval); 9546 break; 9547 case 3: /* register to register */ 9548 destreg = DECODE_RM_BYTE_REGISTER(rl); 9549 DECODE_PRINTF(",1\n"); 9550 TRACE_AND_STEP(); 9551 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 9552 *destreg = destval; 9553 break; 9554 } 9555 DECODE_CLEAR_SEGOVR(); 9556 END_OF_INSTR(); 9557} 9558 9559/**************************************************************************** 9560REMARKS: 9561Handles opcode 0xd1 9562****************************************************************************/ 9563static void 9564x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 9565{ 9566 int mod, rl, rh; 9567 uint destoffset; 9568 9569 /* 9570 * Yet another weirdo special case instruction format. Part of 9571 * the opcode held below in "RH". Doubly nested case would 9572 * result, except that the decoded instruction 9573 */ 9574 START_OF_INSTR(); 9575 FETCH_DECODE_MODRM(mod, rh, rl); 9576#ifdef DEBUG 9577 if (DEBUG_DECODE()) { 9578 /* XXX DECODE_PRINTF may be changed to something more 9579 general, so that it is important to leave the strings 9580 in the same format, even though the result is that the 9581 above test is done twice. */ 9582 switch (rh) { 9583 case 0: 9584 DECODE_PRINTF("ROL\t"); 9585 break; 9586 case 1: 9587 DECODE_PRINTF("ROR\t"); 9588 break; 9589 case 2: 9590 DECODE_PRINTF("RCL\t"); 9591 break; 9592 case 3: 9593 DECODE_PRINTF("RCR\t"); 9594 break; 9595 case 4: 9596 DECODE_PRINTF("SHL\t"); 9597 break; 9598 case 5: 9599 DECODE_PRINTF("SHR\t"); 9600 break; 9601 case 6: 9602 DECODE_PRINTF("SAL\t"); 9603 break; 9604 case 7: 9605 DECODE_PRINTF("SAR\t"); 9606 break; 9607 } 9608 } 9609#endif 9610 /* know operation, decode the mod byte to find the addressing 9611 mode. */ 9612 switch (mod) { 9613 case 0: 9614 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9615 u32 destval; 9616 9617 DECODE_PRINTF("DWORD PTR "); 9618 destoffset = decode_rm00_address(rl); 9619 DECODE_PRINTF(",1\n"); 9620 destval = fetch_data_long(destoffset); 9621 TRACE_AND_STEP(); 9622 destval = (*opcD1_long_operation[rh]) (destval, 1); 9623 store_data_long(destoffset, destval); 9624 } 9625 else { 9626 u16 destval; 9627 9628 DECODE_PRINTF("WORD PTR "); 9629 destoffset = decode_rm00_address(rl); 9630 DECODE_PRINTF(",1\n"); 9631 destval = fetch_data_word(destoffset); 9632 TRACE_AND_STEP(); 9633 destval = (*opcD1_word_operation[rh]) (destval, 1); 9634 store_data_word(destoffset, destval); 9635 } 9636 break; 9637 case 1: 9638 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9639 u32 destval; 9640 9641 DECODE_PRINTF("DWORD PTR "); 9642 destoffset = decode_rm01_address(rl); 9643 DECODE_PRINTF(",1\n"); 9644 destval = fetch_data_long(destoffset); 9645 TRACE_AND_STEP(); 9646 destval = (*opcD1_long_operation[rh]) (destval, 1); 9647 store_data_long(destoffset, destval); 9648 } 9649 else { 9650 u16 destval; 9651 9652 DECODE_PRINTF("WORD PTR "); 9653 destoffset = decode_rm01_address(rl); 9654 DECODE_PRINTF(",1\n"); 9655 destval = fetch_data_word(destoffset); 9656 TRACE_AND_STEP(); 9657 destval = (*opcD1_word_operation[rh]) (destval, 1); 9658 store_data_word(destoffset, destval); 9659 } 9660 break; 9661 case 2: 9662 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9663 u32 destval; 9664 9665 DECODE_PRINTF("DWORD PTR "); 9666 destoffset = decode_rm10_address(rl); 9667 DECODE_PRINTF(",1\n"); 9668 destval = fetch_data_long(destoffset); 9669 TRACE_AND_STEP(); 9670 destval = (*opcD1_long_operation[rh]) (destval, 1); 9671 store_data_long(destoffset, destval); 9672 } 9673 else { 9674 u16 destval; 9675 9676 DECODE_PRINTF("BYTE PTR "); 9677 destoffset = decode_rm10_address(rl); 9678 DECODE_PRINTF(",1\n"); 9679 destval = fetch_data_word(destoffset); 9680 TRACE_AND_STEP(); 9681 destval = (*opcD1_word_operation[rh]) (destval, 1); 9682 store_data_word(destoffset, destval); 9683 } 9684 break; 9685 case 3: /* register to register */ 9686 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9687 u32 destval; 9688 u32 *destreg; 9689 9690 destreg = DECODE_RM_LONG_REGISTER(rl); 9691 DECODE_PRINTF(",1\n"); 9692 TRACE_AND_STEP(); 9693 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 9694 *destreg = destval; 9695 } 9696 else { 9697 u16 destval; 9698 u16 *destreg; 9699 9700 destreg = DECODE_RM_WORD_REGISTER(rl); 9701 DECODE_PRINTF(",1\n"); 9702 TRACE_AND_STEP(); 9703 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 9704 *destreg = destval; 9705 } 9706 break; 9707 } 9708 DECODE_CLEAR_SEGOVR(); 9709 END_OF_INSTR(); 9710} 9711 9712/**************************************************************************** 9713REMARKS: 9714Handles opcode 0xd2 9715****************************************************************************/ 9716static void 9717x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 9718{ 9719 int mod, rl, rh; 9720 u8 *destreg; 9721 uint destoffset; 9722 u8 destval; 9723 u8 amt; 9724 9725 /* 9726 * Yet another weirdo special case instruction format. Part of 9727 * the opcode held below in "RH". Doubly nested case would 9728 * result, except that the decoded instruction 9729 */ 9730 START_OF_INSTR(); 9731 FETCH_DECODE_MODRM(mod, rh, rl); 9732#ifdef DEBUG 9733 if (DEBUG_DECODE()) { 9734 /* XXX DECODE_PRINTF may be changed to something more 9735 general, so that it is important to leave the strings 9736 in the same format, even though the result is that the 9737 above test is done twice. */ 9738 switch (rh) { 9739 case 0: 9740 DECODE_PRINTF("ROL\t"); 9741 break; 9742 case 1: 9743 DECODE_PRINTF("ROR\t"); 9744 break; 9745 case 2: 9746 DECODE_PRINTF("RCL\t"); 9747 break; 9748 case 3: 9749 DECODE_PRINTF("RCR\t"); 9750 break; 9751 case 4: 9752 DECODE_PRINTF("SHL\t"); 9753 break; 9754 case 5: 9755 DECODE_PRINTF("SHR\t"); 9756 break; 9757 case 6: 9758 DECODE_PRINTF("SAL\t"); 9759 break; 9760 case 7: 9761 DECODE_PRINTF("SAR\t"); 9762 break; 9763 } 9764 } 9765#endif 9766 /* know operation, decode the mod byte to find the addressing 9767 mode. */ 9768 amt = M.x86.R_CL; 9769 switch (mod) { 9770 case 0: 9771 DECODE_PRINTF("BYTE PTR "); 9772 destoffset = decode_rm00_address(rl); 9773 DECODE_PRINTF(",CL\n"); 9774 destval = fetch_data_byte(destoffset); 9775 TRACE_AND_STEP(); 9776 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9777 store_data_byte(destoffset, destval); 9778 break; 9779 case 1: 9780 DECODE_PRINTF("BYTE PTR "); 9781 destoffset = decode_rm01_address(rl); 9782 DECODE_PRINTF(",CL\n"); 9783 destval = fetch_data_byte(destoffset); 9784 TRACE_AND_STEP(); 9785 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9786 store_data_byte(destoffset, destval); 9787 break; 9788 case 2: 9789 DECODE_PRINTF("BYTE PTR "); 9790 destoffset = decode_rm10_address(rl); 9791 DECODE_PRINTF(",CL\n"); 9792 destval = fetch_data_byte(destoffset); 9793 TRACE_AND_STEP(); 9794 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9795 store_data_byte(destoffset, destval); 9796 break; 9797 case 3: /* register to register */ 9798 destreg = DECODE_RM_BYTE_REGISTER(rl); 9799 DECODE_PRINTF(",CL\n"); 9800 TRACE_AND_STEP(); 9801 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 9802 *destreg = destval; 9803 break; 9804 } 9805 DECODE_CLEAR_SEGOVR(); 9806 END_OF_INSTR(); 9807} 9808 9809/**************************************************************************** 9810REMARKS: 9811Handles opcode 0xd3 9812****************************************************************************/ 9813static void 9814x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 9815{ 9816 int mod, rl, rh; 9817 uint destoffset; 9818 u8 amt; 9819 9820 /* 9821 * Yet another weirdo special case instruction format. Part of 9822 * the opcode held below in "RH". Doubly nested case would 9823 * result, except that the decoded instruction 9824 */ 9825 START_OF_INSTR(); 9826 FETCH_DECODE_MODRM(mod, rh, rl); 9827#ifdef DEBUG 9828 if (DEBUG_DECODE()) { 9829 /* XXX DECODE_PRINTF may be changed to something more 9830 general, so that it is important to leave the strings 9831 in the same format, even though the result is that the 9832 above test is done twice. */ 9833 switch (rh) { 9834 case 0: 9835 DECODE_PRINTF("ROL\t"); 9836 break; 9837 case 1: 9838 DECODE_PRINTF("ROR\t"); 9839 break; 9840 case 2: 9841 DECODE_PRINTF("RCL\t"); 9842 break; 9843 case 3: 9844 DECODE_PRINTF("RCR\t"); 9845 break; 9846 case 4: 9847 DECODE_PRINTF("SHL\t"); 9848 break; 9849 case 5: 9850 DECODE_PRINTF("SHR\t"); 9851 break; 9852 case 6: 9853 DECODE_PRINTF("SAL\t"); 9854 break; 9855 case 7: 9856 DECODE_PRINTF("SAR\t"); 9857 break; 9858 } 9859 } 9860#endif 9861 /* know operation, decode the mod byte to find the addressing 9862 mode. */ 9863 amt = M.x86.R_CL; 9864 switch (mod) { 9865 case 0: 9866 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9867 u32 destval; 9868 9869 DECODE_PRINTF("DWORD PTR "); 9870 destoffset = decode_rm00_address(rl); 9871 DECODE_PRINTF(",CL\n"); 9872 destval = fetch_data_long(destoffset); 9873 TRACE_AND_STEP(); 9874 destval = (*opcD1_long_operation[rh]) (destval, amt); 9875 store_data_long(destoffset, destval); 9876 } 9877 else { 9878 u16 destval; 9879 9880 DECODE_PRINTF("WORD PTR "); 9881 destoffset = decode_rm00_address(rl); 9882 DECODE_PRINTF(",CL\n"); 9883 destval = fetch_data_word(destoffset); 9884 TRACE_AND_STEP(); 9885 destval = (*opcD1_word_operation[rh]) (destval, amt); 9886 store_data_word(destoffset, destval); 9887 } 9888 break; 9889 case 1: 9890 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9891 u32 destval; 9892 9893 DECODE_PRINTF("DWORD PTR "); 9894 destoffset = decode_rm01_address(rl); 9895 DECODE_PRINTF(",CL\n"); 9896 destval = fetch_data_long(destoffset); 9897 TRACE_AND_STEP(); 9898 destval = (*opcD1_long_operation[rh]) (destval, amt); 9899 store_data_long(destoffset, destval); 9900 } 9901 else { 9902 u16 destval; 9903 9904 DECODE_PRINTF("WORD PTR "); 9905 destoffset = decode_rm01_address(rl); 9906 DECODE_PRINTF(",CL\n"); 9907 destval = fetch_data_word(destoffset); 9908 TRACE_AND_STEP(); 9909 destval = (*opcD1_word_operation[rh]) (destval, amt); 9910 store_data_word(destoffset, destval); 9911 } 9912 break; 9913 case 2: 9914 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9915 u32 destval; 9916 9917 DECODE_PRINTF("DWORD PTR "); 9918 destoffset = decode_rm10_address(rl); 9919 DECODE_PRINTF(",CL\n"); 9920 destval = fetch_data_long(destoffset); 9921 TRACE_AND_STEP(); 9922 destval = (*opcD1_long_operation[rh]) (destval, amt); 9923 store_data_long(destoffset, destval); 9924 } 9925 else { 9926 u16 destval; 9927 9928 DECODE_PRINTF("WORD PTR "); 9929 destoffset = decode_rm10_address(rl); 9930 DECODE_PRINTF(",CL\n"); 9931 destval = fetch_data_word(destoffset); 9932 TRACE_AND_STEP(); 9933 destval = (*opcD1_word_operation[rh]) (destval, amt); 9934 store_data_word(destoffset, destval); 9935 } 9936 break; 9937 case 3: /* register to register */ 9938 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9939 u32 *destreg; 9940 9941 destreg = DECODE_RM_LONG_REGISTER(rl); 9942 DECODE_PRINTF(",CL\n"); 9943 TRACE_AND_STEP(); 9944 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 9945 } 9946 else { 9947 u16 *destreg; 9948 9949 destreg = DECODE_RM_WORD_REGISTER(rl); 9950 DECODE_PRINTF(",CL\n"); 9951 TRACE_AND_STEP(); 9952 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 9953 } 9954 break; 9955 } 9956 DECODE_CLEAR_SEGOVR(); 9957 END_OF_INSTR(); 9958} 9959 9960/**************************************************************************** 9961REMARKS: 9962Handles opcode 0xd4 9963****************************************************************************/ 9964static void 9965x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 9966{ 9967 u8 a; 9968 9969 START_OF_INSTR(); 9970 DECODE_PRINTF("AAM\n"); 9971 a = fetch_byte_imm(); /* this is a stupid encoding. */ 9972 if (a != 10) { 9973 /* fix: add base decoding 9974 aam_word(u8 val, int base a) */ 9975 DECODE_PRINTF("ERROR DECODING AAM\n"); 9976 TRACE_REGS(); 9977 HALT_SYS(); 9978 } 9979 TRACE_AND_STEP(); 9980 /* note the type change here --- returning AL and AH in AX. */ 9981 M.x86.R_AX = aam_word(M.x86.R_AL); 9982 DECODE_CLEAR_SEGOVR(); 9983 END_OF_INSTR(); 9984} 9985 9986/**************************************************************************** 9987REMARKS: 9988Handles opcode 0xd5 9989****************************************************************************/ 9990static void 9991x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 9992{ 9993 u8 a; 9994 9995 START_OF_INSTR(); 9996 DECODE_PRINTF("AAD\n"); 9997 a = fetch_byte_imm(); 9998 if (a != 10) { 9999 /* fix: add base decoding 10000 aad_word(u16 val, int base a) */ 10001 DECODE_PRINTF("ERROR DECODING AAM\n"); 10002 TRACE_REGS(); 10003 HALT_SYS(); 10004 } 10005 TRACE_AND_STEP(); 10006 M.x86.R_AX = aad_word(M.x86.R_AX); 10007 DECODE_CLEAR_SEGOVR(); 10008 END_OF_INSTR(); 10009} 10010 10011/* opcode 0xd6 ILLEGAL OPCODE */ 10012 10013/**************************************************************************** 10014REMARKS: 10015Handles opcode 0xd7 10016****************************************************************************/ 10017static void 10018x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 10019{ 10020 u16 addr; 10021 10022 START_OF_INSTR(); 10023 DECODE_PRINTF("XLAT\n"); 10024 TRACE_AND_STEP(); 10025 addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL); 10026 M.x86.R_AL = fetch_data_byte(addr); 10027 DECODE_CLEAR_SEGOVR(); 10028 END_OF_INSTR(); 10029} 10030 10031/* instuctions D8 .. DF are in i87_ops.c */ 10032 10033/**************************************************************************** 10034REMARKS: 10035Handles opcode 0xe0 10036****************************************************************************/ 10037static void 10038x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 10039{ 10040 s16 ip; 10041 10042 START_OF_INSTR(); 10043 DECODE_PRINTF("LOOPNE\t"); 10044 ip = (s8) fetch_byte_imm(); 10045 ip += (s16) M.x86.R_IP; 10046 DECODE_PRINTF2("%04x\n", ip); 10047 TRACE_AND_STEP(); 10048 M.x86.R_CX -= 1; 10049 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 10050 M.x86.R_IP = ip; 10051 DECODE_CLEAR_SEGOVR(); 10052 END_OF_INSTR(); 10053} 10054 10055/**************************************************************************** 10056REMARKS: 10057Handles opcode 0xe1 10058****************************************************************************/ 10059static void 10060x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 10061{ 10062 s16 ip; 10063 10064 START_OF_INSTR(); 10065 DECODE_PRINTF("LOOPE\t"); 10066 ip = (s8) fetch_byte_imm(); 10067 ip += (s16) M.x86.R_IP; 10068 DECODE_PRINTF2("%04x\n", ip); 10069 TRACE_AND_STEP(); 10070 M.x86.R_CX -= 1; 10071 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 10072 M.x86.R_IP = ip; 10073 DECODE_CLEAR_SEGOVR(); 10074 END_OF_INSTR(); 10075} 10076 10077/**************************************************************************** 10078REMARKS: 10079Handles opcode 0xe2 10080****************************************************************************/ 10081static void 10082x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 10083{ 10084 s16 ip; 10085 10086 START_OF_INSTR(); 10087 DECODE_PRINTF("LOOP\t"); 10088 ip = (s8) fetch_byte_imm(); 10089 ip += (s16) M.x86.R_IP; 10090 DECODE_PRINTF2("%04x\n", ip); 10091 TRACE_AND_STEP(); 10092 M.x86.R_CX -= 1; 10093 if (M.x86.R_CX != 0) 10094 M.x86.R_IP = ip; 10095 DECODE_CLEAR_SEGOVR(); 10096 END_OF_INSTR(); 10097} 10098 10099/**************************************************************************** 10100REMARKS: 10101Handles opcode 0xe3 10102****************************************************************************/ 10103static void 10104x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 10105{ 10106 u16 target; 10107 s8 offset; 10108 10109 /* jump to byte offset if overflow flag is set */ 10110 START_OF_INSTR(); 10111 DECODE_PRINTF("JCXZ\t"); 10112 offset = (s8) fetch_byte_imm(); 10113 target = (u16) (M.x86.R_IP + offset); 10114 DECODE_PRINTF2("%x\n", target); 10115 TRACE_AND_STEP(); 10116 if (M.x86.R_CX == 0) 10117 M.x86.R_IP = target; 10118 DECODE_CLEAR_SEGOVR(); 10119 END_OF_INSTR(); 10120} 10121 10122/**************************************************************************** 10123REMARKS: 10124Handles opcode 0xe4 10125****************************************************************************/ 10126static void 10127x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 10128{ 10129 u8 port; 10130 10131 START_OF_INSTR(); 10132 DECODE_PRINTF("IN\t"); 10133 port = (u8) fetch_byte_imm(); 10134 DECODE_PRINTF2("%x,AL\n", port); 10135 TRACE_AND_STEP(); 10136 M.x86.R_AL = (*sys_inb) (port); 10137 DECODE_CLEAR_SEGOVR(); 10138 END_OF_INSTR(); 10139} 10140 10141/**************************************************************************** 10142REMARKS: 10143Handles opcode 0xe5 10144****************************************************************************/ 10145static void 10146x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 10147{ 10148 u8 port; 10149 10150 START_OF_INSTR(); 10151 DECODE_PRINTF("IN\t"); 10152 port = (u8) fetch_byte_imm(); 10153 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10154 DECODE_PRINTF2("EAX,%x\n", port); 10155 } 10156 else { 10157 DECODE_PRINTF2("AX,%x\n", port); 10158 } 10159 TRACE_AND_STEP(); 10160 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10161 M.x86.R_EAX = (*sys_inl) (port); 10162 } 10163 else { 10164 M.x86.R_AX = (*sys_inw) (port); 10165 } 10166 DECODE_CLEAR_SEGOVR(); 10167 END_OF_INSTR(); 10168} 10169 10170/**************************************************************************** 10171REMARKS: 10172Handles opcode 0xe6 10173****************************************************************************/ 10174static void 10175x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 10176{ 10177 u8 port; 10178 10179 START_OF_INSTR(); 10180 DECODE_PRINTF("OUT\t"); 10181 port = (u8) fetch_byte_imm(); 10182 DECODE_PRINTF2("%x,AL\n", port); 10183 TRACE_AND_STEP(); 10184 (*sys_outb) (port, M.x86.R_AL); 10185 DECODE_CLEAR_SEGOVR(); 10186 END_OF_INSTR(); 10187} 10188 10189/**************************************************************************** 10190REMARKS: 10191Handles opcode 0xe7 10192****************************************************************************/ 10193static void 10194x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 10195{ 10196 u8 port; 10197 10198 START_OF_INSTR(); 10199 DECODE_PRINTF("OUT\t"); 10200 port = (u8) fetch_byte_imm(); 10201 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10202 DECODE_PRINTF2("%x,EAX\n", port); 10203 } 10204 else { 10205 DECODE_PRINTF2("%x,AX\n", port); 10206 } 10207 TRACE_AND_STEP(); 10208 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10209 (*sys_outl) (port, M.x86.R_EAX); 10210 } 10211 else { 10212 (*sys_outw) (port, M.x86.R_AX); 10213 } 10214 DECODE_CLEAR_SEGOVR(); 10215 END_OF_INSTR(); 10216} 10217 10218/**************************************************************************** 10219REMARKS: 10220Handles opcode 0xe8 10221****************************************************************************/ 10222static void 10223x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 10224{ 10225 s16 ip16 = 0; 10226 s32 ip32 = 0; 10227 10228 START_OF_INSTR(); 10229 DECODE_PRINTF("CALL\t"); 10230 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10231 ip32 = (s32) fetch_long_imm(); 10232 ip32 += (s16) M.x86.R_IP; /* CHECK SIGN */ 10233 DECODE_PRINTF2("%04x\n", (u16) ip32); 10234 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, ""); 10235 } 10236 else { 10237 ip16 = (s16) fetch_word_imm(); 10238 ip16 += (s16) M.x86.R_IP; /* CHECK SIGN */ 10239 DECODE_PRINTF2("%04x\n", (u16) ip16); 10240 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, ""); 10241 } 10242 TRACE_AND_STEP(); 10243 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10244 push_long(M.x86.R_EIP); 10245 M.x86.R_EIP = ip32 & 0xffff; 10246 } 10247 else { 10248 push_word(M.x86.R_IP); 10249 M.x86.R_EIP = ip16; 10250 } 10251 DECODE_CLEAR_SEGOVR(); 10252 END_OF_INSTR(); 10253} 10254 10255/**************************************************************************** 10256REMARKS: 10257Handles opcode 0xe9 10258****************************************************************************/ 10259static void 10260x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 10261{ 10262 u32 ip; 10263 10264 START_OF_INSTR(); 10265 DECODE_PRINTF("JMP\t"); 10266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10267 ip = (u32) fetch_long_imm(); 10268 ip += (u32) M.x86.R_EIP; 10269 DECODE_PRINTF2("%08x\n", (u32) ip); 10270 TRACE_AND_STEP(); 10271 M.x86.R_EIP = (u32) ip; 10272 } 10273 else { 10274 ip = (s16) fetch_word_imm(); 10275 ip += (s16) M.x86.R_IP; 10276 DECODE_PRINTF2("%04x\n", (u16) ip); 10277 TRACE_AND_STEP(); 10278 M.x86.R_IP = (u16) ip; 10279 } 10280 DECODE_CLEAR_SEGOVR(); 10281 END_OF_INSTR(); 10282} 10283 10284/**************************************************************************** 10285REMARKS: 10286Handles opcode 0xea 10287****************************************************************************/ 10288static void 10289x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 10290{ 10291 u16 cs; 10292 u32 ip; 10293 10294 START_OF_INSTR(); 10295 DECODE_PRINTF("JMP\tFAR "); 10296 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10297 ip = fetch_long_imm(); 10298 } 10299 else { 10300 ip = fetch_word_imm(); 10301 } 10302 cs = fetch_word_imm(); 10303 DECODE_PRINTF2("%04x:", cs); 10304 DECODE_PRINTF2("%04x\n", ip); 10305 TRACE_AND_STEP(); 10306 M.x86.R_EIP = ip & 0xffff; 10307 M.x86.R_CS = cs; 10308 DECODE_CLEAR_SEGOVR(); 10309 END_OF_INSTR(); 10310} 10311 10312/**************************************************************************** 10313REMARKS: 10314Handles opcode 0xeb 10315****************************************************************************/ 10316static void 10317x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 10318{ 10319 u16 target; 10320 s8 offset; 10321 10322 START_OF_INSTR(); 10323 DECODE_PRINTF("JMP\t"); 10324 offset = (s8) fetch_byte_imm(); 10325 target = (u16) (M.x86.R_IP + offset); 10326 DECODE_PRINTF2("%x\n", target); 10327 TRACE_AND_STEP(); 10328 M.x86.R_IP = target; 10329 DECODE_CLEAR_SEGOVR(); 10330 END_OF_INSTR(); 10331} 10332 10333/**************************************************************************** 10334REMARKS: 10335Handles opcode 0xec 10336****************************************************************************/ 10337static void 10338x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 10339{ 10340 START_OF_INSTR(); 10341 DECODE_PRINTF("IN\tAL,DX\n"); 10342 TRACE_AND_STEP(); 10343 M.x86.R_AL = (*sys_inb) (M.x86.R_DX); 10344 DECODE_CLEAR_SEGOVR(); 10345 END_OF_INSTR(); 10346} 10347 10348/**************************************************************************** 10349REMARKS: 10350Handles opcode 0xed 10351****************************************************************************/ 10352static void 10353x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 10354{ 10355 START_OF_INSTR(); 10356 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10357 DECODE_PRINTF("IN\tEAX,DX\n"); 10358 } 10359 else { 10360 DECODE_PRINTF("IN\tAX,DX\n"); 10361 } 10362 TRACE_AND_STEP(); 10363 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10364 M.x86.R_EAX = (*sys_inl) (M.x86.R_DX); 10365 } 10366 else { 10367 M.x86.R_AX = (*sys_inw) (M.x86.R_DX); 10368 } 10369 DECODE_CLEAR_SEGOVR(); 10370 END_OF_INSTR(); 10371} 10372 10373/**************************************************************************** 10374REMARKS: 10375Handles opcode 0xee 10376****************************************************************************/ 10377static void 10378x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 10379{ 10380 START_OF_INSTR(); 10381 DECODE_PRINTF("OUT\tDX,AL\n"); 10382 TRACE_AND_STEP(); 10383 (*sys_outb) (M.x86.R_DX, M.x86.R_AL); 10384 DECODE_CLEAR_SEGOVR(); 10385 END_OF_INSTR(); 10386} 10387 10388/**************************************************************************** 10389REMARKS: 10390Handles opcode 0xef 10391****************************************************************************/ 10392static void 10393x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 10394{ 10395 START_OF_INSTR(); 10396 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10397 DECODE_PRINTF("OUT\tDX,EAX\n"); 10398 } 10399 else { 10400 DECODE_PRINTF("OUT\tDX,AX\n"); 10401 } 10402 TRACE_AND_STEP(); 10403 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10404 (*sys_outl) (M.x86.R_DX, M.x86.R_EAX); 10405 } 10406 else { 10407 (*sys_outw) (M.x86.R_DX, M.x86.R_AX); 10408 } 10409 DECODE_CLEAR_SEGOVR(); 10410 END_OF_INSTR(); 10411} 10412 10413/**************************************************************************** 10414REMARKS: 10415Handles opcode 0xf0 10416****************************************************************************/ 10417static void 10418x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 10419{ 10420 START_OF_INSTR(); 10421 DECODE_PRINTF("LOCK:\n"); 10422 TRACE_AND_STEP(); 10423 DECODE_CLEAR_SEGOVR(); 10424 END_OF_INSTR(); 10425} 10426 10427/*opcode 0xf1 ILLEGAL OPERATION */ 10428 10429/**************************************************************************** 10430REMARKS: 10431Handles opcode 0xf2 10432****************************************************************************/ 10433static void 10434x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 10435{ 10436 START_OF_INSTR(); 10437 DECODE_PRINTF("REPNE\n"); 10438 TRACE_AND_STEP(); 10439 M.x86.mode |= SYSMODE_PREFIX_REPNE; 10440 DECODE_CLEAR_SEGOVR(); 10441 END_OF_INSTR(); 10442} 10443 10444/**************************************************************************** 10445REMARKS: 10446Handles opcode 0xf3 10447****************************************************************************/ 10448static void 10449x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 10450{ 10451 START_OF_INSTR(); 10452 DECODE_PRINTF("REPE\n"); 10453 TRACE_AND_STEP(); 10454 M.x86.mode |= SYSMODE_PREFIX_REPE; 10455 DECODE_CLEAR_SEGOVR(); 10456 END_OF_INSTR(); 10457} 10458 10459/**************************************************************************** 10460REMARKS: 10461Handles opcode 0xf4 10462****************************************************************************/ 10463static void 10464x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 10465{ 10466 START_OF_INSTR(); 10467 DECODE_PRINTF("HALT\n"); 10468 TRACE_AND_STEP(); 10469 HALT_SYS(); 10470 DECODE_CLEAR_SEGOVR(); 10471 END_OF_INSTR(); 10472} 10473 10474/**************************************************************************** 10475REMARKS: 10476Handles opcode 0xf5 10477****************************************************************************/ 10478static void 10479x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 10480{ 10481 /* complement the carry flag. */ 10482 START_OF_INSTR(); 10483 DECODE_PRINTF("CMC\n"); 10484 TRACE_AND_STEP(); 10485 TOGGLE_FLAG(F_CF); 10486 DECODE_CLEAR_SEGOVR(); 10487 END_OF_INSTR(); 10488} 10489 10490/**************************************************************************** 10491REMARKS: 10492Handles opcode 0xf6 10493****************************************************************************/ 10494static void 10495x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 10496{ 10497 int mod, rl, rh; 10498 u8 *destreg; 10499 uint destoffset; 10500 u8 destval, srcval; 10501 10502 /* long, drawn out code follows. Double switch for a total 10503 of 32 cases. */ 10504 START_OF_INSTR(); 10505 FETCH_DECODE_MODRM(mod, rh, rl); 10506 switch (mod) { 10507 case 0: /* mod=00 */ 10508 switch (rh) { 10509 case 0: /* test byte imm */ 10510 DECODE_PRINTF("TEST\tBYTE PTR "); 10511 destoffset = decode_rm00_address(rl); 10512 DECODE_PRINTF(","); 10513 srcval = fetch_byte_imm(); 10514 DECODE_PRINTF2("%02x\n", srcval); 10515 destval = fetch_data_byte(destoffset); 10516 TRACE_AND_STEP(); 10517 test_byte(destval, srcval); 10518 break; 10519 case 1: 10520 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10521 HALT_SYS(); 10522 break; 10523 case 2: 10524 DECODE_PRINTF("NOT\tBYTE PTR "); 10525 destoffset = decode_rm00_address(rl); 10526 DECODE_PRINTF("\n"); 10527 destval = fetch_data_byte(destoffset); 10528 TRACE_AND_STEP(); 10529 destval = not_byte(destval); 10530 store_data_byte(destoffset, destval); 10531 break; 10532 case 3: 10533 DECODE_PRINTF("NEG\tBYTE PTR "); 10534 destoffset = decode_rm00_address(rl); 10535 DECODE_PRINTF("\n"); 10536 destval = fetch_data_byte(destoffset); 10537 TRACE_AND_STEP(); 10538 destval = neg_byte(destval); 10539 store_data_byte(destoffset, destval); 10540 break; 10541 case 4: 10542 DECODE_PRINTF("MUL\tBYTE PTR "); 10543 destoffset = decode_rm00_address(rl); 10544 DECODE_PRINTF("\n"); 10545 destval = fetch_data_byte(destoffset); 10546 TRACE_AND_STEP(); 10547 mul_byte(destval); 10548 break; 10549 case 5: 10550 DECODE_PRINTF("IMUL\tBYTE PTR "); 10551 destoffset = decode_rm00_address(rl); 10552 DECODE_PRINTF("\n"); 10553 destval = fetch_data_byte(destoffset); 10554 TRACE_AND_STEP(); 10555 imul_byte(destval); 10556 break; 10557 case 6: 10558 DECODE_PRINTF("DIV\tBYTE PTR "); 10559 destoffset = decode_rm00_address(rl); 10560 DECODE_PRINTF("\n"); 10561 destval = fetch_data_byte(destoffset); 10562 TRACE_AND_STEP(); 10563 div_byte(destval); 10564 break; 10565 case 7: 10566 DECODE_PRINTF("IDIV\tBYTE PTR "); 10567 destoffset = decode_rm00_address(rl); 10568 DECODE_PRINTF("\n"); 10569 destval = fetch_data_byte(destoffset); 10570 TRACE_AND_STEP(); 10571 idiv_byte(destval); 10572 break; 10573 } 10574 break; /* end mod==00 */ 10575 case 1: /* mod=01 */ 10576 switch (rh) { 10577 case 0: /* test byte imm */ 10578 DECODE_PRINTF("TEST\tBYTE PTR "); 10579 destoffset = decode_rm01_address(rl); 10580 DECODE_PRINTF(","); 10581 srcval = fetch_byte_imm(); 10582 DECODE_PRINTF2("%02x\n", srcval); 10583 destval = fetch_data_byte(destoffset); 10584 TRACE_AND_STEP(); 10585 test_byte(destval, srcval); 10586 break; 10587 case 1: 10588 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10589 HALT_SYS(); 10590 break; 10591 case 2: 10592 DECODE_PRINTF("NOT\tBYTE PTR "); 10593 destoffset = decode_rm01_address(rl); 10594 DECODE_PRINTF("\n"); 10595 destval = fetch_data_byte(destoffset); 10596 TRACE_AND_STEP(); 10597 destval = not_byte(destval); 10598 store_data_byte(destoffset, destval); 10599 break; 10600 case 3: 10601 DECODE_PRINTF("NEG\tBYTE PTR "); 10602 destoffset = decode_rm01_address(rl); 10603 DECODE_PRINTF("\n"); 10604 destval = fetch_data_byte(destoffset); 10605 TRACE_AND_STEP(); 10606 destval = neg_byte(destval); 10607 store_data_byte(destoffset, destval); 10608 break; 10609 case 4: 10610 DECODE_PRINTF("MUL\tBYTE PTR "); 10611 destoffset = decode_rm01_address(rl); 10612 DECODE_PRINTF("\n"); 10613 destval = fetch_data_byte(destoffset); 10614 TRACE_AND_STEP(); 10615 mul_byte(destval); 10616 break; 10617 case 5: 10618 DECODE_PRINTF("IMUL\tBYTE PTR "); 10619 destoffset = decode_rm01_address(rl); 10620 DECODE_PRINTF("\n"); 10621 destval = fetch_data_byte(destoffset); 10622 TRACE_AND_STEP(); 10623 imul_byte(destval); 10624 break; 10625 case 6: 10626 DECODE_PRINTF("DIV\tBYTE PTR "); 10627 destoffset = decode_rm01_address(rl); 10628 DECODE_PRINTF("\n"); 10629 destval = fetch_data_byte(destoffset); 10630 TRACE_AND_STEP(); 10631 div_byte(destval); 10632 break; 10633 case 7: 10634 DECODE_PRINTF("IDIV\tBYTE PTR "); 10635 destoffset = decode_rm01_address(rl); 10636 DECODE_PRINTF("\n"); 10637 destval = fetch_data_byte(destoffset); 10638 TRACE_AND_STEP(); 10639 idiv_byte(destval); 10640 break; 10641 } 10642 break; /* end mod==01 */ 10643 case 2: /* mod=10 */ 10644 switch (rh) { 10645 case 0: /* test byte imm */ 10646 DECODE_PRINTF("TEST\tBYTE PTR "); 10647 destoffset = decode_rm10_address(rl); 10648 DECODE_PRINTF(","); 10649 srcval = fetch_byte_imm(); 10650 DECODE_PRINTF2("%02x\n", srcval); 10651 destval = fetch_data_byte(destoffset); 10652 TRACE_AND_STEP(); 10653 test_byte(destval, srcval); 10654 break; 10655 case 1: 10656 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10657 HALT_SYS(); 10658 break; 10659 case 2: 10660 DECODE_PRINTF("NOT\tBYTE PTR "); 10661 destoffset = decode_rm10_address(rl); 10662 DECODE_PRINTF("\n"); 10663 destval = fetch_data_byte(destoffset); 10664 TRACE_AND_STEP(); 10665 destval = not_byte(destval); 10666 store_data_byte(destoffset, destval); 10667 break; 10668 case 3: 10669 DECODE_PRINTF("NEG\tBYTE PTR "); 10670 destoffset = decode_rm10_address(rl); 10671 DECODE_PRINTF("\n"); 10672 destval = fetch_data_byte(destoffset); 10673 TRACE_AND_STEP(); 10674 destval = neg_byte(destval); 10675 store_data_byte(destoffset, destval); 10676 break; 10677 case 4: 10678 DECODE_PRINTF("MUL\tBYTE PTR "); 10679 destoffset = decode_rm10_address(rl); 10680 DECODE_PRINTF("\n"); 10681 destval = fetch_data_byte(destoffset); 10682 TRACE_AND_STEP(); 10683 mul_byte(destval); 10684 break; 10685 case 5: 10686 DECODE_PRINTF("IMUL\tBYTE PTR "); 10687 destoffset = decode_rm10_address(rl); 10688 DECODE_PRINTF("\n"); 10689 destval = fetch_data_byte(destoffset); 10690 TRACE_AND_STEP(); 10691 imul_byte(destval); 10692 break; 10693 case 6: 10694 DECODE_PRINTF("DIV\tBYTE PTR "); 10695 destoffset = decode_rm10_address(rl); 10696 DECODE_PRINTF("\n"); 10697 destval = fetch_data_byte(destoffset); 10698 TRACE_AND_STEP(); 10699 div_byte(destval); 10700 break; 10701 case 7: 10702 DECODE_PRINTF("IDIV\tBYTE PTR "); 10703 destoffset = decode_rm10_address(rl); 10704 DECODE_PRINTF("\n"); 10705 destval = fetch_data_byte(destoffset); 10706 TRACE_AND_STEP(); 10707 idiv_byte(destval); 10708 break; 10709 } 10710 break; /* end mod==10 */ 10711 case 3: /* mod=11 */ 10712 switch (rh) { 10713 case 0: /* test byte imm */ 10714 DECODE_PRINTF("TEST\t"); 10715 destreg = DECODE_RM_BYTE_REGISTER(rl); 10716 DECODE_PRINTF(","); 10717 srcval = fetch_byte_imm(); 10718 DECODE_PRINTF2("%02x\n", srcval); 10719 TRACE_AND_STEP(); 10720 test_byte(*destreg, srcval); 10721 break; 10722 case 1: 10723 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10724 HALT_SYS(); 10725 break; 10726 case 2: 10727 DECODE_PRINTF("NOT\t"); 10728 destreg = DECODE_RM_BYTE_REGISTER(rl); 10729 DECODE_PRINTF("\n"); 10730 TRACE_AND_STEP(); 10731 *destreg = not_byte(*destreg); 10732 break; 10733 case 3: 10734 DECODE_PRINTF("NEG\t"); 10735 destreg = DECODE_RM_BYTE_REGISTER(rl); 10736 DECODE_PRINTF("\n"); 10737 TRACE_AND_STEP(); 10738 *destreg = neg_byte(*destreg); 10739 break; 10740 case 4: 10741 DECODE_PRINTF("MUL\t"); 10742 destreg = DECODE_RM_BYTE_REGISTER(rl); 10743 DECODE_PRINTF("\n"); 10744 TRACE_AND_STEP(); 10745 mul_byte(*destreg); /*!!! */ 10746 break; 10747 case 5: 10748 DECODE_PRINTF("IMUL\t"); 10749 destreg = DECODE_RM_BYTE_REGISTER(rl); 10750 DECODE_PRINTF("\n"); 10751 TRACE_AND_STEP(); 10752 imul_byte(*destreg); 10753 break; 10754 case 6: 10755 DECODE_PRINTF("DIV\t"); 10756 destreg = DECODE_RM_BYTE_REGISTER(rl); 10757 DECODE_PRINTF("\n"); 10758 TRACE_AND_STEP(); 10759 div_byte(*destreg); 10760 break; 10761 case 7: 10762 DECODE_PRINTF("IDIV\t"); 10763 destreg = DECODE_RM_BYTE_REGISTER(rl); 10764 DECODE_PRINTF("\n"); 10765 TRACE_AND_STEP(); 10766 idiv_byte(*destreg); 10767 break; 10768 } 10769 break; /* end mod==11 */ 10770 } 10771 DECODE_CLEAR_SEGOVR(); 10772 END_OF_INSTR(); 10773} 10774 10775/**************************************************************************** 10776REMARKS: 10777Handles opcode 0xf7 10778****************************************************************************/ 10779static void 10780x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 10781{ 10782 int mod, rl, rh; 10783 uint destoffset; 10784 10785 /* long, drawn out code follows. Double switch for a total 10786 of 32 cases. */ 10787 START_OF_INSTR(); 10788 FETCH_DECODE_MODRM(mod, rh, rl); 10789 switch (mod) { 10790 case 0: /* mod=00 */ 10791 switch (rh) { 10792 case 0: /* test word imm */ 10793 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10794 u32 destval, srcval; 10795 10796 DECODE_PRINTF("TEST\tDWORD PTR "); 10797 destoffset = decode_rm00_address(rl); 10798 DECODE_PRINTF(","); 10799 srcval = fetch_long_imm(); 10800 DECODE_PRINTF2("%x\n", srcval); 10801 destval = fetch_data_long(destoffset); 10802 TRACE_AND_STEP(); 10803 test_long(destval, srcval); 10804 } 10805 else { 10806 u16 destval, srcval; 10807 10808 DECODE_PRINTF("TEST\tWORD PTR "); 10809 destoffset = decode_rm00_address(rl); 10810 DECODE_PRINTF(","); 10811 srcval = fetch_word_imm(); 10812 DECODE_PRINTF2("%x\n", srcval); 10813 destval = fetch_data_word(destoffset); 10814 TRACE_AND_STEP(); 10815 test_word(destval, srcval); 10816 } 10817 break; 10818 case 1: 10819 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 10820 HALT_SYS(); 10821 break; 10822 case 2: 10823 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10824 u32 destval; 10825 10826 DECODE_PRINTF("NOT\tDWORD PTR "); 10827 destoffset = decode_rm00_address(rl); 10828 DECODE_PRINTF("\n"); 10829 destval = fetch_data_long(destoffset); 10830 TRACE_AND_STEP(); 10831 destval = not_long(destval); 10832 store_data_long(destoffset, destval); 10833 } 10834 else { 10835 u16 destval; 10836 10837 DECODE_PRINTF("NOT\tWORD PTR "); 10838 destoffset = decode_rm00_address(rl); 10839 DECODE_PRINTF("\n"); 10840 destval = fetch_data_word(destoffset); 10841 TRACE_AND_STEP(); 10842 destval = not_word(destval); 10843 store_data_word(destoffset, destval); 10844 } 10845 break; 10846 case 3: 10847 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10848 u32 destval; 10849 10850 DECODE_PRINTF("NEG\tDWORD PTR "); 10851 destoffset = decode_rm00_address(rl); 10852 DECODE_PRINTF("\n"); 10853 destval = fetch_data_long(destoffset); 10854 TRACE_AND_STEP(); 10855 destval = neg_long(destval); 10856 store_data_long(destoffset, destval); 10857 } 10858 else { 10859 u16 destval; 10860 10861 DECODE_PRINTF("NEG\tWORD PTR "); 10862 destoffset = decode_rm00_address(rl); 10863 DECODE_PRINTF("\n"); 10864 destval = fetch_data_word(destoffset); 10865 TRACE_AND_STEP(); 10866 destval = neg_word(destval); 10867 store_data_word(destoffset, destval); 10868 } 10869 break; 10870 case 4: 10871 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10872 u32 destval; 10873 10874 DECODE_PRINTF("MUL\tDWORD PTR "); 10875 destoffset = decode_rm00_address(rl); 10876 DECODE_PRINTF("\n"); 10877 destval = fetch_data_long(destoffset); 10878 TRACE_AND_STEP(); 10879 mul_long(destval); 10880 } 10881 else { 10882 u16 destval; 10883 10884 DECODE_PRINTF("MUL\tWORD PTR "); 10885 destoffset = decode_rm00_address(rl); 10886 DECODE_PRINTF("\n"); 10887 destval = fetch_data_word(destoffset); 10888 TRACE_AND_STEP(); 10889 mul_word(destval); 10890 } 10891 break; 10892 case 5: 10893 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10894 u32 destval; 10895 10896 DECODE_PRINTF("IMUL\tDWORD PTR "); 10897 destoffset = decode_rm00_address(rl); 10898 DECODE_PRINTF("\n"); 10899 destval = fetch_data_long(destoffset); 10900 TRACE_AND_STEP(); 10901 imul_long(destval); 10902 } 10903 else { 10904 u16 destval; 10905 10906 DECODE_PRINTF("IMUL\tWORD PTR "); 10907 destoffset = decode_rm00_address(rl); 10908 DECODE_PRINTF("\n"); 10909 destval = fetch_data_word(destoffset); 10910 TRACE_AND_STEP(); 10911 imul_word(destval); 10912 } 10913 break; 10914 case 6: 10915 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10916 u32 destval; 10917 10918 DECODE_PRINTF("DIV\tDWORD PTR "); 10919 destoffset = decode_rm00_address(rl); 10920 DECODE_PRINTF("\n"); 10921 destval = fetch_data_long(destoffset); 10922 TRACE_AND_STEP(); 10923 div_long(destval); 10924 } 10925 else { 10926 u16 destval; 10927 10928 DECODE_PRINTF("DIV\tWORD PTR "); 10929 destoffset = decode_rm00_address(rl); 10930 DECODE_PRINTF("\n"); 10931 destval = fetch_data_word(destoffset); 10932 TRACE_AND_STEP(); 10933 div_word(destval); 10934 } 10935 break; 10936 case 7: 10937 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10938 u32 destval; 10939 10940 DECODE_PRINTF("IDIV\tDWORD PTR "); 10941 destoffset = decode_rm00_address(rl); 10942 DECODE_PRINTF("\n"); 10943 destval = fetch_data_long(destoffset); 10944 TRACE_AND_STEP(); 10945 idiv_long(destval); 10946 } 10947 else { 10948 u16 destval; 10949 10950 DECODE_PRINTF("IDIV\tWORD PTR "); 10951 destoffset = decode_rm00_address(rl); 10952 DECODE_PRINTF("\n"); 10953 destval = fetch_data_word(destoffset); 10954 TRACE_AND_STEP(); 10955 idiv_word(destval); 10956 } 10957 break; 10958 } 10959 break; /* end mod==00 */ 10960 case 1: /* mod=01 */ 10961 switch (rh) { 10962 case 0: /* test word imm */ 10963 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10964 u32 destval, srcval; 10965 10966 DECODE_PRINTF("TEST\tDWORD PTR "); 10967 destoffset = decode_rm01_address(rl); 10968 DECODE_PRINTF(","); 10969 srcval = fetch_long_imm(); 10970 DECODE_PRINTF2("%x\n", srcval); 10971 destval = fetch_data_long(destoffset); 10972 TRACE_AND_STEP(); 10973 test_long(destval, srcval); 10974 } 10975 else { 10976 u16 destval, srcval; 10977 10978 DECODE_PRINTF("TEST\tWORD PTR "); 10979 destoffset = decode_rm01_address(rl); 10980 DECODE_PRINTF(","); 10981 srcval = fetch_word_imm(); 10982 DECODE_PRINTF2("%x\n", srcval); 10983 destval = fetch_data_word(destoffset); 10984 TRACE_AND_STEP(); 10985 test_word(destval, srcval); 10986 } 10987 break; 10988 case 1: 10989 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10990 HALT_SYS(); 10991 break; 10992 case 2: 10993 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10994 u32 destval; 10995 10996 DECODE_PRINTF("NOT\tDWORD PTR "); 10997 destoffset = decode_rm01_address(rl); 10998 DECODE_PRINTF("\n"); 10999 destval = fetch_data_long(destoffset); 11000 TRACE_AND_STEP(); 11001 destval = not_long(destval); 11002 store_data_long(destoffset, destval); 11003 } 11004 else { 11005 u16 destval; 11006 11007 DECODE_PRINTF("NOT\tWORD PTR "); 11008 destoffset = decode_rm01_address(rl); 11009 DECODE_PRINTF("\n"); 11010 destval = fetch_data_word(destoffset); 11011 TRACE_AND_STEP(); 11012 destval = not_word(destval); 11013 store_data_word(destoffset, destval); 11014 } 11015 break; 11016 case 3: 11017 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11018 u32 destval; 11019 11020 DECODE_PRINTF("NEG\tDWORD PTR "); 11021 destoffset = decode_rm01_address(rl); 11022 DECODE_PRINTF("\n"); 11023 destval = fetch_data_long(destoffset); 11024 TRACE_AND_STEP(); 11025 destval = neg_long(destval); 11026 store_data_long(destoffset, destval); 11027 } 11028 else { 11029 u16 destval; 11030 11031 DECODE_PRINTF("NEG\tWORD PTR "); 11032 destoffset = decode_rm01_address(rl); 11033 DECODE_PRINTF("\n"); 11034 destval = fetch_data_word(destoffset); 11035 TRACE_AND_STEP(); 11036 destval = neg_word(destval); 11037 store_data_word(destoffset, destval); 11038 } 11039 break; 11040 case 4: 11041 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11042 u32 destval; 11043 11044 DECODE_PRINTF("MUL\tDWORD PTR "); 11045 destoffset = decode_rm01_address(rl); 11046 DECODE_PRINTF("\n"); 11047 destval = fetch_data_long(destoffset); 11048 TRACE_AND_STEP(); 11049 mul_long(destval); 11050 } 11051 else { 11052 u16 destval; 11053 11054 DECODE_PRINTF("MUL\tWORD PTR "); 11055 destoffset = decode_rm01_address(rl); 11056 DECODE_PRINTF("\n"); 11057 destval = fetch_data_word(destoffset); 11058 TRACE_AND_STEP(); 11059 mul_word(destval); 11060 } 11061 break; 11062 case 5: 11063 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11064 u32 destval; 11065 11066 DECODE_PRINTF("IMUL\tDWORD PTR "); 11067 destoffset = decode_rm01_address(rl); 11068 DECODE_PRINTF("\n"); 11069 destval = fetch_data_long(destoffset); 11070 TRACE_AND_STEP(); 11071 imul_long(destval); 11072 } 11073 else { 11074 u16 destval; 11075 11076 DECODE_PRINTF("IMUL\tWORD PTR "); 11077 destoffset = decode_rm01_address(rl); 11078 DECODE_PRINTF("\n"); 11079 destval = fetch_data_word(destoffset); 11080 TRACE_AND_STEP(); 11081 imul_word(destval); 11082 } 11083 break; 11084 case 6: 11085 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11086 u32 destval; 11087 11088 DECODE_PRINTF("DIV\tDWORD PTR "); 11089 destoffset = decode_rm01_address(rl); 11090 DECODE_PRINTF("\n"); 11091 destval = fetch_data_long(destoffset); 11092 TRACE_AND_STEP(); 11093 div_long(destval); 11094 } 11095 else { 11096 u16 destval; 11097 11098 DECODE_PRINTF("DIV\tWORD PTR "); 11099 destoffset = decode_rm01_address(rl); 11100 DECODE_PRINTF("\n"); 11101 destval = fetch_data_word(destoffset); 11102 TRACE_AND_STEP(); 11103 div_word(destval); 11104 } 11105 break; 11106 case 7: 11107 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11108 u32 destval; 11109 11110 DECODE_PRINTF("IDIV\tDWORD PTR "); 11111 destoffset = decode_rm01_address(rl); 11112 DECODE_PRINTF("\n"); 11113 destval = fetch_data_long(destoffset); 11114 TRACE_AND_STEP(); 11115 idiv_long(destval); 11116 } 11117 else { 11118 u16 destval; 11119 11120 DECODE_PRINTF("IDIV\tWORD PTR "); 11121 destoffset = decode_rm01_address(rl); 11122 DECODE_PRINTF("\n"); 11123 destval = fetch_data_word(destoffset); 11124 TRACE_AND_STEP(); 11125 idiv_word(destval); 11126 } 11127 break; 11128 } 11129 break; /* end mod==01 */ 11130 case 2: /* mod=10 */ 11131 switch (rh) { 11132 case 0: /* test word imm */ 11133 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11134 u32 destval, srcval; 11135 11136 DECODE_PRINTF("TEST\tDWORD PTR "); 11137 destoffset = decode_rm10_address(rl); 11138 DECODE_PRINTF(","); 11139 srcval = fetch_long_imm(); 11140 DECODE_PRINTF2("%x\n", srcval); 11141 destval = fetch_data_long(destoffset); 11142 TRACE_AND_STEP(); 11143 test_long(destval, srcval); 11144 } 11145 else { 11146 u16 destval, srcval; 11147 11148 DECODE_PRINTF("TEST\tWORD PTR "); 11149 destoffset = decode_rm10_address(rl); 11150 DECODE_PRINTF(","); 11151 srcval = fetch_word_imm(); 11152 DECODE_PRINTF2("%x\n", srcval); 11153 destval = fetch_data_word(destoffset); 11154 TRACE_AND_STEP(); 11155 test_word(destval, srcval); 11156 } 11157 break; 11158 case 1: 11159 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 11160 HALT_SYS(); 11161 break; 11162 case 2: 11163 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11164 u32 destval; 11165 11166 DECODE_PRINTF("NOT\tDWORD PTR "); 11167 destoffset = decode_rm10_address(rl); 11168 DECODE_PRINTF("\n"); 11169 destval = fetch_data_long(destoffset); 11170 TRACE_AND_STEP(); 11171 destval = not_long(destval); 11172 store_data_long(destoffset, destval); 11173 } 11174 else { 11175 u16 destval; 11176 11177 DECODE_PRINTF("NOT\tWORD PTR "); 11178 destoffset = decode_rm10_address(rl); 11179 DECODE_PRINTF("\n"); 11180 destval = fetch_data_word(destoffset); 11181 TRACE_AND_STEP(); 11182 destval = not_word(destval); 11183 store_data_word(destoffset, destval); 11184 } 11185 break; 11186 case 3: 11187 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11188 u32 destval; 11189 11190 DECODE_PRINTF("NEG\tDWORD PTR "); 11191 destoffset = decode_rm10_address(rl); 11192 DECODE_PRINTF("\n"); 11193 destval = fetch_data_long(destoffset); 11194 TRACE_AND_STEP(); 11195 destval = neg_long(destval); 11196 store_data_long(destoffset, destval); 11197 } 11198 else { 11199 u16 destval; 11200 11201 DECODE_PRINTF("NEG\tWORD PTR "); 11202 destoffset = decode_rm10_address(rl); 11203 DECODE_PRINTF("\n"); 11204 destval = fetch_data_word(destoffset); 11205 TRACE_AND_STEP(); 11206 destval = neg_word(destval); 11207 store_data_word(destoffset, destval); 11208 } 11209 break; 11210 case 4: 11211 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11212 u32 destval; 11213 11214 DECODE_PRINTF("MUL\tDWORD PTR "); 11215 destoffset = decode_rm10_address(rl); 11216 DECODE_PRINTF("\n"); 11217 destval = fetch_data_long(destoffset); 11218 TRACE_AND_STEP(); 11219 mul_long(destval); 11220 } 11221 else { 11222 u16 destval; 11223 11224 DECODE_PRINTF("MUL\tWORD PTR "); 11225 destoffset = decode_rm10_address(rl); 11226 DECODE_PRINTF("\n"); 11227 destval = fetch_data_word(destoffset); 11228 TRACE_AND_STEP(); 11229 mul_word(destval); 11230 } 11231 break; 11232 case 5: 11233 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11234 u32 destval; 11235 11236 DECODE_PRINTF("IMUL\tDWORD PTR "); 11237 destoffset = decode_rm10_address(rl); 11238 DECODE_PRINTF("\n"); 11239 destval = fetch_data_long(destoffset); 11240 TRACE_AND_STEP(); 11241 imul_long(destval); 11242 } 11243 else { 11244 u16 destval; 11245 11246 DECODE_PRINTF("IMUL\tWORD PTR "); 11247 destoffset = decode_rm10_address(rl); 11248 DECODE_PRINTF("\n"); 11249 destval = fetch_data_word(destoffset); 11250 TRACE_AND_STEP(); 11251 imul_word(destval); 11252 } 11253 break; 11254 case 6: 11255 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11256 u32 destval; 11257 11258 DECODE_PRINTF("DIV\tDWORD PTR "); 11259 destoffset = decode_rm10_address(rl); 11260 DECODE_PRINTF("\n"); 11261 destval = fetch_data_long(destoffset); 11262 TRACE_AND_STEP(); 11263 div_long(destval); 11264 } 11265 else { 11266 u16 destval; 11267 11268 DECODE_PRINTF("DIV\tWORD PTR "); 11269 destoffset = decode_rm10_address(rl); 11270 DECODE_PRINTF("\n"); 11271 destval = fetch_data_word(destoffset); 11272 TRACE_AND_STEP(); 11273 div_word(destval); 11274 } 11275 break; 11276 case 7: 11277 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11278 u32 destval; 11279 11280 DECODE_PRINTF("IDIV\tDWORD PTR "); 11281 destoffset = decode_rm10_address(rl); 11282 DECODE_PRINTF("\n"); 11283 destval = fetch_data_long(destoffset); 11284 TRACE_AND_STEP(); 11285 idiv_long(destval); 11286 } 11287 else { 11288 u16 destval; 11289 11290 DECODE_PRINTF("IDIV\tWORD PTR "); 11291 destoffset = decode_rm10_address(rl); 11292 DECODE_PRINTF("\n"); 11293 destval = fetch_data_word(destoffset); 11294 TRACE_AND_STEP(); 11295 idiv_word(destval); 11296 } 11297 break; 11298 } 11299 break; /* end mod==10 */ 11300 case 3: /* mod=11 */ 11301 switch (rh) { 11302 case 0: /* test word imm */ 11303 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11304 u32 *destreg; 11305 u32 srcval; 11306 11307 DECODE_PRINTF("TEST\t"); 11308 destreg = DECODE_RM_LONG_REGISTER(rl); 11309 DECODE_PRINTF(","); 11310 srcval = fetch_long_imm(); 11311 DECODE_PRINTF2("%x\n", srcval); 11312 TRACE_AND_STEP(); 11313 test_long(*destreg, srcval); 11314 } 11315 else { 11316 u16 *destreg; 11317 u16 srcval; 11318 11319 DECODE_PRINTF("TEST\t"); 11320 destreg = DECODE_RM_WORD_REGISTER(rl); 11321 DECODE_PRINTF(","); 11322 srcval = fetch_word_imm(); 11323 DECODE_PRINTF2("%x\n", srcval); 11324 TRACE_AND_STEP(); 11325 test_word(*destreg, srcval); 11326 } 11327 break; 11328 case 1: 11329 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 11330 HALT_SYS(); 11331 break; 11332 case 2: 11333 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11334 u32 *destreg; 11335 11336 DECODE_PRINTF("NOT\t"); 11337 destreg = DECODE_RM_LONG_REGISTER(rl); 11338 DECODE_PRINTF("\n"); 11339 TRACE_AND_STEP(); 11340 *destreg = not_long(*destreg); 11341 } 11342 else { 11343 u16 *destreg; 11344 11345 DECODE_PRINTF("NOT\t"); 11346 destreg = DECODE_RM_WORD_REGISTER(rl); 11347 DECODE_PRINTF("\n"); 11348 TRACE_AND_STEP(); 11349 *destreg = not_word(*destreg); 11350 } 11351 break; 11352 case 3: 11353 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11354 u32 *destreg; 11355 11356 DECODE_PRINTF("NEG\t"); 11357 destreg = DECODE_RM_LONG_REGISTER(rl); 11358 DECODE_PRINTF("\n"); 11359 TRACE_AND_STEP(); 11360 *destreg = neg_long(*destreg); 11361 } 11362 else { 11363 u16 *destreg; 11364 11365 DECODE_PRINTF("NEG\t"); 11366 destreg = DECODE_RM_WORD_REGISTER(rl); 11367 DECODE_PRINTF("\n"); 11368 TRACE_AND_STEP(); 11369 *destreg = neg_word(*destreg); 11370 } 11371 break; 11372 case 4: 11373 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11374 u32 *destreg; 11375 11376 DECODE_PRINTF("MUL\t"); 11377 destreg = DECODE_RM_LONG_REGISTER(rl); 11378 DECODE_PRINTF("\n"); 11379 TRACE_AND_STEP(); 11380 mul_long(*destreg); /*!!! */ 11381 } 11382 else { 11383 u16 *destreg; 11384 11385 DECODE_PRINTF("MUL\t"); 11386 destreg = DECODE_RM_WORD_REGISTER(rl); 11387 DECODE_PRINTF("\n"); 11388 TRACE_AND_STEP(); 11389 mul_word(*destreg); /*!!! */ 11390 } 11391 break; 11392 case 5: 11393 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11394 u32 *destreg; 11395 11396 DECODE_PRINTF("IMUL\t"); 11397 destreg = DECODE_RM_LONG_REGISTER(rl); 11398 DECODE_PRINTF("\n"); 11399 TRACE_AND_STEP(); 11400 imul_long(*destreg); 11401 } 11402 else { 11403 u16 *destreg; 11404 11405 DECODE_PRINTF("IMUL\t"); 11406 destreg = DECODE_RM_WORD_REGISTER(rl); 11407 DECODE_PRINTF("\n"); 11408 TRACE_AND_STEP(); 11409 imul_word(*destreg); 11410 } 11411 break; 11412 case 6: 11413 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11414 u32 *destreg; 11415 11416 DECODE_PRINTF("DIV\t"); 11417 destreg = DECODE_RM_LONG_REGISTER(rl); 11418 DECODE_PRINTF("\n"); 11419 TRACE_AND_STEP(); 11420 div_long(*destreg); 11421 } 11422 else { 11423 u16 *destreg; 11424 11425 DECODE_PRINTF("DIV\t"); 11426 destreg = DECODE_RM_WORD_REGISTER(rl); 11427 DECODE_PRINTF("\n"); 11428 TRACE_AND_STEP(); 11429 div_word(*destreg); 11430 } 11431 break; 11432 case 7: 11433 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11434 u32 *destreg; 11435 11436 DECODE_PRINTF("IDIV\t"); 11437 destreg = DECODE_RM_LONG_REGISTER(rl); 11438 DECODE_PRINTF("\n"); 11439 TRACE_AND_STEP(); 11440 idiv_long(*destreg); 11441 } 11442 else { 11443 u16 *destreg; 11444 11445 DECODE_PRINTF("IDIV\t"); 11446 destreg = DECODE_RM_WORD_REGISTER(rl); 11447 DECODE_PRINTF("\n"); 11448 TRACE_AND_STEP(); 11449 idiv_word(*destreg); 11450 } 11451 break; 11452 } 11453 break; /* end mod==11 */ 11454 } 11455 DECODE_CLEAR_SEGOVR(); 11456 END_OF_INSTR(); 11457} 11458 11459/**************************************************************************** 11460REMARKS: 11461Handles opcode 0xf8 11462****************************************************************************/ 11463static void 11464x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 11465{ 11466 /* clear the carry flag. */ 11467 START_OF_INSTR(); 11468 DECODE_PRINTF("CLC\n"); 11469 TRACE_AND_STEP(); 11470 CLEAR_FLAG(F_CF); 11471 DECODE_CLEAR_SEGOVR(); 11472 END_OF_INSTR(); 11473} 11474 11475/**************************************************************************** 11476REMARKS: 11477Handles opcode 0xf9 11478****************************************************************************/ 11479static void 11480x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 11481{ 11482 /* set the carry flag. */ 11483 START_OF_INSTR(); 11484 DECODE_PRINTF("STC\n"); 11485 TRACE_AND_STEP(); 11486 SET_FLAG(F_CF); 11487 DECODE_CLEAR_SEGOVR(); 11488 END_OF_INSTR(); 11489} 11490 11491/**************************************************************************** 11492REMARKS: 11493Handles opcode 0xfa 11494****************************************************************************/ 11495static void 11496x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 11497{ 11498 /* clear interrupts. */ 11499 START_OF_INSTR(); 11500 DECODE_PRINTF("CLI\n"); 11501 TRACE_AND_STEP(); 11502 CLEAR_FLAG(F_IF); 11503 DECODE_CLEAR_SEGOVR(); 11504 END_OF_INSTR(); 11505} 11506 11507/**************************************************************************** 11508REMARKS: 11509Handles opcode 0xfb 11510****************************************************************************/ 11511static void 11512x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 11513{ 11514 /* enable interrupts. */ 11515 START_OF_INSTR(); 11516 DECODE_PRINTF("STI\n"); 11517 TRACE_AND_STEP(); 11518 SET_FLAG(F_IF); 11519 DECODE_CLEAR_SEGOVR(); 11520 END_OF_INSTR(); 11521} 11522 11523/**************************************************************************** 11524REMARKS: 11525Handles opcode 0xfc 11526****************************************************************************/ 11527static void 11528x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 11529{ 11530 /* clear interrupts. */ 11531 START_OF_INSTR(); 11532 DECODE_PRINTF("CLD\n"); 11533 TRACE_AND_STEP(); 11534 CLEAR_FLAG(F_DF); 11535 DECODE_CLEAR_SEGOVR(); 11536 END_OF_INSTR(); 11537} 11538 11539/**************************************************************************** 11540REMARKS: 11541Handles opcode 0xfd 11542****************************************************************************/ 11543static void 11544x86emuOp_std(u8 X86EMU_UNUSED(op1)) 11545{ 11546 /* clear interrupts. */ 11547 START_OF_INSTR(); 11548 DECODE_PRINTF("STD\n"); 11549 TRACE_AND_STEP(); 11550 SET_FLAG(F_DF); 11551 DECODE_CLEAR_SEGOVR(); 11552 END_OF_INSTR(); 11553} 11554 11555/**************************************************************************** 11556REMARKS: 11557Handles opcode 0xfe 11558****************************************************************************/ 11559static void 11560x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 11561{ 11562 int mod, rh, rl; 11563 u8 destval; 11564 uint destoffset; 11565 u8 *destreg; 11566 11567 /* Yet another special case instruction. */ 11568 START_OF_INSTR(); 11569 FETCH_DECODE_MODRM(mod, rh, rl); 11570#ifdef DEBUG 11571 if (DEBUG_DECODE()) { 11572 /* XXX DECODE_PRINTF may be changed to something more 11573 general, so that it is important to leave the strings 11574 in the same format, even though the result is that the 11575 above test is done twice. */ 11576 11577 switch (rh) { 11578 case 0: 11579 DECODE_PRINTF("INC\t"); 11580 break; 11581 case 1: 11582 DECODE_PRINTF("DEC\t"); 11583 break; 11584 case 2: 11585 case 3: 11586 case 4: 11587 case 5: 11588 case 6: 11589 case 7: 11590 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 11591 HALT_SYS(); 11592 break; 11593 } 11594 } 11595#endif 11596 switch (mod) { 11597 case 0: 11598 DECODE_PRINTF("BYTE PTR "); 11599 destoffset = decode_rm00_address(rl); 11600 DECODE_PRINTF("\n"); 11601 switch (rh) { 11602 case 0: /* inc word ptr ... */ 11603 destval = fetch_data_byte(destoffset); 11604 TRACE_AND_STEP(); 11605 destval = inc_byte(destval); 11606 store_data_byte(destoffset, destval); 11607 break; 11608 case 1: /* dec word ptr ... */ 11609 destval = fetch_data_byte(destoffset); 11610 TRACE_AND_STEP(); 11611 destval = dec_byte(destval); 11612 store_data_byte(destoffset, destval); 11613 break; 11614 } 11615 break; 11616 case 1: 11617 DECODE_PRINTF("BYTE PTR "); 11618 destoffset = decode_rm01_address(rl); 11619 DECODE_PRINTF("\n"); 11620 switch (rh) { 11621 case 0: 11622 destval = fetch_data_byte(destoffset); 11623 TRACE_AND_STEP(); 11624 destval = inc_byte(destval); 11625 store_data_byte(destoffset, destval); 11626 break; 11627 case 1: 11628 destval = fetch_data_byte(destoffset); 11629 TRACE_AND_STEP(); 11630 destval = dec_byte(destval); 11631 store_data_byte(destoffset, destval); 11632 break; 11633 } 11634 break; 11635 case 2: 11636 DECODE_PRINTF("BYTE PTR "); 11637 destoffset = decode_rm10_address(rl); 11638 DECODE_PRINTF("\n"); 11639 switch (rh) { 11640 case 0: 11641 destval = fetch_data_byte(destoffset); 11642 TRACE_AND_STEP(); 11643 destval = inc_byte(destval); 11644 store_data_byte(destoffset, destval); 11645 break; 11646 case 1: 11647 destval = fetch_data_byte(destoffset); 11648 TRACE_AND_STEP(); 11649 destval = dec_byte(destval); 11650 store_data_byte(destoffset, destval); 11651 break; 11652 } 11653 break; 11654 case 3: 11655 destreg = DECODE_RM_BYTE_REGISTER(rl); 11656 DECODE_PRINTF("\n"); 11657 switch (rh) { 11658 case 0: 11659 TRACE_AND_STEP(); 11660 *destreg = inc_byte(*destreg); 11661 break; 11662 case 1: 11663 TRACE_AND_STEP(); 11664 *destreg = dec_byte(*destreg); 11665 break; 11666 } 11667 break; 11668 } 11669 DECODE_CLEAR_SEGOVR(); 11670 END_OF_INSTR(); 11671} 11672 11673/**************************************************************************** 11674REMARKS: 11675Handles opcode 0xff 11676****************************************************************************/ 11677static void 11678x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 11679{ 11680 int mod, rh, rl; 11681 uint destoffset = 0; 11682 u16 *destreg; 11683 u16 destval, destval2; 11684 11685 /* Yet another special case instruction. */ 11686 START_OF_INSTR(); 11687 FETCH_DECODE_MODRM(mod, rh, rl); 11688#ifdef DEBUG 11689 if (DEBUG_DECODE()) { 11690 /* XXX DECODE_PRINTF may be changed to something more 11691 general, so that it is important to leave the strings 11692 in the same format, even though the result is that the 11693 above test is done twice. */ 11694 11695 switch (rh) { 11696 case 0: 11697 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11698 DECODE_PRINTF("INC\tDWORD PTR "); 11699 } 11700 else { 11701 DECODE_PRINTF("INC\tWORD PTR "); 11702 } 11703 break; 11704 case 1: 11705 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11706 DECODE_PRINTF("DEC\tDWORD PTR "); 11707 } 11708 else { 11709 DECODE_PRINTF("DEC\tWORD PTR "); 11710 } 11711 break; 11712 case 2: 11713 DECODE_PRINTF("CALL\t"); 11714 break; 11715 case 3: 11716 DECODE_PRINTF("CALL\tFAR "); 11717 break; 11718 case 4: 11719 DECODE_PRINTF("JMP\t"); 11720 break; 11721 case 5: 11722 DECODE_PRINTF("JMP\tFAR "); 11723 break; 11724 case 6: 11725 DECODE_PRINTF("PUSH\t"); 11726 break; 11727 case 7: 11728 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 11729 HALT_SYS(); 11730 break; 11731 } 11732 } 11733#endif 11734 switch (mod) { 11735 case 0: 11736 destoffset = decode_rm00_address(rl); 11737 DECODE_PRINTF("\n"); 11738 switch (rh) { 11739 case 0: /* inc word ptr ... */ 11740 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11741 u32 destval32; 11742 11743 destval32 = fetch_data_long(destoffset); 11744 TRACE_AND_STEP(); 11745 destval32 = inc_long(destval32); 11746 store_data_long(destoffset, destval32); 11747 } 11748 else { 11749 u16 destval16; 11750 11751 destval16 = fetch_data_word(destoffset); 11752 TRACE_AND_STEP(); 11753 destval16 = inc_word(destval16); 11754 store_data_word(destoffset, destval16); 11755 } 11756 break; 11757 case 1: /* dec word ptr ... */ 11758 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11759 u32 destval32; 11760 11761 destval32 = fetch_data_long(destoffset); 11762 TRACE_AND_STEP(); 11763 destval32 = dec_long(destval32); 11764 store_data_long(destoffset, destval32); 11765 } 11766 else { 11767 u16 destval16; 11768 11769 destval16 = fetch_data_word(destoffset); 11770 TRACE_AND_STEP(); 11771 destval16 = dec_word(destval16); 11772 store_data_word(destoffset, destval16); 11773 } 11774 break; 11775 case 2: /* call word ptr ... */ 11776 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11777 destval = fetch_data_long(destoffset); 11778 TRACE_AND_STEP(); 11779 push_long(M.x86.R_EIP); 11780 M.x86.R_EIP = destval; 11781 } else { 11782 destval = fetch_data_word(destoffset); 11783 TRACE_AND_STEP(); 11784 push_word(M.x86.R_IP); 11785 M.x86.R_IP = destval; 11786 } 11787 break; 11788 case 3: /* call far ptr ... */ 11789 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11790 destval = fetch_data_long(destoffset); 11791 destval2 = fetch_data_word(destoffset + 4); 11792 TRACE_AND_STEP(); 11793 push_long(M.x86.R_CS); 11794 M.x86.R_CS = destval2; 11795 push_long(M.x86.R_EIP); 11796 M.x86.R_EIP = destval; 11797 } else { 11798 destval = fetch_data_word(destoffset); 11799 destval2 = fetch_data_word(destoffset + 2); 11800 TRACE_AND_STEP(); 11801 push_word(M.x86.R_CS); 11802 M.x86.R_CS = destval2; 11803 push_word(M.x86.R_IP); 11804 M.x86.R_IP = destval; 11805 } 11806 break; 11807 case 4: /* jmp word ptr ... */ 11808 destval = fetch_data_word(destoffset); 11809 TRACE_AND_STEP(); 11810 M.x86.R_IP = destval; 11811 break; 11812 case 5: /* jmp far ptr ... */ 11813 destval = fetch_data_word(destoffset); 11814 destval2 = fetch_data_word(destoffset + 2); 11815 TRACE_AND_STEP(); 11816 M.x86.R_IP = destval; 11817 M.x86.R_CS = destval2; 11818 break; 11819 case 6: /* push word ptr ... */ 11820 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11821 u32 destval32; 11822 11823 destval32 = fetch_data_long(destoffset); 11824 TRACE_AND_STEP(); 11825 push_long(destval32); 11826 } 11827 else { 11828 u16 destval16; 11829 11830 destval16 = fetch_data_word(destoffset); 11831 TRACE_AND_STEP(); 11832 push_word(destval16); 11833 } 11834 break; 11835 } 11836 break; 11837 case 1: 11838 destoffset = decode_rm01_address(rl); 11839 DECODE_PRINTF("\n"); 11840 switch (rh) { 11841 case 0: 11842 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11843 u32 destval32; 11844 11845 destval32 = fetch_data_long(destoffset); 11846 TRACE_AND_STEP(); 11847 destval32 = inc_long(destval32); 11848 store_data_long(destoffset, destval32); 11849 } 11850 else { 11851 u16 destval16; 11852 11853 destval16 = fetch_data_word(destoffset); 11854 TRACE_AND_STEP(); 11855 destval16 = inc_word(destval16); 11856 store_data_word(destoffset, destval16); 11857 } 11858 break; 11859 case 1: 11860 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11861 u32 destval32; 11862 11863 destval32 = fetch_data_long(destoffset); 11864 TRACE_AND_STEP(); 11865 destval32 = dec_long(destval32); 11866 store_data_long(destoffset, destval32); 11867 } 11868 else { 11869 u16 destval16; 11870 11871 destval16 = fetch_data_word(destoffset); 11872 TRACE_AND_STEP(); 11873 destval16 = dec_word(destval16); 11874 store_data_word(destoffset, destval16); 11875 } 11876 break; 11877 case 2: /* call word ptr ... */ 11878 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11879 destval = fetch_data_long(destoffset); 11880 TRACE_AND_STEP(); 11881 push_long(M.x86.R_EIP); 11882 M.x86.R_EIP = destval; 11883 } else { 11884 destval = fetch_data_word(destoffset); 11885 TRACE_AND_STEP(); 11886 push_word(M.x86.R_IP); 11887 M.x86.R_IP = destval; 11888 } 11889 break; 11890 case 3: /* call far ptr ... */ 11891 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11892 destval = fetch_data_long(destoffset); 11893 destval2 = fetch_data_word(destoffset + 4); 11894 TRACE_AND_STEP(); 11895 push_long(M.x86.R_CS); 11896 M.x86.R_CS = destval2; 11897 push_long(M.x86.R_EIP); 11898 M.x86.R_EIP = destval; 11899 } else { 11900 destval = fetch_data_word(destoffset); 11901 destval2 = fetch_data_word(destoffset + 2); 11902 TRACE_AND_STEP(); 11903 push_word(M.x86.R_CS); 11904 M.x86.R_CS = destval2; 11905 push_word(M.x86.R_IP); 11906 M.x86.R_IP = destval; 11907 } 11908 break; 11909 case 4: /* jmp word ptr ... */ 11910 destval = fetch_data_word(destoffset); 11911 TRACE_AND_STEP(); 11912 M.x86.R_IP = destval; 11913 break; 11914 case 5: /* jmp far ptr ... */ 11915 destval = fetch_data_word(destoffset); 11916 destval2 = fetch_data_word(destoffset + 2); 11917 TRACE_AND_STEP(); 11918 M.x86.R_IP = destval; 11919 M.x86.R_CS = destval2; 11920 break; 11921 case 6: /* push word ptr ... */ 11922 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11923 u32 destval32; 11924 11925 destval32 = fetch_data_long(destoffset); 11926 TRACE_AND_STEP(); 11927 push_long(destval32); 11928 } 11929 else { 11930 u16 destval16; 11931 11932 destval16 = fetch_data_word(destoffset); 11933 TRACE_AND_STEP(); 11934 push_word(destval16); 11935 } 11936 break; 11937 } 11938 break; 11939 case 2: 11940 destoffset = decode_rm10_address(rl); 11941 DECODE_PRINTF("\n"); 11942 switch (rh) { 11943 case 0: 11944 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11945 u32 destval32; 11946 11947 destval32 = fetch_data_long(destoffset); 11948 TRACE_AND_STEP(); 11949 destval32 = inc_long(destval32); 11950 store_data_long(destoffset, destval32); 11951 } 11952 else { 11953 u16 destval16; 11954 11955 destval16 = fetch_data_word(destoffset); 11956 TRACE_AND_STEP(); 11957 destval16 = inc_word(destval16); 11958 store_data_word(destoffset, destval16); 11959 } 11960 break; 11961 case 1: 11962 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11963 u32 destval32; 11964 11965 destval32 = fetch_data_long(destoffset); 11966 TRACE_AND_STEP(); 11967 destval32 = dec_long(destval32); 11968 store_data_long(destoffset, destval32); 11969 } 11970 else { 11971 u16 destval16; 11972 11973 destval16 = fetch_data_word(destoffset); 11974 TRACE_AND_STEP(); 11975 destval16 = dec_word(destval16); 11976 store_data_word(destoffset, destval16); 11977 } 11978 break; 11979 case 2: /* call word ptr ... */ 11980 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11981 destval = fetch_data_long(destoffset); 11982 TRACE_AND_STEP(); 11983 push_long(M.x86.R_EIP); 11984 M.x86.R_EIP = destval; 11985 } else { 11986 destval = fetch_data_word(destoffset); 11987 TRACE_AND_STEP(); 11988 push_word(M.x86.R_IP); 11989 M.x86.R_IP = destval; 11990 } 11991 break; 11992 case 3: /* call far ptr ... */ 11993 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11994 destval = fetch_data_long(destoffset); 11995 destval2 = fetch_data_word(destoffset + 4); 11996 TRACE_AND_STEP(); 11997 push_long(M.x86.R_CS); 11998 M.x86.R_CS = destval2; 11999 push_long(M.x86.R_EIP); 12000 M.x86.R_EIP = destval; 12001 } else { 12002 destval = fetch_data_word(destoffset); 12003 destval2 = fetch_data_word(destoffset + 2); 12004 TRACE_AND_STEP(); 12005 push_word(M.x86.R_CS); 12006 M.x86.R_CS = destval2; 12007 push_word(M.x86.R_IP); 12008 M.x86.R_IP = destval; 12009 } 12010 break; 12011 case 4: /* jmp word ptr ... */ 12012 destval = fetch_data_word(destoffset); 12013 TRACE_AND_STEP(); 12014 M.x86.R_IP = destval; 12015 break; 12016 case 5: /* jmp far ptr ... */ 12017 destval = fetch_data_word(destoffset); 12018 destval2 = fetch_data_word(destoffset + 2); 12019 TRACE_AND_STEP(); 12020 M.x86.R_IP = destval; 12021 M.x86.R_CS = destval2; 12022 break; 12023 case 6: /* push word ptr ... */ 12024 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 12025 u32 destval32; 12026 12027 destval32 = fetch_data_long(destoffset); 12028 TRACE_AND_STEP(); 12029 push_long(destval32); 12030 } 12031 else { 12032 u16 destval16; 12033 12034 destval16 = fetch_data_word(destoffset); 12035 TRACE_AND_STEP(); 12036 push_word(destval16); 12037 } 12038 break; 12039 } 12040 break; 12041 case 3: 12042 switch (rh) { 12043 case 0: 12044 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 12045 u32 *destreg32; 12046 12047 destreg32 = DECODE_RM_LONG_REGISTER(rl); 12048 DECODE_PRINTF("\n"); 12049 TRACE_AND_STEP(); 12050 *destreg32 = inc_long(*destreg32); 12051 } 12052 else { 12053 u16 *destreg16; 12054 12055 destreg16 = DECODE_RM_WORD_REGISTER(rl); 12056 DECODE_PRINTF("\n"); 12057 TRACE_AND_STEP(); 12058 *destreg16 = inc_word(*destreg16); 12059 } 12060 break; 12061 case 1: 12062 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 12063 u32 *destreg32; 12064 12065 destreg32 = DECODE_RM_LONG_REGISTER(rl); 12066 DECODE_PRINTF("\n"); 12067 TRACE_AND_STEP(); 12068 *destreg32 = dec_long(*destreg32); 12069 } 12070 else { 12071 u16 *destreg16; 12072 12073 destreg16 = DECODE_RM_WORD_REGISTER(rl); 12074 DECODE_PRINTF("\n"); 12075 TRACE_AND_STEP(); 12076 *destreg16 = dec_word(*destreg16); 12077 } 12078 break; 12079 case 2: /* call word ptr ... */ 12080 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 12081 destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl); 12082 DECODE_PRINTF("\n"); 12083 TRACE_AND_STEP(); 12084 push_long(M.x86.R_EIP); 12085 M.x86.R_EIP = *destreg; 12086 } else { 12087 destreg = DECODE_RM_WORD_REGISTER(rl); 12088 DECODE_PRINTF("\n"); 12089 TRACE_AND_STEP(); 12090 push_word(M.x86.R_IP); 12091 M.x86.R_IP = *destreg; 12092 } 12093 break; 12094 case 3: /* jmp far ptr ... */ 12095 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 12096 TRACE_AND_STEP(); 12097 HALT_SYS(); 12098 break; 12099 12100 case 4: /* jmp ... */ 12101 destreg = DECODE_RM_WORD_REGISTER(rl); 12102 DECODE_PRINTF("\n"); 12103 TRACE_AND_STEP(); 12104 M.x86.R_IP = (u16) (*destreg); 12105 break; 12106 case 5: /* jmp far ptr ... */ 12107 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 12108 TRACE_AND_STEP(); 12109 HALT_SYS(); 12110 break; 12111 case 6: 12112 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 12113 u32 *destreg32; 12114 12115 destreg32 = DECODE_RM_LONG_REGISTER(rl); 12116 DECODE_PRINTF("\n"); 12117 TRACE_AND_STEP(); 12118 push_long(*destreg32); 12119 } 12120 else { 12121 u16 *destreg16; 12122 12123 destreg16 = DECODE_RM_WORD_REGISTER(rl); 12124 DECODE_PRINTF("\n"); 12125 TRACE_AND_STEP(); 12126 push_word(*destreg16); 12127 } 12128 break; 12129 } 12130 break; 12131 } 12132 DECODE_CLEAR_SEGOVR(); 12133 END_OF_INSTR(); 12134} 12135 12136/*************************************************************************** 12137 * Single byte operation code table: 12138 **************************************************************************/ 12139void (*x86emu_optab[256]) (u8) = { 12140/* 0x00 */ x86emuOp_add_byte_RM_R, 12141/* 0x01 */ x86emuOp_add_word_RM_R, 12142/* 0x02 */ x86emuOp_add_byte_R_RM, 12143/* 0x03 */ x86emuOp_add_word_R_RM, 12144/* 0x04 */ x86emuOp_add_byte_AL_IMM, 12145/* 0x05 */ x86emuOp_add_word_AX_IMM, 12146/* 0x06 */ x86emuOp_push_ES, 12147/* 0x07 */ x86emuOp_pop_ES, 12148/* 0x08 */ x86emuOp_or_byte_RM_R, 12149/* 0x09 */ x86emuOp_or_word_RM_R, 12150/* 0x0a */ x86emuOp_or_byte_R_RM, 12151/* 0x0b */ x86emuOp_or_word_R_RM, 12152/* 0x0c */ x86emuOp_or_byte_AL_IMM, 12153/* 0x0d */ x86emuOp_or_word_AX_IMM, 12154/* 0x0e */ x86emuOp_push_CS, 12155/* 0x0f */ x86emuOp_two_byte, 12156/* 0x10 */ x86emuOp_adc_byte_RM_R, 12157/* 0x11 */ x86emuOp_adc_word_RM_R, 12158/* 0x12 */ x86emuOp_adc_byte_R_RM, 12159/* 0x13 */ x86emuOp_adc_word_R_RM, 12160/* 0x14 */ x86emuOp_adc_byte_AL_IMM, 12161/* 0x15 */ x86emuOp_adc_word_AX_IMM, 12162/* 0x16 */ x86emuOp_push_SS, 12163/* 0x17 */ x86emuOp_pop_SS, 12164/* 0x18 */ x86emuOp_sbb_byte_RM_R, 12165/* 0x19 */ x86emuOp_sbb_word_RM_R, 12166/* 0x1a */ x86emuOp_sbb_byte_R_RM, 12167/* 0x1b */ x86emuOp_sbb_word_R_RM, 12168/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, 12169/* 0x1d */ x86emuOp_sbb_word_AX_IMM, 12170/* 0x1e */ x86emuOp_push_DS, 12171/* 0x1f */ x86emuOp_pop_DS, 12172/* 0x20 */ x86emuOp_and_byte_RM_R, 12173/* 0x21 */ x86emuOp_and_word_RM_R, 12174/* 0x22 */ x86emuOp_and_byte_R_RM, 12175/* 0x23 */ x86emuOp_and_word_R_RM, 12176/* 0x24 */ x86emuOp_and_byte_AL_IMM, 12177/* 0x25 */ x86emuOp_and_word_AX_IMM, 12178/* 0x26 */ x86emuOp_segovr_ES, 12179/* 0x27 */ x86emuOp_daa, 12180/* 0x28 */ x86emuOp_sub_byte_RM_R, 12181/* 0x29 */ x86emuOp_sub_word_RM_R, 12182/* 0x2a */ x86emuOp_sub_byte_R_RM, 12183/* 0x2b */ x86emuOp_sub_word_R_RM, 12184/* 0x2c */ x86emuOp_sub_byte_AL_IMM, 12185/* 0x2d */ x86emuOp_sub_word_AX_IMM, 12186/* 0x2e */ x86emuOp_segovr_CS, 12187/* 0x2f */ x86emuOp_das, 12188/* 0x30 */ x86emuOp_xor_byte_RM_R, 12189/* 0x31 */ x86emuOp_xor_word_RM_R, 12190/* 0x32 */ x86emuOp_xor_byte_R_RM, 12191/* 0x33 */ x86emuOp_xor_word_R_RM, 12192/* 0x34 */ x86emuOp_xor_byte_AL_IMM, 12193/* 0x35 */ x86emuOp_xor_word_AX_IMM, 12194/* 0x36 */ x86emuOp_segovr_SS, 12195/* 0x37 */ x86emuOp_aaa, 12196/* 0x38 */ x86emuOp_cmp_byte_RM_R, 12197/* 0x39 */ x86emuOp_cmp_word_RM_R, 12198/* 0x3a */ x86emuOp_cmp_byte_R_RM, 12199/* 0x3b */ x86emuOp_cmp_word_R_RM, 12200/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, 12201/* 0x3d */ x86emuOp_cmp_word_AX_IMM, 12202/* 0x3e */ x86emuOp_segovr_DS, 12203/* 0x3f */ x86emuOp_aas, 12204/* 0x40 */ x86emuOp_inc_AX, 12205/* 0x41 */ x86emuOp_inc_CX, 12206/* 0x42 */ x86emuOp_inc_DX, 12207/* 0x43 */ x86emuOp_inc_BX, 12208/* 0x44 */ x86emuOp_inc_SP, 12209/* 0x45 */ x86emuOp_inc_BP, 12210/* 0x46 */ x86emuOp_inc_SI, 12211/* 0x47 */ x86emuOp_inc_DI, 12212/* 0x48 */ x86emuOp_dec_AX, 12213/* 0x49 */ x86emuOp_dec_CX, 12214/* 0x4a */ x86emuOp_dec_DX, 12215/* 0x4b */ x86emuOp_dec_BX, 12216/* 0x4c */ x86emuOp_dec_SP, 12217/* 0x4d */ x86emuOp_dec_BP, 12218/* 0x4e */ x86emuOp_dec_SI, 12219/* 0x4f */ x86emuOp_dec_DI, 12220/* 0x50 */ x86emuOp_push_AX, 12221/* 0x51 */ x86emuOp_push_CX, 12222/* 0x52 */ x86emuOp_push_DX, 12223/* 0x53 */ x86emuOp_push_BX, 12224/* 0x54 */ x86emuOp_push_SP, 12225/* 0x55 */ x86emuOp_push_BP, 12226/* 0x56 */ x86emuOp_push_SI, 12227/* 0x57 */ x86emuOp_push_DI, 12228/* 0x58 */ x86emuOp_pop_AX, 12229/* 0x59 */ x86emuOp_pop_CX, 12230/* 0x5a */ x86emuOp_pop_DX, 12231/* 0x5b */ x86emuOp_pop_BX, 12232/* 0x5c */ x86emuOp_pop_SP, 12233/* 0x5d */ x86emuOp_pop_BP, 12234/* 0x5e */ x86emuOp_pop_SI, 12235/* 0x5f */ x86emuOp_pop_DI, 12236/* 0x60 */ x86emuOp_push_all, 12237/* 0x61 */ x86emuOp_pop_all, 12238 /* 0x62 */ x86emuOp_illegal_op, 12239 /* bound */ 12240 /* 0x63 */ x86emuOp_illegal_op, 12241 /* arpl */ 12242/* 0x64 */ x86emuOp_segovr_FS, 12243/* 0x65 */ x86emuOp_segovr_GS, 12244/* 0x66 */ x86emuOp_prefix_data, 12245/* 0x67 */ x86emuOp_prefix_addr, 12246/* 0x68 */ x86emuOp_push_word_IMM, 12247/* 0x69 */ x86emuOp_imul_word_IMM, 12248/* 0x6a */ x86emuOp_push_byte_IMM, 12249/* 0x6b */ x86emuOp_imul_byte_IMM, 12250/* 0x6c */ x86emuOp_ins_byte, 12251/* 0x6d */ x86emuOp_ins_word, 12252/* 0x6e */ x86emuOp_outs_byte, 12253/* 0x6f */ x86emuOp_outs_word, 12254/* 0x70 */ x86emuOp_jump_near_O, 12255/* 0x71 */ x86emuOp_jump_near_NO, 12256/* 0x72 */ x86emuOp_jump_near_B, 12257/* 0x73 */ x86emuOp_jump_near_NB, 12258/* 0x74 */ x86emuOp_jump_near_Z, 12259/* 0x75 */ x86emuOp_jump_near_NZ, 12260/* 0x76 */ x86emuOp_jump_near_BE, 12261/* 0x77 */ x86emuOp_jump_near_NBE, 12262/* 0x78 */ x86emuOp_jump_near_S, 12263/* 0x79 */ x86emuOp_jump_near_NS, 12264/* 0x7a */ x86emuOp_jump_near_P, 12265/* 0x7b */ x86emuOp_jump_near_NP, 12266/* 0x7c */ x86emuOp_jump_near_L, 12267/* 0x7d */ x86emuOp_jump_near_NL, 12268/* 0x7e */ x86emuOp_jump_near_LE, 12269/* 0x7f */ x86emuOp_jump_near_NLE, 12270/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 12271/* 0x81 */ x86emuOp_opc81_word_RM_IMM, 12272/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 12273/* 0x83 */ x86emuOp_opc83_word_RM_IMM, 12274/* 0x84 */ x86emuOp_test_byte_RM_R, 12275/* 0x85 */ x86emuOp_test_word_RM_R, 12276/* 0x86 */ x86emuOp_xchg_byte_RM_R, 12277/* 0x87 */ x86emuOp_xchg_word_RM_R, 12278/* 0x88 */ x86emuOp_mov_byte_RM_R, 12279/* 0x89 */ x86emuOp_mov_word_RM_R, 12280/* 0x8a */ x86emuOp_mov_byte_R_RM, 12281/* 0x8b */ x86emuOp_mov_word_R_RM, 12282/* 0x8c */ x86emuOp_mov_word_RM_SR, 12283/* 0x8d */ x86emuOp_lea_word_R_M, 12284/* 0x8e */ x86emuOp_mov_word_SR_RM, 12285/* 0x8f */ x86emuOp_pop_RM, 12286/* 0x90 */ x86emuOp_nop, 12287/* 0x91 */ x86emuOp_xchg_word_AX_CX, 12288/* 0x92 */ x86emuOp_xchg_word_AX_DX, 12289/* 0x93 */ x86emuOp_xchg_word_AX_BX, 12290/* 0x94 */ x86emuOp_xchg_word_AX_SP, 12291/* 0x95 */ x86emuOp_xchg_word_AX_BP, 12292/* 0x96 */ x86emuOp_xchg_word_AX_SI, 12293/* 0x97 */ x86emuOp_xchg_word_AX_DI, 12294/* 0x98 */ x86emuOp_cbw, 12295/* 0x99 */ x86emuOp_cwd, 12296/* 0x9a */ x86emuOp_call_far_IMM, 12297/* 0x9b */ x86emuOp_wait, 12298/* 0x9c */ x86emuOp_pushf_word, 12299/* 0x9d */ x86emuOp_popf_word, 12300/* 0x9e */ x86emuOp_sahf, 12301/* 0x9f */ x86emuOp_lahf, 12302/* 0xa0 */ x86emuOp_mov_AL_M_IMM, 12303/* 0xa1 */ x86emuOp_mov_AX_M_IMM, 12304/* 0xa2 */ x86emuOp_mov_M_AL_IMM, 12305/* 0xa3 */ x86emuOp_mov_M_AX_IMM, 12306/* 0xa4 */ x86emuOp_movs_byte, 12307/* 0xa5 */ x86emuOp_movs_word, 12308/* 0xa6 */ x86emuOp_cmps_byte, 12309/* 0xa7 */ x86emuOp_cmps_word, 12310/* 0xa8 */ x86emuOp_test_AL_IMM, 12311/* 0xa9 */ x86emuOp_test_AX_IMM, 12312/* 0xaa */ x86emuOp_stos_byte, 12313/* 0xab */ x86emuOp_stos_word, 12314/* 0xac */ x86emuOp_lods_byte, 12315/* 0xad */ x86emuOp_lods_word, 12316/* 0xac */ x86emuOp_scas_byte, 12317/* 0xad */ x86emuOp_scas_word, 12318/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, 12319/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, 12320/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, 12321/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, 12322/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, 12323/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, 12324/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, 12325/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, 12326/* 0xb8 */ x86emuOp_mov_word_AX_IMM, 12327/* 0xb9 */ x86emuOp_mov_word_CX_IMM, 12328/* 0xba */ x86emuOp_mov_word_DX_IMM, 12329/* 0xbb */ x86emuOp_mov_word_BX_IMM, 12330/* 0xbc */ x86emuOp_mov_word_SP_IMM, 12331/* 0xbd */ x86emuOp_mov_word_BP_IMM, 12332/* 0xbe */ x86emuOp_mov_word_SI_IMM, 12333/* 0xbf */ x86emuOp_mov_word_DI_IMM, 12334/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 12335/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 12336/* 0xc2 */ x86emuOp_ret_near_IMM, 12337/* 0xc3 */ x86emuOp_ret_near, 12338/* 0xc4 */ x86emuOp_les_R_IMM, 12339/* 0xc5 */ x86emuOp_lds_R_IMM, 12340/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 12341/* 0xc7 */ x86emuOp_mov_word_RM_IMM, 12342/* 0xc8 */ x86emuOp_enter, 12343/* 0xc9 */ x86emuOp_leave, 12344/* 0xca */ x86emuOp_ret_far_IMM, 12345/* 0xcb */ x86emuOp_ret_far, 12346/* 0xcc */ x86emuOp_int3, 12347/* 0xcd */ x86emuOp_int_IMM, 12348/* 0xce */ x86emuOp_into, 12349/* 0xcf */ x86emuOp_iret, 12350/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 12351/* 0xd1 */ x86emuOp_opcD1_word_RM_1, 12352/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 12353/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 12354/* 0xd4 */ x86emuOp_aam, 12355/* 0xd5 */ x86emuOp_aad, 12356 /* 0xd6 */ x86emuOp_illegal_op, 12357 /* Undocumented SETALC instruction */ 12358/* 0xd7 */ x86emuOp_xlat, 12359/* 0xd8 */ x86emuOp_esc_coprocess_d8, 12360/* 0xd9 */ x86emuOp_esc_coprocess_d9, 12361/* 0xda */ x86emuOp_esc_coprocess_da, 12362/* 0xdb */ x86emuOp_esc_coprocess_db, 12363/* 0xdc */ x86emuOp_esc_coprocess_dc, 12364/* 0xdd */ x86emuOp_esc_coprocess_dd, 12365/* 0xde */ x86emuOp_esc_coprocess_de, 12366/* 0xdf */ x86emuOp_esc_coprocess_df, 12367/* 0xe0 */ x86emuOp_loopne, 12368/* 0xe1 */ x86emuOp_loope, 12369/* 0xe2 */ x86emuOp_loop, 12370/* 0xe3 */ x86emuOp_jcxz, 12371/* 0xe4 */ x86emuOp_in_byte_AL_IMM, 12372/* 0xe5 */ x86emuOp_in_word_AX_IMM, 12373/* 0xe6 */ x86emuOp_out_byte_IMM_AL, 12374/* 0xe7 */ x86emuOp_out_word_IMM_AX, 12375/* 0xe8 */ x86emuOp_call_near_IMM, 12376/* 0xe9 */ x86emuOp_jump_near_IMM, 12377/* 0xea */ x86emuOp_jump_far_IMM, 12378/* 0xeb */ x86emuOp_jump_byte_IMM, 12379/* 0xec */ x86emuOp_in_byte_AL_DX, 12380/* 0xed */ x86emuOp_in_word_AX_DX, 12381/* 0xee */ x86emuOp_out_byte_DX_AL, 12382/* 0xef */ x86emuOp_out_word_DX_AX, 12383/* 0xf0 */ x86emuOp_lock, 12384/* 0xf1 */ x86emuOp_illegal_op, 12385/* 0xf2 */ x86emuOp_repne, 12386/* 0xf3 */ x86emuOp_repe, 12387/* 0xf4 */ x86emuOp_halt, 12388/* 0xf5 */ x86emuOp_cmc, 12389/* 0xf6 */ x86emuOp_opcF6_byte_RM, 12390/* 0xf7 */ x86emuOp_opcF7_word_RM, 12391/* 0xf8 */ x86emuOp_clc, 12392/* 0xf9 */ x86emuOp_stc, 12393/* 0xfa */ x86emuOp_cli, 12394/* 0xfb */ x86emuOp_sti, 12395/* 0xfc */ x86emuOp_cld, 12396/* 0xfd */ x86emuOp_std, 12397/* 0xfe */ x86emuOp_opcFE_byte_RM, 12398/* 0xff */ x86emuOp_opcFF_word_RM, 12399}; 12400