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 preceeding it which gives it's 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 x86emuOp_illegal_op( 85 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 x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1)) 112{ 113 int mod, rl, rh; 114 uint destoffset; 115 u8 *destreg, *srcreg; 116 u8 destval; 117 118 START_OF_INSTR(); 119 DECODE_PRINTF("ADD\t"); 120 FETCH_DECODE_MODRM(mod, rh, rl); 121 switch (mod) { 122 case 0: 123 destoffset = decode_rm00_address(rl); 124 DECODE_PRINTF(","); 125 destval = fetch_data_byte(destoffset); 126 srcreg = DECODE_RM_BYTE_REGISTER(rh); 127 DECODE_PRINTF("\n"); 128 TRACE_AND_STEP(); 129 destval = add_byte(destval, *srcreg); 130 store_data_byte(destoffset, destval); 131 break; 132 case 1: 133 destoffset = decode_rm01_address(rl); 134 DECODE_PRINTF(","); 135 destval = fetch_data_byte(destoffset); 136 srcreg = DECODE_RM_BYTE_REGISTER(rh); 137 DECODE_PRINTF("\n"); 138 TRACE_AND_STEP(); 139 destval = add_byte(destval, *srcreg); 140 store_data_byte(destoffset, destval); 141 break; 142 case 2: 143 destoffset = decode_rm10_address(rl); 144 DECODE_PRINTF(","); 145 destval = fetch_data_byte(destoffset); 146 srcreg = DECODE_RM_BYTE_REGISTER(rh); 147 DECODE_PRINTF("\n"); 148 TRACE_AND_STEP(); 149 destval = add_byte(destval, *srcreg); 150 store_data_byte(destoffset, destval); 151 break; 152 case 3: /* register to register */ 153 destreg = DECODE_RM_BYTE_REGISTER(rl); 154 DECODE_PRINTF(","); 155 srcreg = DECODE_RM_BYTE_REGISTER(rh); 156 DECODE_PRINTF("\n"); 157 TRACE_AND_STEP(); 158 *destreg = add_byte(*destreg, *srcreg); 159 break; 160 } 161 DECODE_CLEAR_SEGOVR(); 162 END_OF_INSTR(); 163} 164 165/**************************************************************************** 166REMARKS: 167Handles opcode 0x01 168****************************************************************************/ 169static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1)) 170{ 171 int mod, rl, rh; 172 uint destoffset; 173 174 START_OF_INSTR(); 175 DECODE_PRINTF("ADD\t"); 176 FETCH_DECODE_MODRM(mod, rh, rl); 177 switch (mod) { 178 case 0: 179 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 180 u32 destval; 181 u32 *srcreg; 182 183 destoffset = decode_rm00_address(rl); 184 DECODE_PRINTF(","); 185 destval = fetch_data_long(destoffset); 186 srcreg = DECODE_RM_LONG_REGISTER(rh); 187 DECODE_PRINTF("\n"); 188 TRACE_AND_STEP(); 189 destval = add_long(destval, *srcreg); 190 store_data_long(destoffset, destval); 191 } else { 192 u16 destval; 193 u16 *srcreg; 194 195 destoffset = decode_rm00_address(rl); 196 DECODE_PRINTF(","); 197 destval = fetch_data_word(destoffset); 198 srcreg = DECODE_RM_WORD_REGISTER(rh); 199 DECODE_PRINTF("\n"); 200 TRACE_AND_STEP(); 201 destval = add_word(destval, *srcreg); 202 store_data_word(destoffset, destval); 203 } 204 break; 205 case 1: 206 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 207 u32 destval; 208 u32 *srcreg; 209 210 destoffset = decode_rm01_address(rl); 211 DECODE_PRINTF(","); 212 destval = fetch_data_long(destoffset); 213 srcreg = DECODE_RM_LONG_REGISTER(rh); 214 DECODE_PRINTF("\n"); 215 TRACE_AND_STEP(); 216 destval = add_long(destval, *srcreg); 217 store_data_long(destoffset, destval); 218 } else { 219 u16 destval; 220 u16 *srcreg; 221 222 destoffset = decode_rm01_address(rl); 223 DECODE_PRINTF(","); 224 destval = fetch_data_word(destoffset); 225 srcreg = DECODE_RM_WORD_REGISTER(rh); 226 DECODE_PRINTF("\n"); 227 TRACE_AND_STEP(); 228 destval = add_word(destval, *srcreg); 229 store_data_word(destoffset, destval); 230 } 231 break; 232 case 2: 233 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 234 u32 destval; 235 u32 *srcreg; 236 237 destoffset = decode_rm10_address(rl); 238 DECODE_PRINTF(","); 239 destval = fetch_data_long(destoffset); 240 srcreg = DECODE_RM_LONG_REGISTER(rh); 241 DECODE_PRINTF("\n"); 242 TRACE_AND_STEP(); 243 destval = add_long(destval, *srcreg); 244 store_data_long(destoffset, destval); 245 } else { 246 u16 destval; 247 u16 *srcreg; 248 249 destoffset = decode_rm10_address(rl); 250 DECODE_PRINTF(","); 251 destval = fetch_data_word(destoffset); 252 srcreg = DECODE_RM_WORD_REGISTER(rh); 253 DECODE_PRINTF("\n"); 254 TRACE_AND_STEP(); 255 destval = add_word(destval, *srcreg); 256 store_data_word(destoffset, destval); 257 } 258 break; 259 case 3: /* register to register */ 260 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 261 u32 *destreg,*srcreg; 262 263 destreg = DECODE_RM_LONG_REGISTER(rl); 264 DECODE_PRINTF(","); 265 srcreg = DECODE_RM_LONG_REGISTER(rh); 266 DECODE_PRINTF("\n"); 267 TRACE_AND_STEP(); 268 *destreg = add_long(*destreg, *srcreg); 269 } else { 270 u16 *destreg,*srcreg; 271 272 destreg = DECODE_RM_WORD_REGISTER(rl); 273 DECODE_PRINTF(","); 274 srcreg = DECODE_RM_WORD_REGISTER(rh); 275 DECODE_PRINTF("\n"); 276 TRACE_AND_STEP(); 277 *destreg = add_word(*destreg, *srcreg); 278 } 279 break; 280 } 281 DECODE_CLEAR_SEGOVR(); 282 END_OF_INSTR(); 283} 284 285/**************************************************************************** 286REMARKS: 287Handles opcode 0x02 288****************************************************************************/ 289static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1)) 290{ 291 int mod, rl, rh; 292 u8 *destreg, *srcreg; 293 uint srcoffset; 294 u8 srcval; 295 296 START_OF_INSTR(); 297 DECODE_PRINTF("ADD\t"); 298 FETCH_DECODE_MODRM(mod, rh, rl); 299 switch (mod) { 300 case 0: 301 destreg = DECODE_RM_BYTE_REGISTER(rh); 302 DECODE_PRINTF(","); 303 srcoffset = decode_rm00_address(rl); 304 srcval = fetch_data_byte(srcoffset); 305 DECODE_PRINTF("\n"); 306 TRACE_AND_STEP(); 307 *destreg = add_byte(*destreg, srcval); 308 break; 309 case 1: 310 destreg = DECODE_RM_BYTE_REGISTER(rh); 311 DECODE_PRINTF(","); 312 srcoffset = decode_rm01_address(rl); 313 srcval = fetch_data_byte(srcoffset); 314 DECODE_PRINTF("\n"); 315 TRACE_AND_STEP(); 316 *destreg = add_byte(*destreg, srcval); 317 break; 318 case 2: 319 destreg = DECODE_RM_BYTE_REGISTER(rh); 320 DECODE_PRINTF(","); 321 srcoffset = decode_rm10_address(rl); 322 srcval = fetch_data_byte(srcoffset); 323 DECODE_PRINTF("\n"); 324 TRACE_AND_STEP(); 325 *destreg = add_byte(*destreg, srcval); 326 break; 327 case 3: /* register to register */ 328 destreg = DECODE_RM_BYTE_REGISTER(rh); 329 DECODE_PRINTF(","); 330 srcreg = DECODE_RM_BYTE_REGISTER(rl); 331 DECODE_PRINTF("\n"); 332 TRACE_AND_STEP(); 333 *destreg = add_byte(*destreg, *srcreg); 334 break; 335 } 336 DECODE_CLEAR_SEGOVR(); 337 END_OF_INSTR(); 338} 339 340/**************************************************************************** 341REMARKS: 342Handles opcode 0x03 343****************************************************************************/ 344static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1)) 345{ 346 int mod, rl, rh; 347 uint srcoffset; 348 349 START_OF_INSTR(); 350 DECODE_PRINTF("ADD\t"); 351 FETCH_DECODE_MODRM(mod, rh, rl); 352 switch (mod) { 353 case 0: 354 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 355 u32 *destreg; 356 u32 srcval; 357 358 destreg = DECODE_RM_LONG_REGISTER(rh); 359 DECODE_PRINTF(","); 360 srcoffset = decode_rm00_address(rl); 361 srcval = fetch_data_long(srcoffset); 362 DECODE_PRINTF("\n"); 363 TRACE_AND_STEP(); 364 *destreg = add_long(*destreg, srcval); 365 } else { 366 u16 *destreg; 367 u16 srcval; 368 369 destreg = DECODE_RM_WORD_REGISTER(rh); 370 DECODE_PRINTF(","); 371 srcoffset = decode_rm00_address(rl); 372 srcval = fetch_data_word(srcoffset); 373 DECODE_PRINTF("\n"); 374 TRACE_AND_STEP(); 375 *destreg = add_word(*destreg, srcval); 376 } 377 break; 378 case 1: 379 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 380 u32 *destreg; 381 u32 srcval; 382 383 destreg = DECODE_RM_LONG_REGISTER(rh); 384 DECODE_PRINTF(","); 385 srcoffset = decode_rm01_address(rl); 386 srcval = fetch_data_long(srcoffset); 387 DECODE_PRINTF("\n"); 388 TRACE_AND_STEP(); 389 *destreg = add_long(*destreg, srcval); 390 } else { 391 u16 *destreg; 392 u16 srcval; 393 394 destreg = DECODE_RM_WORD_REGISTER(rh); 395 DECODE_PRINTF(","); 396 srcoffset = decode_rm01_address(rl); 397 srcval = fetch_data_word(srcoffset); 398 DECODE_PRINTF("\n"); 399 TRACE_AND_STEP(); 400 *destreg = add_word(*destreg, srcval); 401 } 402 break; 403 case 2: 404 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 405 u32 *destreg; 406 u32 srcval; 407 408 destreg = DECODE_RM_LONG_REGISTER(rh); 409 DECODE_PRINTF(","); 410 srcoffset = decode_rm10_address(rl); 411 srcval = fetch_data_long(srcoffset); 412 DECODE_PRINTF("\n"); 413 TRACE_AND_STEP(); 414 *destreg = add_long(*destreg, srcval); 415 } else { 416 u16 *destreg; 417 u16 srcval; 418 419 destreg = DECODE_RM_WORD_REGISTER(rh); 420 DECODE_PRINTF(","); 421 srcoffset = decode_rm10_address(rl); 422 srcval = fetch_data_word(srcoffset); 423 DECODE_PRINTF("\n"); 424 TRACE_AND_STEP(); 425 *destreg = add_word(*destreg, srcval); 426 } 427 break; 428 case 3: /* register to register */ 429 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 430 u32 *destreg,*srcreg; 431 432 destreg = DECODE_RM_LONG_REGISTER(rh); 433 DECODE_PRINTF(","); 434 srcreg = DECODE_RM_LONG_REGISTER(rl); 435 DECODE_PRINTF("\n"); 436 TRACE_AND_STEP(); 437 *destreg = add_long(*destreg, *srcreg); 438 } else { 439 u16 *destreg,*srcreg; 440 441 destreg = DECODE_RM_WORD_REGISTER(rh); 442 DECODE_PRINTF(","); 443 srcreg = DECODE_RM_WORD_REGISTER(rl); 444 DECODE_PRINTF("\n"); 445 TRACE_AND_STEP(); 446 *destreg = add_word(*destreg, *srcreg); 447 } 448 break; 449 } 450 DECODE_CLEAR_SEGOVR(); 451 END_OF_INSTR(); 452} 453 454/**************************************************************************** 455REMARKS: 456Handles opcode 0x04 457****************************************************************************/ 458static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 459{ 460 u8 srcval; 461 462 START_OF_INSTR(); 463 DECODE_PRINTF("ADD\tAL,"); 464 srcval = fetch_byte_imm(); 465 DECODE_PRINTF2("%x\n", srcval); 466 TRACE_AND_STEP(); 467 M.x86.R_AL = add_byte(M.x86.R_AL, srcval); 468 DECODE_CLEAR_SEGOVR(); 469 END_OF_INSTR(); 470} 471 472/**************************************************************************** 473REMARKS: 474Handles opcode 0x05 475****************************************************************************/ 476static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 477{ 478 u32 srcval; 479 480 START_OF_INSTR(); 481 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 482 DECODE_PRINTF("ADD\tEAX,"); 483 srcval = fetch_long_imm(); 484 } else { 485 DECODE_PRINTF("ADD\tAX,"); 486 srcval = fetch_word_imm(); 487 } 488 DECODE_PRINTF2("%x\n", srcval); 489 TRACE_AND_STEP(); 490 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 491 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval); 492 } else { 493 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval); 494 } 495 DECODE_CLEAR_SEGOVR(); 496 END_OF_INSTR(); 497} 498 499/**************************************************************************** 500REMARKS: 501Handles opcode 0x06 502****************************************************************************/ 503static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 504{ 505 START_OF_INSTR(); 506 DECODE_PRINTF("PUSH\tES\n"); 507 TRACE_AND_STEP(); 508 push_word(M.x86.R_ES); 509 DECODE_CLEAR_SEGOVR(); 510 END_OF_INSTR(); 511} 512 513/**************************************************************************** 514REMARKS: 515Handles opcode 0x07 516****************************************************************************/ 517static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 518{ 519 START_OF_INSTR(); 520 DECODE_PRINTF("POP\tES\n"); 521 TRACE_AND_STEP(); 522 M.x86.R_ES = pop_word(); 523 DECODE_CLEAR_SEGOVR(); 524 END_OF_INSTR(); 525} 526 527/**************************************************************************** 528REMARKS: 529Handles opcode 0x08 530****************************************************************************/ 531static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1)) 532{ 533 int mod, rl, rh; 534 u8 *destreg, *srcreg; 535 uint destoffset; 536 u8 destval; 537 538 START_OF_INSTR(); 539 DECODE_PRINTF("OR\t"); 540 FETCH_DECODE_MODRM(mod, rh, rl); 541 switch (mod) { 542 case 0: 543 destoffset = decode_rm00_address(rl); 544 DECODE_PRINTF(","); 545 destval = fetch_data_byte(destoffset); 546 srcreg = DECODE_RM_BYTE_REGISTER(rh); 547 DECODE_PRINTF("\n"); 548 TRACE_AND_STEP(); 549 destval = or_byte(destval, *srcreg); 550 store_data_byte(destoffset, destval); 551 break; 552 case 1: 553 destoffset = decode_rm01_address(rl); 554 DECODE_PRINTF(","); 555 destval = fetch_data_byte(destoffset); 556 srcreg = DECODE_RM_BYTE_REGISTER(rh); 557 DECODE_PRINTF("\n"); 558 TRACE_AND_STEP(); 559 destval = or_byte(destval, *srcreg); 560 store_data_byte(destoffset, destval); 561 break; 562 case 2: 563 destoffset = decode_rm10_address(rl); 564 DECODE_PRINTF(","); 565 destval = fetch_data_byte(destoffset); 566 srcreg = DECODE_RM_BYTE_REGISTER(rh); 567 DECODE_PRINTF("\n"); 568 TRACE_AND_STEP(); 569 destval = or_byte(destval, *srcreg); 570 store_data_byte(destoffset, destval); 571 break; 572 case 3: /* register to register */ 573 destreg = DECODE_RM_BYTE_REGISTER(rl); 574 DECODE_PRINTF(","); 575 srcreg = DECODE_RM_BYTE_REGISTER(rh); 576 DECODE_PRINTF("\n"); 577 TRACE_AND_STEP(); 578 *destreg = or_byte(*destreg, *srcreg); 579 break; 580 } 581 DECODE_CLEAR_SEGOVR(); 582 END_OF_INSTR(); 583} 584 585/**************************************************************************** 586REMARKS: 587Handles opcode 0x09 588****************************************************************************/ 589static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1)) 590{ 591 int mod, rl, rh; 592 uint destoffset; 593 594 START_OF_INSTR(); 595 DECODE_PRINTF("OR\t"); 596 FETCH_DECODE_MODRM(mod, rh, rl); 597 switch (mod) { 598 case 0: 599 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 600 u32 destval; 601 u32 *srcreg; 602 603 destoffset = decode_rm00_address(rl); 604 DECODE_PRINTF(","); 605 destval = fetch_data_long(destoffset); 606 srcreg = DECODE_RM_LONG_REGISTER(rh); 607 DECODE_PRINTF("\n"); 608 TRACE_AND_STEP(); 609 destval = or_long(destval, *srcreg); 610 store_data_long(destoffset, destval); 611 } else { 612 u16 destval; 613 u16 *srcreg; 614 615 destoffset = decode_rm00_address(rl); 616 DECODE_PRINTF(","); 617 destval = fetch_data_word(destoffset); 618 srcreg = DECODE_RM_WORD_REGISTER(rh); 619 DECODE_PRINTF("\n"); 620 TRACE_AND_STEP(); 621 destval = or_word(destval, *srcreg); 622 store_data_word(destoffset, destval); 623 } 624 break; 625 case 1: 626 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 627 u32 destval; 628 u32 *srcreg; 629 630 destoffset = decode_rm01_address(rl); 631 DECODE_PRINTF(","); 632 destval = fetch_data_long(destoffset); 633 srcreg = DECODE_RM_LONG_REGISTER(rh); 634 DECODE_PRINTF("\n"); 635 TRACE_AND_STEP(); 636 destval = or_long(destval, *srcreg); 637 store_data_long(destoffset, destval); 638 } else { 639 u16 destval; 640 u16 *srcreg; 641 642 destoffset = decode_rm01_address(rl); 643 DECODE_PRINTF(","); 644 destval = fetch_data_word(destoffset); 645 srcreg = DECODE_RM_WORD_REGISTER(rh); 646 DECODE_PRINTF("\n"); 647 TRACE_AND_STEP(); 648 destval = or_word(destval, *srcreg); 649 store_data_word(destoffset, destval); 650 } 651 break; 652 case 2: 653 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 654 u32 destval; 655 u32 *srcreg; 656 657 destoffset = decode_rm10_address(rl); 658 DECODE_PRINTF(","); 659 destval = fetch_data_long(destoffset); 660 srcreg = DECODE_RM_LONG_REGISTER(rh); 661 DECODE_PRINTF("\n"); 662 TRACE_AND_STEP(); 663 destval = or_long(destval, *srcreg); 664 store_data_long(destoffset, destval); 665 } else { 666 u16 destval; 667 u16 *srcreg; 668 669 destoffset = decode_rm10_address(rl); 670 DECODE_PRINTF(","); 671 destval = fetch_data_word(destoffset); 672 srcreg = DECODE_RM_WORD_REGISTER(rh); 673 DECODE_PRINTF("\n"); 674 TRACE_AND_STEP(); 675 destval = or_word(destval, *srcreg); 676 store_data_word(destoffset, destval); 677 } 678 break; 679 case 3: /* register to register */ 680 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 681 u32 *destreg,*srcreg; 682 683 destreg = DECODE_RM_LONG_REGISTER(rl); 684 DECODE_PRINTF(","); 685 srcreg = DECODE_RM_LONG_REGISTER(rh); 686 DECODE_PRINTF("\n"); 687 TRACE_AND_STEP(); 688 *destreg = or_long(*destreg, *srcreg); 689 } else { 690 u16 *destreg,*srcreg; 691 692 destreg = DECODE_RM_WORD_REGISTER(rl); 693 DECODE_PRINTF(","); 694 srcreg = DECODE_RM_WORD_REGISTER(rh); 695 DECODE_PRINTF("\n"); 696 TRACE_AND_STEP(); 697 *destreg = or_word(*destreg, *srcreg); 698 } 699 break; 700 } 701 DECODE_CLEAR_SEGOVR(); 702 END_OF_INSTR(); 703} 704 705/**************************************************************************** 706REMARKS: 707Handles opcode 0x0a 708****************************************************************************/ 709static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1)) 710{ 711 int mod, rl, rh; 712 u8 *destreg, *srcreg; 713 uint srcoffset; 714 u8 srcval; 715 716 START_OF_INSTR(); 717 DECODE_PRINTF("OR\t"); 718 FETCH_DECODE_MODRM(mod, rh, rl); 719 switch (mod) { 720 case 0: 721 destreg = DECODE_RM_BYTE_REGISTER(rh); 722 DECODE_PRINTF(","); 723 srcoffset = decode_rm00_address(rl); 724 srcval = fetch_data_byte(srcoffset); 725 DECODE_PRINTF("\n"); 726 TRACE_AND_STEP(); 727 *destreg = or_byte(*destreg, srcval); 728 break; 729 case 1: 730 destreg = DECODE_RM_BYTE_REGISTER(rh); 731 DECODE_PRINTF(","); 732 srcoffset = decode_rm01_address(rl); 733 srcval = fetch_data_byte(srcoffset); 734 DECODE_PRINTF("\n"); 735 TRACE_AND_STEP(); 736 *destreg = or_byte(*destreg, srcval); 737 break; 738 case 2: 739 destreg = DECODE_RM_BYTE_REGISTER(rh); 740 DECODE_PRINTF(","); 741 srcoffset = decode_rm10_address(rl); 742 srcval = fetch_data_byte(srcoffset); 743 DECODE_PRINTF("\n"); 744 TRACE_AND_STEP(); 745 *destreg = or_byte(*destreg, srcval); 746 break; 747 case 3: /* register to register */ 748 destreg = DECODE_RM_BYTE_REGISTER(rh); 749 DECODE_PRINTF(","); 750 srcreg = DECODE_RM_BYTE_REGISTER(rl); 751 DECODE_PRINTF("\n"); 752 TRACE_AND_STEP(); 753 *destreg = or_byte(*destreg, *srcreg); 754 break; 755 } 756 DECODE_CLEAR_SEGOVR(); 757 END_OF_INSTR(); 758} 759 760/**************************************************************************** 761REMARKS: 762Handles opcode 0x0b 763****************************************************************************/ 764static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1)) 765{ 766 int mod, rl, rh; 767 uint srcoffset; 768 769 START_OF_INSTR(); 770 DECODE_PRINTF("OR\t"); 771 FETCH_DECODE_MODRM(mod, rh, rl); 772 switch (mod) { 773 case 0: 774 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 775 u32 *destreg; 776 u32 srcval; 777 778 destreg = DECODE_RM_LONG_REGISTER(rh); 779 DECODE_PRINTF(","); 780 srcoffset = decode_rm00_address(rl); 781 srcval = fetch_data_long(srcoffset); 782 DECODE_PRINTF("\n"); 783 TRACE_AND_STEP(); 784 *destreg = or_long(*destreg, srcval); 785 } else { 786 u16 *destreg; 787 u16 srcval; 788 789 destreg = DECODE_RM_WORD_REGISTER(rh); 790 DECODE_PRINTF(","); 791 srcoffset = decode_rm00_address(rl); 792 srcval = fetch_data_word(srcoffset); 793 DECODE_PRINTF("\n"); 794 TRACE_AND_STEP(); 795 *destreg = or_word(*destreg, srcval); 796 } 797 break; 798 case 1: 799 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 800 u32 *destreg; 801 u32 srcval; 802 803 destreg = DECODE_RM_LONG_REGISTER(rh); 804 DECODE_PRINTF(","); 805 srcoffset = decode_rm01_address(rl); 806 srcval = fetch_data_long(srcoffset); 807 DECODE_PRINTF("\n"); 808 TRACE_AND_STEP(); 809 *destreg = or_long(*destreg, srcval); 810 } else { 811 u16 *destreg; 812 u16 srcval; 813 814 destreg = DECODE_RM_WORD_REGISTER(rh); 815 DECODE_PRINTF(","); 816 srcoffset = decode_rm01_address(rl); 817 srcval = fetch_data_word(srcoffset); 818 DECODE_PRINTF("\n"); 819 TRACE_AND_STEP(); 820 *destreg = or_word(*destreg, srcval); 821 } 822 break; 823 case 2: 824 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 825 u32 *destreg; 826 u32 srcval; 827 828 destreg = DECODE_RM_LONG_REGISTER(rh); 829 DECODE_PRINTF(","); 830 srcoffset = decode_rm10_address(rl); 831 srcval = fetch_data_long(srcoffset); 832 DECODE_PRINTF("\n"); 833 TRACE_AND_STEP(); 834 *destreg = or_long(*destreg, srcval); 835 } else { 836 u16 *destreg; 837 u16 srcval; 838 839 destreg = DECODE_RM_WORD_REGISTER(rh); 840 DECODE_PRINTF(","); 841 srcoffset = decode_rm10_address(rl); 842 srcval = fetch_data_word(srcoffset); 843 DECODE_PRINTF("\n"); 844 TRACE_AND_STEP(); 845 *destreg = or_word(*destreg, srcval); 846 } 847 break; 848 case 3: /* register to register */ 849 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 850 u32 *destreg,*srcreg; 851 852 destreg = DECODE_RM_LONG_REGISTER(rh); 853 DECODE_PRINTF(","); 854 srcreg = DECODE_RM_LONG_REGISTER(rl); 855 DECODE_PRINTF("\n"); 856 TRACE_AND_STEP(); 857 *destreg = or_long(*destreg, *srcreg); 858 } else { 859 u16 *destreg,*srcreg; 860 861 destreg = DECODE_RM_WORD_REGISTER(rh); 862 DECODE_PRINTF(","); 863 srcreg = DECODE_RM_WORD_REGISTER(rl); 864 DECODE_PRINTF("\n"); 865 TRACE_AND_STEP(); 866 *destreg = or_word(*destreg, *srcreg); 867 } 868 break; 869 } 870 DECODE_CLEAR_SEGOVR(); 871 END_OF_INSTR(); 872} 873 874/**************************************************************************** 875REMARKS: 876Handles opcode 0x0c 877****************************************************************************/ 878static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 879{ 880 u8 srcval; 881 882 START_OF_INSTR(); 883 DECODE_PRINTF("OR\tAL,"); 884 srcval = fetch_byte_imm(); 885 DECODE_PRINTF2("%x\n", srcval); 886 TRACE_AND_STEP(); 887 M.x86.R_AL = or_byte(M.x86.R_AL, srcval); 888 DECODE_CLEAR_SEGOVR(); 889 END_OF_INSTR(); 890} 891 892/**************************************************************************** 893REMARKS: 894Handles opcode 0x0d 895****************************************************************************/ 896static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 897{ 898 u32 srcval; 899 900 START_OF_INSTR(); 901 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 902 DECODE_PRINTF("OR\tEAX,"); 903 srcval = fetch_long_imm(); 904 } else { 905 DECODE_PRINTF("OR\tAX,"); 906 srcval = fetch_word_imm(); 907 } 908 DECODE_PRINTF2("%x\n", srcval); 909 TRACE_AND_STEP(); 910 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 911 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval); 912 } else { 913 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval); 914 } 915 DECODE_CLEAR_SEGOVR(); 916 END_OF_INSTR(); 917} 918 919/**************************************************************************** 920REMARKS: 921Handles opcode 0x0e 922****************************************************************************/ 923static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 924{ 925 START_OF_INSTR(); 926 DECODE_PRINTF("PUSH\tCS\n"); 927 TRACE_AND_STEP(); 928 push_word(M.x86.R_CS); 929 DECODE_CLEAR_SEGOVR(); 930 END_OF_INSTR(); 931} 932 933/**************************************************************************** 934REMARKS: 935Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 936****************************************************************************/ 937static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 938{ 939 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 940 INC_DECODED_INST_LEN(1); 941 (*x86emu_optab2[op2])(op2); 942} 943 944/**************************************************************************** 945REMARKS: 946Handles opcode 0x10 947****************************************************************************/ 948static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1)) 949{ 950 int mod, rl, rh; 951 u8 *destreg, *srcreg; 952 uint destoffset; 953 u8 destval; 954 955 START_OF_INSTR(); 956 DECODE_PRINTF("ADC\t"); 957 FETCH_DECODE_MODRM(mod, rh, rl); 958 switch (mod) { 959 case 0: 960 destoffset = decode_rm00_address(rl); 961 DECODE_PRINTF(","); 962 destval = fetch_data_byte(destoffset); 963 srcreg = DECODE_RM_BYTE_REGISTER(rh); 964 DECODE_PRINTF("\n"); 965 TRACE_AND_STEP(); 966 destval = adc_byte(destval, *srcreg); 967 store_data_byte(destoffset, destval); 968 break; 969 case 1: 970 destoffset = decode_rm01_address(rl); 971 DECODE_PRINTF(","); 972 destval = fetch_data_byte(destoffset); 973 srcreg = DECODE_RM_BYTE_REGISTER(rh); 974 DECODE_PRINTF("\n"); 975 TRACE_AND_STEP(); 976 destval = adc_byte(destval, *srcreg); 977 store_data_byte(destoffset, destval); 978 break; 979 case 2: 980 destoffset = decode_rm10_address(rl); 981 DECODE_PRINTF(","); 982 destval = fetch_data_byte(destoffset); 983 srcreg = DECODE_RM_BYTE_REGISTER(rh); 984 DECODE_PRINTF("\n"); 985 TRACE_AND_STEP(); 986 destval = adc_byte(destval, *srcreg); 987 store_data_byte(destoffset, destval); 988 break; 989 case 3: /* register to register */ 990 destreg = DECODE_RM_BYTE_REGISTER(rl); 991 DECODE_PRINTF(","); 992 srcreg = DECODE_RM_BYTE_REGISTER(rh); 993 DECODE_PRINTF("\n"); 994 TRACE_AND_STEP(); 995 *destreg = adc_byte(*destreg, *srcreg); 996 break; 997 } 998 DECODE_CLEAR_SEGOVR(); 999 END_OF_INSTR(); 1000} 1001 1002/**************************************************************************** 1003REMARKS: 1004Handles opcode 0x11 1005****************************************************************************/ 1006static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1)) 1007{ 1008 int mod, rl, rh; 1009 uint destoffset; 1010 1011 START_OF_INSTR(); 1012 DECODE_PRINTF("ADC\t"); 1013 FETCH_DECODE_MODRM(mod, rh, rl); 1014 switch (mod) { 1015 case 0: 1016 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1017 u32 destval; 1018 u32 *srcreg; 1019 1020 destoffset = decode_rm00_address(rl); 1021 DECODE_PRINTF(","); 1022 destval = fetch_data_long(destoffset); 1023 srcreg = DECODE_RM_LONG_REGISTER(rh); 1024 DECODE_PRINTF("\n"); 1025 TRACE_AND_STEP(); 1026 destval = adc_long(destval, *srcreg); 1027 store_data_long(destoffset, destval); 1028 } else { 1029 u16 destval; 1030 u16 *srcreg; 1031 1032 destoffset = decode_rm00_address(rl); 1033 DECODE_PRINTF(","); 1034 destval = fetch_data_word(destoffset); 1035 srcreg = DECODE_RM_WORD_REGISTER(rh); 1036 DECODE_PRINTF("\n"); 1037 TRACE_AND_STEP(); 1038 destval = adc_word(destval, *srcreg); 1039 store_data_word(destoffset, destval); 1040 } 1041 break; 1042 case 1: 1043 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1044 u32 destval; 1045 u32 *srcreg; 1046 1047 destoffset = decode_rm01_address(rl); 1048 DECODE_PRINTF(","); 1049 destval = fetch_data_long(destoffset); 1050 srcreg = DECODE_RM_LONG_REGISTER(rh); 1051 DECODE_PRINTF("\n"); 1052 TRACE_AND_STEP(); 1053 destval = adc_long(destval, *srcreg); 1054 store_data_long(destoffset, destval); 1055 } else { 1056 u16 destval; 1057 u16 *srcreg; 1058 1059 destoffset = decode_rm01_address(rl); 1060 DECODE_PRINTF(","); 1061 destval = fetch_data_word(destoffset); 1062 srcreg = DECODE_RM_WORD_REGISTER(rh); 1063 DECODE_PRINTF("\n"); 1064 TRACE_AND_STEP(); 1065 destval = adc_word(destval, *srcreg); 1066 store_data_word(destoffset, destval); 1067 } 1068 break; 1069 case 2: 1070 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1071 u32 destval; 1072 u32 *srcreg; 1073 1074 destoffset = decode_rm10_address(rl); 1075 DECODE_PRINTF(","); 1076 destval = fetch_data_long(destoffset); 1077 srcreg = DECODE_RM_LONG_REGISTER(rh); 1078 DECODE_PRINTF("\n"); 1079 TRACE_AND_STEP(); 1080 destval = adc_long(destval, *srcreg); 1081 store_data_long(destoffset, destval); 1082 } else { 1083 u16 destval; 1084 u16 *srcreg; 1085 1086 destoffset = decode_rm10_address(rl); 1087 DECODE_PRINTF(","); 1088 destval = fetch_data_word(destoffset); 1089 srcreg = DECODE_RM_WORD_REGISTER(rh); 1090 DECODE_PRINTF("\n"); 1091 TRACE_AND_STEP(); 1092 destval = adc_word(destval, *srcreg); 1093 store_data_word(destoffset, destval); 1094 } 1095 break; 1096 case 3: /* register to register */ 1097 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1098 u32 *destreg,*srcreg; 1099 1100 destreg = DECODE_RM_LONG_REGISTER(rl); 1101 DECODE_PRINTF(","); 1102 srcreg = DECODE_RM_LONG_REGISTER(rh); 1103 DECODE_PRINTF("\n"); 1104 TRACE_AND_STEP(); 1105 *destreg = adc_long(*destreg, *srcreg); 1106 } else { 1107 u16 *destreg,*srcreg; 1108 1109 destreg = DECODE_RM_WORD_REGISTER(rl); 1110 DECODE_PRINTF(","); 1111 srcreg = DECODE_RM_WORD_REGISTER(rh); 1112 DECODE_PRINTF("\n"); 1113 TRACE_AND_STEP(); 1114 *destreg = adc_word(*destreg, *srcreg); 1115 } 1116 break; 1117 } 1118 DECODE_CLEAR_SEGOVR(); 1119 END_OF_INSTR(); 1120} 1121 1122/**************************************************************************** 1123REMARKS: 1124Handles opcode 0x12 1125****************************************************************************/ 1126static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1127{ 1128 int mod, rl, rh; 1129 u8 *destreg, *srcreg; 1130 uint srcoffset; 1131 u8 srcval; 1132 1133 START_OF_INSTR(); 1134 DECODE_PRINTF("ADC\t"); 1135 FETCH_DECODE_MODRM(mod, rh, rl); 1136 switch (mod) { 1137 case 0: 1138 destreg = DECODE_RM_BYTE_REGISTER(rh); 1139 DECODE_PRINTF(","); 1140 srcoffset = decode_rm00_address(rl); 1141 srcval = fetch_data_byte(srcoffset); 1142 DECODE_PRINTF("\n"); 1143 TRACE_AND_STEP(); 1144 *destreg = adc_byte(*destreg, srcval); 1145 break; 1146 case 1: 1147 destreg = DECODE_RM_BYTE_REGISTER(rh); 1148 DECODE_PRINTF(","); 1149 srcoffset = decode_rm01_address(rl); 1150 srcval = fetch_data_byte(srcoffset); 1151 DECODE_PRINTF("\n"); 1152 TRACE_AND_STEP(); 1153 *destreg = adc_byte(*destreg, srcval); 1154 break; 1155 case 2: 1156 destreg = DECODE_RM_BYTE_REGISTER(rh); 1157 DECODE_PRINTF(","); 1158 srcoffset = decode_rm10_address(rl); 1159 srcval = fetch_data_byte(srcoffset); 1160 DECODE_PRINTF("\n"); 1161 TRACE_AND_STEP(); 1162 *destreg = adc_byte(*destreg, srcval); 1163 break; 1164 case 3: /* register to register */ 1165 destreg = DECODE_RM_BYTE_REGISTER(rh); 1166 DECODE_PRINTF(","); 1167 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1168 DECODE_PRINTF("\n"); 1169 TRACE_AND_STEP(); 1170 *destreg = adc_byte(*destreg, *srcreg); 1171 break; 1172 } 1173 DECODE_CLEAR_SEGOVR(); 1174 END_OF_INSTR(); 1175} 1176 1177/**************************************************************************** 1178REMARKS: 1179Handles opcode 0x13 1180****************************************************************************/ 1181static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1)) 1182{ 1183 int mod, rl, rh; 1184 uint srcoffset; 1185 1186 START_OF_INSTR(); 1187 DECODE_PRINTF("ADC\t"); 1188 FETCH_DECODE_MODRM(mod, rh, rl); 1189 switch (mod) { 1190 case 0: 1191 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1192 u32 *destreg; 1193 u32 srcval; 1194 1195 destreg = DECODE_RM_LONG_REGISTER(rh); 1196 DECODE_PRINTF(","); 1197 srcoffset = decode_rm00_address(rl); 1198 srcval = fetch_data_long(srcoffset); 1199 DECODE_PRINTF("\n"); 1200 TRACE_AND_STEP(); 1201 *destreg = adc_long(*destreg, srcval); 1202 } else { 1203 u16 *destreg; 1204 u16 srcval; 1205 1206 destreg = DECODE_RM_WORD_REGISTER(rh); 1207 DECODE_PRINTF(","); 1208 srcoffset = decode_rm00_address(rl); 1209 srcval = fetch_data_word(srcoffset); 1210 DECODE_PRINTF("\n"); 1211 TRACE_AND_STEP(); 1212 *destreg = adc_word(*destreg, srcval); 1213 } 1214 break; 1215 case 1: 1216 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1217 u32 *destreg; 1218 u32 srcval; 1219 1220 destreg = DECODE_RM_LONG_REGISTER(rh); 1221 DECODE_PRINTF(","); 1222 srcoffset = decode_rm01_address(rl); 1223 srcval = fetch_data_long(srcoffset); 1224 DECODE_PRINTF("\n"); 1225 TRACE_AND_STEP(); 1226 *destreg = adc_long(*destreg, srcval); 1227 } else { 1228 u16 *destreg; 1229 u16 srcval; 1230 1231 destreg = DECODE_RM_WORD_REGISTER(rh); 1232 DECODE_PRINTF(","); 1233 srcoffset = decode_rm01_address(rl); 1234 srcval = fetch_data_word(srcoffset); 1235 DECODE_PRINTF("\n"); 1236 TRACE_AND_STEP(); 1237 *destreg = adc_word(*destreg, srcval); 1238 } 1239 break; 1240 case 2: 1241 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1242 u32 *destreg; 1243 u32 srcval; 1244 1245 destreg = DECODE_RM_LONG_REGISTER(rh); 1246 DECODE_PRINTF(","); 1247 srcoffset = decode_rm10_address(rl); 1248 srcval = fetch_data_long(srcoffset); 1249 DECODE_PRINTF("\n"); 1250 TRACE_AND_STEP(); 1251 *destreg = adc_long(*destreg, srcval); 1252 } else { 1253 u16 *destreg; 1254 u16 srcval; 1255 1256 destreg = DECODE_RM_WORD_REGISTER(rh); 1257 DECODE_PRINTF(","); 1258 srcoffset = decode_rm10_address(rl); 1259 srcval = fetch_data_word(srcoffset); 1260 DECODE_PRINTF("\n"); 1261 TRACE_AND_STEP(); 1262 *destreg = adc_word(*destreg, srcval); 1263 } 1264 break; 1265 case 3: /* register to register */ 1266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1267 u32 *destreg,*srcreg; 1268 1269 destreg = DECODE_RM_LONG_REGISTER(rh); 1270 DECODE_PRINTF(","); 1271 srcreg = DECODE_RM_LONG_REGISTER(rl); 1272 DECODE_PRINTF("\n"); 1273 TRACE_AND_STEP(); 1274 *destreg = adc_long(*destreg, *srcreg); 1275 } else { 1276 u16 *destreg,*srcreg; 1277 1278 destreg = DECODE_RM_WORD_REGISTER(rh); 1279 DECODE_PRINTF(","); 1280 srcreg = DECODE_RM_WORD_REGISTER(rl); 1281 DECODE_PRINTF("\n"); 1282 TRACE_AND_STEP(); 1283 *destreg = adc_word(*destreg, *srcreg); 1284 } 1285 break; 1286 } 1287 DECODE_CLEAR_SEGOVR(); 1288 END_OF_INSTR(); 1289} 1290 1291/**************************************************************************** 1292REMARKS: 1293Handles opcode 0x14 1294****************************************************************************/ 1295static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1296{ 1297 u8 srcval; 1298 1299 START_OF_INSTR(); 1300 DECODE_PRINTF("ADC\tAL,"); 1301 srcval = fetch_byte_imm(); 1302 DECODE_PRINTF2("%x\n", srcval); 1303 TRACE_AND_STEP(); 1304 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval); 1305 DECODE_CLEAR_SEGOVR(); 1306 END_OF_INSTR(); 1307} 1308 1309/**************************************************************************** 1310REMARKS: 1311Handles opcode 0x15 1312****************************************************************************/ 1313static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1314{ 1315 u32 srcval; 1316 1317 START_OF_INSTR(); 1318 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1319 DECODE_PRINTF("ADC\tEAX,"); 1320 srcval = fetch_long_imm(); 1321 } else { 1322 DECODE_PRINTF("ADC\tAX,"); 1323 srcval = fetch_word_imm(); 1324 } 1325 DECODE_PRINTF2("%x\n", srcval); 1326 TRACE_AND_STEP(); 1327 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1328 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval); 1329 } else { 1330 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval); 1331 } 1332 DECODE_CLEAR_SEGOVR(); 1333 END_OF_INSTR(); 1334} 1335 1336/**************************************************************************** 1337REMARKS: 1338Handles opcode 0x16 1339****************************************************************************/ 1340static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 1341{ 1342 START_OF_INSTR(); 1343 DECODE_PRINTF("PUSH\tSS\n"); 1344 TRACE_AND_STEP(); 1345 push_word(M.x86.R_SS); 1346 DECODE_CLEAR_SEGOVR(); 1347 END_OF_INSTR(); 1348} 1349 1350/**************************************************************************** 1351REMARKS: 1352Handles opcode 0x17 1353****************************************************************************/ 1354static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 1355{ 1356 START_OF_INSTR(); 1357 DECODE_PRINTF("POP\tSS\n"); 1358 TRACE_AND_STEP(); 1359 M.x86.R_SS = pop_word(); 1360 DECODE_CLEAR_SEGOVR(); 1361 END_OF_INSTR(); 1362} 1363 1364/**************************************************************************** 1365REMARKS: 1366Handles opcode 0x18 1367****************************************************************************/ 1368static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1369{ 1370 int mod, rl, rh; 1371 u8 *destreg, *srcreg; 1372 uint destoffset; 1373 u8 destval; 1374 1375 START_OF_INSTR(); 1376 DECODE_PRINTF("SBB\t"); 1377 FETCH_DECODE_MODRM(mod, rh, rl); 1378 switch (mod) { 1379 case 0: 1380 destoffset = decode_rm00_address(rl); 1381 DECODE_PRINTF(","); 1382 destval = fetch_data_byte(destoffset); 1383 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1384 DECODE_PRINTF("\n"); 1385 TRACE_AND_STEP(); 1386 destval = sbb_byte(destval, *srcreg); 1387 store_data_byte(destoffset, destval); 1388 break; 1389 case 1: 1390 destoffset = decode_rm01_address(rl); 1391 DECODE_PRINTF(","); 1392 destval = fetch_data_byte(destoffset); 1393 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1394 DECODE_PRINTF("\n"); 1395 TRACE_AND_STEP(); 1396 destval = sbb_byte(destval, *srcreg); 1397 store_data_byte(destoffset, destval); 1398 break; 1399 case 2: 1400 destoffset = decode_rm10_address(rl); 1401 DECODE_PRINTF(","); 1402 destval = fetch_data_byte(destoffset); 1403 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1404 DECODE_PRINTF("\n"); 1405 TRACE_AND_STEP(); 1406 destval = sbb_byte(destval, *srcreg); 1407 store_data_byte(destoffset, destval); 1408 break; 1409 case 3: /* register to register */ 1410 destreg = DECODE_RM_BYTE_REGISTER(rl); 1411 DECODE_PRINTF(","); 1412 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1413 DECODE_PRINTF("\n"); 1414 TRACE_AND_STEP(); 1415 *destreg = sbb_byte(*destreg, *srcreg); 1416 break; 1417 } 1418 DECODE_CLEAR_SEGOVR(); 1419 END_OF_INSTR(); 1420} 1421 1422/**************************************************************************** 1423REMARKS: 1424Handles opcode 0x19 1425****************************************************************************/ 1426static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1)) 1427{ 1428 int mod, rl, rh; 1429 uint destoffset; 1430 1431 START_OF_INSTR(); 1432 DECODE_PRINTF("SBB\t"); 1433 FETCH_DECODE_MODRM(mod, rh, rl); 1434 switch (mod) { 1435 case 0: 1436 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1437 u32 destval; 1438 u32 *srcreg; 1439 1440 destoffset = decode_rm00_address(rl); 1441 DECODE_PRINTF(","); 1442 destval = fetch_data_long(destoffset); 1443 srcreg = DECODE_RM_LONG_REGISTER(rh); 1444 DECODE_PRINTF("\n"); 1445 TRACE_AND_STEP(); 1446 destval = sbb_long(destval, *srcreg); 1447 store_data_long(destoffset, destval); 1448 } else { 1449 u16 destval; 1450 u16 *srcreg; 1451 1452 destoffset = decode_rm00_address(rl); 1453 DECODE_PRINTF(","); 1454 destval = fetch_data_word(destoffset); 1455 srcreg = DECODE_RM_WORD_REGISTER(rh); 1456 DECODE_PRINTF("\n"); 1457 TRACE_AND_STEP(); 1458 destval = sbb_word(destval, *srcreg); 1459 store_data_word(destoffset, destval); 1460 } 1461 break; 1462 case 1: 1463 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1464 u32 destval; 1465 u32 *srcreg; 1466 1467 destoffset = decode_rm01_address(rl); 1468 DECODE_PRINTF(","); 1469 destval = fetch_data_long(destoffset); 1470 srcreg = DECODE_RM_LONG_REGISTER(rh); 1471 DECODE_PRINTF("\n"); 1472 TRACE_AND_STEP(); 1473 destval = sbb_long(destval, *srcreg); 1474 store_data_long(destoffset, destval); 1475 } else { 1476 u16 destval; 1477 u16 *srcreg; 1478 1479 destoffset = decode_rm01_address(rl); 1480 DECODE_PRINTF(","); 1481 destval = fetch_data_word(destoffset); 1482 srcreg = DECODE_RM_WORD_REGISTER(rh); 1483 DECODE_PRINTF("\n"); 1484 TRACE_AND_STEP(); 1485 destval = sbb_word(destval, *srcreg); 1486 store_data_word(destoffset, destval); 1487 } 1488 break; 1489 case 2: 1490 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1491 u32 destval; 1492 u32 *srcreg; 1493 1494 destoffset = decode_rm10_address(rl); 1495 DECODE_PRINTF(","); 1496 destval = fetch_data_long(destoffset); 1497 srcreg = DECODE_RM_LONG_REGISTER(rh); 1498 DECODE_PRINTF("\n"); 1499 TRACE_AND_STEP(); 1500 destval = sbb_long(destval, *srcreg); 1501 store_data_long(destoffset, destval); 1502 } else { 1503 u16 destval; 1504 u16 *srcreg; 1505 1506 destoffset = decode_rm10_address(rl); 1507 DECODE_PRINTF(","); 1508 destval = fetch_data_word(destoffset); 1509 srcreg = DECODE_RM_WORD_REGISTER(rh); 1510 DECODE_PRINTF("\n"); 1511 TRACE_AND_STEP(); 1512 destval = sbb_word(destval, *srcreg); 1513 store_data_word(destoffset, destval); 1514 } 1515 break; 1516 case 3: /* register to register */ 1517 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1518 u32 *destreg,*srcreg; 1519 1520 destreg = DECODE_RM_LONG_REGISTER(rl); 1521 DECODE_PRINTF(","); 1522 srcreg = DECODE_RM_LONG_REGISTER(rh); 1523 DECODE_PRINTF("\n"); 1524 TRACE_AND_STEP(); 1525 *destreg = sbb_long(*destreg, *srcreg); 1526 } else { 1527 u16 *destreg,*srcreg; 1528 1529 destreg = DECODE_RM_WORD_REGISTER(rl); 1530 DECODE_PRINTF(","); 1531 srcreg = DECODE_RM_WORD_REGISTER(rh); 1532 DECODE_PRINTF("\n"); 1533 TRACE_AND_STEP(); 1534 *destreg = sbb_word(*destreg, *srcreg); 1535 } 1536 break; 1537 } 1538 DECODE_CLEAR_SEGOVR(); 1539 END_OF_INSTR(); 1540} 1541 1542/**************************************************************************** 1543REMARKS: 1544Handles opcode 0x1a 1545****************************************************************************/ 1546static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1547{ 1548 int mod, rl, rh; 1549 u8 *destreg, *srcreg; 1550 uint srcoffset; 1551 u8 srcval; 1552 1553 START_OF_INSTR(); 1554 DECODE_PRINTF("SBB\t"); 1555 FETCH_DECODE_MODRM(mod, rh, rl); 1556 switch (mod) { 1557 case 0: 1558 destreg = DECODE_RM_BYTE_REGISTER(rh); 1559 DECODE_PRINTF(","); 1560 srcoffset = decode_rm00_address(rl); 1561 srcval = fetch_data_byte(srcoffset); 1562 DECODE_PRINTF("\n"); 1563 TRACE_AND_STEP(); 1564 *destreg = sbb_byte(*destreg, srcval); 1565 break; 1566 case 1: 1567 destreg = DECODE_RM_BYTE_REGISTER(rh); 1568 DECODE_PRINTF(","); 1569 srcoffset = decode_rm01_address(rl); 1570 srcval = fetch_data_byte(srcoffset); 1571 DECODE_PRINTF("\n"); 1572 TRACE_AND_STEP(); 1573 *destreg = sbb_byte(*destreg, srcval); 1574 break; 1575 case 2: 1576 destreg = DECODE_RM_BYTE_REGISTER(rh); 1577 DECODE_PRINTF(","); 1578 srcoffset = decode_rm10_address(rl); 1579 srcval = fetch_data_byte(srcoffset); 1580 DECODE_PRINTF("\n"); 1581 TRACE_AND_STEP(); 1582 *destreg = sbb_byte(*destreg, srcval); 1583 break; 1584 case 3: /* register to register */ 1585 destreg = DECODE_RM_BYTE_REGISTER(rh); 1586 DECODE_PRINTF(","); 1587 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1588 DECODE_PRINTF("\n"); 1589 TRACE_AND_STEP(); 1590 *destreg = sbb_byte(*destreg, *srcreg); 1591 break; 1592 } 1593 DECODE_CLEAR_SEGOVR(); 1594 END_OF_INSTR(); 1595} 1596 1597/**************************************************************************** 1598REMARKS: 1599Handles opcode 0x1b 1600****************************************************************************/ 1601static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1)) 1602{ 1603 int mod, rl, rh; 1604 uint srcoffset; 1605 1606 START_OF_INSTR(); 1607 DECODE_PRINTF("SBB\t"); 1608 FETCH_DECODE_MODRM(mod, rh, rl); 1609 switch (mod) { 1610 case 0: 1611 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1612 u32 *destreg; 1613 u32 srcval; 1614 1615 destreg = DECODE_RM_LONG_REGISTER(rh); 1616 DECODE_PRINTF(","); 1617 srcoffset = decode_rm00_address(rl); 1618 srcval = fetch_data_long(srcoffset); 1619 DECODE_PRINTF("\n"); 1620 TRACE_AND_STEP(); 1621 *destreg = sbb_long(*destreg, srcval); 1622 } else { 1623 u16 *destreg; 1624 u16 srcval; 1625 1626 destreg = DECODE_RM_WORD_REGISTER(rh); 1627 DECODE_PRINTF(","); 1628 srcoffset = decode_rm00_address(rl); 1629 srcval = fetch_data_word(srcoffset); 1630 DECODE_PRINTF("\n"); 1631 TRACE_AND_STEP(); 1632 *destreg = sbb_word(*destreg, srcval); 1633 } 1634 break; 1635 case 1: 1636 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1637 u32 *destreg; 1638 u32 srcval; 1639 1640 destreg = DECODE_RM_LONG_REGISTER(rh); 1641 DECODE_PRINTF(","); 1642 srcoffset = decode_rm01_address(rl); 1643 srcval = fetch_data_long(srcoffset); 1644 DECODE_PRINTF("\n"); 1645 TRACE_AND_STEP(); 1646 *destreg = sbb_long(*destreg, srcval); 1647 } else { 1648 u16 *destreg; 1649 u16 srcval; 1650 1651 destreg = DECODE_RM_WORD_REGISTER(rh); 1652 DECODE_PRINTF(","); 1653 srcoffset = decode_rm01_address(rl); 1654 srcval = fetch_data_word(srcoffset); 1655 DECODE_PRINTF("\n"); 1656 TRACE_AND_STEP(); 1657 *destreg = sbb_word(*destreg, srcval); 1658 } 1659 break; 1660 case 2: 1661 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1662 u32 *destreg; 1663 u32 srcval; 1664 1665 destreg = DECODE_RM_LONG_REGISTER(rh); 1666 DECODE_PRINTF(","); 1667 srcoffset = decode_rm10_address(rl); 1668 srcval = fetch_data_long(srcoffset); 1669 DECODE_PRINTF("\n"); 1670 TRACE_AND_STEP(); 1671 *destreg = sbb_long(*destreg, srcval); 1672 } else { 1673 u16 *destreg; 1674 u16 srcval; 1675 1676 destreg = DECODE_RM_WORD_REGISTER(rh); 1677 DECODE_PRINTF(","); 1678 srcoffset = decode_rm10_address(rl); 1679 srcval = fetch_data_word(srcoffset); 1680 DECODE_PRINTF("\n"); 1681 TRACE_AND_STEP(); 1682 *destreg = sbb_word(*destreg, srcval); 1683 } 1684 break; 1685 case 3: /* register to register */ 1686 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1687 u32 *destreg,*srcreg; 1688 1689 destreg = DECODE_RM_LONG_REGISTER(rh); 1690 DECODE_PRINTF(","); 1691 srcreg = DECODE_RM_LONG_REGISTER(rl); 1692 DECODE_PRINTF("\n"); 1693 TRACE_AND_STEP(); 1694 *destreg = sbb_long(*destreg, *srcreg); 1695 } else { 1696 u16 *destreg,*srcreg; 1697 1698 destreg = DECODE_RM_WORD_REGISTER(rh); 1699 DECODE_PRINTF(","); 1700 srcreg = DECODE_RM_WORD_REGISTER(rl); 1701 DECODE_PRINTF("\n"); 1702 TRACE_AND_STEP(); 1703 *destreg = sbb_word(*destreg, *srcreg); 1704 } 1705 break; 1706 } 1707 DECODE_CLEAR_SEGOVR(); 1708 END_OF_INSTR(); 1709} 1710 1711/**************************************************************************** 1712REMARKS: 1713Handles opcode 0x1c 1714****************************************************************************/ 1715static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1716{ 1717 u8 srcval; 1718 1719 START_OF_INSTR(); 1720 DECODE_PRINTF("SBB\tAL,"); 1721 srcval = fetch_byte_imm(); 1722 DECODE_PRINTF2("%x\n", srcval); 1723 TRACE_AND_STEP(); 1724 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval); 1725 DECODE_CLEAR_SEGOVR(); 1726 END_OF_INSTR(); 1727} 1728 1729/**************************************************************************** 1730REMARKS: 1731Handles opcode 0x1d 1732****************************************************************************/ 1733static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1734{ 1735 u32 srcval; 1736 1737 START_OF_INSTR(); 1738 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1739 DECODE_PRINTF("SBB\tEAX,"); 1740 srcval = fetch_long_imm(); 1741 } else { 1742 DECODE_PRINTF("SBB\tAX,"); 1743 srcval = fetch_word_imm(); 1744 } 1745 DECODE_PRINTF2("%x\n", srcval); 1746 TRACE_AND_STEP(); 1747 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1748 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval); 1749 } else { 1750 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval); 1751 } 1752 DECODE_CLEAR_SEGOVR(); 1753 END_OF_INSTR(); 1754} 1755 1756/**************************************************************************** 1757REMARKS: 1758Handles opcode 0x1e 1759****************************************************************************/ 1760static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 1761{ 1762 START_OF_INSTR(); 1763 DECODE_PRINTF("PUSH\tDS\n"); 1764 TRACE_AND_STEP(); 1765 push_word(M.x86.R_DS); 1766 DECODE_CLEAR_SEGOVR(); 1767 END_OF_INSTR(); 1768} 1769 1770/**************************************************************************** 1771REMARKS: 1772Handles opcode 0x1f 1773****************************************************************************/ 1774static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 1775{ 1776 START_OF_INSTR(); 1777 DECODE_PRINTF("POP\tDS\n"); 1778 TRACE_AND_STEP(); 1779 M.x86.R_DS = pop_word(); 1780 DECODE_CLEAR_SEGOVR(); 1781 END_OF_INSTR(); 1782} 1783 1784/**************************************************************************** 1785REMARKS: 1786Handles opcode 0x20 1787****************************************************************************/ 1788static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1789{ 1790 int mod, rl, rh; 1791 u8 *destreg, *srcreg; 1792 uint destoffset; 1793 u8 destval; 1794 1795 START_OF_INSTR(); 1796 DECODE_PRINTF("AND\t"); 1797 FETCH_DECODE_MODRM(mod, rh, rl); 1798 1799 switch (mod) { 1800 case 0: 1801 destoffset = decode_rm00_address(rl); 1802 DECODE_PRINTF(","); 1803 destval = fetch_data_byte(destoffset); 1804 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1805 DECODE_PRINTF("\n"); 1806 TRACE_AND_STEP(); 1807 destval = and_byte(destval, *srcreg); 1808 store_data_byte(destoffset, destval); 1809 break; 1810 1811 case 1: 1812 destoffset = decode_rm01_address(rl); 1813 DECODE_PRINTF(","); 1814 destval = fetch_data_byte(destoffset); 1815 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1816 DECODE_PRINTF("\n"); 1817 TRACE_AND_STEP(); 1818 destval = and_byte(destval, *srcreg); 1819 store_data_byte(destoffset, destval); 1820 break; 1821 1822 case 2: 1823 destoffset = decode_rm10_address(rl); 1824 DECODE_PRINTF(","); 1825 destval = fetch_data_byte(destoffset); 1826 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1827 DECODE_PRINTF("\n"); 1828 TRACE_AND_STEP(); 1829 destval = and_byte(destval, *srcreg); 1830 store_data_byte(destoffset, destval); 1831 break; 1832 1833 case 3: /* register to register */ 1834 destreg = DECODE_RM_BYTE_REGISTER(rl); 1835 DECODE_PRINTF(","); 1836 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1837 DECODE_PRINTF("\n"); 1838 TRACE_AND_STEP(); 1839 *destreg = and_byte(*destreg, *srcreg); 1840 break; 1841 } 1842 DECODE_CLEAR_SEGOVR(); 1843 END_OF_INSTR(); 1844} 1845 1846/**************************************************************************** 1847REMARKS: 1848Handles opcode 0x21 1849****************************************************************************/ 1850static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1)) 1851{ 1852 int mod, rl, rh; 1853 uint destoffset; 1854 1855 START_OF_INSTR(); 1856 DECODE_PRINTF("AND\t"); 1857 FETCH_DECODE_MODRM(mod, rh, rl); 1858 switch (mod) { 1859 case 0: 1860 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1861 u32 destval; 1862 u32 *srcreg; 1863 1864 destoffset = decode_rm00_address(rl); 1865 DECODE_PRINTF(","); 1866 destval = fetch_data_long(destoffset); 1867 srcreg = DECODE_RM_LONG_REGISTER(rh); 1868 DECODE_PRINTF("\n"); 1869 TRACE_AND_STEP(); 1870 destval = and_long(destval, *srcreg); 1871 store_data_long(destoffset, destval); 1872 } else { 1873 u16 destval; 1874 u16 *srcreg; 1875 1876 destoffset = decode_rm00_address(rl); 1877 DECODE_PRINTF(","); 1878 destval = fetch_data_word(destoffset); 1879 srcreg = DECODE_RM_WORD_REGISTER(rh); 1880 DECODE_PRINTF("\n"); 1881 TRACE_AND_STEP(); 1882 destval = and_word(destval, *srcreg); 1883 store_data_word(destoffset, destval); 1884 } 1885 break; 1886 case 1: 1887 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1888 u32 destval; 1889 u32 *srcreg; 1890 1891 destoffset = decode_rm01_address(rl); 1892 DECODE_PRINTF(","); 1893 destval = fetch_data_long(destoffset); 1894 srcreg = DECODE_RM_LONG_REGISTER(rh); 1895 DECODE_PRINTF("\n"); 1896 TRACE_AND_STEP(); 1897 destval = and_long(destval, *srcreg); 1898 store_data_long(destoffset, destval); 1899 } else { 1900 u16 destval; 1901 u16 *srcreg; 1902 1903 destoffset = decode_rm01_address(rl); 1904 DECODE_PRINTF(","); 1905 destval = fetch_data_word(destoffset); 1906 srcreg = DECODE_RM_WORD_REGISTER(rh); 1907 DECODE_PRINTF("\n"); 1908 TRACE_AND_STEP(); 1909 destval = and_word(destval, *srcreg); 1910 store_data_word(destoffset, destval); 1911 } 1912 break; 1913 case 2: 1914 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1915 u32 destval; 1916 u32 *srcreg; 1917 1918 destoffset = decode_rm10_address(rl); 1919 DECODE_PRINTF(","); 1920 destval = fetch_data_long(destoffset); 1921 srcreg = DECODE_RM_LONG_REGISTER(rh); 1922 DECODE_PRINTF("\n"); 1923 TRACE_AND_STEP(); 1924 destval = and_long(destval, *srcreg); 1925 store_data_long(destoffset, destval); 1926 } else { 1927 u16 destval; 1928 u16 *srcreg; 1929 1930 destoffset = decode_rm10_address(rl); 1931 DECODE_PRINTF(","); 1932 destval = fetch_data_word(destoffset); 1933 srcreg = DECODE_RM_WORD_REGISTER(rh); 1934 DECODE_PRINTF("\n"); 1935 TRACE_AND_STEP(); 1936 destval = and_word(destval, *srcreg); 1937 store_data_word(destoffset, destval); 1938 } 1939 break; 1940 case 3: /* register to register */ 1941 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1942 u32 *destreg,*srcreg; 1943 1944 destreg = DECODE_RM_LONG_REGISTER(rl); 1945 DECODE_PRINTF(","); 1946 srcreg = DECODE_RM_LONG_REGISTER(rh); 1947 DECODE_PRINTF("\n"); 1948 TRACE_AND_STEP(); 1949 *destreg = and_long(*destreg, *srcreg); 1950 } else { 1951 u16 *destreg,*srcreg; 1952 1953 destreg = DECODE_RM_WORD_REGISTER(rl); 1954 DECODE_PRINTF(","); 1955 srcreg = DECODE_RM_WORD_REGISTER(rh); 1956 DECODE_PRINTF("\n"); 1957 TRACE_AND_STEP(); 1958 *destreg = and_word(*destreg, *srcreg); 1959 } 1960 break; 1961 } 1962 DECODE_CLEAR_SEGOVR(); 1963 END_OF_INSTR(); 1964} 1965 1966/**************************************************************************** 1967REMARKS: 1968Handles opcode 0x22 1969****************************************************************************/ 1970static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1971{ 1972 int mod, rl, rh; 1973 u8 *destreg, *srcreg; 1974 uint srcoffset; 1975 u8 srcval; 1976 1977 START_OF_INSTR(); 1978 DECODE_PRINTF("AND\t"); 1979 FETCH_DECODE_MODRM(mod, rh, rl); 1980 switch (mod) { 1981 case 0: 1982 destreg = DECODE_RM_BYTE_REGISTER(rh); 1983 DECODE_PRINTF(","); 1984 srcoffset = decode_rm00_address(rl); 1985 srcval = fetch_data_byte(srcoffset); 1986 DECODE_PRINTF("\n"); 1987 TRACE_AND_STEP(); 1988 *destreg = and_byte(*destreg, srcval); 1989 break; 1990 case 1: 1991 destreg = DECODE_RM_BYTE_REGISTER(rh); 1992 DECODE_PRINTF(","); 1993 srcoffset = decode_rm01_address(rl); 1994 srcval = fetch_data_byte(srcoffset); 1995 DECODE_PRINTF("\n"); 1996 TRACE_AND_STEP(); 1997 *destreg = and_byte(*destreg, srcval); 1998 break; 1999 case 2: 2000 destreg = DECODE_RM_BYTE_REGISTER(rh); 2001 DECODE_PRINTF(","); 2002 srcoffset = decode_rm10_address(rl); 2003 srcval = fetch_data_byte(srcoffset); 2004 DECODE_PRINTF("\n"); 2005 TRACE_AND_STEP(); 2006 *destreg = and_byte(*destreg, srcval); 2007 break; 2008 case 3: /* register to register */ 2009 destreg = DECODE_RM_BYTE_REGISTER(rh); 2010 DECODE_PRINTF(","); 2011 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2012 DECODE_PRINTF("\n"); 2013 TRACE_AND_STEP(); 2014 *destreg = and_byte(*destreg, *srcreg); 2015 break; 2016 } 2017 DECODE_CLEAR_SEGOVR(); 2018 END_OF_INSTR(); 2019} 2020 2021/**************************************************************************** 2022REMARKS: 2023Handles opcode 0x23 2024****************************************************************************/ 2025static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1)) 2026{ 2027 int mod, rl, rh; 2028 uint srcoffset; 2029 2030 START_OF_INSTR(); 2031 DECODE_PRINTF("AND\t"); 2032 FETCH_DECODE_MODRM(mod, rh, rl); 2033 switch (mod) { 2034 case 0: 2035 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2036 u32 *destreg; 2037 u32 srcval; 2038 2039 destreg = DECODE_RM_LONG_REGISTER(rh); 2040 DECODE_PRINTF(","); 2041 srcoffset = decode_rm00_address(rl); 2042 srcval = fetch_data_long(srcoffset); 2043 DECODE_PRINTF("\n"); 2044 TRACE_AND_STEP(); 2045 *destreg = and_long(*destreg, srcval); 2046 } else { 2047 u16 *destreg; 2048 u16 srcval; 2049 2050 destreg = DECODE_RM_WORD_REGISTER(rh); 2051 DECODE_PRINTF(","); 2052 srcoffset = decode_rm00_address(rl); 2053 srcval = fetch_data_word(srcoffset); 2054 DECODE_PRINTF("\n"); 2055 TRACE_AND_STEP(); 2056 *destreg = and_word(*destreg, srcval); 2057 } 2058 break; 2059 case 1: 2060 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2061 u32 *destreg; 2062 u32 srcval; 2063 2064 destreg = DECODE_RM_LONG_REGISTER(rh); 2065 DECODE_PRINTF(","); 2066 srcoffset = decode_rm01_address(rl); 2067 srcval = fetch_data_long(srcoffset); 2068 DECODE_PRINTF("\n"); 2069 TRACE_AND_STEP(); 2070 *destreg = and_long(*destreg, srcval); 2071 break; 2072 } else { 2073 u16 *destreg; 2074 u16 srcval; 2075 2076 destreg = DECODE_RM_WORD_REGISTER(rh); 2077 DECODE_PRINTF(","); 2078 srcoffset = decode_rm01_address(rl); 2079 srcval = fetch_data_word(srcoffset); 2080 DECODE_PRINTF("\n"); 2081 TRACE_AND_STEP(); 2082 *destreg = and_word(*destreg, srcval); 2083 break; 2084 } 2085 case 2: 2086 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2087 u32 *destreg; 2088 u32 srcval; 2089 2090 destreg = DECODE_RM_LONG_REGISTER(rh); 2091 DECODE_PRINTF(","); 2092 srcoffset = decode_rm10_address(rl); 2093 srcval = fetch_data_long(srcoffset); 2094 DECODE_PRINTF("\n"); 2095 TRACE_AND_STEP(); 2096 *destreg = and_long(*destreg, srcval); 2097 } else { 2098 u16 *destreg; 2099 u16 srcval; 2100 2101 destreg = DECODE_RM_WORD_REGISTER(rh); 2102 DECODE_PRINTF(","); 2103 srcoffset = decode_rm10_address(rl); 2104 srcval = fetch_data_word(srcoffset); 2105 DECODE_PRINTF("\n"); 2106 TRACE_AND_STEP(); 2107 *destreg = and_word(*destreg, srcval); 2108 } 2109 break; 2110 case 3: /* register to register */ 2111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2112 u32 *destreg,*srcreg; 2113 2114 destreg = DECODE_RM_LONG_REGISTER(rh); 2115 DECODE_PRINTF(","); 2116 srcreg = DECODE_RM_LONG_REGISTER(rl); 2117 DECODE_PRINTF("\n"); 2118 TRACE_AND_STEP(); 2119 *destreg = and_long(*destreg, *srcreg); 2120 } else { 2121 u16 *destreg,*srcreg; 2122 2123 destreg = DECODE_RM_WORD_REGISTER(rh); 2124 DECODE_PRINTF(","); 2125 srcreg = DECODE_RM_WORD_REGISTER(rl); 2126 DECODE_PRINTF("\n"); 2127 TRACE_AND_STEP(); 2128 *destreg = and_word(*destreg, *srcreg); 2129 } 2130 break; 2131 } 2132 DECODE_CLEAR_SEGOVR(); 2133 END_OF_INSTR(); 2134} 2135 2136/**************************************************************************** 2137REMARKS: 2138Handles opcode 0x24 2139****************************************************************************/ 2140static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2141{ 2142 u8 srcval; 2143 2144 START_OF_INSTR(); 2145 DECODE_PRINTF("AND\tAL,"); 2146 srcval = fetch_byte_imm(); 2147 DECODE_PRINTF2("%x\n", srcval); 2148 TRACE_AND_STEP(); 2149 M.x86.R_AL = and_byte(M.x86.R_AL, srcval); 2150 DECODE_CLEAR_SEGOVR(); 2151 END_OF_INSTR(); 2152} 2153 2154/**************************************************************************** 2155REMARKS: 2156Handles opcode 0x25 2157****************************************************************************/ 2158static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2159{ 2160 u32 srcval; 2161 2162 START_OF_INSTR(); 2163 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2164 DECODE_PRINTF("AND\tEAX,"); 2165 srcval = fetch_long_imm(); 2166 } else { 2167 DECODE_PRINTF("AND\tAX,"); 2168 srcval = fetch_word_imm(); 2169 } 2170 DECODE_PRINTF2("%x\n", srcval); 2171 TRACE_AND_STEP(); 2172 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2173 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval); 2174 } else { 2175 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval); 2176 } 2177 DECODE_CLEAR_SEGOVR(); 2178 END_OF_INSTR(); 2179} 2180 2181/**************************************************************************** 2182REMARKS: 2183Handles opcode 0x26 2184****************************************************************************/ 2185static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 2186{ 2187 START_OF_INSTR(); 2188 DECODE_PRINTF("ES:\n"); 2189 TRACE_AND_STEP(); 2190 M.x86.mode |= SYSMODE_SEGOVR_ES; 2191 /* 2192 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 2193 * opcode subroutines we do not want to do this. 2194 */ 2195 END_OF_INSTR(); 2196} 2197 2198/**************************************************************************** 2199REMARKS: 2200Handles opcode 0x27 2201****************************************************************************/ 2202static void x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 2203{ 2204 START_OF_INSTR(); 2205 DECODE_PRINTF("DAA\n"); 2206 TRACE_AND_STEP(); 2207 M.x86.R_AL = daa_byte(M.x86.R_AL); 2208 DECODE_CLEAR_SEGOVR(); 2209 END_OF_INSTR(); 2210} 2211 2212/**************************************************************************** 2213REMARKS: 2214Handles opcode 0x28 2215****************************************************************************/ 2216static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2217{ 2218 int mod, rl, rh; 2219 u8 *destreg, *srcreg; 2220 uint destoffset; 2221 u8 destval; 2222 2223 START_OF_INSTR(); 2224 DECODE_PRINTF("SUB\t"); 2225 FETCH_DECODE_MODRM(mod, rh, rl); 2226 switch (mod) { 2227 case 0: 2228 destoffset = decode_rm00_address(rl); 2229 DECODE_PRINTF(","); 2230 destval = fetch_data_byte(destoffset); 2231 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2232 DECODE_PRINTF("\n"); 2233 TRACE_AND_STEP(); 2234 destval = sub_byte(destval, *srcreg); 2235 store_data_byte(destoffset, destval); 2236 break; 2237 case 1: 2238 destoffset = decode_rm01_address(rl); 2239 DECODE_PRINTF(","); 2240 destval = fetch_data_byte(destoffset); 2241 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2242 DECODE_PRINTF("\n"); 2243 TRACE_AND_STEP(); 2244 destval = sub_byte(destval, *srcreg); 2245 store_data_byte(destoffset, destval); 2246 break; 2247 case 2: 2248 destoffset = decode_rm10_address(rl); 2249 DECODE_PRINTF(","); 2250 destval = fetch_data_byte(destoffset); 2251 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2252 DECODE_PRINTF("\n"); 2253 TRACE_AND_STEP(); 2254 destval = sub_byte(destval, *srcreg); 2255 store_data_byte(destoffset, destval); 2256 break; 2257 case 3: /* register to register */ 2258 destreg = DECODE_RM_BYTE_REGISTER(rl); 2259 DECODE_PRINTF(","); 2260 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2261 DECODE_PRINTF("\n"); 2262 TRACE_AND_STEP(); 2263 *destreg = sub_byte(*destreg, *srcreg); 2264 break; 2265 } 2266 DECODE_CLEAR_SEGOVR(); 2267 END_OF_INSTR(); 2268} 2269 2270/**************************************************************************** 2271REMARKS: 2272Handles opcode 0x29 2273****************************************************************************/ 2274static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1)) 2275{ 2276 int mod, rl, rh; 2277 uint destoffset; 2278 2279 START_OF_INSTR(); 2280 DECODE_PRINTF("SUB\t"); 2281 FETCH_DECODE_MODRM(mod, rh, rl); 2282 switch (mod) { 2283 case 0: 2284 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2285 u32 destval; 2286 u32 *srcreg; 2287 2288 destoffset = decode_rm00_address(rl); 2289 DECODE_PRINTF(","); 2290 destval = fetch_data_long(destoffset); 2291 srcreg = DECODE_RM_LONG_REGISTER(rh); 2292 DECODE_PRINTF("\n"); 2293 TRACE_AND_STEP(); 2294 destval = sub_long(destval, *srcreg); 2295 store_data_long(destoffset, destval); 2296 } else { 2297 u16 destval; 2298 u16 *srcreg; 2299 2300 destoffset = decode_rm00_address(rl); 2301 DECODE_PRINTF(","); 2302 destval = fetch_data_word(destoffset); 2303 srcreg = DECODE_RM_WORD_REGISTER(rh); 2304 DECODE_PRINTF("\n"); 2305 TRACE_AND_STEP(); 2306 destval = sub_word(destval, *srcreg); 2307 store_data_word(destoffset, destval); 2308 } 2309 break; 2310 case 1: 2311 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2312 u32 destval; 2313 u32 *srcreg; 2314 2315 destoffset = decode_rm01_address(rl); 2316 DECODE_PRINTF(","); 2317 destval = fetch_data_long(destoffset); 2318 srcreg = DECODE_RM_LONG_REGISTER(rh); 2319 DECODE_PRINTF("\n"); 2320 TRACE_AND_STEP(); 2321 destval = sub_long(destval, *srcreg); 2322 store_data_long(destoffset, destval); 2323 } else { 2324 u16 destval; 2325 u16 *srcreg; 2326 2327 destoffset = decode_rm01_address(rl); 2328 DECODE_PRINTF(","); 2329 destval = fetch_data_word(destoffset); 2330 srcreg = DECODE_RM_WORD_REGISTER(rh); 2331 DECODE_PRINTF("\n"); 2332 TRACE_AND_STEP(); 2333 destval = sub_word(destval, *srcreg); 2334 store_data_word(destoffset, destval); 2335 } 2336 break; 2337 case 2: 2338 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2339 u32 destval; 2340 u32 *srcreg; 2341 2342 destoffset = decode_rm10_address(rl); 2343 DECODE_PRINTF(","); 2344 destval = fetch_data_long(destoffset); 2345 srcreg = DECODE_RM_LONG_REGISTER(rh); 2346 DECODE_PRINTF("\n"); 2347 TRACE_AND_STEP(); 2348 destval = sub_long(destval, *srcreg); 2349 store_data_long(destoffset, destval); 2350 } else { 2351 u16 destval; 2352 u16 *srcreg; 2353 2354 destoffset = decode_rm10_address(rl); 2355 DECODE_PRINTF(","); 2356 destval = fetch_data_word(destoffset); 2357 srcreg = DECODE_RM_WORD_REGISTER(rh); 2358 DECODE_PRINTF("\n"); 2359 TRACE_AND_STEP(); 2360 destval = sub_word(destval, *srcreg); 2361 store_data_word(destoffset, destval); 2362 } 2363 break; 2364 case 3: /* register to register */ 2365 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2366 u32 *destreg,*srcreg; 2367 2368 destreg = DECODE_RM_LONG_REGISTER(rl); 2369 DECODE_PRINTF(","); 2370 srcreg = DECODE_RM_LONG_REGISTER(rh); 2371 DECODE_PRINTF("\n"); 2372 TRACE_AND_STEP(); 2373 *destreg = sub_long(*destreg, *srcreg); 2374 } else { 2375 u16 *destreg,*srcreg; 2376 2377 destreg = DECODE_RM_WORD_REGISTER(rl); 2378 DECODE_PRINTF(","); 2379 srcreg = DECODE_RM_WORD_REGISTER(rh); 2380 DECODE_PRINTF("\n"); 2381 TRACE_AND_STEP(); 2382 *destreg = sub_word(*destreg, *srcreg); 2383 } 2384 break; 2385 } 2386 DECODE_CLEAR_SEGOVR(); 2387 END_OF_INSTR(); 2388} 2389 2390/**************************************************************************** 2391REMARKS: 2392Handles opcode 0x2a 2393****************************************************************************/ 2394static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2395{ 2396 int mod, rl, rh; 2397 u8 *destreg, *srcreg; 2398 uint srcoffset; 2399 u8 srcval; 2400 2401 START_OF_INSTR(); 2402 DECODE_PRINTF("SUB\t"); 2403 FETCH_DECODE_MODRM(mod, rh, rl); 2404 switch (mod) { 2405 case 0: 2406 destreg = DECODE_RM_BYTE_REGISTER(rh); 2407 DECODE_PRINTF(","); 2408 srcoffset = decode_rm00_address(rl); 2409 srcval = fetch_data_byte(srcoffset); 2410 DECODE_PRINTF("\n"); 2411 TRACE_AND_STEP(); 2412 *destreg = sub_byte(*destreg, srcval); 2413 break; 2414 case 1: 2415 destreg = DECODE_RM_BYTE_REGISTER(rh); 2416 DECODE_PRINTF(","); 2417 srcoffset = decode_rm01_address(rl); 2418 srcval = fetch_data_byte(srcoffset); 2419 DECODE_PRINTF("\n"); 2420 TRACE_AND_STEP(); 2421 *destreg = sub_byte(*destreg, srcval); 2422 break; 2423 case 2: 2424 destreg = DECODE_RM_BYTE_REGISTER(rh); 2425 DECODE_PRINTF(","); 2426 srcoffset = decode_rm10_address(rl); 2427 srcval = fetch_data_byte(srcoffset); 2428 DECODE_PRINTF("\n"); 2429 TRACE_AND_STEP(); 2430 *destreg = sub_byte(*destreg, srcval); 2431 break; 2432 case 3: /* register to register */ 2433 destreg = DECODE_RM_BYTE_REGISTER(rh); 2434 DECODE_PRINTF(","); 2435 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2436 DECODE_PRINTF("\n"); 2437 TRACE_AND_STEP(); 2438 *destreg = sub_byte(*destreg, *srcreg); 2439 break; 2440 } 2441 DECODE_CLEAR_SEGOVR(); 2442 END_OF_INSTR(); 2443} 2444 2445/**************************************************************************** 2446REMARKS: 2447Handles opcode 0x2b 2448****************************************************************************/ 2449static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1)) 2450{ 2451 int mod, rl, rh; 2452 uint srcoffset; 2453 2454 START_OF_INSTR(); 2455 DECODE_PRINTF("SUB\t"); 2456 FETCH_DECODE_MODRM(mod, rh, rl); 2457 switch (mod) { 2458 case 0: 2459 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2460 u32 *destreg; 2461 u32 srcval; 2462 2463 destreg = DECODE_RM_LONG_REGISTER(rh); 2464 DECODE_PRINTF(","); 2465 srcoffset = decode_rm00_address(rl); 2466 srcval = fetch_data_long(srcoffset); 2467 DECODE_PRINTF("\n"); 2468 TRACE_AND_STEP(); 2469 *destreg = sub_long(*destreg, srcval); 2470 } else { 2471 u16 *destreg; 2472 u16 srcval; 2473 2474 destreg = DECODE_RM_WORD_REGISTER(rh); 2475 DECODE_PRINTF(","); 2476 srcoffset = decode_rm00_address(rl); 2477 srcval = fetch_data_word(srcoffset); 2478 DECODE_PRINTF("\n"); 2479 TRACE_AND_STEP(); 2480 *destreg = sub_word(*destreg, srcval); 2481 } 2482 break; 2483 case 1: 2484 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2485 u32 *destreg; 2486 u32 srcval; 2487 2488 destreg = DECODE_RM_LONG_REGISTER(rh); 2489 DECODE_PRINTF(","); 2490 srcoffset = decode_rm01_address(rl); 2491 srcval = fetch_data_long(srcoffset); 2492 DECODE_PRINTF("\n"); 2493 TRACE_AND_STEP(); 2494 *destreg = sub_long(*destreg, srcval); 2495 } else { 2496 u16 *destreg; 2497 u16 srcval; 2498 2499 destreg = DECODE_RM_WORD_REGISTER(rh); 2500 DECODE_PRINTF(","); 2501 srcoffset = decode_rm01_address(rl); 2502 srcval = fetch_data_word(srcoffset); 2503 DECODE_PRINTF("\n"); 2504 TRACE_AND_STEP(); 2505 *destreg = sub_word(*destreg, srcval); 2506 } 2507 break; 2508 case 2: 2509 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2510 u32 *destreg; 2511 u32 srcval; 2512 2513 destreg = DECODE_RM_LONG_REGISTER(rh); 2514 DECODE_PRINTF(","); 2515 srcoffset = decode_rm10_address(rl); 2516 srcval = fetch_data_long(srcoffset); 2517 DECODE_PRINTF("\n"); 2518 TRACE_AND_STEP(); 2519 *destreg = sub_long(*destreg, srcval); 2520 } else { 2521 u16 *destreg; 2522 u16 srcval; 2523 2524 destreg = DECODE_RM_WORD_REGISTER(rh); 2525 DECODE_PRINTF(","); 2526 srcoffset = decode_rm10_address(rl); 2527 srcval = fetch_data_word(srcoffset); 2528 DECODE_PRINTF("\n"); 2529 TRACE_AND_STEP(); 2530 *destreg = sub_word(*destreg, srcval); 2531 } 2532 break; 2533 case 3: /* register to register */ 2534 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2535 u32 *destreg,*srcreg; 2536 2537 destreg = DECODE_RM_LONG_REGISTER(rh); 2538 DECODE_PRINTF(","); 2539 srcreg = DECODE_RM_LONG_REGISTER(rl); 2540 DECODE_PRINTF("\n"); 2541 TRACE_AND_STEP(); 2542 *destreg = sub_long(*destreg, *srcreg); 2543 } else { 2544 u16 *destreg,*srcreg; 2545 2546 destreg = DECODE_RM_WORD_REGISTER(rh); 2547 DECODE_PRINTF(","); 2548 srcreg = DECODE_RM_WORD_REGISTER(rl); 2549 DECODE_PRINTF("\n"); 2550 TRACE_AND_STEP(); 2551 *destreg = sub_word(*destreg, *srcreg); 2552 } 2553 break; 2554 } 2555 DECODE_CLEAR_SEGOVR(); 2556 END_OF_INSTR(); 2557} 2558 2559/**************************************************************************** 2560REMARKS: 2561Handles opcode 0x2c 2562****************************************************************************/ 2563static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2564{ 2565 u8 srcval; 2566 2567 START_OF_INSTR(); 2568 DECODE_PRINTF("SUB\tAL,"); 2569 srcval = fetch_byte_imm(); 2570 DECODE_PRINTF2("%x\n", srcval); 2571 TRACE_AND_STEP(); 2572 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval); 2573 DECODE_CLEAR_SEGOVR(); 2574 END_OF_INSTR(); 2575} 2576 2577/**************************************************************************** 2578REMARKS: 2579Handles opcode 0x2d 2580****************************************************************************/ 2581static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2582{ 2583 u32 srcval; 2584 2585 START_OF_INSTR(); 2586 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2587 DECODE_PRINTF("SUB\tEAX,"); 2588 srcval = fetch_long_imm(); 2589 } else { 2590 DECODE_PRINTF("SUB\tAX,"); 2591 srcval = fetch_word_imm(); 2592 } 2593 DECODE_PRINTF2("%x\n", srcval); 2594 TRACE_AND_STEP(); 2595 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2596 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval); 2597 } else { 2598 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval); 2599 } 2600 DECODE_CLEAR_SEGOVR(); 2601 END_OF_INSTR(); 2602} 2603 2604/**************************************************************************** 2605REMARKS: 2606Handles opcode 0x2e 2607****************************************************************************/ 2608static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 2609{ 2610 START_OF_INSTR(); 2611 DECODE_PRINTF("CS:\n"); 2612 TRACE_AND_STEP(); 2613 M.x86.mode |= SYSMODE_SEGOVR_CS; 2614 /* note no DECODE_CLEAR_SEGOVR here. */ 2615 END_OF_INSTR(); 2616} 2617 2618/**************************************************************************** 2619REMARKS: 2620Handles opcode 0x2f 2621****************************************************************************/ 2622static void x86emuOp_das(u8 X86EMU_UNUSED(op1)) 2623{ 2624 START_OF_INSTR(); 2625 DECODE_PRINTF("DAS\n"); 2626 TRACE_AND_STEP(); 2627 M.x86.R_AL = das_byte(M.x86.R_AL); 2628 DECODE_CLEAR_SEGOVR(); 2629 END_OF_INSTR(); 2630} 2631 2632/**************************************************************************** 2633REMARKS: 2634Handles opcode 0x30 2635****************************************************************************/ 2636static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2637{ 2638 int mod, rl, rh; 2639 u8 *destreg, *srcreg; 2640 uint destoffset; 2641 u8 destval; 2642 2643 START_OF_INSTR(); 2644 DECODE_PRINTF("XOR\t"); 2645 FETCH_DECODE_MODRM(mod, rh, rl); 2646 switch (mod) { 2647 case 0: 2648 destoffset = decode_rm00_address(rl); 2649 DECODE_PRINTF(","); 2650 destval = fetch_data_byte(destoffset); 2651 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2652 DECODE_PRINTF("\n"); 2653 TRACE_AND_STEP(); 2654 destval = xor_byte(destval, *srcreg); 2655 store_data_byte(destoffset, destval); 2656 break; 2657 case 1: 2658 destoffset = decode_rm01_address(rl); 2659 DECODE_PRINTF(","); 2660 destval = fetch_data_byte(destoffset); 2661 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2662 DECODE_PRINTF("\n"); 2663 TRACE_AND_STEP(); 2664 destval = xor_byte(destval, *srcreg); 2665 store_data_byte(destoffset, destval); 2666 break; 2667 case 2: 2668 destoffset = decode_rm10_address(rl); 2669 DECODE_PRINTF(","); 2670 destval = fetch_data_byte(destoffset); 2671 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2672 DECODE_PRINTF("\n"); 2673 TRACE_AND_STEP(); 2674 destval = xor_byte(destval, *srcreg); 2675 store_data_byte(destoffset, destval); 2676 break; 2677 case 3: /* register to register */ 2678 destreg = DECODE_RM_BYTE_REGISTER(rl); 2679 DECODE_PRINTF(","); 2680 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2681 DECODE_PRINTF("\n"); 2682 TRACE_AND_STEP(); 2683 *destreg = xor_byte(*destreg, *srcreg); 2684 break; 2685 } 2686 DECODE_CLEAR_SEGOVR(); 2687 END_OF_INSTR(); 2688} 2689 2690/**************************************************************************** 2691REMARKS: 2692Handles opcode 0x31 2693****************************************************************************/ 2694static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1)) 2695{ 2696 int mod, rl, rh; 2697 uint destoffset; 2698 2699 START_OF_INSTR(); 2700 DECODE_PRINTF("XOR\t"); 2701 FETCH_DECODE_MODRM(mod, rh, rl); 2702 switch (mod) { 2703 case 0: 2704 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2705 u32 destval; 2706 u32 *srcreg; 2707 2708 destoffset = decode_rm00_address(rl); 2709 DECODE_PRINTF(","); 2710 destval = fetch_data_long(destoffset); 2711 srcreg = DECODE_RM_LONG_REGISTER(rh); 2712 DECODE_PRINTF("\n"); 2713 TRACE_AND_STEP(); 2714 destval = xor_long(destval, *srcreg); 2715 store_data_long(destoffset, destval); 2716 } else { 2717 u16 destval; 2718 u16 *srcreg; 2719 2720 destoffset = decode_rm00_address(rl); 2721 DECODE_PRINTF(","); 2722 destval = fetch_data_word(destoffset); 2723 srcreg = DECODE_RM_WORD_REGISTER(rh); 2724 DECODE_PRINTF("\n"); 2725 TRACE_AND_STEP(); 2726 destval = xor_word(destval, *srcreg); 2727 store_data_word(destoffset, destval); 2728 } 2729 break; 2730 case 1: 2731 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2732 u32 destval; 2733 u32 *srcreg; 2734 2735 destoffset = decode_rm01_address(rl); 2736 DECODE_PRINTF(","); 2737 destval = fetch_data_long(destoffset); 2738 srcreg = DECODE_RM_LONG_REGISTER(rh); 2739 DECODE_PRINTF("\n"); 2740 TRACE_AND_STEP(); 2741 destval = xor_long(destval, *srcreg); 2742 store_data_long(destoffset, destval); 2743 } else { 2744 u16 destval; 2745 u16 *srcreg; 2746 2747 destoffset = decode_rm01_address(rl); 2748 DECODE_PRINTF(","); 2749 destval = fetch_data_word(destoffset); 2750 srcreg = DECODE_RM_WORD_REGISTER(rh); 2751 DECODE_PRINTF("\n"); 2752 TRACE_AND_STEP(); 2753 destval = xor_word(destval, *srcreg); 2754 store_data_word(destoffset, destval); 2755 } 2756 break; 2757 case 2: 2758 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2759 u32 destval; 2760 u32 *srcreg; 2761 2762 destoffset = decode_rm10_address(rl); 2763 DECODE_PRINTF(","); 2764 destval = fetch_data_long(destoffset); 2765 srcreg = DECODE_RM_LONG_REGISTER(rh); 2766 DECODE_PRINTF("\n"); 2767 TRACE_AND_STEP(); 2768 destval = xor_long(destval, *srcreg); 2769 store_data_long(destoffset, destval); 2770 } else { 2771 u16 destval; 2772 u16 *srcreg; 2773 2774 destoffset = decode_rm10_address(rl); 2775 DECODE_PRINTF(","); 2776 destval = fetch_data_word(destoffset); 2777 srcreg = DECODE_RM_WORD_REGISTER(rh); 2778 DECODE_PRINTF("\n"); 2779 TRACE_AND_STEP(); 2780 destval = xor_word(destval, *srcreg); 2781 store_data_word(destoffset, destval); 2782 } 2783 break; 2784 case 3: /* register to register */ 2785 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2786 u32 *destreg,*srcreg; 2787 2788 destreg = DECODE_RM_LONG_REGISTER(rl); 2789 DECODE_PRINTF(","); 2790 srcreg = DECODE_RM_LONG_REGISTER(rh); 2791 DECODE_PRINTF("\n"); 2792 TRACE_AND_STEP(); 2793 *destreg = xor_long(*destreg, *srcreg); 2794 } else { 2795 u16 *destreg,*srcreg; 2796 2797 destreg = DECODE_RM_WORD_REGISTER(rl); 2798 DECODE_PRINTF(","); 2799 srcreg = DECODE_RM_WORD_REGISTER(rh); 2800 DECODE_PRINTF("\n"); 2801 TRACE_AND_STEP(); 2802 *destreg = xor_word(*destreg, *srcreg); 2803 } 2804 break; 2805 } 2806 DECODE_CLEAR_SEGOVR(); 2807 END_OF_INSTR(); 2808} 2809 2810/**************************************************************************** 2811REMARKS: 2812Handles opcode 0x32 2813****************************************************************************/ 2814static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2815{ 2816 int mod, rl, rh; 2817 u8 *destreg, *srcreg; 2818 uint srcoffset; 2819 u8 srcval; 2820 2821 START_OF_INSTR(); 2822 DECODE_PRINTF("XOR\t"); 2823 FETCH_DECODE_MODRM(mod, rh, rl); 2824 switch (mod) { 2825 case 0: 2826 destreg = DECODE_RM_BYTE_REGISTER(rh); 2827 DECODE_PRINTF(","); 2828 srcoffset = decode_rm00_address(rl); 2829 srcval = fetch_data_byte(srcoffset); 2830 DECODE_PRINTF("\n"); 2831 TRACE_AND_STEP(); 2832 *destreg = xor_byte(*destreg, srcval); 2833 break; 2834 case 1: 2835 destreg = DECODE_RM_BYTE_REGISTER(rh); 2836 DECODE_PRINTF(","); 2837 srcoffset = decode_rm01_address(rl); 2838 srcval = fetch_data_byte(srcoffset); 2839 DECODE_PRINTF("\n"); 2840 TRACE_AND_STEP(); 2841 *destreg = xor_byte(*destreg, srcval); 2842 break; 2843 case 2: 2844 destreg = DECODE_RM_BYTE_REGISTER(rh); 2845 DECODE_PRINTF(","); 2846 srcoffset = decode_rm10_address(rl); 2847 srcval = fetch_data_byte(srcoffset); 2848 DECODE_PRINTF("\n"); 2849 TRACE_AND_STEP(); 2850 *destreg = xor_byte(*destreg, srcval); 2851 break; 2852 case 3: /* register to register */ 2853 destreg = DECODE_RM_BYTE_REGISTER(rh); 2854 DECODE_PRINTF(","); 2855 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2856 DECODE_PRINTF("\n"); 2857 TRACE_AND_STEP(); 2858 *destreg = xor_byte(*destreg, *srcreg); 2859 break; 2860 } 2861 DECODE_CLEAR_SEGOVR(); 2862 END_OF_INSTR(); 2863} 2864 2865/**************************************************************************** 2866REMARKS: 2867Handles opcode 0x33 2868****************************************************************************/ 2869static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1)) 2870{ 2871 int mod, rl, rh; 2872 uint srcoffset; 2873 2874 START_OF_INSTR(); 2875 DECODE_PRINTF("XOR\t"); 2876 FETCH_DECODE_MODRM(mod, rh, rl); 2877 switch (mod) { 2878 case 0: 2879 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2880 u32 *destreg; 2881 u32 srcval; 2882 2883 destreg = DECODE_RM_LONG_REGISTER(rh); 2884 DECODE_PRINTF(","); 2885 srcoffset = decode_rm00_address(rl); 2886 srcval = fetch_data_long(srcoffset); 2887 DECODE_PRINTF("\n"); 2888 TRACE_AND_STEP(); 2889 *destreg = xor_long(*destreg, srcval); 2890 } else { 2891 u16 *destreg; 2892 u16 srcval; 2893 2894 destreg = DECODE_RM_WORD_REGISTER(rh); 2895 DECODE_PRINTF(","); 2896 srcoffset = decode_rm00_address(rl); 2897 srcval = fetch_data_word(srcoffset); 2898 DECODE_PRINTF("\n"); 2899 TRACE_AND_STEP(); 2900 *destreg = xor_word(*destreg, srcval); 2901 } 2902 break; 2903 case 1: 2904 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2905 u32 *destreg; 2906 u32 srcval; 2907 2908 destreg = DECODE_RM_LONG_REGISTER(rh); 2909 DECODE_PRINTF(","); 2910 srcoffset = decode_rm01_address(rl); 2911 srcval = fetch_data_long(srcoffset); 2912 DECODE_PRINTF("\n"); 2913 TRACE_AND_STEP(); 2914 *destreg = xor_long(*destreg, srcval); 2915 } else { 2916 u16 *destreg; 2917 u16 srcval; 2918 2919 destreg = DECODE_RM_WORD_REGISTER(rh); 2920 DECODE_PRINTF(","); 2921 srcoffset = decode_rm01_address(rl); 2922 srcval = fetch_data_word(srcoffset); 2923 DECODE_PRINTF("\n"); 2924 TRACE_AND_STEP(); 2925 *destreg = xor_word(*destreg, srcval); 2926 } 2927 break; 2928 case 2: 2929 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2930 u32 *destreg; 2931 u32 srcval; 2932 2933 destreg = DECODE_RM_LONG_REGISTER(rh); 2934 DECODE_PRINTF(","); 2935 srcoffset = decode_rm10_address(rl); 2936 srcval = fetch_data_long(srcoffset); 2937 DECODE_PRINTF("\n"); 2938 TRACE_AND_STEP(); 2939 *destreg = xor_long(*destreg, srcval); 2940 } else { 2941 u16 *destreg; 2942 u16 srcval; 2943 2944 destreg = DECODE_RM_WORD_REGISTER(rh); 2945 DECODE_PRINTF(","); 2946 srcoffset = decode_rm10_address(rl); 2947 srcval = fetch_data_word(srcoffset); 2948 DECODE_PRINTF("\n"); 2949 TRACE_AND_STEP(); 2950 *destreg = xor_word(*destreg, srcval); 2951 } 2952 break; 2953 case 3: /* register to register */ 2954 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2955 u32 *destreg,*srcreg; 2956 2957 destreg = DECODE_RM_LONG_REGISTER(rh); 2958 DECODE_PRINTF(","); 2959 srcreg = DECODE_RM_LONG_REGISTER(rl); 2960 DECODE_PRINTF("\n"); 2961 TRACE_AND_STEP(); 2962 *destreg = xor_long(*destreg, *srcreg); 2963 } else { 2964 u16 *destreg,*srcreg; 2965 2966 destreg = DECODE_RM_WORD_REGISTER(rh); 2967 DECODE_PRINTF(","); 2968 srcreg = DECODE_RM_WORD_REGISTER(rl); 2969 DECODE_PRINTF("\n"); 2970 TRACE_AND_STEP(); 2971 *destreg = xor_word(*destreg, *srcreg); 2972 } 2973 break; 2974 } 2975 DECODE_CLEAR_SEGOVR(); 2976 END_OF_INSTR(); 2977} 2978 2979/**************************************************************************** 2980REMARKS: 2981Handles opcode 0x34 2982****************************************************************************/ 2983static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2984{ 2985 u8 srcval; 2986 2987 START_OF_INSTR(); 2988 DECODE_PRINTF("XOR\tAL,"); 2989 srcval = fetch_byte_imm(); 2990 DECODE_PRINTF2("%x\n", srcval); 2991 TRACE_AND_STEP(); 2992 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval); 2993 DECODE_CLEAR_SEGOVR(); 2994 END_OF_INSTR(); 2995} 2996 2997/**************************************************************************** 2998REMARKS: 2999Handles opcode 0x35 3000****************************************************************************/ 3001static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3002{ 3003 u32 srcval; 3004 3005 START_OF_INSTR(); 3006 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3007 DECODE_PRINTF("XOR\tEAX,"); 3008 srcval = fetch_long_imm(); 3009 } else { 3010 DECODE_PRINTF("XOR\tAX,"); 3011 srcval = fetch_word_imm(); 3012 } 3013 DECODE_PRINTF2("%x\n", srcval); 3014 TRACE_AND_STEP(); 3015 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3016 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval); 3017 } else { 3018 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval); 3019 } 3020 DECODE_CLEAR_SEGOVR(); 3021 END_OF_INSTR(); 3022} 3023 3024/**************************************************************************** 3025REMARKS: 3026Handles opcode 0x36 3027****************************************************************************/ 3028static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 3029{ 3030 START_OF_INSTR(); 3031 DECODE_PRINTF("SS:\n"); 3032 TRACE_AND_STEP(); 3033 M.x86.mode |= SYSMODE_SEGOVR_SS; 3034 /* no DECODE_CLEAR_SEGOVR ! */ 3035 END_OF_INSTR(); 3036} 3037 3038/**************************************************************************** 3039REMARKS: 3040Handles opcode 0x37 3041****************************************************************************/ 3042static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 3043{ 3044 START_OF_INSTR(); 3045 DECODE_PRINTF("AAA\n"); 3046 TRACE_AND_STEP(); 3047 M.x86.R_AX = aaa_word(M.x86.R_AX); 3048 DECODE_CLEAR_SEGOVR(); 3049 END_OF_INSTR(); 3050} 3051 3052/**************************************************************************** 3053REMARKS: 3054Handles opcode 0x38 3055****************************************************************************/ 3056static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1)) 3057{ 3058 int mod, rl, rh; 3059 uint destoffset; 3060 u8 *destreg, *srcreg; 3061 u8 destval; 3062 3063 START_OF_INSTR(); 3064 DECODE_PRINTF("CMP\t"); 3065 FETCH_DECODE_MODRM(mod, rh, rl); 3066 switch (mod) { 3067 case 0: 3068 destoffset = decode_rm00_address(rl); 3069 DECODE_PRINTF(","); 3070 destval = fetch_data_byte(destoffset); 3071 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3072 DECODE_PRINTF("\n"); 3073 TRACE_AND_STEP(); 3074 cmp_byte(destval, *srcreg); 3075 break; 3076 case 1: 3077 destoffset = decode_rm01_address(rl); 3078 DECODE_PRINTF(","); 3079 destval = fetch_data_byte(destoffset); 3080 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3081 DECODE_PRINTF("\n"); 3082 TRACE_AND_STEP(); 3083 cmp_byte(destval, *srcreg); 3084 break; 3085 case 2: 3086 destoffset = decode_rm10_address(rl); 3087 DECODE_PRINTF(","); 3088 destval = fetch_data_byte(destoffset); 3089 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3090 DECODE_PRINTF("\n"); 3091 TRACE_AND_STEP(); 3092 cmp_byte(destval, *srcreg); 3093 break; 3094 case 3: /* register to register */ 3095 destreg = DECODE_RM_BYTE_REGISTER(rl); 3096 DECODE_PRINTF(","); 3097 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3098 DECODE_PRINTF("\n"); 3099 TRACE_AND_STEP(); 3100 cmp_byte(*destreg, *srcreg); 3101 break; 3102 } 3103 DECODE_CLEAR_SEGOVR(); 3104 END_OF_INSTR(); 3105} 3106 3107/**************************************************************************** 3108REMARKS: 3109Handles opcode 0x39 3110****************************************************************************/ 3111static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1)) 3112{ 3113 int mod, rl, rh; 3114 uint destoffset; 3115 3116 START_OF_INSTR(); 3117 DECODE_PRINTF("CMP\t"); 3118 FETCH_DECODE_MODRM(mod, rh, rl); 3119 switch (mod) { 3120 case 0: 3121 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3122 u32 destval; 3123 u32 *srcreg; 3124 3125 destoffset = decode_rm00_address(rl); 3126 DECODE_PRINTF(","); 3127 destval = fetch_data_long(destoffset); 3128 srcreg = DECODE_RM_LONG_REGISTER(rh); 3129 DECODE_PRINTF("\n"); 3130 TRACE_AND_STEP(); 3131 cmp_long(destval, *srcreg); 3132 } else { 3133 u16 destval; 3134 u16 *srcreg; 3135 3136 destoffset = decode_rm00_address(rl); 3137 DECODE_PRINTF(","); 3138 destval = fetch_data_word(destoffset); 3139 srcreg = DECODE_RM_WORD_REGISTER(rh); 3140 DECODE_PRINTF("\n"); 3141 TRACE_AND_STEP(); 3142 cmp_word(destval, *srcreg); 3143 } 3144 break; 3145 case 1: 3146 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3147 u32 destval; 3148 u32 *srcreg; 3149 3150 destoffset = decode_rm01_address(rl); 3151 DECODE_PRINTF(","); 3152 destval = fetch_data_long(destoffset); 3153 srcreg = DECODE_RM_LONG_REGISTER(rh); 3154 DECODE_PRINTF("\n"); 3155 TRACE_AND_STEP(); 3156 cmp_long(destval, *srcreg); 3157 } else { 3158 u16 destval; 3159 u16 *srcreg; 3160 3161 destoffset = decode_rm01_address(rl); 3162 DECODE_PRINTF(","); 3163 destval = fetch_data_word(destoffset); 3164 srcreg = DECODE_RM_WORD_REGISTER(rh); 3165 DECODE_PRINTF("\n"); 3166 TRACE_AND_STEP(); 3167 cmp_word(destval, *srcreg); 3168 } 3169 break; 3170 case 2: 3171 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3172 u32 destval; 3173 u32 *srcreg; 3174 3175 destoffset = decode_rm10_address(rl); 3176 DECODE_PRINTF(","); 3177 destval = fetch_data_long(destoffset); 3178 srcreg = DECODE_RM_LONG_REGISTER(rh); 3179 DECODE_PRINTF("\n"); 3180 TRACE_AND_STEP(); 3181 cmp_long(destval, *srcreg); 3182 } else { 3183 u16 destval; 3184 u16 *srcreg; 3185 3186 destoffset = decode_rm10_address(rl); 3187 DECODE_PRINTF(","); 3188 destval = fetch_data_word(destoffset); 3189 srcreg = DECODE_RM_WORD_REGISTER(rh); 3190 DECODE_PRINTF("\n"); 3191 TRACE_AND_STEP(); 3192 cmp_word(destval, *srcreg); 3193 } 3194 break; 3195 case 3: /* register to register */ 3196 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3197 u32 *destreg,*srcreg; 3198 3199 destreg = DECODE_RM_LONG_REGISTER(rl); 3200 DECODE_PRINTF(","); 3201 srcreg = DECODE_RM_LONG_REGISTER(rh); 3202 DECODE_PRINTF("\n"); 3203 TRACE_AND_STEP(); 3204 cmp_long(*destreg, *srcreg); 3205 } else { 3206 u16 *destreg,*srcreg; 3207 3208 destreg = DECODE_RM_WORD_REGISTER(rl); 3209 DECODE_PRINTF(","); 3210 srcreg = DECODE_RM_WORD_REGISTER(rh); 3211 DECODE_PRINTF("\n"); 3212 TRACE_AND_STEP(); 3213 cmp_word(*destreg, *srcreg); 3214 } 3215 break; 3216 } 3217 DECODE_CLEAR_SEGOVR(); 3218 END_OF_INSTR(); 3219} 3220 3221/**************************************************************************** 3222REMARKS: 3223Handles opcode 0x3a 3224****************************************************************************/ 3225static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1)) 3226{ 3227 int mod, rl, rh; 3228 u8 *destreg, *srcreg; 3229 uint srcoffset; 3230 u8 srcval; 3231 3232 START_OF_INSTR(); 3233 DECODE_PRINTF("CMP\t"); 3234 FETCH_DECODE_MODRM(mod, rh, rl); 3235 switch (mod) { 3236 case 0: 3237 destreg = DECODE_RM_BYTE_REGISTER(rh); 3238 DECODE_PRINTF(","); 3239 srcoffset = decode_rm00_address(rl); 3240 srcval = fetch_data_byte(srcoffset); 3241 DECODE_PRINTF("\n"); 3242 TRACE_AND_STEP(); 3243 cmp_byte(*destreg, srcval); 3244 break; 3245 case 1: 3246 destreg = DECODE_RM_BYTE_REGISTER(rh); 3247 DECODE_PRINTF(","); 3248 srcoffset = decode_rm01_address(rl); 3249 srcval = fetch_data_byte(srcoffset); 3250 DECODE_PRINTF("\n"); 3251 TRACE_AND_STEP(); 3252 cmp_byte(*destreg, srcval); 3253 break; 3254 case 2: 3255 destreg = DECODE_RM_BYTE_REGISTER(rh); 3256 DECODE_PRINTF(","); 3257 srcoffset = decode_rm10_address(rl); 3258 srcval = fetch_data_byte(srcoffset); 3259 DECODE_PRINTF("\n"); 3260 TRACE_AND_STEP(); 3261 cmp_byte(*destreg, srcval); 3262 break; 3263 case 3: /* register to register */ 3264 destreg = DECODE_RM_BYTE_REGISTER(rh); 3265 DECODE_PRINTF(","); 3266 srcreg = DECODE_RM_BYTE_REGISTER(rl); 3267 DECODE_PRINTF("\n"); 3268 TRACE_AND_STEP(); 3269 cmp_byte(*destreg, *srcreg); 3270 break; 3271 } 3272 DECODE_CLEAR_SEGOVR(); 3273 END_OF_INSTR(); 3274} 3275 3276/**************************************************************************** 3277REMARKS: 3278Handles opcode 0x3b 3279****************************************************************************/ 3280static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1)) 3281{ 3282 int mod, rl, rh; 3283 uint srcoffset; 3284 3285 START_OF_INSTR(); 3286 DECODE_PRINTF("CMP\t"); 3287 FETCH_DECODE_MODRM(mod, rh, rl); 3288 switch (mod) { 3289 case 0: 3290 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3291 u32 *destreg; 3292 u32 srcval; 3293 3294 destreg = DECODE_RM_LONG_REGISTER(rh); 3295 DECODE_PRINTF(","); 3296 srcoffset = decode_rm00_address(rl); 3297 srcval = fetch_data_long(srcoffset); 3298 DECODE_PRINTF("\n"); 3299 TRACE_AND_STEP(); 3300 cmp_long(*destreg, srcval); 3301 } else { 3302 u16 *destreg; 3303 u16 srcval; 3304 3305 destreg = DECODE_RM_WORD_REGISTER(rh); 3306 DECODE_PRINTF(","); 3307 srcoffset = decode_rm00_address(rl); 3308 srcval = fetch_data_word(srcoffset); 3309 DECODE_PRINTF("\n"); 3310 TRACE_AND_STEP(); 3311 cmp_word(*destreg, srcval); 3312 } 3313 break; 3314 case 1: 3315 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3316 u32 *destreg; 3317 u32 srcval; 3318 3319 destreg = DECODE_RM_LONG_REGISTER(rh); 3320 DECODE_PRINTF(","); 3321 srcoffset = decode_rm01_address(rl); 3322 srcval = fetch_data_long(srcoffset); 3323 DECODE_PRINTF("\n"); 3324 TRACE_AND_STEP(); 3325 cmp_long(*destreg, srcval); 3326 } else { 3327 u16 *destreg; 3328 u16 srcval; 3329 3330 destreg = DECODE_RM_WORD_REGISTER(rh); 3331 DECODE_PRINTF(","); 3332 srcoffset = decode_rm01_address(rl); 3333 srcval = fetch_data_word(srcoffset); 3334 DECODE_PRINTF("\n"); 3335 TRACE_AND_STEP(); 3336 cmp_word(*destreg, srcval); 3337 } 3338 break; 3339 case 2: 3340 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3341 u32 *destreg; 3342 u32 srcval; 3343 3344 destreg = DECODE_RM_LONG_REGISTER(rh); 3345 DECODE_PRINTF(","); 3346 srcoffset = decode_rm10_address(rl); 3347 srcval = fetch_data_long(srcoffset); 3348 DECODE_PRINTF("\n"); 3349 TRACE_AND_STEP(); 3350 cmp_long(*destreg, srcval); 3351 } else { 3352 u16 *destreg; 3353 u16 srcval; 3354 3355 destreg = DECODE_RM_WORD_REGISTER(rh); 3356 DECODE_PRINTF(","); 3357 srcoffset = decode_rm10_address(rl); 3358 srcval = fetch_data_word(srcoffset); 3359 DECODE_PRINTF("\n"); 3360 TRACE_AND_STEP(); 3361 cmp_word(*destreg, srcval); 3362 } 3363 break; 3364 case 3: /* register to register */ 3365 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3366 u32 *destreg,*srcreg; 3367 3368 destreg = DECODE_RM_LONG_REGISTER(rh); 3369 DECODE_PRINTF(","); 3370 srcreg = DECODE_RM_LONG_REGISTER(rl); 3371 DECODE_PRINTF("\n"); 3372 TRACE_AND_STEP(); 3373 cmp_long(*destreg, *srcreg); 3374 } else { 3375 u16 *destreg,*srcreg; 3376 3377 destreg = DECODE_RM_WORD_REGISTER(rh); 3378 DECODE_PRINTF(","); 3379 srcreg = DECODE_RM_WORD_REGISTER(rl); 3380 DECODE_PRINTF("\n"); 3381 TRACE_AND_STEP(); 3382 cmp_word(*destreg, *srcreg); 3383 } 3384 break; 3385 } 3386 DECODE_CLEAR_SEGOVR(); 3387 END_OF_INSTR(); 3388} 3389 3390/**************************************************************************** 3391REMARKS: 3392Handles opcode 0x3c 3393****************************************************************************/ 3394static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 3395{ 3396 u8 srcval; 3397 3398 START_OF_INSTR(); 3399 DECODE_PRINTF("CMP\tAL,"); 3400 srcval = fetch_byte_imm(); 3401 DECODE_PRINTF2("%x\n", srcval); 3402 TRACE_AND_STEP(); 3403 cmp_byte(M.x86.R_AL, srcval); 3404 DECODE_CLEAR_SEGOVR(); 3405 END_OF_INSTR(); 3406} 3407 3408/**************************************************************************** 3409REMARKS: 3410Handles opcode 0x3d 3411****************************************************************************/ 3412static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3413{ 3414 u32 srcval; 3415 3416 START_OF_INSTR(); 3417 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3418 DECODE_PRINTF("CMP\tEAX,"); 3419 srcval = fetch_long_imm(); 3420 } else { 3421 DECODE_PRINTF("CMP\tAX,"); 3422 srcval = fetch_word_imm(); 3423 } 3424 DECODE_PRINTF2("%x\n", srcval); 3425 TRACE_AND_STEP(); 3426 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3427 cmp_long(M.x86.R_EAX, srcval); 3428 } else { 3429 cmp_word(M.x86.R_AX, (u16)srcval); 3430 } 3431 DECODE_CLEAR_SEGOVR(); 3432 END_OF_INSTR(); 3433} 3434 3435/**************************************************************************** 3436REMARKS: 3437Handles opcode 0x3e 3438****************************************************************************/ 3439static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 3440{ 3441 START_OF_INSTR(); 3442 DECODE_PRINTF("DS:\n"); 3443 TRACE_AND_STEP(); 3444 M.x86.mode |= SYSMODE_SEGOVR_DS; 3445 /* NO DECODE_CLEAR_SEGOVR! */ 3446 END_OF_INSTR(); 3447} 3448 3449/**************************************************************************** 3450REMARKS: 3451Handles opcode 0x3f 3452****************************************************************************/ 3453static void x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 3454{ 3455 START_OF_INSTR(); 3456 DECODE_PRINTF("AAS\n"); 3457 TRACE_AND_STEP(); 3458 M.x86.R_AX = aas_word(M.x86.R_AX); 3459 DECODE_CLEAR_SEGOVR(); 3460 END_OF_INSTR(); 3461} 3462 3463/**************************************************************************** 3464REMARKS: 3465Handles opcode 0x40 3466****************************************************************************/ 3467static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1)) 3468{ 3469 START_OF_INSTR(); 3470 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3471 DECODE_PRINTF("INC\tEAX\n"); 3472 } else { 3473 DECODE_PRINTF("INC\tAX\n"); 3474 } 3475 TRACE_AND_STEP(); 3476 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3477 M.x86.R_EAX = inc_long(M.x86.R_EAX); 3478 } else { 3479 M.x86.R_AX = inc_word(M.x86.R_AX); 3480 } 3481 DECODE_CLEAR_SEGOVR(); 3482 END_OF_INSTR(); 3483} 3484 3485/**************************************************************************** 3486REMARKS: 3487Handles opcode 0x41 3488****************************************************************************/ 3489static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1)) 3490{ 3491 START_OF_INSTR(); 3492 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3493 DECODE_PRINTF("INC\tECX\n"); 3494 } else { 3495 DECODE_PRINTF("INC\tCX\n"); 3496 } 3497 TRACE_AND_STEP(); 3498 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3499 M.x86.R_ECX = inc_long(M.x86.R_ECX); 3500 } else { 3501 M.x86.R_CX = inc_word(M.x86.R_CX); 3502 } 3503 DECODE_CLEAR_SEGOVR(); 3504 END_OF_INSTR(); 3505} 3506 3507/**************************************************************************** 3508REMARKS: 3509Handles opcode 0x42 3510****************************************************************************/ 3511static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1)) 3512{ 3513 START_OF_INSTR(); 3514 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3515 DECODE_PRINTF("INC\tEDX\n"); 3516 } else { 3517 DECODE_PRINTF("INC\tDX\n"); 3518 } 3519 TRACE_AND_STEP(); 3520 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3521 M.x86.R_EDX = inc_long(M.x86.R_EDX); 3522 } else { 3523 M.x86.R_DX = inc_word(M.x86.R_DX); 3524 } 3525 DECODE_CLEAR_SEGOVR(); 3526 END_OF_INSTR(); 3527} 3528 3529/**************************************************************************** 3530REMARKS: 3531Handles opcode 0x43 3532****************************************************************************/ 3533static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1)) 3534{ 3535 START_OF_INSTR(); 3536 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3537 DECODE_PRINTF("INC\tEBX\n"); 3538 } else { 3539 DECODE_PRINTF("INC\tBX\n"); 3540 } 3541 TRACE_AND_STEP(); 3542 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3543 M.x86.R_EBX = inc_long(M.x86.R_EBX); 3544 } else { 3545 M.x86.R_BX = inc_word(M.x86.R_BX); 3546 } 3547 DECODE_CLEAR_SEGOVR(); 3548 END_OF_INSTR(); 3549} 3550 3551/**************************************************************************** 3552REMARKS: 3553Handles opcode 0x44 3554****************************************************************************/ 3555static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1)) 3556{ 3557 START_OF_INSTR(); 3558 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3559 DECODE_PRINTF("INC\tESP\n"); 3560 } else { 3561 DECODE_PRINTF("INC\tSP\n"); 3562 } 3563 TRACE_AND_STEP(); 3564 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3565 M.x86.R_ESP = inc_long(M.x86.R_ESP); 3566 } else { 3567 M.x86.R_SP = inc_word(M.x86.R_SP); 3568 } 3569 DECODE_CLEAR_SEGOVR(); 3570 END_OF_INSTR(); 3571} 3572 3573/**************************************************************************** 3574REMARKS: 3575Handles opcode 0x45 3576****************************************************************************/ 3577static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1)) 3578{ 3579 START_OF_INSTR(); 3580 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3581 DECODE_PRINTF("INC\tEBP\n"); 3582 } else { 3583 DECODE_PRINTF("INC\tBP\n"); 3584 } 3585 TRACE_AND_STEP(); 3586 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3587 M.x86.R_EBP = inc_long(M.x86.R_EBP); 3588 } else { 3589 M.x86.R_BP = inc_word(M.x86.R_BP); 3590 } 3591 DECODE_CLEAR_SEGOVR(); 3592 END_OF_INSTR(); 3593} 3594 3595/**************************************************************************** 3596REMARKS: 3597Handles opcode 0x46 3598****************************************************************************/ 3599static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1)) 3600{ 3601 START_OF_INSTR(); 3602 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3603 DECODE_PRINTF("INC\tESI\n"); 3604 } else { 3605 DECODE_PRINTF("INC\tSI\n"); 3606 } 3607 TRACE_AND_STEP(); 3608 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3609 M.x86.R_ESI = inc_long(M.x86.R_ESI); 3610 } else { 3611 M.x86.R_SI = inc_word(M.x86.R_SI); 3612 } 3613 DECODE_CLEAR_SEGOVR(); 3614 END_OF_INSTR(); 3615} 3616 3617/**************************************************************************** 3618REMARKS: 3619Handles opcode 0x47 3620****************************************************************************/ 3621static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1)) 3622{ 3623 START_OF_INSTR(); 3624 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3625 DECODE_PRINTF("INC\tEDI\n"); 3626 } else { 3627 DECODE_PRINTF("INC\tDI\n"); 3628 } 3629 TRACE_AND_STEP(); 3630 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3631 M.x86.R_EDI = inc_long(M.x86.R_EDI); 3632 } else { 3633 M.x86.R_DI = inc_word(M.x86.R_DI); 3634 } 3635 DECODE_CLEAR_SEGOVR(); 3636 END_OF_INSTR(); 3637} 3638 3639/**************************************************************************** 3640REMARKS: 3641Handles opcode 0x48 3642****************************************************************************/ 3643static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1)) 3644{ 3645 START_OF_INSTR(); 3646 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3647 DECODE_PRINTF("DEC\tEAX\n"); 3648 } else { 3649 DECODE_PRINTF("DEC\tAX\n"); 3650 } 3651 TRACE_AND_STEP(); 3652 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3653 M.x86.R_EAX = dec_long(M.x86.R_EAX); 3654 } else { 3655 M.x86.R_AX = dec_word(M.x86.R_AX); 3656 } 3657 DECODE_CLEAR_SEGOVR(); 3658 END_OF_INSTR(); 3659} 3660 3661/**************************************************************************** 3662REMARKS: 3663Handles opcode 0x49 3664****************************************************************************/ 3665static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1)) 3666{ 3667 START_OF_INSTR(); 3668 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3669 DECODE_PRINTF("DEC\tECX\n"); 3670 } else { 3671 DECODE_PRINTF("DEC\tCX\n"); 3672 } 3673 TRACE_AND_STEP(); 3674 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3675 M.x86.R_ECX = dec_long(M.x86.R_ECX); 3676 } else { 3677 M.x86.R_CX = dec_word(M.x86.R_CX); 3678 } 3679 DECODE_CLEAR_SEGOVR(); 3680 END_OF_INSTR(); 3681} 3682 3683/**************************************************************************** 3684REMARKS: 3685Handles opcode 0x4a 3686****************************************************************************/ 3687static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1)) 3688{ 3689 START_OF_INSTR(); 3690 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3691 DECODE_PRINTF("DEC\tEDX\n"); 3692 } else { 3693 DECODE_PRINTF("DEC\tDX\n"); 3694 } 3695 TRACE_AND_STEP(); 3696 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3697 M.x86.R_EDX = dec_long(M.x86.R_EDX); 3698 } else { 3699 M.x86.R_DX = dec_word(M.x86.R_DX); 3700 } 3701 DECODE_CLEAR_SEGOVR(); 3702 END_OF_INSTR(); 3703} 3704 3705/**************************************************************************** 3706REMARKS: 3707Handles opcode 0x4b 3708****************************************************************************/ 3709static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1)) 3710{ 3711 START_OF_INSTR(); 3712 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3713 DECODE_PRINTF("DEC\tEBX\n"); 3714 } else { 3715 DECODE_PRINTF("DEC\tBX\n"); 3716 } 3717 TRACE_AND_STEP(); 3718 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3719 M.x86.R_EBX = dec_long(M.x86.R_EBX); 3720 } else { 3721 M.x86.R_BX = dec_word(M.x86.R_BX); 3722 } 3723 DECODE_CLEAR_SEGOVR(); 3724 END_OF_INSTR(); 3725} 3726 3727/**************************************************************************** 3728REMARKS: 3729Handles opcode 0x4c 3730****************************************************************************/ 3731static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1)) 3732{ 3733 START_OF_INSTR(); 3734 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3735 DECODE_PRINTF("DEC\tESP\n"); 3736 } else { 3737 DECODE_PRINTF("DEC\tSP\n"); 3738 } 3739 TRACE_AND_STEP(); 3740 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3741 M.x86.R_ESP = dec_long(M.x86.R_ESP); 3742 } else { 3743 M.x86.R_SP = dec_word(M.x86.R_SP); 3744 } 3745 DECODE_CLEAR_SEGOVR(); 3746 END_OF_INSTR(); 3747} 3748 3749/**************************************************************************** 3750REMARKS: 3751Handles opcode 0x4d 3752****************************************************************************/ 3753static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1)) 3754{ 3755 START_OF_INSTR(); 3756 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3757 DECODE_PRINTF("DEC\tEBP\n"); 3758 } else { 3759 DECODE_PRINTF("DEC\tBP\n"); 3760 } 3761 TRACE_AND_STEP(); 3762 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3763 M.x86.R_EBP = dec_long(M.x86.R_EBP); 3764 } else { 3765 M.x86.R_BP = dec_word(M.x86.R_BP); 3766 } 3767 DECODE_CLEAR_SEGOVR(); 3768 END_OF_INSTR(); 3769} 3770 3771/**************************************************************************** 3772REMARKS: 3773Handles opcode 0x4e 3774****************************************************************************/ 3775static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1)) 3776{ 3777 START_OF_INSTR(); 3778 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3779 DECODE_PRINTF("DEC\tESI\n"); 3780 } else { 3781 DECODE_PRINTF("DEC\tSI\n"); 3782 } 3783 TRACE_AND_STEP(); 3784 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3785 M.x86.R_ESI = dec_long(M.x86.R_ESI); 3786 } else { 3787 M.x86.R_SI = dec_word(M.x86.R_SI); 3788 } 3789 DECODE_CLEAR_SEGOVR(); 3790 END_OF_INSTR(); 3791} 3792 3793/**************************************************************************** 3794REMARKS: 3795Handles opcode 0x4f 3796****************************************************************************/ 3797static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1)) 3798{ 3799 START_OF_INSTR(); 3800 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3801 DECODE_PRINTF("DEC\tEDI\n"); 3802 } else { 3803 DECODE_PRINTF("DEC\tDI\n"); 3804 } 3805 TRACE_AND_STEP(); 3806 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3807 M.x86.R_EDI = dec_long(M.x86.R_EDI); 3808 } else { 3809 M.x86.R_DI = dec_word(M.x86.R_DI); 3810 } 3811 DECODE_CLEAR_SEGOVR(); 3812 END_OF_INSTR(); 3813} 3814 3815/**************************************************************************** 3816REMARKS: 3817Handles opcode 0x50 3818****************************************************************************/ 3819static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1)) 3820{ 3821 START_OF_INSTR(); 3822 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3823 DECODE_PRINTF("PUSH\tEAX\n"); 3824 } else { 3825 DECODE_PRINTF("PUSH\tAX\n"); 3826 } 3827 TRACE_AND_STEP(); 3828 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3829 push_long(M.x86.R_EAX); 3830 } else { 3831 push_word(M.x86.R_AX); 3832 } 3833 DECODE_CLEAR_SEGOVR(); 3834 END_OF_INSTR(); 3835} 3836 3837/**************************************************************************** 3838REMARKS: 3839Handles opcode 0x51 3840****************************************************************************/ 3841static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1)) 3842{ 3843 START_OF_INSTR(); 3844 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3845 DECODE_PRINTF("PUSH\tECX\n"); 3846 } else { 3847 DECODE_PRINTF("PUSH\tCX\n"); 3848 } 3849 TRACE_AND_STEP(); 3850 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3851 push_long(M.x86.R_ECX); 3852 } else { 3853 push_word(M.x86.R_CX); 3854 } 3855 DECODE_CLEAR_SEGOVR(); 3856 END_OF_INSTR(); 3857} 3858 3859/**************************************************************************** 3860REMARKS: 3861Handles opcode 0x52 3862****************************************************************************/ 3863static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1)) 3864{ 3865 START_OF_INSTR(); 3866 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3867 DECODE_PRINTF("PUSH\tEDX\n"); 3868 } else { 3869 DECODE_PRINTF("PUSH\tDX\n"); 3870 } 3871 TRACE_AND_STEP(); 3872 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3873 push_long(M.x86.R_EDX); 3874 } else { 3875 push_word(M.x86.R_DX); 3876 } 3877 DECODE_CLEAR_SEGOVR(); 3878 END_OF_INSTR(); 3879} 3880 3881/**************************************************************************** 3882REMARKS: 3883Handles opcode 0x53 3884****************************************************************************/ 3885static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1)) 3886{ 3887 START_OF_INSTR(); 3888 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3889 DECODE_PRINTF("PUSH\tEBX\n"); 3890 } else { 3891 DECODE_PRINTF("PUSH\tBX\n"); 3892 } 3893 TRACE_AND_STEP(); 3894 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3895 push_long(M.x86.R_EBX); 3896 } else { 3897 push_word(M.x86.R_BX); 3898 } 3899 DECODE_CLEAR_SEGOVR(); 3900 END_OF_INSTR(); 3901} 3902 3903/**************************************************************************** 3904REMARKS: 3905Handles opcode 0x54 3906****************************************************************************/ 3907static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1)) 3908{ 3909 START_OF_INSTR(); 3910 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3911 DECODE_PRINTF("PUSH\tESP\n"); 3912 } else { 3913 DECODE_PRINTF("PUSH\tSP\n"); 3914 } 3915 TRACE_AND_STEP(); 3916 /* Always push (E)SP, since we are emulating an i386 and above 3917 * processor. This is necessary as some BIOS'es use this to check 3918 * what type of processor is in the system. 3919 */ 3920 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3921 push_long(M.x86.R_ESP); 3922 } else { 3923 push_word((u16)(M.x86.R_SP)); 3924 } 3925 DECODE_CLEAR_SEGOVR(); 3926 END_OF_INSTR(); 3927} 3928 3929/**************************************************************************** 3930REMARKS: 3931Handles opcode 0x55 3932****************************************************************************/ 3933static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1)) 3934{ 3935 START_OF_INSTR(); 3936 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3937 DECODE_PRINTF("PUSH\tEBP\n"); 3938 } else { 3939 DECODE_PRINTF("PUSH\tBP\n"); 3940 } 3941 TRACE_AND_STEP(); 3942 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3943 push_long(M.x86.R_EBP); 3944 } else { 3945 push_word(M.x86.R_BP); 3946 } 3947 DECODE_CLEAR_SEGOVR(); 3948 END_OF_INSTR(); 3949} 3950 3951/**************************************************************************** 3952REMARKS: 3953Handles opcode 0x56 3954****************************************************************************/ 3955static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1)) 3956{ 3957 START_OF_INSTR(); 3958 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3959 DECODE_PRINTF("PUSH\tESI\n"); 3960 } else { 3961 DECODE_PRINTF("PUSH\tSI\n"); 3962 } 3963 TRACE_AND_STEP(); 3964 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3965 push_long(M.x86.R_ESI); 3966 } else { 3967 push_word(M.x86.R_SI); 3968 } 3969 DECODE_CLEAR_SEGOVR(); 3970 END_OF_INSTR(); 3971} 3972 3973/**************************************************************************** 3974REMARKS: 3975Handles opcode 0x57 3976****************************************************************************/ 3977static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1)) 3978{ 3979 START_OF_INSTR(); 3980 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3981 DECODE_PRINTF("PUSH\tEDI\n"); 3982 } else { 3983 DECODE_PRINTF("PUSH\tDI\n"); 3984 } 3985 TRACE_AND_STEP(); 3986 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3987 push_long(M.x86.R_EDI); 3988 } else { 3989 push_word(M.x86.R_DI); 3990 } 3991 DECODE_CLEAR_SEGOVR(); 3992 END_OF_INSTR(); 3993} 3994 3995/**************************************************************************** 3996REMARKS: 3997Handles opcode 0x58 3998****************************************************************************/ 3999static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1)) 4000{ 4001 START_OF_INSTR(); 4002 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4003 DECODE_PRINTF("POP\tEAX\n"); 4004 } else { 4005 DECODE_PRINTF("POP\tAX\n"); 4006 } 4007 TRACE_AND_STEP(); 4008 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4009 M.x86.R_EAX = pop_long(); 4010 } else { 4011 M.x86.R_AX = pop_word(); 4012 } 4013 DECODE_CLEAR_SEGOVR(); 4014 END_OF_INSTR(); 4015} 4016 4017/**************************************************************************** 4018REMARKS: 4019Handles opcode 0x59 4020****************************************************************************/ 4021static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1)) 4022{ 4023 START_OF_INSTR(); 4024 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4025 DECODE_PRINTF("POP\tECX\n"); 4026 } else { 4027 DECODE_PRINTF("POP\tCX\n"); 4028 } 4029 TRACE_AND_STEP(); 4030 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4031 M.x86.R_ECX = pop_long(); 4032 } else { 4033 M.x86.R_CX = pop_word(); 4034 } 4035 DECODE_CLEAR_SEGOVR(); 4036 END_OF_INSTR(); 4037} 4038 4039/**************************************************************************** 4040REMARKS: 4041Handles opcode 0x5a 4042****************************************************************************/ 4043static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1)) 4044{ 4045 START_OF_INSTR(); 4046 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4047 DECODE_PRINTF("POP\tEDX\n"); 4048 } else { 4049 DECODE_PRINTF("POP\tDX\n"); 4050 } 4051 TRACE_AND_STEP(); 4052 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4053 M.x86.R_EDX = pop_long(); 4054 } else { 4055 M.x86.R_DX = pop_word(); 4056 } 4057 DECODE_CLEAR_SEGOVR(); 4058 END_OF_INSTR(); 4059} 4060 4061/**************************************************************************** 4062REMARKS: 4063Handles opcode 0x5b 4064****************************************************************************/ 4065static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1)) 4066{ 4067 START_OF_INSTR(); 4068 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4069 DECODE_PRINTF("POP\tEBX\n"); 4070 } else { 4071 DECODE_PRINTF("POP\tBX\n"); 4072 } 4073 TRACE_AND_STEP(); 4074 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4075 M.x86.R_EBX = pop_long(); 4076 } else { 4077 M.x86.R_BX = pop_word(); 4078 } 4079 DECODE_CLEAR_SEGOVR(); 4080 END_OF_INSTR(); 4081} 4082 4083/**************************************************************************** 4084REMARKS: 4085Handles opcode 0x5c 4086****************************************************************************/ 4087static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1)) 4088{ 4089 START_OF_INSTR(); 4090 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4091 DECODE_PRINTF("POP\tESP\n"); 4092 } else { 4093 DECODE_PRINTF("POP\tSP\n"); 4094 } 4095 TRACE_AND_STEP(); 4096 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4097 M.x86.R_ESP = pop_long(); 4098 } else { 4099 M.x86.R_SP = pop_word(); 4100 } 4101 DECODE_CLEAR_SEGOVR(); 4102 END_OF_INSTR(); 4103} 4104 4105/**************************************************************************** 4106REMARKS: 4107Handles opcode 0x5d 4108****************************************************************************/ 4109static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1)) 4110{ 4111 START_OF_INSTR(); 4112 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4113 DECODE_PRINTF("POP\tEBP\n"); 4114 } else { 4115 DECODE_PRINTF("POP\tBP\n"); 4116 } 4117 TRACE_AND_STEP(); 4118 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4119 M.x86.R_EBP = pop_long(); 4120 } else { 4121 M.x86.R_BP = pop_word(); 4122 } 4123 DECODE_CLEAR_SEGOVR(); 4124 END_OF_INSTR(); 4125} 4126 4127/**************************************************************************** 4128REMARKS: 4129Handles opcode 0x5e 4130****************************************************************************/ 4131static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1)) 4132{ 4133 START_OF_INSTR(); 4134 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4135 DECODE_PRINTF("POP\tESI\n"); 4136 } else { 4137 DECODE_PRINTF("POP\tSI\n"); 4138 } 4139 TRACE_AND_STEP(); 4140 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4141 M.x86.R_ESI = pop_long(); 4142 } else { 4143 M.x86.R_SI = pop_word(); 4144 } 4145 DECODE_CLEAR_SEGOVR(); 4146 END_OF_INSTR(); 4147} 4148 4149/**************************************************************************** 4150REMARKS: 4151Handles opcode 0x5f 4152****************************************************************************/ 4153static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1)) 4154{ 4155 START_OF_INSTR(); 4156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4157 DECODE_PRINTF("POP\tEDI\n"); 4158 } else { 4159 DECODE_PRINTF("POP\tDI\n"); 4160 } 4161 TRACE_AND_STEP(); 4162 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4163 M.x86.R_EDI = pop_long(); 4164 } else { 4165 M.x86.R_DI = pop_word(); 4166 } 4167 DECODE_CLEAR_SEGOVR(); 4168 END_OF_INSTR(); 4169} 4170 4171/**************************************************************************** 4172REMARKS: 4173Handles opcode 0x60 4174****************************************************************************/ 4175static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 4176{ 4177 START_OF_INSTR(); 4178 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4179 DECODE_PRINTF("PUSHAD\n"); 4180 } else { 4181 DECODE_PRINTF("PUSHA\n"); 4182 } 4183 TRACE_AND_STEP(); 4184 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4185 u32 old_sp = M.x86.R_ESP; 4186 4187 push_long(M.x86.R_EAX); 4188 push_long(M.x86.R_ECX); 4189 push_long(M.x86.R_EDX); 4190 push_long(M.x86.R_EBX); 4191 push_long(old_sp); 4192 push_long(M.x86.R_EBP); 4193 push_long(M.x86.R_ESI); 4194 push_long(M.x86.R_EDI); 4195 } else { 4196 u16 old_sp = M.x86.R_SP; 4197 4198 push_word(M.x86.R_AX); 4199 push_word(M.x86.R_CX); 4200 push_word(M.x86.R_DX); 4201 push_word(M.x86.R_BX); 4202 push_word(old_sp); 4203 push_word(M.x86.R_BP); 4204 push_word(M.x86.R_SI); 4205 push_word(M.x86.R_DI); 4206 } 4207 DECODE_CLEAR_SEGOVR(); 4208 END_OF_INSTR(); 4209} 4210 4211/**************************************************************************** 4212REMARKS: 4213Handles opcode 0x61 4214****************************************************************************/ 4215static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 4216{ 4217 START_OF_INSTR(); 4218 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4219 DECODE_PRINTF("POPAD\n"); 4220 } else { 4221 DECODE_PRINTF("POPA\n"); 4222 } 4223 TRACE_AND_STEP(); 4224 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4225 M.x86.R_EDI = pop_long(); 4226 M.x86.R_ESI = pop_long(); 4227 M.x86.R_EBP = pop_long(); 4228 M.x86.R_ESP += 4; /* skip ESP */ 4229 M.x86.R_EBX = pop_long(); 4230 M.x86.R_EDX = pop_long(); 4231 M.x86.R_ECX = pop_long(); 4232 M.x86.R_EAX = pop_long(); 4233 } else { 4234 M.x86.R_DI = pop_word(); 4235 M.x86.R_SI = pop_word(); 4236 M.x86.R_BP = pop_word(); 4237 M.x86.R_SP += 2; /* skip SP */ 4238 M.x86.R_BX = pop_word(); 4239 M.x86.R_DX = pop_word(); 4240 M.x86.R_CX = pop_word(); 4241 M.x86.R_AX = pop_word(); 4242 } 4243 DECODE_CLEAR_SEGOVR(); 4244 END_OF_INSTR(); 4245} 4246 4247/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4248/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4249 4250/**************************************************************************** 4251REMARKS: 4252Handles opcode 0x64 4253****************************************************************************/ 4254static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 4255{ 4256 START_OF_INSTR(); 4257 DECODE_PRINTF("FS:\n"); 4258 TRACE_AND_STEP(); 4259 M.x86.mode |= SYSMODE_SEGOVR_FS; 4260 /* 4261 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4262 * opcode subroutines we do not want to do this. 4263 */ 4264 END_OF_INSTR(); 4265} 4266 4267/**************************************************************************** 4268REMARKS: 4269Handles opcode 0x65 4270****************************************************************************/ 4271static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 4272{ 4273 START_OF_INSTR(); 4274 DECODE_PRINTF("GS:\n"); 4275 TRACE_AND_STEP(); 4276 M.x86.mode |= SYSMODE_SEGOVR_GS; 4277 /* 4278 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4279 * opcode subroutines we do not want to do this. 4280 */ 4281 END_OF_INSTR(); 4282} 4283 4284/**************************************************************************** 4285REMARKS: 4286Handles opcode 0x66 - prefix for 32-bit register 4287****************************************************************************/ 4288static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 4289{ 4290 START_OF_INSTR(); 4291 DECODE_PRINTF("DATA:\n"); 4292 TRACE_AND_STEP(); 4293 M.x86.mode |= SYSMODE_PREFIX_DATA; 4294 /* note no DECODE_CLEAR_SEGOVR here. */ 4295 END_OF_INSTR(); 4296} 4297 4298/**************************************************************************** 4299REMARKS: 4300Handles opcode 0x67 - prefix for 32-bit address 4301****************************************************************************/ 4302static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 4303{ 4304 START_OF_INSTR(); 4305 DECODE_PRINTF("ADDR:\n"); 4306 TRACE_AND_STEP(); 4307 M.x86.mode |= SYSMODE_PREFIX_ADDR; 4308 /* note no DECODE_CLEAR_SEGOVR here. */ 4309 END_OF_INSTR(); 4310} 4311 4312/**************************************************************************** 4313REMARKS: 4314Handles opcode 0x68 4315****************************************************************************/ 4316static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 4317{ 4318 u32 imm; 4319 4320 START_OF_INSTR(); 4321 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4322 imm = fetch_long_imm(); 4323 } else { 4324 imm = fetch_word_imm(); 4325 } 4326 DECODE_PRINTF2("PUSH\t%x\n", imm); 4327 TRACE_AND_STEP(); 4328 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4329 push_long(imm); 4330 } else { 4331 push_word((u16)imm); 4332 } 4333 DECODE_CLEAR_SEGOVR(); 4334 END_OF_INSTR(); 4335} 4336 4337/**************************************************************************** 4338REMARKS: 4339Handles opcode 0x69 4340****************************************************************************/ 4341static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 4342{ 4343 int mod, rl, rh; 4344 uint srcoffset; 4345 4346 START_OF_INSTR(); 4347 DECODE_PRINTF("IMUL\t"); 4348 FETCH_DECODE_MODRM(mod, rh, rl); 4349 switch (mod) { 4350 case 0: 4351 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4352 u32 *destreg; 4353 u32 srcval; 4354 u32 res_lo,res_hi; 4355 s32 imm; 4356 4357 destreg = DECODE_RM_LONG_REGISTER(rh); 4358 DECODE_PRINTF(","); 4359 srcoffset = decode_rm00_address(rl); 4360 srcval = fetch_data_long(srcoffset); 4361 imm = fetch_long_imm(); 4362 DECODE_PRINTF2(",%d\n", (s32)imm); 4363 TRACE_AND_STEP(); 4364 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4365 if (res_hi != 0) { 4366 SET_FLAG(F_CF); 4367 SET_FLAG(F_OF); 4368 } else { 4369 CLEAR_FLAG(F_CF); 4370 CLEAR_FLAG(F_OF); 4371 } 4372 *destreg = (u32)res_lo; 4373 } else { 4374 u16 *destreg; 4375 u16 srcval; 4376 u32 res; 4377 s16 imm; 4378 4379 destreg = DECODE_RM_WORD_REGISTER(rh); 4380 DECODE_PRINTF(","); 4381 srcoffset = decode_rm00_address(rl); 4382 srcval = fetch_data_word(srcoffset); 4383 imm = fetch_word_imm(); 4384 DECODE_PRINTF2(",%d\n", (s32)imm); 4385 TRACE_AND_STEP(); 4386 res = (s16)srcval * (s16)imm; 4387 if (res > 0xFFFF) { 4388 SET_FLAG(F_CF); 4389 SET_FLAG(F_OF); 4390 } else { 4391 CLEAR_FLAG(F_CF); 4392 CLEAR_FLAG(F_OF); 4393 } 4394 *destreg = (u16)res; 4395 } 4396 break; 4397 case 1: 4398 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4399 u32 *destreg; 4400 u32 srcval; 4401 u32 res_lo,res_hi; 4402 s32 imm; 4403 4404 destreg = DECODE_RM_LONG_REGISTER(rh); 4405 DECODE_PRINTF(","); 4406 srcoffset = decode_rm01_address(rl); 4407 srcval = fetch_data_long(srcoffset); 4408 imm = fetch_long_imm(); 4409 DECODE_PRINTF2(",%d\n", (s32)imm); 4410 TRACE_AND_STEP(); 4411 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4412 if (res_hi != 0) { 4413 SET_FLAG(F_CF); 4414 SET_FLAG(F_OF); 4415 } else { 4416 CLEAR_FLAG(F_CF); 4417 CLEAR_FLAG(F_OF); 4418 } 4419 *destreg = (u32)res_lo; 4420 } else { 4421 u16 *destreg; 4422 u16 srcval; 4423 u32 res; 4424 s16 imm; 4425 4426 destreg = DECODE_RM_WORD_REGISTER(rh); 4427 DECODE_PRINTF(","); 4428 srcoffset = decode_rm01_address(rl); 4429 srcval = fetch_data_word(srcoffset); 4430 imm = fetch_word_imm(); 4431 DECODE_PRINTF2(",%d\n", (s32)imm); 4432 TRACE_AND_STEP(); 4433 res = (s16)srcval * (s16)imm; 4434 if (res > 0xFFFF) { 4435 SET_FLAG(F_CF); 4436 SET_FLAG(F_OF); 4437 } else { 4438 CLEAR_FLAG(F_CF); 4439 CLEAR_FLAG(F_OF); 4440 } 4441 *destreg = (u16)res; 4442 } 4443 break; 4444 case 2: 4445 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4446 u32 *destreg; 4447 u32 srcval; 4448 u32 res_lo,res_hi; 4449 s32 imm; 4450 4451 destreg = DECODE_RM_LONG_REGISTER(rh); 4452 DECODE_PRINTF(","); 4453 srcoffset = decode_rm10_address(rl); 4454 srcval = fetch_data_long(srcoffset); 4455 imm = fetch_long_imm(); 4456 DECODE_PRINTF2(",%d\n", (s32)imm); 4457 TRACE_AND_STEP(); 4458 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4459 if (res_hi != 0) { 4460 SET_FLAG(F_CF); 4461 SET_FLAG(F_OF); 4462 } else { 4463 CLEAR_FLAG(F_CF); 4464 CLEAR_FLAG(F_OF); 4465 } 4466 *destreg = (u32)res_lo; 4467 } else { 4468 u16 *destreg; 4469 u16 srcval; 4470 u32 res; 4471 s16 imm; 4472 4473 destreg = DECODE_RM_WORD_REGISTER(rh); 4474 DECODE_PRINTF(","); 4475 srcoffset = decode_rm10_address(rl); 4476 srcval = fetch_data_word(srcoffset); 4477 imm = fetch_word_imm(); 4478 DECODE_PRINTF2(",%d\n", (s32)imm); 4479 TRACE_AND_STEP(); 4480 res = (s16)srcval * (s16)imm; 4481 if (res > 0xFFFF) { 4482 SET_FLAG(F_CF); 4483 SET_FLAG(F_OF); 4484 } else { 4485 CLEAR_FLAG(F_CF); 4486 CLEAR_FLAG(F_OF); 4487 } 4488 *destreg = (u16)res; 4489 } 4490 break; 4491 case 3: /* register to register */ 4492 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4493 u32 *destreg,*srcreg; 4494 u32 res_lo,res_hi; 4495 s32 imm; 4496 4497 destreg = DECODE_RM_LONG_REGISTER(rh); 4498 DECODE_PRINTF(","); 4499 srcreg = DECODE_RM_LONG_REGISTER(rl); 4500 imm = fetch_long_imm(); 4501 DECODE_PRINTF2(",%d\n", (s32)imm); 4502 TRACE_AND_STEP(); 4503 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4504 if (res_hi != 0) { 4505 SET_FLAG(F_CF); 4506 SET_FLAG(F_OF); 4507 } else { 4508 CLEAR_FLAG(F_CF); 4509 CLEAR_FLAG(F_OF); 4510 } 4511 *destreg = (u32)res_lo; 4512 } else { 4513 u16 *destreg,*srcreg; 4514 u32 res; 4515 s16 imm; 4516 4517 destreg = DECODE_RM_WORD_REGISTER(rh); 4518 DECODE_PRINTF(","); 4519 srcreg = DECODE_RM_WORD_REGISTER(rl); 4520 imm = fetch_word_imm(); 4521 DECODE_PRINTF2(",%d\n", (s32)imm); 4522 res = (s16)*srcreg * (s16)imm; 4523 if (res > 0xFFFF) { 4524 SET_FLAG(F_CF); 4525 SET_FLAG(F_OF); 4526 } else { 4527 CLEAR_FLAG(F_CF); 4528 CLEAR_FLAG(F_OF); 4529 } 4530 *destreg = (u16)res; 4531 } 4532 break; 4533 } 4534 DECODE_CLEAR_SEGOVR(); 4535 END_OF_INSTR(); 4536} 4537 4538/**************************************************************************** 4539REMARKS: 4540Handles opcode 0x6a 4541****************************************************************************/ 4542static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 4543{ 4544 s16 imm; 4545 4546 START_OF_INSTR(); 4547 imm = (s8)fetch_byte_imm(); 4548 DECODE_PRINTF2("PUSH\t%d\n", imm); 4549 TRACE_AND_STEP(); 4550 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4551 push_long((s32)imm); 4552 } else { 4553 push_word(imm); 4554 } 4555 DECODE_CLEAR_SEGOVR(); 4556 END_OF_INSTR(); 4557} 4558 4559/**************************************************************************** 4560REMARKS: 4561Handles opcode 0x6b 4562****************************************************************************/ 4563static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 4564{ 4565 int mod, rl, rh; 4566 uint srcoffset; 4567 s8 imm; 4568 4569 START_OF_INSTR(); 4570 DECODE_PRINTF("IMUL\t"); 4571 FETCH_DECODE_MODRM(mod, rh, rl); 4572 switch (mod) { 4573 case 0: 4574 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4575 u32 *destreg; 4576 u32 srcval; 4577 u32 res_lo,res_hi; 4578 4579 destreg = DECODE_RM_LONG_REGISTER(rh); 4580 DECODE_PRINTF(","); 4581 srcoffset = decode_rm00_address(rl); 4582 srcval = fetch_data_long(srcoffset); 4583 imm = fetch_byte_imm(); 4584 DECODE_PRINTF2(",%d\n", (s32)imm); 4585 TRACE_AND_STEP(); 4586 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4587 if (res_hi != 0) { 4588 SET_FLAG(F_CF); 4589 SET_FLAG(F_OF); 4590 } else { 4591 CLEAR_FLAG(F_CF); 4592 CLEAR_FLAG(F_OF); 4593 } 4594 *destreg = (u32)res_lo; 4595 } else { 4596 u16 *destreg; 4597 u16 srcval; 4598 u32 res; 4599 4600 destreg = DECODE_RM_WORD_REGISTER(rh); 4601 DECODE_PRINTF(","); 4602 srcoffset = decode_rm00_address(rl); 4603 srcval = fetch_data_word(srcoffset); 4604 imm = fetch_byte_imm(); 4605 DECODE_PRINTF2(",%d\n", (s32)imm); 4606 TRACE_AND_STEP(); 4607 res = (s16)srcval * (s16)imm; 4608 if (res > 0xFFFF) { 4609 SET_FLAG(F_CF); 4610 SET_FLAG(F_OF); 4611 } else { 4612 CLEAR_FLAG(F_CF); 4613 CLEAR_FLAG(F_OF); 4614 } 4615 *destreg = (u16)res; 4616 } 4617 break; 4618 case 1: 4619 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4620 u32 *destreg; 4621 u32 srcval; 4622 u32 res_lo,res_hi; 4623 4624 destreg = DECODE_RM_LONG_REGISTER(rh); 4625 DECODE_PRINTF(","); 4626 srcoffset = decode_rm01_address(rl); 4627 srcval = fetch_data_long(srcoffset); 4628 imm = fetch_byte_imm(); 4629 DECODE_PRINTF2(",%d\n", (s32)imm); 4630 TRACE_AND_STEP(); 4631 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4632 if (res_hi != 0) { 4633 SET_FLAG(F_CF); 4634 SET_FLAG(F_OF); 4635 } else { 4636 CLEAR_FLAG(F_CF); 4637 CLEAR_FLAG(F_OF); 4638 } 4639 *destreg = (u32)res_lo; 4640 } else { 4641 u16 *destreg; 4642 u16 srcval; 4643 u32 res; 4644 4645 destreg = DECODE_RM_WORD_REGISTER(rh); 4646 DECODE_PRINTF(","); 4647 srcoffset = decode_rm01_address(rl); 4648 srcval = fetch_data_word(srcoffset); 4649 imm = fetch_byte_imm(); 4650 DECODE_PRINTF2(",%d\n", (s32)imm); 4651 TRACE_AND_STEP(); 4652 res = (s16)srcval * (s16)imm; 4653 if (res > 0xFFFF) { 4654 SET_FLAG(F_CF); 4655 SET_FLAG(F_OF); 4656 } else { 4657 CLEAR_FLAG(F_CF); 4658 CLEAR_FLAG(F_OF); 4659 } 4660 *destreg = (u16)res; 4661 } 4662 break; 4663 case 2: 4664 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4665 u32 *destreg; 4666 u32 srcval; 4667 u32 res_lo,res_hi; 4668 4669 destreg = DECODE_RM_LONG_REGISTER(rh); 4670 DECODE_PRINTF(","); 4671 srcoffset = decode_rm10_address(rl); 4672 srcval = fetch_data_long(srcoffset); 4673 imm = fetch_byte_imm(); 4674 DECODE_PRINTF2(",%d\n", (s32)imm); 4675 TRACE_AND_STEP(); 4676 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4677 if (res_hi != 0) { 4678 SET_FLAG(F_CF); 4679 SET_FLAG(F_OF); 4680 } else { 4681 CLEAR_FLAG(F_CF); 4682 CLEAR_FLAG(F_OF); 4683 } 4684 *destreg = (u32)res_lo; 4685 } else { 4686 u16 *destreg; 4687 u16 srcval; 4688 u32 res; 4689 4690 destreg = DECODE_RM_WORD_REGISTER(rh); 4691 DECODE_PRINTF(","); 4692 srcoffset = decode_rm10_address(rl); 4693 srcval = fetch_data_word(srcoffset); 4694 imm = fetch_byte_imm(); 4695 DECODE_PRINTF2(",%d\n", (s32)imm); 4696 TRACE_AND_STEP(); 4697 res = (s16)srcval * (s16)imm; 4698 if (res > 0xFFFF) { 4699 SET_FLAG(F_CF); 4700 SET_FLAG(F_OF); 4701 } else { 4702 CLEAR_FLAG(F_CF); 4703 CLEAR_FLAG(F_OF); 4704 } 4705 *destreg = (u16)res; 4706 } 4707 break; 4708 case 3: /* register to register */ 4709 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4710 u32 *destreg,*srcreg; 4711 u32 res_lo,res_hi; 4712 4713 destreg = DECODE_RM_LONG_REGISTER(rh); 4714 DECODE_PRINTF(","); 4715 srcreg = DECODE_RM_LONG_REGISTER(rl); 4716 imm = fetch_byte_imm(); 4717 DECODE_PRINTF2(",%d\n", (s32)imm); 4718 TRACE_AND_STEP(); 4719 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4720 if (res_hi != 0) { 4721 SET_FLAG(F_CF); 4722 SET_FLAG(F_OF); 4723 } else { 4724 CLEAR_FLAG(F_CF); 4725 CLEAR_FLAG(F_OF); 4726 } 4727 *destreg = (u32)res_lo; 4728 } else { 4729 u16 *destreg,*srcreg; 4730 u32 res; 4731 4732 destreg = DECODE_RM_WORD_REGISTER(rh); 4733 DECODE_PRINTF(","); 4734 srcreg = DECODE_RM_WORD_REGISTER(rl); 4735 imm = fetch_byte_imm(); 4736 DECODE_PRINTF2(",%d\n", (s32)imm); 4737 res = (s16)*srcreg * (s16)imm; 4738 if (res > 0xFFFF) { 4739 SET_FLAG(F_CF); 4740 SET_FLAG(F_OF); 4741 } else { 4742 CLEAR_FLAG(F_CF); 4743 CLEAR_FLAG(F_OF); 4744 } 4745 *destreg = (u16)res; 4746 } 4747 break; 4748 } 4749 DECODE_CLEAR_SEGOVR(); 4750 END_OF_INSTR(); 4751} 4752 4753/**************************************************************************** 4754REMARKS: 4755Handles opcode 0x6c 4756****************************************************************************/ 4757static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 4758{ 4759 START_OF_INSTR(); 4760 DECODE_PRINTF("INSB\n"); 4761 ins(1); 4762 TRACE_AND_STEP(); 4763 DECODE_CLEAR_SEGOVR(); 4764 END_OF_INSTR(); 4765} 4766 4767/**************************************************************************** 4768REMARKS: 4769Handles opcode 0x6d 4770****************************************************************************/ 4771static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 4772{ 4773 START_OF_INSTR(); 4774 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4775 DECODE_PRINTF("INSD\n"); 4776 ins(4); 4777 } else { 4778 DECODE_PRINTF("INSW\n"); 4779 ins(2); 4780 } 4781 TRACE_AND_STEP(); 4782 DECODE_CLEAR_SEGOVR(); 4783 END_OF_INSTR(); 4784} 4785 4786/**************************************************************************** 4787REMARKS: 4788Handles opcode 0x6e 4789****************************************************************************/ 4790static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 4791{ 4792 START_OF_INSTR(); 4793 DECODE_PRINTF("OUTSB\n"); 4794 outs(1); 4795 TRACE_AND_STEP(); 4796 DECODE_CLEAR_SEGOVR(); 4797 END_OF_INSTR(); 4798} 4799 4800/**************************************************************************** 4801REMARKS: 4802Handles opcode 0x6f 4803****************************************************************************/ 4804static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 4805{ 4806 START_OF_INSTR(); 4807 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4808 DECODE_PRINTF("OUTSD\n"); 4809 outs(4); 4810 } else { 4811 DECODE_PRINTF("OUTSW\n"); 4812 outs(2); 4813 } 4814 TRACE_AND_STEP(); 4815 DECODE_CLEAR_SEGOVR(); 4816 END_OF_INSTR(); 4817} 4818 4819/**************************************************************************** 4820REMARKS: 4821Handles opcode 0x70 4822****************************************************************************/ 4823static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1)) 4824{ 4825 s8 offset; 4826 u16 target; 4827 4828 /* jump to byte offset if overflow flag is set */ 4829 START_OF_INSTR(); 4830 DECODE_PRINTF("JO\t"); 4831 offset = (s8)fetch_byte_imm(); 4832 target = (u16)(M.x86.R_IP + (s16)offset); 4833 DECODE_PRINTF2("%x\n", target); 4834 TRACE_AND_STEP(); 4835 if (ACCESS_FLAG(F_OF)) 4836 M.x86.R_IP = target; 4837 DECODE_CLEAR_SEGOVR(); 4838 END_OF_INSTR(); 4839} 4840 4841/**************************************************************************** 4842REMARKS: 4843Handles opcode 0x71 4844****************************************************************************/ 4845static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1)) 4846{ 4847 s8 offset; 4848 u16 target; 4849 4850 /* jump to byte offset if overflow is not set */ 4851 START_OF_INSTR(); 4852 DECODE_PRINTF("JNO\t"); 4853 offset = (s8)fetch_byte_imm(); 4854 target = (u16)(M.x86.R_IP + (s16)offset); 4855 DECODE_PRINTF2("%x\n", target); 4856 TRACE_AND_STEP(); 4857 if (!ACCESS_FLAG(F_OF)) 4858 M.x86.R_IP = target; 4859 DECODE_CLEAR_SEGOVR(); 4860 END_OF_INSTR(); 4861} 4862 4863/**************************************************************************** 4864REMARKS: 4865Handles opcode 0x72 4866****************************************************************************/ 4867static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1)) 4868{ 4869 s8 offset; 4870 u16 target; 4871 4872 /* jump to byte offset if carry flag is set. */ 4873 START_OF_INSTR(); 4874 DECODE_PRINTF("JB\t"); 4875 offset = (s8)fetch_byte_imm(); 4876 target = (u16)(M.x86.R_IP + (s16)offset); 4877 DECODE_PRINTF2("%x\n", target); 4878 TRACE_AND_STEP(); 4879 if (ACCESS_FLAG(F_CF)) 4880 M.x86.R_IP = target; 4881 DECODE_CLEAR_SEGOVR(); 4882 END_OF_INSTR(); 4883} 4884 4885/**************************************************************************** 4886REMARKS: 4887Handles opcode 0x73 4888****************************************************************************/ 4889static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1)) 4890{ 4891 s8 offset; 4892 u16 target; 4893 4894 /* jump to byte offset if carry flag is clear. */ 4895 START_OF_INSTR(); 4896 DECODE_PRINTF("JNB\t"); 4897 offset = (s8)fetch_byte_imm(); 4898 target = (u16)(M.x86.R_IP + (s16)offset); 4899 DECODE_PRINTF2("%x\n", target); 4900 TRACE_AND_STEP(); 4901 if (!ACCESS_FLAG(F_CF)) 4902 M.x86.R_IP = target; 4903 DECODE_CLEAR_SEGOVR(); 4904 END_OF_INSTR(); 4905} 4906 4907/**************************************************************************** 4908REMARKS: 4909Handles opcode 0x74 4910****************************************************************************/ 4911static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1)) 4912{ 4913 s8 offset; 4914 u16 target; 4915 4916 /* jump to byte offset if zero flag is set. */ 4917 START_OF_INSTR(); 4918 DECODE_PRINTF("JZ\t"); 4919 offset = (s8)fetch_byte_imm(); 4920 target = (u16)(M.x86.R_IP + (s16)offset); 4921 DECODE_PRINTF2("%x\n", target); 4922 TRACE_AND_STEP(); 4923 if (ACCESS_FLAG(F_ZF)) 4924 M.x86.R_IP = target; 4925 DECODE_CLEAR_SEGOVR(); 4926 END_OF_INSTR(); 4927} 4928 4929/**************************************************************************** 4930REMARKS: 4931Handles opcode 0x75 4932****************************************************************************/ 4933static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1)) 4934{ 4935 s8 offset; 4936 u16 target; 4937 4938 /* jump to byte offset if zero flag is clear. */ 4939 START_OF_INSTR(); 4940 DECODE_PRINTF("JNZ\t"); 4941 offset = (s8)fetch_byte_imm(); 4942 target = (u16)(M.x86.R_IP + (s16)offset); 4943 DECODE_PRINTF2("%x\n", target); 4944 TRACE_AND_STEP(); 4945 if (!ACCESS_FLAG(F_ZF)) 4946 M.x86.R_IP = target; 4947 DECODE_CLEAR_SEGOVR(); 4948 END_OF_INSTR(); 4949} 4950 4951/**************************************************************************** 4952REMARKS: 4953Handles opcode 0x76 4954****************************************************************************/ 4955static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1)) 4956{ 4957 s8 offset; 4958 u16 target; 4959 4960 /* jump to byte offset if carry flag is set or if the zero 4961 flag is set. */ 4962 START_OF_INSTR(); 4963 DECODE_PRINTF("JBE\t"); 4964 offset = (s8)fetch_byte_imm(); 4965 target = (u16)(M.x86.R_IP + (s16)offset); 4966 DECODE_PRINTF2("%x\n", target); 4967 TRACE_AND_STEP(); 4968 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) 4969 M.x86.R_IP = target; 4970 DECODE_CLEAR_SEGOVR(); 4971 END_OF_INSTR(); 4972} 4973 4974/**************************************************************************** 4975REMARKS: 4976Handles opcode 0x77 4977****************************************************************************/ 4978static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1)) 4979{ 4980 s8 offset; 4981 u16 target; 4982 4983 /* jump to byte offset if carry flag is clear and if the zero 4984 flag is clear */ 4985 START_OF_INSTR(); 4986 DECODE_PRINTF("JNBE\t"); 4987 offset = (s8)fetch_byte_imm(); 4988 target = (u16)(M.x86.R_IP + (s16)offset); 4989 DECODE_PRINTF2("%x\n", target); 4990 TRACE_AND_STEP(); 4991 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))) 4992 M.x86.R_IP = target; 4993 DECODE_CLEAR_SEGOVR(); 4994 END_OF_INSTR(); 4995} 4996 4997/**************************************************************************** 4998REMARKS: 4999Handles opcode 0x78 5000****************************************************************************/ 5001static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1)) 5002{ 5003 s8 offset; 5004 u16 target; 5005 5006 /* jump to byte offset if sign flag is set */ 5007 START_OF_INSTR(); 5008 DECODE_PRINTF("JS\t"); 5009 offset = (s8)fetch_byte_imm(); 5010 target = (u16)(M.x86.R_IP + (s16)offset); 5011 DECODE_PRINTF2("%x\n", target); 5012 TRACE_AND_STEP(); 5013 if (ACCESS_FLAG(F_SF)) 5014 M.x86.R_IP = target; 5015 DECODE_CLEAR_SEGOVR(); 5016 END_OF_INSTR(); 5017} 5018 5019/**************************************************************************** 5020REMARKS: 5021Handles opcode 0x79 5022****************************************************************************/ 5023static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1)) 5024{ 5025 s8 offset; 5026 u16 target; 5027 5028 /* jump to byte offset if sign flag is clear */ 5029 START_OF_INSTR(); 5030 DECODE_PRINTF("JNS\t"); 5031 offset = (s8)fetch_byte_imm(); 5032 target = (u16)(M.x86.R_IP + (s16)offset); 5033 DECODE_PRINTF2("%x\n", target); 5034 TRACE_AND_STEP(); 5035 if (!ACCESS_FLAG(F_SF)) 5036 M.x86.R_IP = target; 5037 DECODE_CLEAR_SEGOVR(); 5038 END_OF_INSTR(); 5039} 5040 5041/**************************************************************************** 5042REMARKS: 5043Handles opcode 0x7a 5044****************************************************************************/ 5045static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1)) 5046{ 5047 s8 offset; 5048 u16 target; 5049 5050 /* jump to byte offset if parity flag is set (even parity) */ 5051 START_OF_INSTR(); 5052 DECODE_PRINTF("JP\t"); 5053 offset = (s8)fetch_byte_imm(); 5054 target = (u16)(M.x86.R_IP + (s16)offset); 5055 DECODE_PRINTF2("%x\n", target); 5056 TRACE_AND_STEP(); 5057 if (ACCESS_FLAG(F_PF)) 5058 M.x86.R_IP = target; 5059 DECODE_CLEAR_SEGOVR(); 5060 END_OF_INSTR(); 5061} 5062 5063/**************************************************************************** 5064REMARKS: 5065Handles opcode 0x7b 5066****************************************************************************/ 5067static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1)) 5068{ 5069 s8 offset; 5070 u16 target; 5071 5072 /* jump to byte offset if parity flag is clear (odd parity) */ 5073 START_OF_INSTR(); 5074 DECODE_PRINTF("JNP\t"); 5075 offset = (s8)fetch_byte_imm(); 5076 target = (u16)(M.x86.R_IP + (s16)offset); 5077 DECODE_PRINTF2("%x\n", target); 5078 TRACE_AND_STEP(); 5079 if (!ACCESS_FLAG(F_PF)) 5080 M.x86.R_IP = target; 5081 DECODE_CLEAR_SEGOVR(); 5082 END_OF_INSTR(); 5083} 5084 5085/**************************************************************************** 5086REMARKS: 5087Handles opcode 0x7c 5088****************************************************************************/ 5089static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1)) 5090{ 5091 s8 offset; 5092 u16 target; 5093 int sf, of; 5094 5095 /* jump to byte offset if sign flag not equal to overflow flag. */ 5096 START_OF_INSTR(); 5097 DECODE_PRINTF("JL\t"); 5098 offset = (s8)fetch_byte_imm(); 5099 target = (u16)(M.x86.R_IP + (s16)offset); 5100 DECODE_PRINTF2("%x\n", target); 5101 TRACE_AND_STEP(); 5102 sf = ACCESS_FLAG(F_SF) != 0; 5103 of = ACCESS_FLAG(F_OF) != 0; 5104 if (sf ^ of) 5105 M.x86.R_IP = target; 5106 DECODE_CLEAR_SEGOVR(); 5107 END_OF_INSTR(); 5108} 5109 5110/**************************************************************************** 5111REMARKS: 5112Handles opcode 0x7d 5113****************************************************************************/ 5114static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1)) 5115{ 5116 s8 offset; 5117 u16 target; 5118 int sf, of; 5119 5120 /* jump to byte offset if sign flag not equal to overflow flag. */ 5121 START_OF_INSTR(); 5122 DECODE_PRINTF("JNL\t"); 5123 offset = (s8)fetch_byte_imm(); 5124 target = (u16)(M.x86.R_IP + (s16)offset); 5125 DECODE_PRINTF2("%x\n", target); 5126 TRACE_AND_STEP(); 5127 sf = ACCESS_FLAG(F_SF) != 0; 5128 of = ACCESS_FLAG(F_OF) != 0; 5129 /* note: inverse of above, but using == instead of xor. */ 5130 if (sf == of) 5131 M.x86.R_IP = target; 5132 DECODE_CLEAR_SEGOVR(); 5133 END_OF_INSTR(); 5134} 5135 5136/**************************************************************************** 5137REMARKS: 5138Handles opcode 0x7e 5139****************************************************************************/ 5140static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1)) 5141{ 5142 s8 offset; 5143 u16 target; 5144 int sf, of; 5145 5146 /* jump to byte offset if sign flag not equal to overflow flag 5147 or the zero flag is set */ 5148 START_OF_INSTR(); 5149 DECODE_PRINTF("JLE\t"); 5150 offset = (s8)fetch_byte_imm(); 5151 target = (u16)(M.x86.R_IP + (s16)offset); 5152 DECODE_PRINTF2("%x\n", target); 5153 TRACE_AND_STEP(); 5154 sf = ACCESS_FLAG(F_SF) != 0; 5155 of = ACCESS_FLAG(F_OF) != 0; 5156 if ((sf ^ of) || ACCESS_FLAG(F_ZF)) 5157 M.x86.R_IP = target; 5158 DECODE_CLEAR_SEGOVR(); 5159 END_OF_INSTR(); 5160} 5161 5162/**************************************************************************** 5163REMARKS: 5164Handles opcode 0x7f 5165****************************************************************************/ 5166static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1)) 5167{ 5168 s8 offset; 5169 u16 target; 5170 int sf, of; 5171 5172 /* jump to byte offset if sign flag equal to overflow flag. 5173 and the zero flag is clear */ 5174 START_OF_INSTR(); 5175 DECODE_PRINTF("JNLE\t"); 5176 offset = (s8)fetch_byte_imm(); 5177 target = (u16)(M.x86.R_IP + (s16)offset); 5178 DECODE_PRINTF2("%x\n", target); 5179 TRACE_AND_STEP(); 5180 sf = ACCESS_FLAG(F_SF) != 0; 5181 of = ACCESS_FLAG(F_OF) != 0; 5182 if ((sf == of) && !ACCESS_FLAG(F_ZF)) 5183 M.x86.R_IP = target; 5184 DECODE_CLEAR_SEGOVR(); 5185 END_OF_INSTR(); 5186} 5187 5188static u8 (*opc80_byte_operation[])(u8 d, u8 s) = 5189{ 5190 add_byte, /* 00 */ 5191 or_byte, /* 01 */ 5192 adc_byte, /* 02 */ 5193 sbb_byte, /* 03 */ 5194 and_byte, /* 04 */ 5195 sub_byte, /* 05 */ 5196 xor_byte, /* 06 */ 5197 cmp_byte, /* 07 */ 5198}; 5199 5200/**************************************************************************** 5201REMARKS: 5202Handles opcode 0x80 5203****************************************************************************/ 5204static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5205{ 5206 int mod, rl, rh; 5207 u8 *destreg; 5208 uint destoffset; 5209 u8 imm; 5210 u8 destval; 5211 5212 /* 5213 * Weirdo special case instruction format. Part of the opcode 5214 * held below in "RH". Doubly nested case would result, except 5215 * that the decoded instruction 5216 */ 5217 START_OF_INSTR(); 5218 FETCH_DECODE_MODRM(mod, rh, rl); 5219#ifdef DEBUG 5220 if (DEBUG_DECODE()) { 5221 /* XXX DECODE_PRINTF may be changed to something more 5222 general, so that it is important to leave the strings 5223 in the same format, even though the result is that the 5224 above test is done twice. */ 5225 5226 switch (rh) { 5227 case 0: 5228 DECODE_PRINTF("ADD\t"); 5229 break; 5230 case 1: 5231 DECODE_PRINTF("OR\t"); 5232 break; 5233 case 2: 5234 DECODE_PRINTF("ADC\t"); 5235 break; 5236 case 3: 5237 DECODE_PRINTF("SBB\t"); 5238 break; 5239 case 4: 5240 DECODE_PRINTF("AND\t"); 5241 break; 5242 case 5: 5243 DECODE_PRINTF("SUB\t"); 5244 break; 5245 case 6: 5246 DECODE_PRINTF("XOR\t"); 5247 break; 5248 case 7: 5249 DECODE_PRINTF("CMP\t"); 5250 break; 5251 } 5252 } 5253#endif 5254 /* know operation, decode the mod byte to find the addressing 5255 mode. */ 5256 switch (mod) { 5257 case 0: 5258 DECODE_PRINTF("BYTE PTR "); 5259 destoffset = decode_rm00_address(rl); 5260 DECODE_PRINTF(","); 5261 destval = fetch_data_byte(destoffset); 5262 imm = fetch_byte_imm(); 5263 DECODE_PRINTF2("%x\n", imm); 5264 TRACE_AND_STEP(); 5265 destval = (*opc80_byte_operation[rh]) (destval, imm); 5266 if (rh != 7) 5267 store_data_byte(destoffset, destval); 5268 break; 5269 case 1: 5270 DECODE_PRINTF("BYTE PTR "); 5271 destoffset = decode_rm01_address(rl); 5272 DECODE_PRINTF(","); 5273 destval = fetch_data_byte(destoffset); 5274 imm = fetch_byte_imm(); 5275 DECODE_PRINTF2("%x\n", imm); 5276 TRACE_AND_STEP(); 5277 destval = (*opc80_byte_operation[rh]) (destval, imm); 5278 if (rh != 7) 5279 store_data_byte(destoffset, destval); 5280 break; 5281 case 2: 5282 DECODE_PRINTF("BYTE PTR "); 5283 destoffset = decode_rm10_address(rl); 5284 DECODE_PRINTF(","); 5285 destval = fetch_data_byte(destoffset); 5286 imm = fetch_byte_imm(); 5287 DECODE_PRINTF2("%x\n", imm); 5288 TRACE_AND_STEP(); 5289 destval = (*opc80_byte_operation[rh]) (destval, imm); 5290 if (rh != 7) 5291 store_data_byte(destoffset, destval); 5292 break; 5293 case 3: /* register to register */ 5294 destreg = DECODE_RM_BYTE_REGISTER(rl); 5295 DECODE_PRINTF(","); 5296 imm = fetch_byte_imm(); 5297 DECODE_PRINTF2("%x\n", imm); 5298 TRACE_AND_STEP(); 5299 destval = (*opc80_byte_operation[rh]) (*destreg, imm); 5300 if (rh != 7) 5301 *destreg = destval; 5302 break; 5303 } 5304 DECODE_CLEAR_SEGOVR(); 5305 END_OF_INSTR(); 5306} 5307 5308static u16 (*opc81_word_operation[])(u16 d, u16 s) = 5309{ 5310 add_word, /*00 */ 5311 or_word, /*01 */ 5312 adc_word, /*02 */ 5313 sbb_word, /*03 */ 5314 and_word, /*04 */ 5315 sub_word, /*05 */ 5316 xor_word, /*06 */ 5317 cmp_word, /*07 */ 5318}; 5319 5320static u32 (*opc81_long_operation[])(u32 d, u32 s) = 5321{ 5322 add_long, /*00 */ 5323 or_long, /*01 */ 5324 adc_long, /*02 */ 5325 sbb_long, /*03 */ 5326 and_long, /*04 */ 5327 sub_long, /*05 */ 5328 xor_long, /*06 */ 5329 cmp_long, /*07 */ 5330}; 5331 5332/**************************************************************************** 5333REMARKS: 5334Handles opcode 0x81 5335****************************************************************************/ 5336static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5337{ 5338 int mod, rl, rh; 5339 uint destoffset; 5340 5341 /* 5342 * Weirdo special case instruction format. Part of the opcode 5343 * held below in "RH". Doubly nested case would result, except 5344 * that the decoded instruction 5345 */ 5346 START_OF_INSTR(); 5347 FETCH_DECODE_MODRM(mod, rh, rl); 5348#ifdef DEBUG 5349 if (DEBUG_DECODE()) { 5350 /* XXX DECODE_PRINTF may be changed to something more 5351 general, so that it is important to leave the strings 5352 in the same format, even though the result is that the 5353 above test is done twice. */ 5354 5355 switch (rh) { 5356 case 0: 5357 DECODE_PRINTF("ADD\t"); 5358 break; 5359 case 1: 5360 DECODE_PRINTF("OR\t"); 5361 break; 5362 case 2: 5363 DECODE_PRINTF("ADC\t"); 5364 break; 5365 case 3: 5366 DECODE_PRINTF("SBB\t"); 5367 break; 5368 case 4: 5369 DECODE_PRINTF("AND\t"); 5370 break; 5371 case 5: 5372 DECODE_PRINTF("SUB\t"); 5373 break; 5374 case 6: 5375 DECODE_PRINTF("XOR\t"); 5376 break; 5377 case 7: 5378 DECODE_PRINTF("CMP\t"); 5379 break; 5380 } 5381 } 5382#endif 5383 /* 5384 * Know operation, decode the mod byte to find the addressing 5385 * mode. 5386 */ 5387 switch (mod) { 5388 case 0: 5389 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5390 u32 destval,imm; 5391 5392 DECODE_PRINTF("DWORD PTR "); 5393 destoffset = decode_rm00_address(rl); 5394 DECODE_PRINTF(","); 5395 destval = fetch_data_long(destoffset); 5396 imm = fetch_long_imm(); 5397 DECODE_PRINTF2("%x\n", imm); 5398 TRACE_AND_STEP(); 5399 destval = (*opc81_long_operation[rh]) (destval, imm); 5400 if (rh != 7) 5401 store_data_long(destoffset, destval); 5402 } else { 5403 u16 destval,imm; 5404 5405 DECODE_PRINTF("WORD PTR "); 5406 destoffset = decode_rm00_address(rl); 5407 DECODE_PRINTF(","); 5408 destval = fetch_data_word(destoffset); 5409 imm = fetch_word_imm(); 5410 DECODE_PRINTF2("%x\n", imm); 5411 TRACE_AND_STEP(); 5412 destval = (*opc81_word_operation[rh]) (destval, imm); 5413 if (rh != 7) 5414 store_data_word(destoffset, destval); 5415 } 5416 break; 5417 case 1: 5418 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5419 u32 destval,imm; 5420 5421 DECODE_PRINTF("DWORD PTR "); 5422 destoffset = decode_rm01_address(rl); 5423 DECODE_PRINTF(","); 5424 destval = fetch_data_long(destoffset); 5425 imm = fetch_long_imm(); 5426 DECODE_PRINTF2("%x\n", imm); 5427 TRACE_AND_STEP(); 5428 destval = (*opc81_long_operation[rh]) (destval, imm); 5429 if (rh != 7) 5430 store_data_long(destoffset, destval); 5431 } else { 5432 u16 destval,imm; 5433 5434 DECODE_PRINTF("WORD PTR "); 5435 destoffset = decode_rm01_address(rl); 5436 DECODE_PRINTF(","); 5437 destval = fetch_data_word(destoffset); 5438 imm = fetch_word_imm(); 5439 DECODE_PRINTF2("%x\n", imm); 5440 TRACE_AND_STEP(); 5441 destval = (*opc81_word_operation[rh]) (destval, imm); 5442 if (rh != 7) 5443 store_data_word(destoffset, destval); 5444 } 5445 break; 5446 case 2: 5447 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5448 u32 destval,imm; 5449 5450 DECODE_PRINTF("DWORD PTR "); 5451 destoffset = decode_rm10_address(rl); 5452 DECODE_PRINTF(","); 5453 destval = fetch_data_long(destoffset); 5454 imm = fetch_long_imm(); 5455 DECODE_PRINTF2("%x\n", imm); 5456 TRACE_AND_STEP(); 5457 destval = (*opc81_long_operation[rh]) (destval, imm); 5458 if (rh != 7) 5459 store_data_long(destoffset, destval); 5460 } else { 5461 u16 destval,imm; 5462 5463 DECODE_PRINTF("WORD PTR "); 5464 destoffset = decode_rm10_address(rl); 5465 DECODE_PRINTF(","); 5466 destval = fetch_data_word(destoffset); 5467 imm = fetch_word_imm(); 5468 DECODE_PRINTF2("%x\n", imm); 5469 TRACE_AND_STEP(); 5470 destval = (*opc81_word_operation[rh]) (destval, imm); 5471 if (rh != 7) 5472 store_data_word(destoffset, destval); 5473 } 5474 break; 5475 case 3: /* register to register */ 5476 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5477 u32 *destreg; 5478 u32 destval,imm; 5479 5480 destreg = DECODE_RM_LONG_REGISTER(rl); 5481 DECODE_PRINTF(","); 5482 imm = fetch_long_imm(); 5483 DECODE_PRINTF2("%x\n", imm); 5484 TRACE_AND_STEP(); 5485 destval = (*opc81_long_operation[rh]) (*destreg, imm); 5486 if (rh != 7) 5487 *destreg = destval; 5488 } else { 5489 u16 *destreg; 5490 u16 destval,imm; 5491 5492 destreg = DECODE_RM_WORD_REGISTER(rl); 5493 DECODE_PRINTF(","); 5494 imm = fetch_word_imm(); 5495 DECODE_PRINTF2("%x\n", imm); 5496 TRACE_AND_STEP(); 5497 destval = (*opc81_word_operation[rh]) (*destreg, imm); 5498 if (rh != 7) 5499 *destreg = destval; 5500 } 5501 break; 5502 } 5503 DECODE_CLEAR_SEGOVR(); 5504 END_OF_INSTR(); 5505} 5506 5507static u8 (*opc82_byte_operation[])(u8 s, u8 d) = 5508{ 5509 add_byte, /*00 */ 5510 or_byte, /*01 *//*YYY UNUSED ???? */ 5511 adc_byte, /*02 */ 5512 sbb_byte, /*03 */ 5513 and_byte, /*04 *//*YYY UNUSED ???? */ 5514 sub_byte, /*05 */ 5515 xor_byte, /*06 *//*YYY UNUSED ???? */ 5516 cmp_byte, /*07 */ 5517}; 5518 5519/**************************************************************************** 5520REMARKS: 5521Handles opcode 0x82 5522****************************************************************************/ 5523static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5524{ 5525 int mod, rl, rh; 5526 u8 *destreg; 5527 uint destoffset; 5528 u8 imm; 5529 u8 destval; 5530 5531 /* 5532 * Weirdo special case instruction format. Part of the opcode 5533 * held below in "RH". Doubly nested case would result, except 5534 * that the decoded instruction Similar to opcode 81, except that 5535 * the immediate byte is sign extended to a word length. 5536 */ 5537 START_OF_INSTR(); 5538 FETCH_DECODE_MODRM(mod, rh, rl); 5539#ifdef DEBUG 5540 if (DEBUG_DECODE()) { 5541 /* XXX DECODE_PRINTF may be changed to something more 5542 general, so that it is important to leave the strings 5543 in the same format, even though the result is that the 5544 above test is done twice. */ 5545 switch (rh) { 5546 case 0: 5547 DECODE_PRINTF("ADD\t"); 5548 break; 5549 case 1: 5550 DECODE_PRINTF("OR\t"); 5551 break; 5552 case 2: 5553 DECODE_PRINTF("ADC\t"); 5554 break; 5555 case 3: 5556 DECODE_PRINTF("SBB\t"); 5557 break; 5558 case 4: 5559 DECODE_PRINTF("AND\t"); 5560 break; 5561 case 5: 5562 DECODE_PRINTF("SUB\t"); 5563 break; 5564 case 6: 5565 DECODE_PRINTF("XOR\t"); 5566 break; 5567 case 7: 5568 DECODE_PRINTF("CMP\t"); 5569 break; 5570 } 5571 } 5572#endif 5573 /* know operation, decode the mod byte to find the addressing 5574 mode. */ 5575 switch (mod) { 5576 case 0: 5577 DECODE_PRINTF("BYTE PTR "); 5578 destoffset = decode_rm00_address(rl); 5579 destval = fetch_data_byte(destoffset); 5580 imm = fetch_byte_imm(); 5581 DECODE_PRINTF2(",%x\n", imm); 5582 TRACE_AND_STEP(); 5583 destval = (*opc82_byte_operation[rh]) (destval, imm); 5584 if (rh != 7) 5585 store_data_byte(destoffset, destval); 5586 break; 5587 case 1: 5588 DECODE_PRINTF("BYTE PTR "); 5589 destoffset = decode_rm01_address(rl); 5590 destval = fetch_data_byte(destoffset); 5591 imm = fetch_byte_imm(); 5592 DECODE_PRINTF2(",%x\n", imm); 5593 TRACE_AND_STEP(); 5594 destval = (*opc82_byte_operation[rh]) (destval, imm); 5595 if (rh != 7) 5596 store_data_byte(destoffset, destval); 5597 break; 5598 case 2: 5599 DECODE_PRINTF("BYTE PTR "); 5600 destoffset = decode_rm10_address(rl); 5601 destval = fetch_data_byte(destoffset); 5602 imm = fetch_byte_imm(); 5603 DECODE_PRINTF2(",%x\n", imm); 5604 TRACE_AND_STEP(); 5605 destval = (*opc82_byte_operation[rh]) (destval, imm); 5606 if (rh != 7) 5607 store_data_byte(destoffset, destval); 5608 break; 5609 case 3: /* register to register */ 5610 destreg = DECODE_RM_BYTE_REGISTER(rl); 5611 imm = fetch_byte_imm(); 5612 DECODE_PRINTF2(",%x\n", imm); 5613 TRACE_AND_STEP(); 5614 destval = (*opc82_byte_operation[rh]) (*destreg, imm); 5615 if (rh != 7) 5616 *destreg = destval; 5617 break; 5618 } 5619 DECODE_CLEAR_SEGOVR(); 5620 END_OF_INSTR(); 5621} 5622 5623static u16 (*opc83_word_operation[])(u16 s, u16 d) = 5624{ 5625 add_word, /*00 */ 5626 or_word, /*01 *//*YYY UNUSED ???? */ 5627 adc_word, /*02 */ 5628 sbb_word, /*03 */ 5629 and_word, /*04 *//*YYY UNUSED ???? */ 5630 sub_word, /*05 */ 5631 xor_word, /*06 *//*YYY UNUSED ???? */ 5632 cmp_word, /*07 */ 5633}; 5634 5635static u32 (*opc83_long_operation[])(u32 s, u32 d) = 5636{ 5637 add_long, /*00 */ 5638 or_long, /*01 *//*YYY UNUSED ???? */ 5639 adc_long, /*02 */ 5640 sbb_long, /*03 */ 5641 and_long, /*04 *//*YYY UNUSED ???? */ 5642 sub_long, /*05 */ 5643 xor_long, /*06 *//*YYY UNUSED ???? */ 5644 cmp_long, /*07 */ 5645}; 5646 5647/**************************************************************************** 5648REMARKS: 5649Handles opcode 0x83 5650****************************************************************************/ 5651static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5652{ 5653 int mod, rl, rh; 5654 uint destoffset; 5655 5656 /* 5657 * Weirdo special case instruction format. Part of the opcode 5658 * held below in "RH". Doubly nested case would result, except 5659 * that the decoded instruction Similar to opcode 81, except that 5660 * the immediate byte is sign extended to a word length. 5661 */ 5662 START_OF_INSTR(); 5663 FETCH_DECODE_MODRM(mod, rh, rl); 5664#ifdef DEBUG 5665 if (DEBUG_DECODE()) { 5666 /* XXX DECODE_PRINTF may be changed to something more 5667 general, so that it is important to leave the strings 5668 in the same format, even though the result is that the 5669 above test is done twice. */ 5670 switch (rh) { 5671 case 0: 5672 DECODE_PRINTF("ADD\t"); 5673 break; 5674 case 1: 5675 DECODE_PRINTF("OR\t"); 5676 break; 5677 case 2: 5678 DECODE_PRINTF("ADC\t"); 5679 break; 5680 case 3: 5681 DECODE_PRINTF("SBB\t"); 5682 break; 5683 case 4: 5684 DECODE_PRINTF("AND\t"); 5685 break; 5686 case 5: 5687 DECODE_PRINTF("SUB\t"); 5688 break; 5689 case 6: 5690 DECODE_PRINTF("XOR\t"); 5691 break; 5692 case 7: 5693 DECODE_PRINTF("CMP\t"); 5694 break; 5695 } 5696 } 5697#endif 5698 /* know operation, decode the mod byte to find the addressing 5699 mode. */ 5700 switch (mod) { 5701 case 0: 5702 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5703 u32 destval,imm; 5704 5705 DECODE_PRINTF("DWORD PTR "); 5706 destoffset = decode_rm00_address(rl); 5707 destval = fetch_data_long(destoffset); 5708 imm = (s8) fetch_byte_imm(); 5709 DECODE_PRINTF2(",%x\n", imm); 5710 TRACE_AND_STEP(); 5711 destval = (*opc83_long_operation[rh]) (destval, imm); 5712 if (rh != 7) 5713 store_data_long(destoffset, destval); 5714 } else { 5715 u16 destval,imm; 5716 5717 DECODE_PRINTF("WORD PTR "); 5718 destoffset = decode_rm00_address(rl); 5719 destval = fetch_data_word(destoffset); 5720 imm = (s8) fetch_byte_imm(); 5721 DECODE_PRINTF2(",%x\n", imm); 5722 TRACE_AND_STEP(); 5723 destval = (*opc83_word_operation[rh]) (destval, imm); 5724 if (rh != 7) 5725 store_data_word(destoffset, destval); 5726 } 5727 break; 5728 case 1: 5729 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5730 u32 destval,imm; 5731 5732 DECODE_PRINTF("DWORD PTR "); 5733 destoffset = decode_rm01_address(rl); 5734 destval = fetch_data_long(destoffset); 5735 imm = (s8) fetch_byte_imm(); 5736 DECODE_PRINTF2(",%x\n", imm); 5737 TRACE_AND_STEP(); 5738 destval = (*opc83_long_operation[rh]) (destval, imm); 5739 if (rh != 7) 5740 store_data_long(destoffset, destval); 5741 } else { 5742 u16 destval,imm; 5743 5744 DECODE_PRINTF("WORD PTR "); 5745 destoffset = decode_rm01_address(rl); 5746 destval = fetch_data_word(destoffset); 5747 imm = (s8) fetch_byte_imm(); 5748 DECODE_PRINTF2(",%x\n", imm); 5749 TRACE_AND_STEP(); 5750 destval = (*opc83_word_operation[rh]) (destval, imm); 5751 if (rh != 7) 5752 store_data_word(destoffset, destval); 5753 } 5754 break; 5755 case 2: 5756 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5757 u32 destval,imm; 5758 5759 DECODE_PRINTF("DWORD PTR "); 5760 destoffset = decode_rm10_address(rl); 5761 destval = fetch_data_long(destoffset); 5762 imm = (s8) fetch_byte_imm(); 5763 DECODE_PRINTF2(",%x\n", imm); 5764 TRACE_AND_STEP(); 5765 destval = (*opc83_long_operation[rh]) (destval, imm); 5766 if (rh != 7) 5767 store_data_long(destoffset, destval); 5768 } else { 5769 u16 destval,imm; 5770 5771 DECODE_PRINTF("WORD PTR "); 5772 destoffset = decode_rm10_address(rl); 5773 destval = fetch_data_word(destoffset); 5774 imm = (s8) fetch_byte_imm(); 5775 DECODE_PRINTF2(",%x\n", imm); 5776 TRACE_AND_STEP(); 5777 destval = (*opc83_word_operation[rh]) (destval, imm); 5778 if (rh != 7) 5779 store_data_word(destoffset, destval); 5780 } 5781 break; 5782 case 3: /* register to register */ 5783 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5784 u32 *destreg; 5785 u32 destval,imm; 5786 5787 destreg = DECODE_RM_LONG_REGISTER(rl); 5788 imm = (s8) fetch_byte_imm(); 5789 DECODE_PRINTF2(",%x\n", imm); 5790 TRACE_AND_STEP(); 5791 destval = (*opc83_long_operation[rh]) (*destreg, imm); 5792 if (rh != 7) 5793 *destreg = destval; 5794 } else { 5795 u16 *destreg; 5796 u16 destval,imm; 5797 5798 destreg = DECODE_RM_WORD_REGISTER(rl); 5799 imm = (s8) fetch_byte_imm(); 5800 DECODE_PRINTF2(",%x\n", imm); 5801 TRACE_AND_STEP(); 5802 destval = (*opc83_word_operation[rh]) (*destreg, imm); 5803 if (rh != 7) 5804 *destreg = destval; 5805 } 5806 break; 5807 } 5808 DECODE_CLEAR_SEGOVR(); 5809 END_OF_INSTR(); 5810} 5811 5812/**************************************************************************** 5813REMARKS: 5814Handles opcode 0x84 5815****************************************************************************/ 5816static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5817{ 5818 int mod, rl, rh; 5819 u8 *destreg, *srcreg; 5820 uint destoffset; 5821 u8 destval; 5822 5823 START_OF_INSTR(); 5824 DECODE_PRINTF("TEST\t"); 5825 FETCH_DECODE_MODRM(mod, rh, rl); 5826 switch (mod) { 5827 case 0: 5828 destoffset = decode_rm00_address(rl); 5829 DECODE_PRINTF(","); 5830 destval = fetch_data_byte(destoffset); 5831 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5832 DECODE_PRINTF("\n"); 5833 TRACE_AND_STEP(); 5834 test_byte(destval, *srcreg); 5835 break; 5836 case 1: 5837 destoffset = decode_rm01_address(rl); 5838 DECODE_PRINTF(","); 5839 destval = fetch_data_byte(destoffset); 5840 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5841 DECODE_PRINTF("\n"); 5842 TRACE_AND_STEP(); 5843 test_byte(destval, *srcreg); 5844 break; 5845 case 2: 5846 destoffset = decode_rm10_address(rl); 5847 DECODE_PRINTF(","); 5848 destval = fetch_data_byte(destoffset); 5849 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5850 DECODE_PRINTF("\n"); 5851 TRACE_AND_STEP(); 5852 test_byte(destval, *srcreg); 5853 break; 5854 case 3: /* register to register */ 5855 destreg = DECODE_RM_BYTE_REGISTER(rl); 5856 DECODE_PRINTF(","); 5857 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5858 DECODE_PRINTF("\n"); 5859 TRACE_AND_STEP(); 5860 test_byte(*destreg, *srcreg); 5861 break; 5862 } 5863 DECODE_CLEAR_SEGOVR(); 5864 END_OF_INSTR(); 5865} 5866 5867/**************************************************************************** 5868REMARKS: 5869Handles opcode 0x85 5870****************************************************************************/ 5871static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 5872{ 5873 int mod, rl, rh; 5874 uint destoffset; 5875 5876 START_OF_INSTR(); 5877 DECODE_PRINTF("TEST\t"); 5878 FETCH_DECODE_MODRM(mod, rh, rl); 5879 switch (mod) { 5880 case 0: 5881 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5882 u32 destval; 5883 u32 *srcreg; 5884 5885 destoffset = decode_rm00_address(rl); 5886 DECODE_PRINTF(","); 5887 destval = fetch_data_long(destoffset); 5888 srcreg = DECODE_RM_LONG_REGISTER(rh); 5889 DECODE_PRINTF("\n"); 5890 TRACE_AND_STEP(); 5891 test_long(destval, *srcreg); 5892 } else { 5893 u16 destval; 5894 u16 *srcreg; 5895 5896 destoffset = decode_rm00_address(rl); 5897 DECODE_PRINTF(","); 5898 destval = fetch_data_word(destoffset); 5899 srcreg = DECODE_RM_WORD_REGISTER(rh); 5900 DECODE_PRINTF("\n"); 5901 TRACE_AND_STEP(); 5902 test_word(destval, *srcreg); 5903 } 5904 break; 5905 case 1: 5906 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5907 u32 destval; 5908 u32 *srcreg; 5909 5910 destoffset = decode_rm01_address(rl); 5911 DECODE_PRINTF(","); 5912 destval = fetch_data_long(destoffset); 5913 srcreg = DECODE_RM_LONG_REGISTER(rh); 5914 DECODE_PRINTF("\n"); 5915 TRACE_AND_STEP(); 5916 test_long(destval, *srcreg); 5917 } else { 5918 u16 destval; 5919 u16 *srcreg; 5920 5921 destoffset = decode_rm01_address(rl); 5922 DECODE_PRINTF(","); 5923 destval = fetch_data_word(destoffset); 5924 srcreg = DECODE_RM_WORD_REGISTER(rh); 5925 DECODE_PRINTF("\n"); 5926 TRACE_AND_STEP(); 5927 test_word(destval, *srcreg); 5928 } 5929 break; 5930 case 2: 5931 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5932 u32 destval; 5933 u32 *srcreg; 5934 5935 destoffset = decode_rm10_address(rl); 5936 DECODE_PRINTF(","); 5937 destval = fetch_data_long(destoffset); 5938 srcreg = DECODE_RM_LONG_REGISTER(rh); 5939 DECODE_PRINTF("\n"); 5940 TRACE_AND_STEP(); 5941 test_long(destval, *srcreg); 5942 } else { 5943 u16 destval; 5944 u16 *srcreg; 5945 5946 destoffset = decode_rm10_address(rl); 5947 DECODE_PRINTF(","); 5948 destval = fetch_data_word(destoffset); 5949 srcreg = DECODE_RM_WORD_REGISTER(rh); 5950 DECODE_PRINTF("\n"); 5951 TRACE_AND_STEP(); 5952 test_word(destval, *srcreg); 5953 } 5954 break; 5955 case 3: /* register to register */ 5956 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5957 u32 *destreg,*srcreg; 5958 5959 destreg = DECODE_RM_LONG_REGISTER(rl); 5960 DECODE_PRINTF(","); 5961 srcreg = DECODE_RM_LONG_REGISTER(rh); 5962 DECODE_PRINTF("\n"); 5963 TRACE_AND_STEP(); 5964 test_long(*destreg, *srcreg); 5965 } else { 5966 u16 *destreg,*srcreg; 5967 5968 destreg = DECODE_RM_WORD_REGISTER(rl); 5969 DECODE_PRINTF(","); 5970 srcreg = DECODE_RM_WORD_REGISTER(rh); 5971 DECODE_PRINTF("\n"); 5972 TRACE_AND_STEP(); 5973 test_word(*destreg, *srcreg); 5974 } 5975 break; 5976 } 5977 DECODE_CLEAR_SEGOVR(); 5978 END_OF_INSTR(); 5979} 5980 5981/**************************************************************************** 5982REMARKS: 5983Handles opcode 0x86 5984****************************************************************************/ 5985static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5986{ 5987 int mod, rl, rh; 5988 u8 *destreg, *srcreg; 5989 uint destoffset; 5990 u8 destval; 5991 u8 tmp; 5992 5993 START_OF_INSTR(); 5994 DECODE_PRINTF("XCHG\t"); 5995 FETCH_DECODE_MODRM(mod, rh, rl); 5996 switch (mod) { 5997 case 0: 5998 destoffset = decode_rm00_address(rl); 5999 DECODE_PRINTF(","); 6000 destval = fetch_data_byte(destoffset); 6001 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6002 DECODE_PRINTF("\n"); 6003 TRACE_AND_STEP(); 6004 tmp = *srcreg; 6005 *srcreg = destval; 6006 destval = tmp; 6007 store_data_byte(destoffset, destval); 6008 break; 6009 case 1: 6010 destoffset = decode_rm01_address(rl); 6011 DECODE_PRINTF(","); 6012 destval = fetch_data_byte(destoffset); 6013 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6014 DECODE_PRINTF("\n"); 6015 TRACE_AND_STEP(); 6016 tmp = *srcreg; 6017 *srcreg = destval; 6018 destval = tmp; 6019 store_data_byte(destoffset, destval); 6020 break; 6021 case 2: 6022 destoffset = decode_rm10_address(rl); 6023 DECODE_PRINTF(","); 6024 destval = fetch_data_byte(destoffset); 6025 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6026 DECODE_PRINTF("\n"); 6027 TRACE_AND_STEP(); 6028 tmp = *srcreg; 6029 *srcreg = destval; 6030 destval = tmp; 6031 store_data_byte(destoffset, destval); 6032 break; 6033 case 3: /* register to register */ 6034 destreg = DECODE_RM_BYTE_REGISTER(rl); 6035 DECODE_PRINTF(","); 6036 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6037 DECODE_PRINTF("\n"); 6038 TRACE_AND_STEP(); 6039 tmp = *srcreg; 6040 *srcreg = *destreg; 6041 *destreg = tmp; 6042 break; 6043 } 6044 DECODE_CLEAR_SEGOVR(); 6045 END_OF_INSTR(); 6046} 6047 6048/**************************************************************************** 6049REMARKS: 6050Handles opcode 0x87 6051****************************************************************************/ 6052static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 6053{ 6054 int mod, rl, rh; 6055 uint destoffset; 6056 6057 START_OF_INSTR(); 6058 DECODE_PRINTF("XCHG\t"); 6059 FETCH_DECODE_MODRM(mod, rh, rl); 6060 switch (mod) { 6061 case 0: 6062 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6063 u32 *srcreg; 6064 u32 destval,tmp; 6065 6066 destoffset = decode_rm00_address(rl); 6067 DECODE_PRINTF(","); 6068 destval = fetch_data_long(destoffset); 6069 srcreg = DECODE_RM_LONG_REGISTER(rh); 6070 DECODE_PRINTF("\n"); 6071 TRACE_AND_STEP(); 6072 tmp = *srcreg; 6073 *srcreg = destval; 6074 destval = tmp; 6075 store_data_long(destoffset, destval); 6076 } else { 6077 u16 *srcreg; 6078 u16 destval,tmp; 6079 6080 destoffset = decode_rm00_address(rl); 6081 DECODE_PRINTF(","); 6082 destval = fetch_data_word(destoffset); 6083 srcreg = DECODE_RM_WORD_REGISTER(rh); 6084 DECODE_PRINTF("\n"); 6085 TRACE_AND_STEP(); 6086 tmp = *srcreg; 6087 *srcreg = destval; 6088 destval = tmp; 6089 store_data_word(destoffset, destval); 6090 } 6091 break; 6092 case 1: 6093 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6094 u32 *srcreg; 6095 u32 destval,tmp; 6096 6097 destoffset = decode_rm01_address(rl); 6098 DECODE_PRINTF(","); 6099 destval = fetch_data_long(destoffset); 6100 srcreg = DECODE_RM_LONG_REGISTER(rh); 6101 DECODE_PRINTF("\n"); 6102 TRACE_AND_STEP(); 6103 tmp = *srcreg; 6104 *srcreg = destval; 6105 destval = tmp; 6106 store_data_long(destoffset, destval); 6107 } else { 6108 u16 *srcreg; 6109 u16 destval,tmp; 6110 6111 destoffset = decode_rm01_address(rl); 6112 DECODE_PRINTF(","); 6113 destval = fetch_data_word(destoffset); 6114 srcreg = DECODE_RM_WORD_REGISTER(rh); 6115 DECODE_PRINTF("\n"); 6116 TRACE_AND_STEP(); 6117 tmp = *srcreg; 6118 *srcreg = destval; 6119 destval = tmp; 6120 store_data_word(destoffset, destval); 6121 } 6122 break; 6123 case 2: 6124 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6125 u32 *srcreg; 6126 u32 destval,tmp; 6127 6128 destoffset = decode_rm10_address(rl); 6129 DECODE_PRINTF(","); 6130 destval = fetch_data_long(destoffset); 6131 srcreg = DECODE_RM_LONG_REGISTER(rh); 6132 DECODE_PRINTF("\n"); 6133 TRACE_AND_STEP(); 6134 tmp = *srcreg; 6135 *srcreg = destval; 6136 destval = tmp; 6137 store_data_long(destoffset, destval); 6138 } else { 6139 u16 *srcreg; 6140 u16 destval,tmp; 6141 6142 destoffset = decode_rm10_address(rl); 6143 DECODE_PRINTF(","); 6144 destval = fetch_data_word(destoffset); 6145 srcreg = DECODE_RM_WORD_REGISTER(rh); 6146 DECODE_PRINTF("\n"); 6147 TRACE_AND_STEP(); 6148 tmp = *srcreg; 6149 *srcreg = destval; 6150 destval = tmp; 6151 store_data_word(destoffset, destval); 6152 } 6153 break; 6154 case 3: /* register to register */ 6155 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6156 u32 *destreg,*srcreg; 6157 u32 tmp; 6158 6159 destreg = DECODE_RM_LONG_REGISTER(rl); 6160 DECODE_PRINTF(","); 6161 srcreg = DECODE_RM_LONG_REGISTER(rh); 6162 DECODE_PRINTF("\n"); 6163 TRACE_AND_STEP(); 6164 tmp = *srcreg; 6165 *srcreg = *destreg; 6166 *destreg = tmp; 6167 } else { 6168 u16 *destreg,*srcreg; 6169 u16 tmp; 6170 6171 destreg = DECODE_RM_WORD_REGISTER(rl); 6172 DECODE_PRINTF(","); 6173 srcreg = DECODE_RM_WORD_REGISTER(rh); 6174 DECODE_PRINTF("\n"); 6175 TRACE_AND_STEP(); 6176 tmp = *srcreg; 6177 *srcreg = *destreg; 6178 *destreg = tmp; 6179 } 6180 break; 6181 } 6182 DECODE_CLEAR_SEGOVR(); 6183 END_OF_INSTR(); 6184} 6185 6186/**************************************************************************** 6187REMARKS: 6188Handles opcode 0x88 6189****************************************************************************/ 6190static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6191{ 6192 int mod, rl, rh; 6193 u8 *destreg, *srcreg; 6194 uint destoffset; 6195 6196 START_OF_INSTR(); 6197 DECODE_PRINTF("MOV\t"); 6198 FETCH_DECODE_MODRM(mod, rh, rl); 6199 switch (mod) { 6200 case 0: 6201 destoffset = decode_rm00_address(rl); 6202 DECODE_PRINTF(","); 6203 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6204 DECODE_PRINTF("\n"); 6205 TRACE_AND_STEP(); 6206 store_data_byte(destoffset, *srcreg); 6207 break; 6208 case 1: 6209 destoffset = decode_rm01_address(rl); 6210 DECODE_PRINTF(","); 6211 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6212 DECODE_PRINTF("\n"); 6213 TRACE_AND_STEP(); 6214 store_data_byte(destoffset, *srcreg); 6215 break; 6216 case 2: 6217 destoffset = decode_rm10_address(rl); 6218 DECODE_PRINTF(","); 6219 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6220 DECODE_PRINTF("\n"); 6221 TRACE_AND_STEP(); 6222 store_data_byte(destoffset, *srcreg); 6223 break; 6224 case 3: /* register to register */ 6225 destreg = DECODE_RM_BYTE_REGISTER(rl); 6226 DECODE_PRINTF(","); 6227 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6228 DECODE_PRINTF("\n"); 6229 TRACE_AND_STEP(); 6230 *destreg = *srcreg; 6231 break; 6232 } 6233 DECODE_CLEAR_SEGOVR(); 6234 END_OF_INSTR(); 6235} 6236 6237/**************************************************************************** 6238REMARKS: 6239Handles opcode 0x89 6240****************************************************************************/ 6241static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 6242{ 6243 int mod, rl, rh; 6244 u32 destoffset; 6245 6246 START_OF_INSTR(); 6247 DECODE_PRINTF("MOV\t"); 6248 FETCH_DECODE_MODRM(mod, rh, rl); 6249 switch (mod) { 6250 case 0: 6251 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6252 u32 *srcreg; 6253 6254 destoffset = decode_rm00_address(rl); 6255 DECODE_PRINTF(","); 6256 srcreg = DECODE_RM_LONG_REGISTER(rh); 6257 DECODE_PRINTF("\n"); 6258 TRACE_AND_STEP(); 6259 store_data_long(destoffset, *srcreg); 6260 } else { 6261 u16 *srcreg; 6262 6263 destoffset = decode_rm00_address(rl); 6264 DECODE_PRINTF(","); 6265 srcreg = DECODE_RM_WORD_REGISTER(rh); 6266 DECODE_PRINTF("\n"); 6267 TRACE_AND_STEP(); 6268 store_data_word(destoffset, *srcreg); 6269 } 6270 break; 6271 case 1: 6272 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6273 u32 *srcreg; 6274 6275 destoffset = decode_rm01_address(rl); 6276 DECODE_PRINTF(","); 6277 srcreg = DECODE_RM_LONG_REGISTER(rh); 6278 DECODE_PRINTF("\n"); 6279 TRACE_AND_STEP(); 6280 store_data_long(destoffset, *srcreg); 6281 } else { 6282 u16 *srcreg; 6283 6284 destoffset = decode_rm01_address(rl); 6285 DECODE_PRINTF(","); 6286 srcreg = DECODE_RM_WORD_REGISTER(rh); 6287 DECODE_PRINTF("\n"); 6288 TRACE_AND_STEP(); 6289 store_data_word(destoffset, *srcreg); 6290 } 6291 break; 6292 case 2: 6293 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6294 u32 *srcreg; 6295 6296 destoffset = decode_rm10_address(rl); 6297 DECODE_PRINTF(","); 6298 srcreg = DECODE_RM_LONG_REGISTER(rh); 6299 DECODE_PRINTF("\n"); 6300 TRACE_AND_STEP(); 6301 store_data_long(destoffset, *srcreg); 6302 } else { 6303 u16 *srcreg; 6304 6305 destoffset = decode_rm10_address(rl); 6306 DECODE_PRINTF(","); 6307 srcreg = DECODE_RM_WORD_REGISTER(rh); 6308 DECODE_PRINTF("\n"); 6309 TRACE_AND_STEP(); 6310 store_data_word(destoffset, *srcreg); 6311 } 6312 break; 6313 case 3: /* register to register */ 6314 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6315 u32 *destreg,*srcreg; 6316 6317 destreg = DECODE_RM_LONG_REGISTER(rl); 6318 DECODE_PRINTF(","); 6319 srcreg = DECODE_RM_LONG_REGISTER(rh); 6320 DECODE_PRINTF("\n"); 6321 TRACE_AND_STEP(); 6322 *destreg = *srcreg; 6323 } else { 6324 u16 *destreg,*srcreg; 6325 6326 destreg = DECODE_RM_WORD_REGISTER(rl); 6327 DECODE_PRINTF(","); 6328 srcreg = DECODE_RM_WORD_REGISTER(rh); 6329 DECODE_PRINTF("\n"); 6330 TRACE_AND_STEP(); 6331 *destreg = *srcreg; 6332 } 6333 break; 6334 } 6335 DECODE_CLEAR_SEGOVR(); 6336 END_OF_INSTR(); 6337} 6338 6339/**************************************************************************** 6340REMARKS: 6341Handles opcode 0x8a 6342****************************************************************************/ 6343static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 6344{ 6345 int mod, rl, rh; 6346 u8 *destreg, *srcreg; 6347 uint srcoffset; 6348 u8 srcval; 6349 6350 START_OF_INSTR(); 6351 DECODE_PRINTF("MOV\t"); 6352 FETCH_DECODE_MODRM(mod, rh, rl); 6353 switch (mod) { 6354 case 0: 6355 destreg = DECODE_RM_BYTE_REGISTER(rh); 6356 DECODE_PRINTF(","); 6357 srcoffset = decode_rm00_address(rl); 6358 srcval = fetch_data_byte(srcoffset); 6359 DECODE_PRINTF("\n"); 6360 TRACE_AND_STEP(); 6361 *destreg = srcval; 6362 break; 6363 case 1: 6364 destreg = DECODE_RM_BYTE_REGISTER(rh); 6365 DECODE_PRINTF(","); 6366 srcoffset = decode_rm01_address(rl); 6367 srcval = fetch_data_byte(srcoffset); 6368 DECODE_PRINTF("\n"); 6369 TRACE_AND_STEP(); 6370 *destreg = srcval; 6371 break; 6372 case 2: 6373 destreg = DECODE_RM_BYTE_REGISTER(rh); 6374 DECODE_PRINTF(","); 6375 srcoffset = decode_rm10_address(rl); 6376 srcval = fetch_data_byte(srcoffset); 6377 DECODE_PRINTF("\n"); 6378 TRACE_AND_STEP(); 6379 *destreg = srcval; 6380 break; 6381 case 3: /* register to register */ 6382 destreg = DECODE_RM_BYTE_REGISTER(rh); 6383 DECODE_PRINTF(","); 6384 srcreg = DECODE_RM_BYTE_REGISTER(rl); 6385 DECODE_PRINTF("\n"); 6386 TRACE_AND_STEP(); 6387 *destreg = *srcreg; 6388 break; 6389 } 6390 DECODE_CLEAR_SEGOVR(); 6391 END_OF_INSTR(); 6392} 6393 6394/**************************************************************************** 6395REMARKS: 6396Handles opcode 0x8b 6397****************************************************************************/ 6398static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 6399{ 6400 int mod, rl, rh; 6401 uint srcoffset; 6402 6403 START_OF_INSTR(); 6404 DECODE_PRINTF("MOV\t"); 6405 FETCH_DECODE_MODRM(mod, rh, rl); 6406 switch (mod) { 6407 case 0: 6408 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6409 u32 *destreg; 6410 u32 srcval; 6411 6412 destreg = DECODE_RM_LONG_REGISTER(rh); 6413 DECODE_PRINTF(","); 6414 srcoffset = decode_rm00_address(rl); 6415 srcval = fetch_data_long(srcoffset); 6416 DECODE_PRINTF("\n"); 6417 TRACE_AND_STEP(); 6418 *destreg = srcval; 6419 } else { 6420 u16 *destreg; 6421 u16 srcval; 6422 6423 destreg = DECODE_RM_WORD_REGISTER(rh); 6424 DECODE_PRINTF(","); 6425 srcoffset = decode_rm00_address(rl); 6426 srcval = fetch_data_word(srcoffset); 6427 DECODE_PRINTF("\n"); 6428 TRACE_AND_STEP(); 6429 *destreg = srcval; 6430 } 6431 break; 6432 case 1: 6433 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6434 u32 *destreg; 6435 u32 srcval; 6436 6437 destreg = DECODE_RM_LONG_REGISTER(rh); 6438 DECODE_PRINTF(","); 6439 srcoffset = decode_rm01_address(rl); 6440 srcval = fetch_data_long(srcoffset); 6441 DECODE_PRINTF("\n"); 6442 TRACE_AND_STEP(); 6443 *destreg = srcval; 6444 } else { 6445 u16 *destreg; 6446 u16 srcval; 6447 6448 destreg = DECODE_RM_WORD_REGISTER(rh); 6449 DECODE_PRINTF(","); 6450 srcoffset = decode_rm01_address(rl); 6451 srcval = fetch_data_word(srcoffset); 6452 DECODE_PRINTF("\n"); 6453 TRACE_AND_STEP(); 6454 *destreg = srcval; 6455 } 6456 break; 6457 case 2: 6458 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6459 u32 *destreg; 6460 u32 srcval; 6461 6462 destreg = DECODE_RM_LONG_REGISTER(rh); 6463 DECODE_PRINTF(","); 6464 srcoffset = decode_rm10_address(rl); 6465 srcval = fetch_data_long(srcoffset); 6466 DECODE_PRINTF("\n"); 6467 TRACE_AND_STEP(); 6468 *destreg = srcval; 6469 } else { 6470 u16 *destreg; 6471 u16 srcval; 6472 6473 destreg = DECODE_RM_WORD_REGISTER(rh); 6474 DECODE_PRINTF(","); 6475 srcoffset = decode_rm10_address(rl); 6476 srcval = fetch_data_word(srcoffset); 6477 DECODE_PRINTF("\n"); 6478 TRACE_AND_STEP(); 6479 *destreg = srcval; 6480 } 6481 break; 6482 case 3: /* register to register */ 6483 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6484 u32 *destreg, *srcreg; 6485 6486 destreg = DECODE_RM_LONG_REGISTER(rh); 6487 DECODE_PRINTF(","); 6488 srcreg = DECODE_RM_LONG_REGISTER(rl); 6489 DECODE_PRINTF("\n"); 6490 TRACE_AND_STEP(); 6491 *destreg = *srcreg; 6492 } else { 6493 u16 *destreg, *srcreg; 6494 6495 destreg = DECODE_RM_WORD_REGISTER(rh); 6496 DECODE_PRINTF(","); 6497 srcreg = DECODE_RM_WORD_REGISTER(rl); 6498 DECODE_PRINTF("\n"); 6499 TRACE_AND_STEP(); 6500 *destreg = *srcreg; 6501 } 6502 break; 6503 } 6504 DECODE_CLEAR_SEGOVR(); 6505 END_OF_INSTR(); 6506} 6507 6508/**************************************************************************** 6509REMARKS: 6510Handles opcode 0x8c 6511****************************************************************************/ 6512static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 6513{ 6514 int mod, rl, rh; 6515 u16 *destreg, *srcreg; 6516 uint destoffset; 6517 u16 destval; 6518 6519 START_OF_INSTR(); 6520 DECODE_PRINTF("MOV\t"); 6521 FETCH_DECODE_MODRM(mod, rh, rl); 6522 switch (mod) { 6523 case 0: 6524 destoffset = decode_rm00_address(rl); 6525 DECODE_PRINTF(","); 6526 srcreg = decode_rm_seg_register(rh); 6527 DECODE_PRINTF("\n"); 6528 TRACE_AND_STEP(); 6529 destval = *srcreg; 6530 store_data_word(destoffset, destval); 6531 break; 6532 case 1: 6533 destoffset = decode_rm01_address(rl); 6534 DECODE_PRINTF(","); 6535 srcreg = decode_rm_seg_register(rh); 6536 DECODE_PRINTF("\n"); 6537 TRACE_AND_STEP(); 6538 destval = *srcreg; 6539 store_data_word(destoffset, destval); 6540 break; 6541 case 2: 6542 destoffset = decode_rm10_address(rl); 6543 DECODE_PRINTF(","); 6544 srcreg = decode_rm_seg_register(rh); 6545 DECODE_PRINTF("\n"); 6546 TRACE_AND_STEP(); 6547 destval = *srcreg; 6548 store_data_word(destoffset, destval); 6549 break; 6550 case 3: /* register to register */ 6551 destreg = DECODE_RM_WORD_REGISTER(rl); 6552 DECODE_PRINTF(","); 6553 srcreg = decode_rm_seg_register(rh); 6554 DECODE_PRINTF("\n"); 6555 TRACE_AND_STEP(); 6556 *destreg = *srcreg; 6557 break; 6558 } 6559 DECODE_CLEAR_SEGOVR(); 6560 END_OF_INSTR(); 6561} 6562 6563/**************************************************************************** 6564REMARKS: 6565Handles opcode 0x8d 6566****************************************************************************/ 6567static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 6568{ 6569 int mod, rl, rh; 6570 uint destoffset; 6571 6572 START_OF_INSTR(); 6573 DECODE_PRINTF("LEA\t"); 6574 FETCH_DECODE_MODRM(mod, rh, rl); 6575 switch (mod) { 6576 case 0: 6577 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6578 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6579 DECODE_PRINTF(","); 6580 destoffset = decode_rm00_address(rl); 6581 DECODE_PRINTF("\n"); 6582 TRACE_AND_STEP(); 6583 *srcreg = (u32)destoffset; 6584 } else { 6585 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6586 DECODE_PRINTF(","); 6587 destoffset = decode_rm00_address(rl); 6588 DECODE_PRINTF("\n"); 6589 TRACE_AND_STEP(); 6590 *srcreg = (u16)destoffset; 6591 } 6592 break; 6593 case 1: 6594 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6595 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6596 DECODE_PRINTF(","); 6597 destoffset = decode_rm01_address(rl); 6598 DECODE_PRINTF("\n"); 6599 TRACE_AND_STEP(); 6600 *srcreg = (u32)destoffset; 6601 } else { 6602 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6603 DECODE_PRINTF(","); 6604 destoffset = decode_rm01_address(rl); 6605 DECODE_PRINTF("\n"); 6606 TRACE_AND_STEP(); 6607 *srcreg = (u16)destoffset; 6608 } 6609 break; 6610 case 2: 6611 if (M.x86.mode & SYSMODE_PREFIX_ADDR) { 6612 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); 6613 DECODE_PRINTF(","); 6614 destoffset = decode_rm10_address(rl); 6615 DECODE_PRINTF("\n"); 6616 TRACE_AND_STEP(); 6617 *srcreg = (u32)destoffset; 6618 } else { 6619 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); 6620 DECODE_PRINTF(","); 6621 destoffset = decode_rm10_address(rl); 6622 DECODE_PRINTF("\n"); 6623 TRACE_AND_STEP(); 6624 *srcreg = (u16)destoffset; 6625 } 6626 break; 6627 case 3: /* register to register */ 6628 /* undefined. Do nothing. */ 6629 break; 6630 } 6631 DECODE_CLEAR_SEGOVR(); 6632 END_OF_INSTR(); 6633} 6634 6635/**************************************************************************** 6636REMARKS: 6637Handles opcode 0x8e 6638****************************************************************************/ 6639static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 6640{ 6641 int mod, rl, rh; 6642 u16 *destreg, *srcreg; 6643 uint srcoffset; 6644 u16 srcval; 6645 6646 START_OF_INSTR(); 6647 DECODE_PRINTF("MOV\t"); 6648 FETCH_DECODE_MODRM(mod, rh, rl); 6649 switch (mod) { 6650 case 0: 6651 destreg = decode_rm_seg_register(rh); 6652 DECODE_PRINTF(","); 6653 srcoffset = decode_rm00_address(rl); 6654 srcval = fetch_data_word(srcoffset); 6655 DECODE_PRINTF("\n"); 6656 TRACE_AND_STEP(); 6657 *destreg = srcval; 6658 break; 6659 case 1: 6660 destreg = decode_rm_seg_register(rh); 6661 DECODE_PRINTF(","); 6662 srcoffset = decode_rm01_address(rl); 6663 srcval = fetch_data_word(srcoffset); 6664 DECODE_PRINTF("\n"); 6665 TRACE_AND_STEP(); 6666 *destreg = srcval; 6667 break; 6668 case 2: 6669 destreg = decode_rm_seg_register(rh); 6670 DECODE_PRINTF(","); 6671 srcoffset = decode_rm10_address(rl); 6672 srcval = fetch_data_word(srcoffset); 6673 DECODE_PRINTF("\n"); 6674 TRACE_AND_STEP(); 6675 *destreg = srcval; 6676 break; 6677 case 3: /* register to register */ 6678 destreg = decode_rm_seg_register(rh); 6679 DECODE_PRINTF(","); 6680 srcreg = DECODE_RM_WORD_REGISTER(rl); 6681 DECODE_PRINTF("\n"); 6682 TRACE_AND_STEP(); 6683 *destreg = *srcreg; 6684 break; 6685 } 6686 /* 6687 * Clean up, and reset all the R_xSP pointers to the correct 6688 * locations. This is about 3x too much overhead (doing all the 6689 * segreg ptrs when only one is needed, but this instruction 6690 * *cannot* be that common, and this isn't too much work anyway. 6691 */ 6692 DECODE_CLEAR_SEGOVR(); 6693 END_OF_INSTR(); 6694} 6695 6696/**************************************************************************** 6697REMARKS: 6698Handles opcode 0x8f 6699****************************************************************************/ 6700static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 6701{ 6702 int mod, rl, rh; 6703 uint destoffset; 6704 6705 START_OF_INSTR(); 6706 DECODE_PRINTF("POP\t"); 6707 FETCH_DECODE_MODRM(mod, rh, rl); 6708 if (rh != 0) { 6709 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 6710 HALT_SYS(); 6711 } 6712 switch (mod) { 6713 case 0: 6714 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6715 u32 destval; 6716 6717 destoffset = decode_rm00_address(rl); 6718 DECODE_PRINTF("\n"); 6719 TRACE_AND_STEP(); 6720 destval = pop_long(); 6721 store_data_long(destoffset, destval); 6722 } else { 6723 u16 destval; 6724 6725 destoffset = decode_rm00_address(rl); 6726 DECODE_PRINTF("\n"); 6727 TRACE_AND_STEP(); 6728 destval = pop_word(); 6729 store_data_word(destoffset, destval); 6730 } 6731 break; 6732 case 1: 6733 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6734 u32 destval; 6735 6736 destoffset = decode_rm01_address(rl); 6737 DECODE_PRINTF("\n"); 6738 TRACE_AND_STEP(); 6739 destval = pop_long(); 6740 store_data_long(destoffset, destval); 6741 } else { 6742 u16 destval; 6743 6744 destoffset = decode_rm01_address(rl); 6745 DECODE_PRINTF("\n"); 6746 TRACE_AND_STEP(); 6747 destval = pop_word(); 6748 store_data_word(destoffset, destval); 6749 } 6750 break; 6751 case 2: 6752 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6753 u32 destval; 6754 6755 destoffset = decode_rm10_address(rl); 6756 DECODE_PRINTF("\n"); 6757 TRACE_AND_STEP(); 6758 destval = pop_long(); 6759 store_data_long(destoffset, destval); 6760 } else { 6761 u16 destval; 6762 6763 destoffset = decode_rm10_address(rl); 6764 DECODE_PRINTF("\n"); 6765 TRACE_AND_STEP(); 6766 destval = pop_word(); 6767 store_data_word(destoffset, destval); 6768 } 6769 break; 6770 case 3: /* register to register */ 6771 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6772 u32 *destreg; 6773 6774 destreg = DECODE_RM_LONG_REGISTER(rl); 6775 DECODE_PRINTF("\n"); 6776 TRACE_AND_STEP(); 6777 *destreg = pop_long(); 6778 } else { 6779 u16 *destreg; 6780 6781 destreg = DECODE_RM_WORD_REGISTER(rl); 6782 DECODE_PRINTF("\n"); 6783 TRACE_AND_STEP(); 6784 *destreg = pop_word(); 6785 } 6786 break; 6787 } 6788 DECODE_CLEAR_SEGOVR(); 6789 END_OF_INSTR(); 6790} 6791 6792/**************************************************************************** 6793REMARKS: 6794Handles opcode 0x90 6795****************************************************************************/ 6796static void x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 6797{ 6798 START_OF_INSTR(); 6799 DECODE_PRINTF("NOP\n"); 6800 TRACE_AND_STEP(); 6801 DECODE_CLEAR_SEGOVR(); 6802 END_OF_INSTR(); 6803} 6804 6805/**************************************************************************** 6806REMARKS: 6807Handles opcode 0x91 6808****************************************************************************/ 6809static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1)) 6810{ 6811 u32 tmp; 6812 6813 START_OF_INSTR(); 6814 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6815 DECODE_PRINTF("XCHG\tEAX,ECX\n"); 6816 } else { 6817 DECODE_PRINTF("XCHG\tAX,CX\n"); 6818 } 6819 TRACE_AND_STEP(); 6820 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6821 tmp = M.x86.R_EAX; 6822 M.x86.R_EAX = M.x86.R_ECX; 6823 M.x86.R_ECX = tmp; 6824 } else { 6825 tmp = M.x86.R_AX; 6826 M.x86.R_AX = M.x86.R_CX; 6827 M.x86.R_CX = (u16)tmp; 6828 } 6829 DECODE_CLEAR_SEGOVR(); 6830 END_OF_INSTR(); 6831} 6832 6833/**************************************************************************** 6834REMARKS: 6835Handles opcode 0x92 6836****************************************************************************/ 6837static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1)) 6838{ 6839 u32 tmp; 6840 6841 START_OF_INSTR(); 6842 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6843 DECODE_PRINTF("XCHG\tEAX,EDX\n"); 6844 } else { 6845 DECODE_PRINTF("XCHG\tAX,DX\n"); 6846 } 6847 TRACE_AND_STEP(); 6848 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6849 tmp = M.x86.R_EAX; 6850 M.x86.R_EAX = M.x86.R_EDX; 6851 M.x86.R_EDX = tmp; 6852 } else { 6853 tmp = M.x86.R_AX; 6854 M.x86.R_AX = M.x86.R_DX; 6855 M.x86.R_DX = (u16)tmp; 6856 } 6857 DECODE_CLEAR_SEGOVR(); 6858 END_OF_INSTR(); 6859} 6860 6861/**************************************************************************** 6862REMARKS: 6863Handles opcode 0x93 6864****************************************************************************/ 6865static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1)) 6866{ 6867 u32 tmp; 6868 6869 START_OF_INSTR(); 6870 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6871 DECODE_PRINTF("XCHG\tEAX,EBX\n"); 6872 } else { 6873 DECODE_PRINTF("XCHG\tAX,BX\n"); 6874 } 6875 TRACE_AND_STEP(); 6876 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6877 tmp = M.x86.R_EAX; 6878 M.x86.R_EAX = M.x86.R_EBX; 6879 M.x86.R_EBX = tmp; 6880 } else { 6881 tmp = M.x86.R_AX; 6882 M.x86.R_AX = M.x86.R_BX; 6883 M.x86.R_BX = (u16)tmp; 6884 } 6885 DECODE_CLEAR_SEGOVR(); 6886 END_OF_INSTR(); 6887} 6888 6889/**************************************************************************** 6890REMARKS: 6891Handles opcode 0x94 6892****************************************************************************/ 6893static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1)) 6894{ 6895 u32 tmp; 6896 6897 START_OF_INSTR(); 6898 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6899 DECODE_PRINTF("XCHG\tEAX,ESP\n"); 6900 } else { 6901 DECODE_PRINTF("XCHG\tAX,SP\n"); 6902 } 6903 TRACE_AND_STEP(); 6904 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6905 tmp = M.x86.R_EAX; 6906 M.x86.R_EAX = M.x86.R_ESP; 6907 M.x86.R_ESP = tmp; 6908 } else { 6909 tmp = M.x86.R_AX; 6910 M.x86.R_AX = M.x86.R_SP; 6911 M.x86.R_SP = (u16)tmp; 6912 } 6913 DECODE_CLEAR_SEGOVR(); 6914 END_OF_INSTR(); 6915} 6916 6917/**************************************************************************** 6918REMARKS: 6919Handles opcode 0x95 6920****************************************************************************/ 6921static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1)) 6922{ 6923 u32 tmp; 6924 6925 START_OF_INSTR(); 6926 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6927 DECODE_PRINTF("XCHG\tEAX,EBP\n"); 6928 } else { 6929 DECODE_PRINTF("XCHG\tAX,BP\n"); 6930 } 6931 TRACE_AND_STEP(); 6932 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6933 tmp = M.x86.R_EAX; 6934 M.x86.R_EAX = M.x86.R_EBP; 6935 M.x86.R_EBP = tmp; 6936 } else { 6937 tmp = M.x86.R_AX; 6938 M.x86.R_AX = M.x86.R_BP; 6939 M.x86.R_BP = (u16)tmp; 6940 } 6941 DECODE_CLEAR_SEGOVR(); 6942 END_OF_INSTR(); 6943} 6944 6945/**************************************************************************** 6946REMARKS: 6947Handles opcode 0x96 6948****************************************************************************/ 6949static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1)) 6950{ 6951 u32 tmp; 6952 6953 START_OF_INSTR(); 6954 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6955 DECODE_PRINTF("XCHG\tEAX,ESI\n"); 6956 } else { 6957 DECODE_PRINTF("XCHG\tAX,SI\n"); 6958 } 6959 TRACE_AND_STEP(); 6960 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6961 tmp = M.x86.R_EAX; 6962 M.x86.R_EAX = M.x86.R_ESI; 6963 M.x86.R_ESI = tmp; 6964 } else { 6965 tmp = M.x86.R_AX; 6966 M.x86.R_AX = M.x86.R_SI; 6967 M.x86.R_SI = (u16)tmp; 6968 } 6969 DECODE_CLEAR_SEGOVR(); 6970 END_OF_INSTR(); 6971} 6972 6973/**************************************************************************** 6974REMARKS: 6975Handles opcode 0x97 6976****************************************************************************/ 6977static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1)) 6978{ 6979 u32 tmp; 6980 6981 START_OF_INSTR(); 6982 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6983 DECODE_PRINTF("XCHG\tEAX,EDI\n"); 6984 } else { 6985 DECODE_PRINTF("XCHG\tAX,DI\n"); 6986 } 6987 TRACE_AND_STEP(); 6988 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6989 tmp = M.x86.R_EAX; 6990 M.x86.R_EAX = M.x86.R_EDI; 6991 M.x86.R_EDI = tmp; 6992 } else { 6993 tmp = M.x86.R_AX; 6994 M.x86.R_AX = M.x86.R_DI; 6995 M.x86.R_DI = (u16)tmp; 6996 } 6997 DECODE_CLEAR_SEGOVR(); 6998 END_OF_INSTR(); 6999} 7000 7001/**************************************************************************** 7002REMARKS: 7003Handles opcode 0x98 7004****************************************************************************/ 7005static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 7006{ 7007 START_OF_INSTR(); 7008 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7009 DECODE_PRINTF("CWDE\n"); 7010 } else { 7011 DECODE_PRINTF("CBW\n"); 7012 } 7013 TRACE_AND_STEP(); 7014 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7015 if (M.x86.R_AX & 0x8000) { 7016 M.x86.R_EAX |= 0xffff0000; 7017 } else { 7018 M.x86.R_EAX &= 0x0000ffff; 7019 } 7020 } else { 7021 if (M.x86.R_AL & 0x80) { 7022 M.x86.R_AH = 0xff; 7023 } else { 7024 M.x86.R_AH = 0x0; 7025 } 7026 } 7027 DECODE_CLEAR_SEGOVR(); 7028 END_OF_INSTR(); 7029} 7030 7031/**************************************************************************** 7032REMARKS: 7033Handles opcode 0x99 7034****************************************************************************/ 7035static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 7036{ 7037 START_OF_INSTR(); 7038 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7039 DECODE_PRINTF("CDQ\n"); 7040 } else { 7041 DECODE_PRINTF("CWD\n"); 7042 } 7043 DECODE_PRINTF("CWD\n"); 7044 TRACE_AND_STEP(); 7045 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7046 if (M.x86.R_EAX & 0x80000000) { 7047 M.x86.R_EDX = 0xffffffff; 7048 } else { 7049 M.x86.R_EDX = 0x0; 7050 } 7051 } else { 7052 if (M.x86.R_AX & 0x8000) { 7053 M.x86.R_DX = 0xffff; 7054 } else { 7055 M.x86.R_DX = 0x0; 7056 } 7057 } 7058 DECODE_CLEAR_SEGOVR(); 7059 END_OF_INSTR(); 7060} 7061 7062/**************************************************************************** 7063REMARKS: 7064Handles opcode 0x9a 7065****************************************************************************/ 7066static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 7067{ 7068 u32 farseg, faroff; 7069 7070 START_OF_INSTR(); 7071 DECODE_PRINTF("CALL\t"); 7072 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7073 faroff = fetch_long_imm(); 7074 farseg = fetch_word_imm(); 7075 } else { 7076 faroff = fetch_word_imm(); 7077 farseg = fetch_word_imm(); 7078 } 7079 DECODE_PRINTF2("%04x:", farseg); 7080 DECODE_PRINTF2("%04x\n", faroff); 7081 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 7082 7083 /* XXX 7084 * 7085 * Hooked interrupt vectors calling into our "BIOS" will cause 7086 * problems unless all intersegment stuff is checked for BIOS 7087 * access. Check needed here. For moment, let it alone. 7088 */ 7089 TRACE_AND_STEP(); 7090 push_word(M.x86.R_CS); 7091 M.x86.R_CS = farseg; 7092 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7093 push_long(M.x86.R_EIP); 7094 } else { 7095 push_word(M.x86.R_IP); 7096 } 7097 M.x86.R_EIP = faroff & 0xffff; 7098 DECODE_CLEAR_SEGOVR(); 7099 END_OF_INSTR(); 7100} 7101 7102/**************************************************************************** 7103REMARKS: 7104Handles opcode 0x9b 7105****************************************************************************/ 7106static void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 7107{ 7108 START_OF_INSTR(); 7109 DECODE_PRINTF("WAIT"); 7110 TRACE_AND_STEP(); 7111 /* NADA. */ 7112 DECODE_CLEAR_SEGOVR(); 7113 END_OF_INSTR(); 7114} 7115 7116/**************************************************************************** 7117REMARKS: 7118Handles opcode 0x9c 7119****************************************************************************/ 7120static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 7121{ 7122 u32 flags; 7123 7124 START_OF_INSTR(); 7125 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7126 DECODE_PRINTF("PUSHFD\n"); 7127 } else { 7128 DECODE_PRINTF("PUSHF\n"); 7129 } 7130 TRACE_AND_STEP(); 7131 7132 /* clear out *all* bits not representing flags, and turn on real bits */ 7133 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 7134 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7135 push_long(flags); 7136 } else { 7137 push_word((u16)flags); 7138 } 7139 DECODE_CLEAR_SEGOVR(); 7140 END_OF_INSTR(); 7141} 7142 7143/**************************************************************************** 7144REMARKS: 7145Handles opcode 0x9d 7146****************************************************************************/ 7147static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 7148{ 7149 START_OF_INSTR(); 7150 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7151 DECODE_PRINTF("POPFD\n"); 7152 } else { 7153 DECODE_PRINTF("POPF\n"); 7154 } 7155 TRACE_AND_STEP(); 7156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7157 M.x86.R_EFLG = pop_long(); 7158 } else { 7159 M.x86.R_FLG = pop_word(); 7160 } 7161 DECODE_CLEAR_SEGOVR(); 7162 END_OF_INSTR(); 7163} 7164 7165/**************************************************************************** 7166REMARKS: 7167Handles opcode 0x9e 7168****************************************************************************/ 7169static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 7170{ 7171 START_OF_INSTR(); 7172 DECODE_PRINTF("SAHF\n"); 7173 TRACE_AND_STEP(); 7174 /* clear the lower bits of the flag register */ 7175 M.x86.R_FLG &= 0xffffff00; 7176 /* or in the AH register into the flags register */ 7177 M.x86.R_FLG |= M.x86.R_AH; 7178 DECODE_CLEAR_SEGOVR(); 7179 END_OF_INSTR(); 7180} 7181 7182/**************************************************************************** 7183REMARKS: 7184Handles opcode 0x9f 7185****************************************************************************/ 7186static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 7187{ 7188 START_OF_INSTR(); 7189 DECODE_PRINTF("LAHF\n"); 7190 TRACE_AND_STEP(); 7191 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 7192 /*undocumented TC++ behavior??? Nope. It's documented, but 7193 you have too look real hard to notice it. */ 7194 M.x86.R_AH |= 0x2; 7195 DECODE_CLEAR_SEGOVR(); 7196 END_OF_INSTR(); 7197} 7198 7199/**************************************************************************** 7200REMARKS: 7201Handles opcode 0xa0 7202****************************************************************************/ 7203static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 7204{ 7205 u16 offset; 7206 7207 START_OF_INSTR(); 7208 DECODE_PRINTF("MOV\tAL,"); 7209 offset = fetch_word_imm(); 7210 DECODE_PRINTF2("[%04x]\n", offset); 7211 TRACE_AND_STEP(); 7212 M.x86.R_AL = fetch_data_byte(offset); 7213 DECODE_CLEAR_SEGOVR(); 7214 END_OF_INSTR(); 7215} 7216 7217/**************************************************************************** 7218REMARKS: 7219Handles opcode 0xa1 7220****************************************************************************/ 7221static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 7222{ 7223 u16 offset; 7224 7225 START_OF_INSTR(); 7226 offset = fetch_word_imm(); 7227 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7228 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 7229 } else { 7230 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 7231 } 7232 TRACE_AND_STEP(); 7233 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7234 M.x86.R_EAX = fetch_data_long(offset); 7235 } else { 7236 M.x86.R_AX = fetch_data_word(offset); 7237 } 7238 DECODE_CLEAR_SEGOVR(); 7239 END_OF_INSTR(); 7240} 7241 7242/**************************************************************************** 7243REMARKS: 7244Handles opcode 0xa2 7245****************************************************************************/ 7246static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 7247{ 7248 u16 offset; 7249 7250 START_OF_INSTR(); 7251 DECODE_PRINTF("MOV\t"); 7252 offset = fetch_word_imm(); 7253 DECODE_PRINTF2("[%04x],AL\n", offset); 7254 TRACE_AND_STEP(); 7255 store_data_byte(offset, M.x86.R_AL); 7256 DECODE_CLEAR_SEGOVR(); 7257 END_OF_INSTR(); 7258} 7259 7260/**************************************************************************** 7261REMARKS: 7262Handles opcode 0xa3 7263****************************************************************************/ 7264static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 7265{ 7266 u16 offset; 7267 7268 START_OF_INSTR(); 7269 offset = fetch_word_imm(); 7270 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7271 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 7272 } else { 7273 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 7274 } 7275 TRACE_AND_STEP(); 7276 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7277 store_data_long(offset, M.x86.R_EAX); 7278 } else { 7279 store_data_word(offset, M.x86.R_AX); 7280 } 7281 DECODE_CLEAR_SEGOVR(); 7282 END_OF_INSTR(); 7283} 7284 7285/**************************************************************************** 7286REMARKS: 7287Handles opcode 0xa4 7288****************************************************************************/ 7289static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 7290{ 7291 u8 val; 7292 u32 count; 7293 int inc; 7294 7295 START_OF_INSTR(); 7296 DECODE_PRINTF("MOVS\tBYTE\n"); 7297 if (ACCESS_FLAG(F_DF)) /* down */ 7298 inc = -1; 7299 else 7300 inc = 1; 7301 TRACE_AND_STEP(); 7302 count = 1; 7303 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7304 /* dont care whether REPE or REPNE */ 7305 /* move them until CX is ZERO. */ 7306 count = M.x86.R_CX; 7307 M.x86.R_CX = 0; 7308 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7309 } 7310 while (count--) { 7311 val = fetch_data_byte(M.x86.R_SI); 7312 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 7313 M.x86.R_SI += inc; 7314 M.x86.R_DI += inc; 7315 } 7316 DECODE_CLEAR_SEGOVR(); 7317 END_OF_INSTR(); 7318} 7319 7320/**************************************************************************** 7321REMARKS: 7322Handles opcode 0xa5 7323****************************************************************************/ 7324static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 7325{ 7326 u32 val; 7327 int inc; 7328 u32 count; 7329 7330 START_OF_INSTR(); 7331 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7332 DECODE_PRINTF("MOVS\tDWORD\n"); 7333 if (ACCESS_FLAG(F_DF)) /* down */ 7334 inc = -4; 7335 else 7336 inc = 4; 7337 } else { 7338 DECODE_PRINTF("MOVS\tWORD\n"); 7339 if (ACCESS_FLAG(F_DF)) /* down */ 7340 inc = -2; 7341 else 7342 inc = 2; 7343 } 7344 TRACE_AND_STEP(); 7345 count = 1; 7346 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7347 /* dont care whether REPE or REPNE */ 7348 /* move them until CX is ZERO. */ 7349 count = M.x86.R_CX; 7350 M.x86.R_CX = 0; 7351 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7352 } 7353 while (count--) { 7354 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7355 val = fetch_data_long(M.x86.R_SI); 7356 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 7357 } else { 7358 val = fetch_data_word(M.x86.R_SI); 7359 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 7360 } 7361 M.x86.R_SI += inc; 7362 M.x86.R_DI += inc; 7363 } 7364 DECODE_CLEAR_SEGOVR(); 7365 END_OF_INSTR(); 7366} 7367 7368/**************************************************************************** 7369REMARKS: 7370Handles opcode 0xa6 7371****************************************************************************/ 7372static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 7373{ 7374 s8 val1, val2; 7375 int inc; 7376 7377 START_OF_INSTR(); 7378 DECODE_PRINTF("CMPS\tBYTE\n"); 7379 TRACE_AND_STEP(); 7380 if (ACCESS_FLAG(F_DF)) /* down */ 7381 inc = -1; 7382 else 7383 inc = 1; 7384 7385 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7386 /* REPE */ 7387 /* move them until CX is ZERO. */ 7388 while (M.x86.R_CX != 0) { 7389 val1 = fetch_data_byte(M.x86.R_SI); 7390 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7391 cmp_byte(val1, val2); 7392 M.x86.R_CX -= 1; 7393 M.x86.R_SI += inc; 7394 M.x86.R_DI += inc; 7395 if (ACCESS_FLAG(F_ZF) == 0) 7396 break; 7397 } 7398 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7399 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7400 /* REPNE */ 7401 /* move them until CX is ZERO. */ 7402 while (M.x86.R_CX != 0) { 7403 val1 = fetch_data_byte(M.x86.R_SI); 7404 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7405 cmp_byte(val1, val2); 7406 M.x86.R_CX -= 1; 7407 M.x86.R_SI += inc; 7408 M.x86.R_DI += inc; 7409 if (ACCESS_FLAG(F_ZF)) 7410 break; /* zero flag set means equal */ 7411 } 7412 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7413 } else { 7414 val1 = fetch_data_byte(M.x86.R_SI); 7415 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7416 cmp_byte(val1, val2); 7417 M.x86.R_SI += inc; 7418 M.x86.R_DI += inc; 7419 } 7420 DECODE_CLEAR_SEGOVR(); 7421 END_OF_INSTR(); 7422} 7423 7424/**************************************************************************** 7425REMARKS: 7426Handles opcode 0xa7 7427****************************************************************************/ 7428static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 7429{ 7430 u32 val1,val2; 7431 int inc; 7432 7433 START_OF_INSTR(); 7434 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7435 DECODE_PRINTF("CMPS\tDWORD\n"); 7436 if (ACCESS_FLAG(F_DF)) /* down */ 7437 inc = -4; 7438 else 7439 inc = 4; 7440 } else { 7441 DECODE_PRINTF("CMPS\tWORD\n"); 7442 if (ACCESS_FLAG(F_DF)) /* down */ 7443 inc = -2; 7444 else 7445 inc = 2; 7446 } 7447 TRACE_AND_STEP(); 7448 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7449 /* REPE */ 7450 /* move them until CX is ZERO. */ 7451 while (M.x86.R_CX != 0) { 7452 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7453 val1 = fetch_data_long(M.x86.R_SI); 7454 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7455 cmp_long(val1, val2); 7456 } else { 7457 val1 = fetch_data_word(M.x86.R_SI); 7458 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7459 cmp_word((u16)val1, (u16)val2); 7460 } 7461 M.x86.R_CX -= 1; 7462 M.x86.R_SI += inc; 7463 M.x86.R_DI += inc; 7464 if (ACCESS_FLAG(F_ZF) == 0) 7465 break; 7466 } 7467 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7468 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7469 /* REPNE */ 7470 /* move them until CX is ZERO. */ 7471 while (M.x86.R_CX != 0) { 7472 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7473 val1 = fetch_data_long(M.x86.R_SI); 7474 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7475 cmp_long(val1, val2); 7476 } else { 7477 val1 = fetch_data_word(M.x86.R_SI); 7478 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7479 cmp_word((u16)val1, (u16)val2); 7480 } 7481 M.x86.R_CX -= 1; 7482 M.x86.R_SI += inc; 7483 M.x86.R_DI += inc; 7484 if (ACCESS_FLAG(F_ZF)) 7485 break; /* zero flag set means equal */ 7486 } 7487 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7488 } else { 7489 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7490 val1 = fetch_data_long(M.x86.R_SI); 7491 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7492 cmp_long(val1, val2); 7493 } else { 7494 val1 = fetch_data_word(M.x86.R_SI); 7495 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7496 cmp_word((u16)val1, (u16)val2); 7497 } 7498 M.x86.R_SI += inc; 7499 M.x86.R_DI += inc; 7500 } 7501 DECODE_CLEAR_SEGOVR(); 7502 END_OF_INSTR(); 7503} 7504 7505/**************************************************************************** 7506REMARKS: 7507Handles opcode 0xa8 7508****************************************************************************/ 7509static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 7510{ 7511 int imm; 7512 7513 START_OF_INSTR(); 7514 DECODE_PRINTF("TEST\tAL,"); 7515 imm = fetch_byte_imm(); 7516 DECODE_PRINTF2("%04x\n", imm); 7517 TRACE_AND_STEP(); 7518 test_byte(M.x86.R_AL, (u8)imm); 7519 DECODE_CLEAR_SEGOVR(); 7520 END_OF_INSTR(); 7521} 7522 7523/**************************************************************************** 7524REMARKS: 7525Handles opcode 0xa9 7526****************************************************************************/ 7527static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 7528{ 7529 u32 srcval; 7530 7531 START_OF_INSTR(); 7532 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7533 DECODE_PRINTF("TEST\tEAX,"); 7534 srcval = fetch_long_imm(); 7535 } else { 7536 DECODE_PRINTF("TEST\tAX,"); 7537 srcval = fetch_word_imm(); 7538 } 7539 DECODE_PRINTF2("%x\n", srcval); 7540 TRACE_AND_STEP(); 7541 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7542 test_long(M.x86.R_EAX, srcval); 7543 } else { 7544 test_word(M.x86.R_AX, (u16)srcval); 7545 } 7546 DECODE_CLEAR_SEGOVR(); 7547 END_OF_INSTR(); 7548} 7549 7550/**************************************************************************** 7551REMARKS: 7552Handles opcode 0xaa 7553****************************************************************************/ 7554static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 7555{ 7556 int inc; 7557 7558 START_OF_INSTR(); 7559 DECODE_PRINTF("STOS\tBYTE\n"); 7560 if (ACCESS_FLAG(F_DF)) /* down */ 7561 inc = -1; 7562 else 7563 inc = 1; 7564 TRACE_AND_STEP(); 7565 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7566 /* dont care whether REPE or REPNE */ 7567 /* move them until CX is ZERO. */ 7568 while (M.x86.R_CX != 0) { 7569 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7570 M.x86.R_CX -= 1; 7571 M.x86.R_DI += inc; 7572 } 7573 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7574 } else { 7575 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7576 M.x86.R_DI += inc; 7577 } 7578 DECODE_CLEAR_SEGOVR(); 7579 END_OF_INSTR(); 7580} 7581 7582/**************************************************************************** 7583REMARKS: 7584Handles opcode 0xab 7585****************************************************************************/ 7586static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 7587{ 7588 int inc; 7589 u32 count; 7590 7591 START_OF_INSTR(); 7592 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7593 DECODE_PRINTF("STOS\tDWORD\n"); 7594 if (ACCESS_FLAG(F_DF)) /* down */ 7595 inc = -4; 7596 else 7597 inc = 4; 7598 } else { 7599 DECODE_PRINTF("STOS\tWORD\n"); 7600 if (ACCESS_FLAG(F_DF)) /* down */ 7601 inc = -2; 7602 else 7603 inc = 2; 7604 } 7605 TRACE_AND_STEP(); 7606 count = 1; 7607 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7608 /* dont care whether REPE or REPNE */ 7609 /* move them until CX is ZERO. */ 7610 count = M.x86.R_CX; 7611 M.x86.R_CX = 0; 7612 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7613 } 7614 while (count--) { 7615 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7616 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 7617 } else { 7618 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 7619 } 7620 M.x86.R_DI += inc; 7621 } 7622 DECODE_CLEAR_SEGOVR(); 7623 END_OF_INSTR(); 7624} 7625 7626/**************************************************************************** 7627REMARKS: 7628Handles opcode 0xac 7629****************************************************************************/ 7630static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 7631{ 7632 int inc; 7633 7634 START_OF_INSTR(); 7635 DECODE_PRINTF("LODS\tBYTE\n"); 7636 TRACE_AND_STEP(); 7637 if (ACCESS_FLAG(F_DF)) /* down */ 7638 inc = -1; 7639 else 7640 inc = 1; 7641 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7642 /* dont care whether REPE or REPNE */ 7643 /* move them until CX is ZERO. */ 7644 while (M.x86.R_CX != 0) { 7645 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7646 M.x86.R_CX -= 1; 7647 M.x86.R_SI += inc; 7648 } 7649 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7650 } else { 7651 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7652 M.x86.R_SI += inc; 7653 } 7654 DECODE_CLEAR_SEGOVR(); 7655 END_OF_INSTR(); 7656} 7657 7658/**************************************************************************** 7659REMARKS: 7660Handles opcode 0xad 7661****************************************************************************/ 7662static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 7663{ 7664 int inc; 7665 u32 count; 7666 7667 START_OF_INSTR(); 7668 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7669 DECODE_PRINTF("LODS\tDWORD\n"); 7670 if (ACCESS_FLAG(F_DF)) /* down */ 7671 inc = -4; 7672 else 7673 inc = 4; 7674 } else { 7675 DECODE_PRINTF("LODS\tWORD\n"); 7676 if (ACCESS_FLAG(F_DF)) /* down */ 7677 inc = -2; 7678 else 7679 inc = 2; 7680 } 7681 TRACE_AND_STEP(); 7682 count = 1; 7683 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7684 /* dont care whether REPE or REPNE */ 7685 /* move them until CX is ZERO. */ 7686 count = M.x86.R_CX; 7687 M.x86.R_CX = 0; 7688 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7689 } 7690 while (count--) { 7691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7692 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 7693 } else { 7694 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 7695 } 7696 M.x86.R_SI += inc; 7697 } 7698 DECODE_CLEAR_SEGOVR(); 7699 END_OF_INSTR(); 7700} 7701 7702/**************************************************************************** 7703REMARKS: 7704Handles opcode 0xae 7705****************************************************************************/ 7706static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 7707{ 7708 s8 val2; 7709 int inc; 7710 7711 START_OF_INSTR(); 7712 DECODE_PRINTF("SCAS\tBYTE\n"); 7713 TRACE_AND_STEP(); 7714 if (ACCESS_FLAG(F_DF)) /* down */ 7715 inc = -1; 7716 else 7717 inc = 1; 7718 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7719 /* REPE */ 7720 /* move them until CX is ZERO. */ 7721 while (M.x86.R_CX != 0) { 7722 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7723 cmp_byte(M.x86.R_AL, val2); 7724 M.x86.R_CX -= 1; 7725 M.x86.R_DI += inc; 7726 if (ACCESS_FLAG(F_ZF) == 0) 7727 break; 7728 } 7729 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7730 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7731 /* REPNE */ 7732 /* move them until CX is ZERO. */ 7733 while (M.x86.R_CX != 0) { 7734 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7735 cmp_byte(M.x86.R_AL, val2); 7736 M.x86.R_CX -= 1; 7737 M.x86.R_DI += inc; 7738 if (ACCESS_FLAG(F_ZF)) 7739 break; /* zero flag set means equal */ 7740 } 7741 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7742 } else { 7743 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7744 cmp_byte(M.x86.R_AL, val2); 7745 M.x86.R_DI += inc; 7746 } 7747 DECODE_CLEAR_SEGOVR(); 7748 END_OF_INSTR(); 7749} 7750 7751/**************************************************************************** 7752REMARKS: 7753Handles opcode 0xaf 7754****************************************************************************/ 7755static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 7756{ 7757 int inc; 7758 u32 val; 7759 7760 START_OF_INSTR(); 7761 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7762 DECODE_PRINTF("SCAS\tDWORD\n"); 7763 if (ACCESS_FLAG(F_DF)) /* down */ 7764 inc = -4; 7765 else 7766 inc = 4; 7767 } else { 7768 DECODE_PRINTF("SCAS\tWORD\n"); 7769 if (ACCESS_FLAG(F_DF)) /* down */ 7770 inc = -2; 7771 else 7772 inc = 2; 7773 } 7774 TRACE_AND_STEP(); 7775 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7776 /* REPE */ 7777 /* move them until CX is ZERO. */ 7778 while (M.x86.R_CX != 0) { 7779 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7780 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7781 cmp_long(M.x86.R_EAX, val); 7782 } else { 7783 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7784 cmp_word(M.x86.R_AX, (u16)val); 7785 } 7786 M.x86.R_CX -= 1; 7787 M.x86.R_DI += inc; 7788 if (ACCESS_FLAG(F_ZF) == 0) 7789 break; 7790 } 7791 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7792 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7793 /* REPNE */ 7794 /* move them until CX is ZERO. */ 7795 while (M.x86.R_CX != 0) { 7796 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7797 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7798 cmp_long(M.x86.R_EAX, val); 7799 } else { 7800 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7801 cmp_word(M.x86.R_AX, (u16)val); 7802 } 7803 M.x86.R_CX -= 1; 7804 M.x86.R_DI += inc; 7805 if (ACCESS_FLAG(F_ZF)) 7806 break; /* zero flag set means equal */ 7807 } 7808 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7809 } else { 7810 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7811 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7812 cmp_long(M.x86.R_EAX, val); 7813 } else { 7814 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7815 cmp_word(M.x86.R_AX, (u16)val); 7816 } 7817 M.x86.R_DI += inc; 7818 } 7819 DECODE_CLEAR_SEGOVR(); 7820 END_OF_INSTR(); 7821} 7822 7823/**************************************************************************** 7824REMARKS: 7825Handles opcode 0xb0 7826****************************************************************************/ 7827static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 7828{ 7829 u8 imm; 7830 7831 START_OF_INSTR(); 7832 DECODE_PRINTF("MOV\tAL,"); 7833 imm = fetch_byte_imm(); 7834 DECODE_PRINTF2("%x\n", imm); 7835 TRACE_AND_STEP(); 7836 M.x86.R_AL = imm; 7837 DECODE_CLEAR_SEGOVR(); 7838 END_OF_INSTR(); 7839} 7840 7841/**************************************************************************** 7842REMARKS: 7843Handles opcode 0xb1 7844****************************************************************************/ 7845static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) 7846{ 7847 u8 imm; 7848 7849 START_OF_INSTR(); 7850 DECODE_PRINTF("MOV\tCL,"); 7851 imm = fetch_byte_imm(); 7852 DECODE_PRINTF2("%x\n", imm); 7853 TRACE_AND_STEP(); 7854 M.x86.R_CL = imm; 7855 DECODE_CLEAR_SEGOVR(); 7856 END_OF_INSTR(); 7857} 7858 7859/**************************************************************************** 7860REMARKS: 7861Handles opcode 0xb2 7862****************************************************************************/ 7863static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) 7864{ 7865 u8 imm; 7866 7867 START_OF_INSTR(); 7868 DECODE_PRINTF("MOV\tDL,"); 7869 imm = fetch_byte_imm(); 7870 DECODE_PRINTF2("%x\n", imm); 7871 TRACE_AND_STEP(); 7872 M.x86.R_DL = imm; 7873 DECODE_CLEAR_SEGOVR(); 7874 END_OF_INSTR(); 7875} 7876 7877/**************************************************************************** 7878REMARKS: 7879Handles opcode 0xb3 7880****************************************************************************/ 7881static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) 7882{ 7883 u8 imm; 7884 7885 START_OF_INSTR(); 7886 DECODE_PRINTF("MOV\tBL,"); 7887 imm = fetch_byte_imm(); 7888 DECODE_PRINTF2("%x\n", imm); 7889 TRACE_AND_STEP(); 7890 M.x86.R_BL = imm; 7891 DECODE_CLEAR_SEGOVR(); 7892 END_OF_INSTR(); 7893} 7894 7895/**************************************************************************** 7896REMARKS: 7897Handles opcode 0xb4 7898****************************************************************************/ 7899static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) 7900{ 7901 u8 imm; 7902 7903 START_OF_INSTR(); 7904 DECODE_PRINTF("MOV\tAH,"); 7905 imm = fetch_byte_imm(); 7906 DECODE_PRINTF2("%x\n", imm); 7907 TRACE_AND_STEP(); 7908 M.x86.R_AH = imm; 7909 DECODE_CLEAR_SEGOVR(); 7910 END_OF_INSTR(); 7911} 7912 7913/**************************************************************************** 7914REMARKS: 7915Handles opcode 0xb5 7916****************************************************************************/ 7917static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) 7918{ 7919 u8 imm; 7920 7921 START_OF_INSTR(); 7922 DECODE_PRINTF("MOV\tCH,"); 7923 imm = fetch_byte_imm(); 7924 DECODE_PRINTF2("%x\n", imm); 7925 TRACE_AND_STEP(); 7926 M.x86.R_CH = imm; 7927 DECODE_CLEAR_SEGOVR(); 7928 END_OF_INSTR(); 7929} 7930 7931/**************************************************************************** 7932REMARKS: 7933Handles opcode 0xb6 7934****************************************************************************/ 7935static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) 7936{ 7937 u8 imm; 7938 7939 START_OF_INSTR(); 7940 DECODE_PRINTF("MOV\tDH,"); 7941 imm = fetch_byte_imm(); 7942 DECODE_PRINTF2("%x\n", imm); 7943 TRACE_AND_STEP(); 7944 M.x86.R_DH = imm; 7945 DECODE_CLEAR_SEGOVR(); 7946 END_OF_INSTR(); 7947} 7948 7949/**************************************************************************** 7950REMARKS: 7951Handles opcode 0xb7 7952****************************************************************************/ 7953static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) 7954{ 7955 u8 imm; 7956 7957 START_OF_INSTR(); 7958 DECODE_PRINTF("MOV\tBH,"); 7959 imm = fetch_byte_imm(); 7960 DECODE_PRINTF2("%x\n", imm); 7961 TRACE_AND_STEP(); 7962 M.x86.R_BH = imm; 7963 DECODE_CLEAR_SEGOVR(); 7964 END_OF_INSTR(); 7965} 7966 7967/**************************************************************************** 7968REMARKS: 7969Handles opcode 0xb8 7970****************************************************************************/ 7971static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 7972{ 7973 u32 srcval; 7974 7975 START_OF_INSTR(); 7976 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7977 DECODE_PRINTF("MOV\tEAX,"); 7978 srcval = fetch_long_imm(); 7979 } else { 7980 DECODE_PRINTF("MOV\tAX,"); 7981 srcval = fetch_word_imm(); 7982 } 7983 DECODE_PRINTF2("%x\n", srcval); 7984 TRACE_AND_STEP(); 7985 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7986 M.x86.R_EAX = srcval; 7987 } else { 7988 M.x86.R_AX = (u16)srcval; 7989 } 7990 DECODE_CLEAR_SEGOVR(); 7991 END_OF_INSTR(); 7992} 7993 7994/**************************************************************************** 7995REMARKS: 7996Handles opcode 0xb9 7997****************************************************************************/ 7998static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) 7999{ 8000 u32 srcval; 8001 8002 START_OF_INSTR(); 8003 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8004 DECODE_PRINTF("MOV\tECX,"); 8005 srcval = fetch_long_imm(); 8006 } else { 8007 DECODE_PRINTF("MOV\tCX,"); 8008 srcval = fetch_word_imm(); 8009 } 8010 DECODE_PRINTF2("%x\n", srcval); 8011 TRACE_AND_STEP(); 8012 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8013 M.x86.R_ECX = srcval; 8014 } else { 8015 M.x86.R_CX = (u16)srcval; 8016 } 8017 DECODE_CLEAR_SEGOVR(); 8018 END_OF_INSTR(); 8019} 8020 8021/**************************************************************************** 8022REMARKS: 8023Handles opcode 0xba 8024****************************************************************************/ 8025static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) 8026{ 8027 u32 srcval; 8028 8029 START_OF_INSTR(); 8030 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8031 DECODE_PRINTF("MOV\tEDX,"); 8032 srcval = fetch_long_imm(); 8033 } else { 8034 DECODE_PRINTF("MOV\tDX,"); 8035 srcval = fetch_word_imm(); 8036 } 8037 DECODE_PRINTF2("%x\n", srcval); 8038 TRACE_AND_STEP(); 8039 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8040 M.x86.R_EDX = srcval; 8041 } else { 8042 M.x86.R_DX = (u16)srcval; 8043 } 8044 DECODE_CLEAR_SEGOVR(); 8045 END_OF_INSTR(); 8046} 8047 8048/**************************************************************************** 8049REMARKS: 8050Handles opcode 0xbb 8051****************************************************************************/ 8052static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) 8053{ 8054 u32 srcval; 8055 8056 START_OF_INSTR(); 8057 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8058 DECODE_PRINTF("MOV\tEBX,"); 8059 srcval = fetch_long_imm(); 8060 } else { 8061 DECODE_PRINTF("MOV\tBX,"); 8062 srcval = fetch_word_imm(); 8063 } 8064 DECODE_PRINTF2("%x\n", srcval); 8065 TRACE_AND_STEP(); 8066 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8067 M.x86.R_EBX = srcval; 8068 } else { 8069 M.x86.R_BX = (u16)srcval; 8070 } 8071 DECODE_CLEAR_SEGOVR(); 8072 END_OF_INSTR(); 8073} 8074 8075/**************************************************************************** 8076REMARKS: 8077Handles opcode 0xbc 8078****************************************************************************/ 8079static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) 8080{ 8081 u32 srcval; 8082 8083 START_OF_INSTR(); 8084 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8085 DECODE_PRINTF("MOV\tESP,"); 8086 srcval = fetch_long_imm(); 8087 } else { 8088 DECODE_PRINTF("MOV\tSP,"); 8089 srcval = fetch_word_imm(); 8090 } 8091 DECODE_PRINTF2("%x\n", srcval); 8092 TRACE_AND_STEP(); 8093 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8094 M.x86.R_ESP = srcval; 8095 } else { 8096 M.x86.R_SP = (u16)srcval; 8097 } 8098 DECODE_CLEAR_SEGOVR(); 8099 END_OF_INSTR(); 8100} 8101 8102/**************************************************************************** 8103REMARKS: 8104Handles opcode 0xbd 8105****************************************************************************/ 8106static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) 8107{ 8108 u32 srcval; 8109 8110 START_OF_INSTR(); 8111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8112 DECODE_PRINTF("MOV\tEBP,"); 8113 srcval = fetch_long_imm(); 8114 } else { 8115 DECODE_PRINTF("MOV\tBP,"); 8116 srcval = fetch_word_imm(); 8117 } 8118 DECODE_PRINTF2("%x\n", srcval); 8119 TRACE_AND_STEP(); 8120 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8121 M.x86.R_EBP = srcval; 8122 } else { 8123 M.x86.R_BP = (u16)srcval; 8124 } 8125 DECODE_CLEAR_SEGOVR(); 8126 END_OF_INSTR(); 8127} 8128 8129/**************************************************************************** 8130REMARKS: 8131Handles opcode 0xbe 8132****************************************************************************/ 8133static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) 8134{ 8135 u32 srcval; 8136 8137 START_OF_INSTR(); 8138 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8139 DECODE_PRINTF("MOV\tESI,"); 8140 srcval = fetch_long_imm(); 8141 } else { 8142 DECODE_PRINTF("MOV\tSI,"); 8143 srcval = fetch_word_imm(); 8144 } 8145 DECODE_PRINTF2("%x\n", srcval); 8146 TRACE_AND_STEP(); 8147 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8148 M.x86.R_ESI = srcval; 8149 } else { 8150 M.x86.R_SI = (u16)srcval; 8151 } 8152 DECODE_CLEAR_SEGOVR(); 8153 END_OF_INSTR(); 8154} 8155 8156/**************************************************************************** 8157REMARKS: 8158Handles opcode 0xbf 8159****************************************************************************/ 8160static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) 8161{ 8162 u32 srcval; 8163 8164 START_OF_INSTR(); 8165 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8166 DECODE_PRINTF("MOV\tEDI,"); 8167 srcval = fetch_long_imm(); 8168 } else { 8169 DECODE_PRINTF("MOV\tDI,"); 8170 srcval = fetch_word_imm(); 8171 } 8172 DECODE_PRINTF2("%x\n", srcval); 8173 TRACE_AND_STEP(); 8174 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8175 M.x86.R_EDI = srcval; 8176 } else { 8177 M.x86.R_DI = (u16)srcval; 8178 } 8179 DECODE_CLEAR_SEGOVR(); 8180 END_OF_INSTR(); 8181} 8182 8183/* used by opcodes c0, d0, and d2. */ 8184static u8(*opcD0_byte_operation[])(u8 d, u8 s) = 8185{ 8186 rol_byte, 8187 ror_byte, 8188 rcl_byte, 8189 rcr_byte, 8190 shl_byte, 8191 shr_byte, 8192 shl_byte, /* sal_byte === shl_byte by definition */ 8193 sar_byte, 8194}; 8195 8196/**************************************************************************** 8197REMARKS: 8198Handles opcode 0xc0 8199****************************************************************************/ 8200static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 8201{ 8202 int mod, rl, rh; 8203 u8 *destreg; 8204 uint destoffset; 8205 u8 destval; 8206 u8 amt; 8207 8208 /* 8209 * Yet another weirdo special case instruction format. Part of 8210 * the opcode held below in "RH". Doubly nested case would 8211 * result, except that the decoded instruction 8212 */ 8213 START_OF_INSTR(); 8214 FETCH_DECODE_MODRM(mod, rh, rl); 8215#ifdef DEBUG 8216 if (DEBUG_DECODE()) { 8217 /* XXX DECODE_PRINTF may be changed to something more 8218 general, so that it is important to leave the strings 8219 in the same format, even though the result is that the 8220 above test is done twice. */ 8221 8222 switch (rh) { 8223 case 0: 8224 DECODE_PRINTF("ROL\t"); 8225 break; 8226 case 1: 8227 DECODE_PRINTF("ROR\t"); 8228 break; 8229 case 2: 8230 DECODE_PRINTF("RCL\t"); 8231 break; 8232 case 3: 8233 DECODE_PRINTF("RCR\t"); 8234 break; 8235 case 4: 8236 DECODE_PRINTF("SHL\t"); 8237 break; 8238 case 5: 8239 DECODE_PRINTF("SHR\t"); 8240 break; 8241 case 6: 8242 DECODE_PRINTF("SAL\t"); 8243 break; 8244 case 7: 8245 DECODE_PRINTF("SAR\t"); 8246 break; 8247 } 8248 } 8249#endif 8250 /* know operation, decode the mod byte to find the addressing 8251 mode. */ 8252 switch (mod) { 8253 case 0: 8254 DECODE_PRINTF("BYTE PTR "); 8255 destoffset = decode_rm00_address(rl); 8256 amt = fetch_byte_imm(); 8257 DECODE_PRINTF2(",%x\n", amt); 8258 destval = fetch_data_byte(destoffset); 8259 TRACE_AND_STEP(); 8260 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8261 store_data_byte(destoffset, destval); 8262 break; 8263 case 1: 8264 DECODE_PRINTF("BYTE PTR "); 8265 destoffset = decode_rm01_address(rl); 8266 amt = fetch_byte_imm(); 8267 DECODE_PRINTF2(",%x\n", amt); 8268 destval = fetch_data_byte(destoffset); 8269 TRACE_AND_STEP(); 8270 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8271 store_data_byte(destoffset, destval); 8272 break; 8273 case 2: 8274 DECODE_PRINTF("BYTE PTR "); 8275 destoffset = decode_rm10_address(rl); 8276 amt = fetch_byte_imm(); 8277 DECODE_PRINTF2(",%x\n", amt); 8278 destval = fetch_data_byte(destoffset); 8279 TRACE_AND_STEP(); 8280 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8281 store_data_byte(destoffset, destval); 8282 break; 8283 case 3: /* register to register */ 8284 destreg = DECODE_RM_BYTE_REGISTER(rl); 8285 amt = fetch_byte_imm(); 8286 DECODE_PRINTF2(",%x\n", amt); 8287 TRACE_AND_STEP(); 8288 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 8289 *destreg = destval; 8290 break; 8291 } 8292 DECODE_CLEAR_SEGOVR(); 8293 END_OF_INSTR(); 8294} 8295 8296/* used by opcodes c1, d1, and d3. */ 8297static u16(*opcD1_word_operation[])(u16 s, u8 d) = 8298{ 8299 rol_word, 8300 ror_word, 8301 rcl_word, 8302 rcr_word, 8303 shl_word, 8304 shr_word, 8305 shl_word, /* sal_byte === shl_byte by definition */ 8306 sar_word, 8307}; 8308 8309/* used by opcodes c1, d1, and d3. */ 8310static u32 (*opcD1_long_operation[])(u32 s, u8 d) = 8311{ 8312 rol_long, 8313 ror_long, 8314 rcl_long, 8315 rcr_long, 8316 shl_long, 8317 shr_long, 8318 shl_long, /* sal_byte === shl_byte by definition */ 8319 sar_long, 8320}; 8321 8322/**************************************************************************** 8323REMARKS: 8324Handles opcode 0xc1 8325****************************************************************************/ 8326static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 8327{ 8328 int mod, rl, rh; 8329 uint destoffset; 8330 u8 amt; 8331 8332 /* 8333 * Yet another weirdo special case instruction format. Part of 8334 * the opcode held below in "RH". Doubly nested case would 8335 * result, except that the decoded instruction 8336 */ 8337 START_OF_INSTR(); 8338 FETCH_DECODE_MODRM(mod, rh, rl); 8339#ifdef DEBUG 8340 if (DEBUG_DECODE()) { 8341 /* XXX DECODE_PRINTF may be changed to something more 8342 general, so that it is important to leave the strings 8343 in the same format, even though the result is that the 8344 above test is done twice. */ 8345 8346 switch (rh) { 8347 case 0: 8348 DECODE_PRINTF("ROL\t"); 8349 break; 8350 case 1: 8351 DECODE_PRINTF("ROR\t"); 8352 break; 8353 case 2: 8354 DECODE_PRINTF("RCL\t"); 8355 break; 8356 case 3: 8357 DECODE_PRINTF("RCR\t"); 8358 break; 8359 case 4: 8360 DECODE_PRINTF("SHL\t"); 8361 break; 8362 case 5: 8363 DECODE_PRINTF("SHR\t"); 8364 break; 8365 case 6: 8366 DECODE_PRINTF("SAL\t"); 8367 break; 8368 case 7: 8369 DECODE_PRINTF("SAR\t"); 8370 break; 8371 } 8372 } 8373#endif 8374 /* know operation, decode the mod byte to find the addressing 8375 mode. */ 8376 switch (mod) { 8377 case 0: 8378 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8379 u32 destval; 8380 8381 DECODE_PRINTF("DWORD PTR "); 8382 destoffset = decode_rm00_address(rl); 8383 amt = fetch_byte_imm(); 8384 DECODE_PRINTF2(",%x\n", amt); 8385 destval = fetch_data_long(destoffset); 8386 TRACE_AND_STEP(); 8387 destval = (*opcD1_long_operation[rh]) (destval, amt); 8388 store_data_long(destoffset, destval); 8389 } else { 8390 u16 destval; 8391 8392 DECODE_PRINTF("WORD PTR "); 8393 destoffset = decode_rm00_address(rl); 8394 amt = fetch_byte_imm(); 8395 DECODE_PRINTF2(",%x\n", amt); 8396 destval = fetch_data_word(destoffset); 8397 TRACE_AND_STEP(); 8398 destval = (*opcD1_word_operation[rh]) (destval, amt); 8399 store_data_word(destoffset, destval); 8400 } 8401 break; 8402 case 1: 8403 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8404 u32 destval; 8405 8406 DECODE_PRINTF("DWORD PTR "); 8407 destoffset = decode_rm01_address(rl); 8408 amt = fetch_byte_imm(); 8409 DECODE_PRINTF2(",%x\n", amt); 8410 destval = fetch_data_long(destoffset); 8411 TRACE_AND_STEP(); 8412 destval = (*opcD1_long_operation[rh]) (destval, amt); 8413 store_data_long(destoffset, destval); 8414 } else { 8415 u16 destval; 8416 8417 DECODE_PRINTF("WORD PTR "); 8418 destoffset = decode_rm01_address(rl); 8419 amt = fetch_byte_imm(); 8420 DECODE_PRINTF2(",%x\n", amt); 8421 destval = fetch_data_word(destoffset); 8422 TRACE_AND_STEP(); 8423 destval = (*opcD1_word_operation[rh]) (destval, amt); 8424 store_data_word(destoffset, destval); 8425 } 8426 break; 8427 case 2: 8428 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8429 u32 destval; 8430 8431 DECODE_PRINTF("DWORD PTR "); 8432 destoffset = decode_rm10_address(rl); 8433 amt = fetch_byte_imm(); 8434 DECODE_PRINTF2(",%x\n", amt); 8435 destval = fetch_data_long(destoffset); 8436 TRACE_AND_STEP(); 8437 destval = (*opcD1_long_operation[rh]) (destval, amt); 8438 store_data_long(destoffset, destval); 8439 } else { 8440 u16 destval; 8441 8442 DECODE_PRINTF("WORD PTR "); 8443 destoffset = decode_rm10_address(rl); 8444 amt = fetch_byte_imm(); 8445 DECODE_PRINTF2(",%x\n", amt); 8446 destval = fetch_data_word(destoffset); 8447 TRACE_AND_STEP(); 8448 destval = (*opcD1_word_operation[rh]) (destval, amt); 8449 store_data_word(destoffset, destval); 8450 } 8451 break; 8452 case 3: /* register to register */ 8453 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8454 u32 *destreg; 8455 8456 destreg = DECODE_RM_LONG_REGISTER(rl); 8457 amt = fetch_byte_imm(); 8458 DECODE_PRINTF2(",%x\n", amt); 8459 TRACE_AND_STEP(); 8460 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 8461 } else { 8462 u16 *destreg; 8463 8464 destreg = DECODE_RM_WORD_REGISTER(rl); 8465 amt = fetch_byte_imm(); 8466 DECODE_PRINTF2(",%x\n", amt); 8467 TRACE_AND_STEP(); 8468 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 8469 } 8470 break; 8471 } 8472 DECODE_CLEAR_SEGOVR(); 8473 END_OF_INSTR(); 8474} 8475 8476/**************************************************************************** 8477REMARKS: 8478Handles opcode 0xc2 8479****************************************************************************/ 8480static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 8481{ 8482 u16 imm; 8483 8484 START_OF_INSTR(); 8485 DECODE_PRINTF("RET\t"); 8486 imm = fetch_word_imm(); 8487 DECODE_PRINTF2("%x\n", imm); 8488 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8489 TRACE_AND_STEP(); 8490 M.x86.R_IP = pop_word(); 8491 M.x86.R_SP += imm; 8492 DECODE_CLEAR_SEGOVR(); 8493 END_OF_INSTR(); 8494} 8495 8496/**************************************************************************** 8497REMARKS: 8498Handles opcode 0xc3 8499****************************************************************************/ 8500static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 8501{ 8502 START_OF_INSTR(); 8503 DECODE_PRINTF("RET\n"); 8504 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8505 TRACE_AND_STEP(); 8506 M.x86.R_IP = pop_word(); 8507 DECODE_CLEAR_SEGOVR(); 8508 END_OF_INSTR(); 8509} 8510 8511/**************************************************************************** 8512REMARKS: 8513Handles opcode 0xc4 8514****************************************************************************/ 8515static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 8516{ 8517 int mod, rh, rl; 8518 u16 *dstreg; 8519 uint srcoffset; 8520 8521 START_OF_INSTR(); 8522 DECODE_PRINTF("LES\t"); 8523 FETCH_DECODE_MODRM(mod, rh, rl); 8524 switch (mod) { 8525 case 0: 8526 dstreg = DECODE_RM_WORD_REGISTER(rh); 8527 DECODE_PRINTF(","); 8528 srcoffset = decode_rm00_address(rl); 8529 DECODE_PRINTF("\n"); 8530 TRACE_AND_STEP(); 8531 *dstreg = fetch_data_word(srcoffset); 8532 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8533 break; 8534 case 1: 8535 dstreg = DECODE_RM_WORD_REGISTER(rh); 8536 DECODE_PRINTF(","); 8537 srcoffset = decode_rm01_address(rl); 8538 DECODE_PRINTF("\n"); 8539 TRACE_AND_STEP(); 8540 *dstreg = fetch_data_word(srcoffset); 8541 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8542 break; 8543 case 2: 8544 dstreg = DECODE_RM_WORD_REGISTER(rh); 8545 DECODE_PRINTF(","); 8546 srcoffset = decode_rm10_address(rl); 8547 DECODE_PRINTF("\n"); 8548 TRACE_AND_STEP(); 8549 *dstreg = fetch_data_word(srcoffset); 8550 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8551 break; 8552 case 3: /* register to register */ 8553 /* UNDEFINED! */ 8554 TRACE_AND_STEP(); 8555 } 8556 DECODE_CLEAR_SEGOVR(); 8557 END_OF_INSTR(); 8558} 8559 8560/**************************************************************************** 8561REMARKS: 8562Handles opcode 0xc5 8563****************************************************************************/ 8564static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 8565{ 8566 int mod, rh, rl; 8567 u16 *dstreg; 8568 uint srcoffset; 8569 8570 START_OF_INSTR(); 8571 DECODE_PRINTF("LDS\t"); 8572 FETCH_DECODE_MODRM(mod, rh, rl); 8573 switch (mod) { 8574 case 0: 8575 dstreg = DECODE_RM_WORD_REGISTER(rh); 8576 DECODE_PRINTF(","); 8577 srcoffset = decode_rm00_address(rl); 8578 DECODE_PRINTF("\n"); 8579 TRACE_AND_STEP(); 8580 *dstreg = fetch_data_word(srcoffset); 8581 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8582 break; 8583 case 1: 8584 dstreg = DECODE_RM_WORD_REGISTER(rh); 8585 DECODE_PRINTF(","); 8586 srcoffset = decode_rm01_address(rl); 8587 DECODE_PRINTF("\n"); 8588 TRACE_AND_STEP(); 8589 *dstreg = fetch_data_word(srcoffset); 8590 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8591 break; 8592 case 2: 8593 dstreg = DECODE_RM_WORD_REGISTER(rh); 8594 DECODE_PRINTF(","); 8595 srcoffset = decode_rm10_address(rl); 8596 DECODE_PRINTF("\n"); 8597 TRACE_AND_STEP(); 8598 *dstreg = fetch_data_word(srcoffset); 8599 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8600 break; 8601 case 3: /* register to register */ 8602 /* UNDEFINED! */ 8603 TRACE_AND_STEP(); 8604 } 8605 DECODE_CLEAR_SEGOVR(); 8606 END_OF_INSTR(); 8607} 8608 8609/**************************************************************************** 8610REMARKS: 8611Handles opcode 0xc6 8612****************************************************************************/ 8613static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 8614{ 8615 int mod, rl, rh; 8616 u8 *destreg; 8617 uint destoffset; 8618 u8 imm; 8619 8620 START_OF_INSTR(); 8621 DECODE_PRINTF("MOV\t"); 8622 FETCH_DECODE_MODRM(mod, rh, rl); 8623 if (rh != 0) { 8624 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 8625 HALT_SYS(); 8626 } 8627 switch (mod) { 8628 case 0: 8629 DECODE_PRINTF("BYTE PTR "); 8630 destoffset = decode_rm00_address(rl); 8631 imm = fetch_byte_imm(); 8632 DECODE_PRINTF2(",%2x\n", imm); 8633 TRACE_AND_STEP(); 8634 store_data_byte(destoffset, imm); 8635 break; 8636 case 1: 8637 DECODE_PRINTF("BYTE PTR "); 8638 destoffset = decode_rm01_address(rl); 8639 imm = fetch_byte_imm(); 8640 DECODE_PRINTF2(",%2x\n", imm); 8641 TRACE_AND_STEP(); 8642 store_data_byte(destoffset, imm); 8643 break; 8644 case 2: 8645 DECODE_PRINTF("BYTE PTR "); 8646 destoffset = decode_rm10_address(rl); 8647 imm = fetch_byte_imm(); 8648 DECODE_PRINTF2(",%2x\n", imm); 8649 TRACE_AND_STEP(); 8650 store_data_byte(destoffset, imm); 8651 break; 8652 case 3: /* register to register */ 8653 destreg = DECODE_RM_BYTE_REGISTER(rl); 8654 imm = fetch_byte_imm(); 8655 DECODE_PRINTF2(",%2x\n", imm); 8656 TRACE_AND_STEP(); 8657 *destreg = imm; 8658 break; 8659 } 8660 DECODE_CLEAR_SEGOVR(); 8661 END_OF_INSTR(); 8662} 8663 8664/**************************************************************************** 8665REMARKS: 8666Handles opcode 0xc7 8667****************************************************************************/ 8668static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 8669{ 8670 int mod, rl, rh; 8671 uint destoffset; 8672 8673 START_OF_INSTR(); 8674 DECODE_PRINTF("MOV\t"); 8675 FETCH_DECODE_MODRM(mod, rh, rl); 8676 if (rh != 0) { 8677 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 8678 HALT_SYS(); 8679 } 8680 switch (mod) { 8681 case 0: 8682 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8683 u32 imm; 8684 8685 DECODE_PRINTF("DWORD PTR "); 8686 destoffset = decode_rm00_address(rl); 8687 imm = fetch_long_imm(); 8688 DECODE_PRINTF2(",%x\n", imm); 8689 TRACE_AND_STEP(); 8690 store_data_long(destoffset, imm); 8691 } else { 8692 u16 imm; 8693 8694 DECODE_PRINTF("WORD PTR "); 8695 destoffset = decode_rm00_address(rl); 8696 imm = fetch_word_imm(); 8697 DECODE_PRINTF2(",%x\n", imm); 8698 TRACE_AND_STEP(); 8699 store_data_word(destoffset, imm); 8700 } 8701 break; 8702 case 1: 8703 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8704 u32 imm; 8705 8706 DECODE_PRINTF("DWORD PTR "); 8707 destoffset = decode_rm01_address(rl); 8708 imm = fetch_long_imm(); 8709 DECODE_PRINTF2(",%x\n", imm); 8710 TRACE_AND_STEP(); 8711 store_data_long(destoffset, imm); 8712 } else { 8713 u16 imm; 8714 8715 DECODE_PRINTF("WORD PTR "); 8716 destoffset = decode_rm01_address(rl); 8717 imm = fetch_word_imm(); 8718 DECODE_PRINTF2(",%x\n", imm); 8719 TRACE_AND_STEP(); 8720 store_data_word(destoffset, imm); 8721 } 8722 break; 8723 case 2: 8724 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8725 u32 imm; 8726 8727 DECODE_PRINTF("DWORD PTR "); 8728 destoffset = decode_rm10_address(rl); 8729 imm = fetch_long_imm(); 8730 DECODE_PRINTF2(",%x\n", imm); 8731 TRACE_AND_STEP(); 8732 store_data_long(destoffset, imm); 8733 } else { 8734 u16 imm; 8735 8736 DECODE_PRINTF("WORD PTR "); 8737 destoffset = decode_rm10_address(rl); 8738 imm = fetch_word_imm(); 8739 DECODE_PRINTF2(",%x\n", imm); 8740 TRACE_AND_STEP(); 8741 store_data_word(destoffset, imm); 8742 } 8743 break; 8744 case 3: /* register to register */ 8745 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8746 u32 *destreg; 8747 u32 imm; 8748 8749 destreg = DECODE_RM_LONG_REGISTER(rl); 8750 imm = fetch_long_imm(); 8751 DECODE_PRINTF2(",%x\n", imm); 8752 TRACE_AND_STEP(); 8753 *destreg = imm; 8754 } else { 8755 u16 *destreg; 8756 u16 imm; 8757 8758 destreg = DECODE_RM_WORD_REGISTER(rl); 8759 imm = fetch_word_imm(); 8760 DECODE_PRINTF2(",%x\n", imm); 8761 TRACE_AND_STEP(); 8762 *destreg = imm; 8763 } 8764 break; 8765 } 8766 DECODE_CLEAR_SEGOVR(); 8767 END_OF_INSTR(); 8768} 8769 8770/**************************************************************************** 8771REMARKS: 8772Handles opcode 0xc8 8773****************************************************************************/ 8774static void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 8775{ 8776 u16 local,frame_pointer; 8777 u8 nesting; 8778 int i; 8779 8780 START_OF_INSTR(); 8781 local = fetch_word_imm(); 8782 nesting = fetch_byte_imm(); 8783 DECODE_PRINTF2("ENTER %x\n", local); 8784 DECODE_PRINTF2(",%x\n", nesting); 8785 TRACE_AND_STEP(); 8786 push_word(M.x86.R_BP); 8787 frame_pointer = M.x86.R_SP; 8788 if (nesting > 0) { 8789 for (i = 1; i < nesting; i++) { 8790 M.x86.R_BP -= 2; 8791 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 8792 } 8793 push_word(frame_pointer); 8794 } 8795 M.x86.R_BP = frame_pointer; 8796 M.x86.R_SP = (u16)(M.x86.R_SP - local); 8797 DECODE_CLEAR_SEGOVR(); 8798 END_OF_INSTR(); 8799} 8800 8801/**************************************************************************** 8802REMARKS: 8803Handles opcode 0xc9 8804****************************************************************************/ 8805static void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 8806{ 8807 START_OF_INSTR(); 8808 DECODE_PRINTF("LEAVE\n"); 8809 TRACE_AND_STEP(); 8810 M.x86.R_SP = M.x86.R_BP; 8811 M.x86.R_BP = pop_word(); 8812 DECODE_CLEAR_SEGOVR(); 8813 END_OF_INSTR(); 8814} 8815 8816/**************************************************************************** 8817REMARKS: 8818Handles opcode 0xca 8819****************************************************************************/ 8820static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 8821{ 8822 u16 imm; 8823 8824 START_OF_INSTR(); 8825 DECODE_PRINTF("RETF\t"); 8826 imm = fetch_word_imm(); 8827 DECODE_PRINTF2("%x\n", imm); 8828 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8829 TRACE_AND_STEP(); 8830 M.x86.R_IP = pop_word(); 8831 M.x86.R_CS = pop_word(); 8832 M.x86.R_SP += imm; 8833 DECODE_CLEAR_SEGOVR(); 8834 END_OF_INSTR(); 8835} 8836 8837/**************************************************************************** 8838REMARKS: 8839Handles opcode 0xcb 8840****************************************************************************/ 8841static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 8842{ 8843 START_OF_INSTR(); 8844 DECODE_PRINTF("RETF\n"); 8845 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8846 TRACE_AND_STEP(); 8847 M.x86.R_IP = pop_word(); 8848 M.x86.R_CS = pop_word(); 8849 DECODE_CLEAR_SEGOVR(); 8850 END_OF_INSTR(); 8851} 8852 8853/**************************************************************************** 8854REMARKS: 8855Handles opcode 0xcc 8856****************************************************************************/ 8857static void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 8858{ 8859 START_OF_INSTR(); 8860 DECODE_PRINTF("INT 3\n"); 8861 TRACE_AND_STEP(); 8862 if (_X86EMU_intrTab[3]) { 8863 (*_X86EMU_intrTab[3])(3); 8864 } else { 8865 push_word((u16)M.x86.R_FLG); 8866 CLEAR_FLAG(F_IF); 8867 CLEAR_FLAG(F_TF); 8868 push_word(M.x86.R_CS); 8869 M.x86.R_CS = mem_access_word(3 * 4 + 2); 8870 push_word(M.x86.R_IP); 8871 M.x86.R_IP = mem_access_word(3 * 4); 8872 } 8873 DECODE_CLEAR_SEGOVR(); 8874 END_OF_INSTR(); 8875} 8876 8877/**************************************************************************** 8878REMARKS: 8879Handles opcode 0xcd 8880****************************************************************************/ 8881static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 8882{ 8883 u8 intnum; 8884 8885 START_OF_INSTR(); 8886 DECODE_PRINTF("INT\t"); 8887 intnum = fetch_byte_imm(); 8888 DECODE_PRINTF2("%x\n", intnum); 8889 TRACE_AND_STEP(); 8890 if (_X86EMU_intrTab[intnum]) { 8891 (*_X86EMU_intrTab[intnum])(intnum); 8892 } else { 8893 push_word((u16)M.x86.R_FLG); 8894 CLEAR_FLAG(F_IF); 8895 CLEAR_FLAG(F_TF); 8896 push_word(M.x86.R_CS); 8897 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 8898 push_word(M.x86.R_IP); 8899 M.x86.R_IP = mem_access_word(intnum * 4); 8900 } 8901 DECODE_CLEAR_SEGOVR(); 8902 END_OF_INSTR(); 8903} 8904 8905/**************************************************************************** 8906REMARKS: 8907Handles opcode 0xce 8908****************************************************************************/ 8909static void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 8910{ 8911 START_OF_INSTR(); 8912 DECODE_PRINTF("INTO\n"); 8913 TRACE_AND_STEP(); 8914 if (ACCESS_FLAG(F_OF)) { 8915 if (_X86EMU_intrTab[4]) { 8916 (*_X86EMU_intrTab[4])(4); 8917 } else { 8918 push_word((u16)M.x86.R_FLG); 8919 CLEAR_FLAG(F_IF); 8920 CLEAR_FLAG(F_TF); 8921 push_word(M.x86.R_CS); 8922 M.x86.R_CS = mem_access_word(4 * 4 + 2); 8923 push_word(M.x86.R_IP); 8924 M.x86.R_IP = mem_access_word(4 * 4); 8925 } 8926 } 8927 DECODE_CLEAR_SEGOVR(); 8928 END_OF_INSTR(); 8929} 8930 8931/**************************************************************************** 8932REMARKS: 8933Handles opcode 0xcf 8934****************************************************************************/ 8935static void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 8936{ 8937 START_OF_INSTR(); 8938 DECODE_PRINTF("IRET\n"); 8939 8940 TRACE_AND_STEP(); 8941 8942 M.x86.R_IP = pop_word(); 8943 M.x86.R_CS = pop_word(); 8944 M.x86.R_FLG = pop_word(); 8945 DECODE_CLEAR_SEGOVR(); 8946 END_OF_INSTR(); 8947} 8948 8949/**************************************************************************** 8950REMARKS: 8951Handles opcode 0xd0 8952****************************************************************************/ 8953static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 8954{ 8955 int mod, rl, rh; 8956 u8 *destreg; 8957 uint destoffset; 8958 u8 destval; 8959 8960 /* 8961 * Yet another weirdo special case instruction format. Part of 8962 * the opcode held below in "RH". Doubly nested case would 8963 * result, except that the decoded instruction 8964 */ 8965 START_OF_INSTR(); 8966 FETCH_DECODE_MODRM(mod, rh, rl); 8967#ifdef DEBUG 8968 if (DEBUG_DECODE()) { 8969 /* XXX DECODE_PRINTF may be changed to something more 8970 general, so that it is important to leave the strings 8971 in the same format, even though the result is that the 8972 above test is done twice. */ 8973 switch (rh) { 8974 case 0: 8975 DECODE_PRINTF("ROL\t"); 8976 break; 8977 case 1: 8978 DECODE_PRINTF("ROR\t"); 8979 break; 8980 case 2: 8981 DECODE_PRINTF("RCL\t"); 8982 break; 8983 case 3: 8984 DECODE_PRINTF("RCR\t"); 8985 break; 8986 case 4: 8987 DECODE_PRINTF("SHL\t"); 8988 break; 8989 case 5: 8990 DECODE_PRINTF("SHR\t"); 8991 break; 8992 case 6: 8993 DECODE_PRINTF("SAL\t"); 8994 break; 8995 case 7: 8996 DECODE_PRINTF("SAR\t"); 8997 break; 8998 } 8999 } 9000#endif 9001 /* know operation, decode the mod byte to find the addressing 9002 mode. */ 9003 switch (mod) { 9004 case 0: 9005 DECODE_PRINTF("BYTE PTR "); 9006 destoffset = decode_rm00_address(rl); 9007 DECODE_PRINTF(",1\n"); 9008 destval = fetch_data_byte(destoffset); 9009 TRACE_AND_STEP(); 9010 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9011 store_data_byte(destoffset, destval); 9012 break; 9013 case 1: 9014 DECODE_PRINTF("BYTE PTR "); 9015 destoffset = decode_rm01_address(rl); 9016 DECODE_PRINTF(",1\n"); 9017 destval = fetch_data_byte(destoffset); 9018 TRACE_AND_STEP(); 9019 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9020 store_data_byte(destoffset, destval); 9021 break; 9022 case 2: 9023 DECODE_PRINTF("BYTE PTR "); 9024 destoffset = decode_rm10_address(rl); 9025 DECODE_PRINTF(",1\n"); 9026 destval = fetch_data_byte(destoffset); 9027 TRACE_AND_STEP(); 9028 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9029 store_data_byte(destoffset, destval); 9030 break; 9031 case 3: /* register to register */ 9032 destreg = DECODE_RM_BYTE_REGISTER(rl); 9033 DECODE_PRINTF(",1\n"); 9034 TRACE_AND_STEP(); 9035 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 9036 *destreg = destval; 9037 break; 9038 } 9039 DECODE_CLEAR_SEGOVR(); 9040 END_OF_INSTR(); 9041} 9042 9043/**************************************************************************** 9044REMARKS: 9045Handles opcode 0xd1 9046****************************************************************************/ 9047static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 9048{ 9049 int mod, rl, rh; 9050 uint destoffset; 9051 9052 /* 9053 * Yet another weirdo special case instruction format. Part of 9054 * the opcode held below in "RH". Doubly nested case would 9055 * result, except that the decoded instruction 9056 */ 9057 START_OF_INSTR(); 9058 FETCH_DECODE_MODRM(mod, rh, rl); 9059#ifdef DEBUG 9060 if (DEBUG_DECODE()) { 9061 /* XXX DECODE_PRINTF may be changed to something more 9062 general, so that it is important to leave the strings 9063 in the same format, even though the result is that the 9064 above test is done twice. */ 9065 switch (rh) { 9066 case 0: 9067 DECODE_PRINTF("ROL\t"); 9068 break; 9069 case 1: 9070 DECODE_PRINTF("ROR\t"); 9071 break; 9072 case 2: 9073 DECODE_PRINTF("RCL\t"); 9074 break; 9075 case 3: 9076 DECODE_PRINTF("RCR\t"); 9077 break; 9078 case 4: 9079 DECODE_PRINTF("SHL\t"); 9080 break; 9081 case 5: 9082 DECODE_PRINTF("SHR\t"); 9083 break; 9084 case 6: 9085 DECODE_PRINTF("SAL\t"); 9086 break; 9087 case 7: 9088 DECODE_PRINTF("SAR\t"); 9089 break; 9090 } 9091 } 9092#endif 9093 /* know operation, decode the mod byte to find the addressing 9094 mode. */ 9095 switch (mod) { 9096 case 0: 9097 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9098 u32 destval; 9099 9100 DECODE_PRINTF("DWORD PTR "); 9101 destoffset = decode_rm00_address(rl); 9102 DECODE_PRINTF(",1\n"); 9103 destval = fetch_data_long(destoffset); 9104 TRACE_AND_STEP(); 9105 destval = (*opcD1_long_operation[rh]) (destval, 1); 9106 store_data_long(destoffset, destval); 9107 } else { 9108 u16 destval; 9109 9110 DECODE_PRINTF("WORD PTR "); 9111 destoffset = decode_rm00_address(rl); 9112 DECODE_PRINTF(",1\n"); 9113 destval = fetch_data_word(destoffset); 9114 TRACE_AND_STEP(); 9115 destval = (*opcD1_word_operation[rh]) (destval, 1); 9116 store_data_word(destoffset, destval); 9117 } 9118 break; 9119 case 1: 9120 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9121 u32 destval; 9122 9123 DECODE_PRINTF("DWORD PTR "); 9124 destoffset = decode_rm01_address(rl); 9125 DECODE_PRINTF(",1\n"); 9126 destval = fetch_data_long(destoffset); 9127 TRACE_AND_STEP(); 9128 destval = (*opcD1_long_operation[rh]) (destval, 1); 9129 store_data_long(destoffset, destval); 9130 } else { 9131 u16 destval; 9132 9133 DECODE_PRINTF("WORD PTR "); 9134 destoffset = decode_rm01_address(rl); 9135 DECODE_PRINTF(",1\n"); 9136 destval = fetch_data_word(destoffset); 9137 TRACE_AND_STEP(); 9138 destval = (*opcD1_word_operation[rh]) (destval, 1); 9139 store_data_word(destoffset, destval); 9140 } 9141 break; 9142 case 2: 9143 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9144 u32 destval; 9145 9146 DECODE_PRINTF("DWORD PTR "); 9147 destoffset = decode_rm10_address(rl); 9148 DECODE_PRINTF(",1\n"); 9149 destval = fetch_data_long(destoffset); 9150 TRACE_AND_STEP(); 9151 destval = (*opcD1_long_operation[rh]) (destval, 1); 9152 store_data_long(destoffset, destval); 9153 } else { 9154 u16 destval; 9155 9156 DECODE_PRINTF("BYTE PTR "); 9157 destoffset = decode_rm10_address(rl); 9158 DECODE_PRINTF(",1\n"); 9159 destval = fetch_data_word(destoffset); 9160 TRACE_AND_STEP(); 9161 destval = (*opcD1_word_operation[rh]) (destval, 1); 9162 store_data_word(destoffset, destval); 9163 } 9164 break; 9165 case 3: /* register to register */ 9166 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9167 u32 destval; 9168 u32 *destreg; 9169 9170 destreg = DECODE_RM_LONG_REGISTER(rl); 9171 DECODE_PRINTF(",1\n"); 9172 TRACE_AND_STEP(); 9173 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 9174 *destreg = destval; 9175 } else { 9176 u16 destval; 9177 u16 *destreg; 9178 9179 destreg = DECODE_RM_WORD_REGISTER(rl); 9180 DECODE_PRINTF(",1\n"); 9181 TRACE_AND_STEP(); 9182 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 9183 *destreg = destval; 9184 } 9185 break; 9186 } 9187 DECODE_CLEAR_SEGOVR(); 9188 END_OF_INSTR(); 9189} 9190 9191/**************************************************************************** 9192REMARKS: 9193Handles opcode 0xd2 9194****************************************************************************/ 9195static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 9196{ 9197 int mod, rl, rh; 9198 u8 *destreg; 9199 uint destoffset; 9200 u8 destval; 9201 u8 amt; 9202 9203 /* 9204 * Yet another weirdo special case instruction format. Part of 9205 * the opcode held below in "RH". Doubly nested case would 9206 * result, except that the decoded instruction 9207 */ 9208 START_OF_INSTR(); 9209 FETCH_DECODE_MODRM(mod, rh, rl); 9210#ifdef DEBUG 9211 if (DEBUG_DECODE()) { 9212 /* XXX DECODE_PRINTF may be changed to something more 9213 general, so that it is important to leave the strings 9214 in the same format, even though the result is that the 9215 above test is done twice. */ 9216 switch (rh) { 9217 case 0: 9218 DECODE_PRINTF("ROL\t"); 9219 break; 9220 case 1: 9221 DECODE_PRINTF("ROR\t"); 9222 break; 9223 case 2: 9224 DECODE_PRINTF("RCL\t"); 9225 break; 9226 case 3: 9227 DECODE_PRINTF("RCR\t"); 9228 break; 9229 case 4: 9230 DECODE_PRINTF("SHL\t"); 9231 break; 9232 case 5: 9233 DECODE_PRINTF("SHR\t"); 9234 break; 9235 case 6: 9236 DECODE_PRINTF("SAL\t"); 9237 break; 9238 case 7: 9239 DECODE_PRINTF("SAR\t"); 9240 break; 9241 } 9242 } 9243#endif 9244 /* know operation, decode the mod byte to find the addressing 9245 mode. */ 9246 amt = M.x86.R_CL; 9247 switch (mod) { 9248 case 0: 9249 DECODE_PRINTF("BYTE PTR "); 9250 destoffset = decode_rm00_address(rl); 9251 DECODE_PRINTF(",CL\n"); 9252 destval = fetch_data_byte(destoffset); 9253 TRACE_AND_STEP(); 9254 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9255 store_data_byte(destoffset, destval); 9256 break; 9257 case 1: 9258 DECODE_PRINTF("BYTE PTR "); 9259 destoffset = decode_rm01_address(rl); 9260 DECODE_PRINTF(",CL\n"); 9261 destval = fetch_data_byte(destoffset); 9262 TRACE_AND_STEP(); 9263 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9264 store_data_byte(destoffset, destval); 9265 break; 9266 case 2: 9267 DECODE_PRINTF("BYTE PTR "); 9268 destoffset = decode_rm10_address(rl); 9269 DECODE_PRINTF(",CL\n"); 9270 destval = fetch_data_byte(destoffset); 9271 TRACE_AND_STEP(); 9272 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9273 store_data_byte(destoffset, destval); 9274 break; 9275 case 3: /* register to register */ 9276 destreg = DECODE_RM_BYTE_REGISTER(rl); 9277 DECODE_PRINTF(",CL\n"); 9278 TRACE_AND_STEP(); 9279 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 9280 *destreg = destval; 9281 break; 9282 } 9283 DECODE_CLEAR_SEGOVR(); 9284 END_OF_INSTR(); 9285} 9286 9287/**************************************************************************** 9288REMARKS: 9289Handles opcode 0xd3 9290****************************************************************************/ 9291static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 9292{ 9293 int mod, rl, rh; 9294 uint destoffset; 9295 u8 amt; 9296 9297 /* 9298 * Yet another weirdo special case instruction format. Part of 9299 * the opcode held below in "RH". Doubly nested case would 9300 * result, except that the decoded instruction 9301 */ 9302 START_OF_INSTR(); 9303 FETCH_DECODE_MODRM(mod, rh, rl); 9304#ifdef DEBUG 9305 if (DEBUG_DECODE()) { 9306 /* XXX DECODE_PRINTF may be changed to something more 9307 general, so that it is important to leave the strings 9308 in the same format, even though the result is that the 9309 above test is done twice. */ 9310 switch (rh) { 9311 case 0: 9312 DECODE_PRINTF("ROL\t"); 9313 break; 9314 case 1: 9315 DECODE_PRINTF("ROR\t"); 9316 break; 9317 case 2: 9318 DECODE_PRINTF("RCL\t"); 9319 break; 9320 case 3: 9321 DECODE_PRINTF("RCR\t"); 9322 break; 9323 case 4: 9324 DECODE_PRINTF("SHL\t"); 9325 break; 9326 case 5: 9327 DECODE_PRINTF("SHR\t"); 9328 break; 9329 case 6: 9330 DECODE_PRINTF("SAL\t"); 9331 break; 9332 case 7: 9333 DECODE_PRINTF("SAR\t"); 9334 break; 9335 } 9336 } 9337#endif 9338 /* know operation, decode the mod byte to find the addressing 9339 mode. */ 9340 amt = M.x86.R_CL; 9341 switch (mod) { 9342 case 0: 9343 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9344 u32 destval; 9345 9346 DECODE_PRINTF("DWORD PTR "); 9347 destoffset = decode_rm00_address(rl); 9348 DECODE_PRINTF(",CL\n"); 9349 destval = fetch_data_long(destoffset); 9350 TRACE_AND_STEP(); 9351 destval = (*opcD1_long_operation[rh]) (destval, amt); 9352 store_data_long(destoffset, destval); 9353 } else { 9354 u16 destval; 9355 9356 DECODE_PRINTF("WORD PTR "); 9357 destoffset = decode_rm00_address(rl); 9358 DECODE_PRINTF(",CL\n"); 9359 destval = fetch_data_word(destoffset); 9360 TRACE_AND_STEP(); 9361 destval = (*opcD1_word_operation[rh]) (destval, amt); 9362 store_data_word(destoffset, destval); 9363 } 9364 break; 9365 case 1: 9366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9367 u32 destval; 9368 9369 DECODE_PRINTF("DWORD PTR "); 9370 destoffset = decode_rm01_address(rl); 9371 DECODE_PRINTF(",CL\n"); 9372 destval = fetch_data_long(destoffset); 9373 TRACE_AND_STEP(); 9374 destval = (*opcD1_long_operation[rh]) (destval, amt); 9375 store_data_long(destoffset, destval); 9376 } else { 9377 u16 destval; 9378 9379 DECODE_PRINTF("WORD PTR "); 9380 destoffset = decode_rm01_address(rl); 9381 DECODE_PRINTF(",CL\n"); 9382 destval = fetch_data_word(destoffset); 9383 TRACE_AND_STEP(); 9384 destval = (*opcD1_word_operation[rh]) (destval, amt); 9385 store_data_word(destoffset, destval); 9386 } 9387 break; 9388 case 2: 9389 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9390 u32 destval; 9391 9392 DECODE_PRINTF("DWORD PTR "); 9393 destoffset = decode_rm10_address(rl); 9394 DECODE_PRINTF(",CL\n"); 9395 destval = fetch_data_long(destoffset); 9396 TRACE_AND_STEP(); 9397 destval = (*opcD1_long_operation[rh]) (destval, amt); 9398 store_data_long(destoffset, destval); 9399 } else { 9400 u16 destval; 9401 9402 DECODE_PRINTF("WORD PTR "); 9403 destoffset = decode_rm10_address(rl); 9404 DECODE_PRINTF(",CL\n"); 9405 destval = fetch_data_word(destoffset); 9406 TRACE_AND_STEP(); 9407 destval = (*opcD1_word_operation[rh]) (destval, amt); 9408 store_data_word(destoffset, destval); 9409 } 9410 break; 9411 case 3: /* register to register */ 9412 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9413 u32 *destreg; 9414 9415 destreg = DECODE_RM_LONG_REGISTER(rl); 9416 DECODE_PRINTF(",CL\n"); 9417 TRACE_AND_STEP(); 9418 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 9419 } else { 9420 u16 *destreg; 9421 9422 destreg = DECODE_RM_WORD_REGISTER(rl); 9423 DECODE_PRINTF(",CL\n"); 9424 TRACE_AND_STEP(); 9425 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 9426 } 9427 break; 9428 } 9429 DECODE_CLEAR_SEGOVR(); 9430 END_OF_INSTR(); 9431} 9432 9433/**************************************************************************** 9434REMARKS: 9435Handles opcode 0xd4 9436****************************************************************************/ 9437static void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 9438{ 9439 u8 a; 9440 9441 START_OF_INSTR(); 9442 DECODE_PRINTF("AAM\n"); 9443 a = fetch_byte_imm(); /* this is a stupid encoding. */ 9444 if (a != 10) { 9445 /* fix: add base decoding 9446 aam_word(u8 val, int base a) */ 9447 DECODE_PRINTF("ERROR DECODING AAM\n"); 9448 TRACE_REGS(); 9449 HALT_SYS(); 9450 } 9451 TRACE_AND_STEP(); 9452 /* note the type change here --- returning AL and AH in AX. */ 9453 M.x86.R_AX = aam_word(M.x86.R_AL); 9454 DECODE_CLEAR_SEGOVR(); 9455 END_OF_INSTR(); 9456} 9457 9458/**************************************************************************** 9459REMARKS: 9460Handles opcode 0xd5 9461****************************************************************************/ 9462static void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 9463{ 9464 u8 a; 9465 9466 START_OF_INSTR(); 9467 DECODE_PRINTF("AAD\n"); 9468 a = fetch_byte_imm(); 9469 if (a != 10) { 9470 /* fix: add base decoding 9471 aad_word(u16 val, int base a) */ 9472 DECODE_PRINTF("ERROR DECODING AAM\n"); 9473 TRACE_REGS(); 9474 HALT_SYS(); 9475 } 9476 TRACE_AND_STEP(); 9477 M.x86.R_AX = aad_word(M.x86.R_AX); 9478 DECODE_CLEAR_SEGOVR(); 9479 END_OF_INSTR(); 9480} 9481 9482/* opcode 0xd6 ILLEGAL OPCODE */ 9483 9484/**************************************************************************** 9485REMARKS: 9486Handles opcode 0xd7 9487****************************************************************************/ 9488static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 9489{ 9490 u16 addr; 9491 9492 START_OF_INSTR(); 9493 DECODE_PRINTF("XLAT\n"); 9494 TRACE_AND_STEP(); 9495 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 9496 M.x86.R_AL = fetch_data_byte(addr); 9497 DECODE_CLEAR_SEGOVR(); 9498 END_OF_INSTR(); 9499} 9500 9501/* instuctions D8 .. DF are in i87_ops.c */ 9502 9503/**************************************************************************** 9504REMARKS: 9505Handles opcode 0xe0 9506****************************************************************************/ 9507static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 9508{ 9509 s16 ip; 9510 9511 START_OF_INSTR(); 9512 DECODE_PRINTF("LOOPNE\t"); 9513 ip = (s8) fetch_byte_imm(); 9514 ip += (s16) M.x86.R_IP; 9515 DECODE_PRINTF2("%04x\n", ip); 9516 TRACE_AND_STEP(); 9517 M.x86.R_CX -= 1; 9518 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 9519 M.x86.R_IP = ip; 9520 DECODE_CLEAR_SEGOVR(); 9521 END_OF_INSTR(); 9522} 9523 9524/**************************************************************************** 9525REMARKS: 9526Handles opcode 0xe1 9527****************************************************************************/ 9528static void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 9529{ 9530 s16 ip; 9531 9532 START_OF_INSTR(); 9533 DECODE_PRINTF("LOOPE\t"); 9534 ip = (s8) fetch_byte_imm(); 9535 ip += (s16) M.x86.R_IP; 9536 DECODE_PRINTF2("%04x\n", ip); 9537 TRACE_AND_STEP(); 9538 M.x86.R_CX -= 1; 9539 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 9540 M.x86.R_IP = ip; 9541 DECODE_CLEAR_SEGOVR(); 9542 END_OF_INSTR(); 9543} 9544 9545/**************************************************************************** 9546REMARKS: 9547Handles opcode 0xe2 9548****************************************************************************/ 9549static void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 9550{ 9551 s16 ip; 9552 9553 START_OF_INSTR(); 9554 DECODE_PRINTF("LOOP\t"); 9555 ip = (s8) fetch_byte_imm(); 9556 ip += (s16) M.x86.R_IP; 9557 DECODE_PRINTF2("%04x\n", ip); 9558 TRACE_AND_STEP(); 9559 M.x86.R_CX -= 1; 9560 if (M.x86.R_CX != 0) 9561 M.x86.R_IP = ip; 9562 DECODE_CLEAR_SEGOVR(); 9563 END_OF_INSTR(); 9564} 9565 9566/**************************************************************************** 9567REMARKS: 9568Handles opcode 0xe3 9569****************************************************************************/ 9570static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 9571{ 9572 u16 target; 9573 s8 offset; 9574 9575 /* jump to byte offset if overflow flag is set */ 9576 START_OF_INSTR(); 9577 DECODE_PRINTF("JCXZ\t"); 9578 offset = (s8)fetch_byte_imm(); 9579 target = (u16)(M.x86.R_IP + offset); 9580 DECODE_PRINTF2("%x\n", target); 9581 TRACE_AND_STEP(); 9582 if (M.x86.R_CX == 0) 9583 M.x86.R_IP = target; 9584 DECODE_CLEAR_SEGOVR(); 9585 END_OF_INSTR(); 9586} 9587 9588/**************************************************************************** 9589REMARKS: 9590Handles opcode 0xe4 9591****************************************************************************/ 9592static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 9593{ 9594 u8 port; 9595 9596 START_OF_INSTR(); 9597 DECODE_PRINTF("IN\t"); 9598 port = (u8) fetch_byte_imm(); 9599 DECODE_PRINTF2("%x,AL\n", port); 9600 TRACE_AND_STEP(); 9601 M.x86.R_AL = (*sys_inb)(port); 9602 DECODE_CLEAR_SEGOVR(); 9603 END_OF_INSTR(); 9604} 9605 9606/**************************************************************************** 9607REMARKS: 9608Handles opcode 0xe5 9609****************************************************************************/ 9610static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 9611{ 9612 u8 port; 9613 9614 START_OF_INSTR(); 9615 DECODE_PRINTF("IN\t"); 9616 port = (u8) fetch_byte_imm(); 9617 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9618 DECODE_PRINTF2("EAX,%x\n", port); 9619 } else { 9620 DECODE_PRINTF2("AX,%x\n", port); 9621 } 9622 TRACE_AND_STEP(); 9623 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9624 M.x86.R_EAX = (*sys_inl)(port); 9625 } else { 9626 M.x86.R_AX = (*sys_inw)(port); 9627 } 9628 DECODE_CLEAR_SEGOVR(); 9629 END_OF_INSTR(); 9630} 9631 9632/**************************************************************************** 9633REMARKS: 9634Handles opcode 0xe6 9635****************************************************************************/ 9636static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 9637{ 9638 u8 port; 9639 9640 START_OF_INSTR(); 9641 DECODE_PRINTF("OUT\t"); 9642 port = (u8) fetch_byte_imm(); 9643 DECODE_PRINTF2("%x,AL\n", port); 9644 TRACE_AND_STEP(); 9645 (*sys_outb)(port, M.x86.R_AL); 9646 DECODE_CLEAR_SEGOVR(); 9647 END_OF_INSTR(); 9648} 9649 9650/**************************************************************************** 9651REMARKS: 9652Handles opcode 0xe7 9653****************************************************************************/ 9654static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 9655{ 9656 u8 port; 9657 9658 START_OF_INSTR(); 9659 DECODE_PRINTF("OUT\t"); 9660 port = (u8) fetch_byte_imm(); 9661 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9662 DECODE_PRINTF2("%x,EAX\n", port); 9663 } else { 9664 DECODE_PRINTF2("%x,AX\n", port); 9665 } 9666 TRACE_AND_STEP(); 9667 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9668 (*sys_outl)(port, M.x86.R_EAX); 9669 } else { 9670 (*sys_outw)(port, M.x86.R_AX); 9671 } 9672 DECODE_CLEAR_SEGOVR(); 9673 END_OF_INSTR(); 9674} 9675 9676/**************************************************************************** 9677REMARKS: 9678Handles opcode 0xe8 9679****************************************************************************/ 9680static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 9681{ 9682 s16 ip16; 9683 s32 ip32; 9684 9685 START_OF_INSTR(); 9686 DECODE_PRINTF("CALL\t"); 9687 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9688 ip32 = (s32) fetch_long_imm(); 9689 ip32 += (s16) M.x86.R_IP; /* CHECK SIGN */ 9690 DECODE_PRINTF2("%04x\n", (u16)ip32); 9691 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, ""); 9692 } else { 9693 ip16 = (s16) fetch_word_imm(); 9694 ip16 += (s16) M.x86.R_IP; /* CHECK SIGN */ 9695 DECODE_PRINTF2("%04x\n", (u16)ip16); 9696 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, ""); 9697 } 9698 TRACE_AND_STEP(); 9699 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9700 push_long(M.x86.R_EIP); 9701 M.x86.R_EIP = ip32 & 0xffff; 9702 } else { 9703 push_word(M.x86.R_IP); 9704 M.x86.R_EIP = ip16; 9705 } 9706 DECODE_CLEAR_SEGOVR(); 9707 END_OF_INSTR(); 9708} 9709 9710/**************************************************************************** 9711REMARKS: 9712Handles opcode 0xe9 9713****************************************************************************/ 9714static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 9715{ 9716 u32 ip; 9717 9718 START_OF_INSTR(); 9719 DECODE_PRINTF("JMP\t"); 9720 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9721 ip = (u32)fetch_long_imm(); 9722 ip += (u32)M.x86.R_EIP; 9723 DECODE_PRINTF2("%08x\n", (u32)ip); 9724 TRACE_AND_STEP(); 9725 M.x86.R_EIP = (u32)ip; 9726 } else { 9727 ip = (s16)fetch_word_imm(); 9728 ip += (s16)M.x86.R_IP; 9729 DECODE_PRINTF2("%04x\n", (u16)ip); 9730 TRACE_AND_STEP(); 9731 M.x86.R_IP = (u16)ip; 9732 } 9733 DECODE_CLEAR_SEGOVR(); 9734 END_OF_INSTR(); 9735} 9736 9737/**************************************************************************** 9738REMARKS: 9739Handles opcode 0xea 9740****************************************************************************/ 9741static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 9742{ 9743 u16 cs; 9744 u32 ip; 9745 9746 START_OF_INSTR(); 9747 DECODE_PRINTF("JMP\tFAR "); 9748 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9749 ip = fetch_long_imm(); 9750 } else { 9751 ip = fetch_word_imm(); 9752 } 9753 cs = fetch_word_imm(); 9754 DECODE_PRINTF2("%04x:", cs); 9755 DECODE_PRINTF2("%04x\n", ip); 9756 TRACE_AND_STEP(); 9757 M.x86.R_EIP = ip & 0xffff; 9758 M.x86.R_CS = cs; 9759 DECODE_CLEAR_SEGOVR(); 9760 END_OF_INSTR(); 9761} 9762 9763/**************************************************************************** 9764REMARKS: 9765Handles opcode 0xeb 9766****************************************************************************/ 9767static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 9768{ 9769 u16 target; 9770 s8 offset; 9771 9772 START_OF_INSTR(); 9773 DECODE_PRINTF("JMP\t"); 9774 offset = (s8)fetch_byte_imm(); 9775 target = (u16)(M.x86.R_IP + offset); 9776 DECODE_PRINTF2("%x\n", target); 9777 TRACE_AND_STEP(); 9778 M.x86.R_IP = target; 9779 DECODE_CLEAR_SEGOVR(); 9780 END_OF_INSTR(); 9781} 9782 9783/**************************************************************************** 9784REMARKS: 9785Handles opcode 0xec 9786****************************************************************************/ 9787static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 9788{ 9789 START_OF_INSTR(); 9790 DECODE_PRINTF("IN\tAL,DX\n"); 9791 TRACE_AND_STEP(); 9792 M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 9793 DECODE_CLEAR_SEGOVR(); 9794 END_OF_INSTR(); 9795} 9796 9797/**************************************************************************** 9798REMARKS: 9799Handles opcode 0xed 9800****************************************************************************/ 9801static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 9802{ 9803 START_OF_INSTR(); 9804 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9805 DECODE_PRINTF("IN\tEAX,DX\n"); 9806 } else { 9807 DECODE_PRINTF("IN\tAX,DX\n"); 9808 } 9809 TRACE_AND_STEP(); 9810 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9811 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 9812 } else { 9813 M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 9814 } 9815 DECODE_CLEAR_SEGOVR(); 9816 END_OF_INSTR(); 9817} 9818 9819/**************************************************************************** 9820REMARKS: 9821Handles opcode 0xee 9822****************************************************************************/ 9823static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 9824{ 9825 START_OF_INSTR(); 9826 DECODE_PRINTF("OUT\tDX,AL\n"); 9827 TRACE_AND_STEP(); 9828 (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 9829 DECODE_CLEAR_SEGOVR(); 9830 END_OF_INSTR(); 9831} 9832 9833/**************************************************************************** 9834REMARKS: 9835Handles opcode 0xef 9836****************************************************************************/ 9837static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 9838{ 9839 START_OF_INSTR(); 9840 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9841 DECODE_PRINTF("OUT\tDX,EAX\n"); 9842 } else { 9843 DECODE_PRINTF("OUT\tDX,AX\n"); 9844 } 9845 TRACE_AND_STEP(); 9846 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9847 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 9848 } else { 9849 (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 9850 } 9851 DECODE_CLEAR_SEGOVR(); 9852 END_OF_INSTR(); 9853} 9854 9855/**************************************************************************** 9856REMARKS: 9857Handles opcode 0xf0 9858****************************************************************************/ 9859static void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 9860{ 9861 START_OF_INSTR(); 9862 DECODE_PRINTF("LOCK:\n"); 9863 TRACE_AND_STEP(); 9864 DECODE_CLEAR_SEGOVR(); 9865 END_OF_INSTR(); 9866} 9867 9868/*opcode 0xf1 ILLEGAL OPERATION */ 9869 9870/**************************************************************************** 9871REMARKS: 9872Handles opcode 0xf2 9873****************************************************************************/ 9874static void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 9875{ 9876 START_OF_INSTR(); 9877 DECODE_PRINTF("REPNE\n"); 9878 TRACE_AND_STEP(); 9879 M.x86.mode |= SYSMODE_PREFIX_REPNE; 9880 DECODE_CLEAR_SEGOVR(); 9881 END_OF_INSTR(); 9882} 9883 9884/**************************************************************************** 9885REMARKS: 9886Handles opcode 0xf3 9887****************************************************************************/ 9888static void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 9889{ 9890 START_OF_INSTR(); 9891 DECODE_PRINTF("REPE\n"); 9892 TRACE_AND_STEP(); 9893 M.x86.mode |= SYSMODE_PREFIX_REPE; 9894 DECODE_CLEAR_SEGOVR(); 9895 END_OF_INSTR(); 9896} 9897 9898/**************************************************************************** 9899REMARKS: 9900Handles opcode 0xf4 9901****************************************************************************/ 9902static void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 9903{ 9904 START_OF_INSTR(); 9905 DECODE_PRINTF("HALT\n"); 9906 TRACE_AND_STEP(); 9907 HALT_SYS(); 9908 DECODE_CLEAR_SEGOVR(); 9909 END_OF_INSTR(); 9910} 9911 9912/**************************************************************************** 9913REMARKS: 9914Handles opcode 0xf5 9915****************************************************************************/ 9916static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 9917{ 9918 /* complement the carry flag. */ 9919 START_OF_INSTR(); 9920 DECODE_PRINTF("CMC\n"); 9921 TRACE_AND_STEP(); 9922 TOGGLE_FLAG(F_CF); 9923 DECODE_CLEAR_SEGOVR(); 9924 END_OF_INSTR(); 9925} 9926 9927/**************************************************************************** 9928REMARKS: 9929Handles opcode 0xf6 9930****************************************************************************/ 9931static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 9932{ 9933 int mod, rl, rh; 9934 u8 *destreg; 9935 uint destoffset; 9936 u8 destval, srcval; 9937 9938 /* long, drawn out code follows. Double switch for a total 9939 of 32 cases. */ 9940 START_OF_INSTR(); 9941 FETCH_DECODE_MODRM(mod, rh, rl); 9942 switch (mod) { 9943 case 0: /* mod=00 */ 9944 switch (rh) { 9945 case 0: /* test byte imm */ 9946 DECODE_PRINTF("TEST\tBYTE PTR "); 9947 destoffset = decode_rm00_address(rl); 9948 DECODE_PRINTF(","); 9949 srcval = fetch_byte_imm(); 9950 DECODE_PRINTF2("%02x\n", srcval); 9951 destval = fetch_data_byte(destoffset); 9952 TRACE_AND_STEP(); 9953 test_byte(destval, srcval); 9954 break; 9955 case 1: 9956 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 9957 HALT_SYS(); 9958 break; 9959 case 2: 9960 DECODE_PRINTF("NOT\tBYTE PTR "); 9961 destoffset = decode_rm00_address(rl); 9962 DECODE_PRINTF("\n"); 9963 destval = fetch_data_byte(destoffset); 9964 TRACE_AND_STEP(); 9965 destval = not_byte(destval); 9966 store_data_byte(destoffset, destval); 9967 break; 9968 case 3: 9969 DECODE_PRINTF("NEG\tBYTE PTR "); 9970 destoffset = decode_rm00_address(rl); 9971 DECODE_PRINTF("\n"); 9972 destval = fetch_data_byte(destoffset); 9973 TRACE_AND_STEP(); 9974 destval = neg_byte(destval); 9975 store_data_byte(destoffset, destval); 9976 break; 9977 case 4: 9978 DECODE_PRINTF("MUL\tBYTE PTR "); 9979 destoffset = decode_rm00_address(rl); 9980 DECODE_PRINTF("\n"); 9981 destval = fetch_data_byte(destoffset); 9982 TRACE_AND_STEP(); 9983 mul_byte(destval); 9984 break; 9985 case 5: 9986 DECODE_PRINTF("IMUL\tBYTE PTR "); 9987 destoffset = decode_rm00_address(rl); 9988 DECODE_PRINTF("\n"); 9989 destval = fetch_data_byte(destoffset); 9990 TRACE_AND_STEP(); 9991 imul_byte(destval); 9992 break; 9993 case 6: 9994 DECODE_PRINTF("DIV\tBYTE PTR "); 9995 destoffset = decode_rm00_address(rl); 9996 DECODE_PRINTF("\n"); 9997 destval = fetch_data_byte(destoffset); 9998 TRACE_AND_STEP(); 9999 div_byte(destval); 10000 break; 10001 case 7: 10002 DECODE_PRINTF("IDIV\tBYTE PTR "); 10003 destoffset = decode_rm00_address(rl); 10004 DECODE_PRINTF("\n"); 10005 destval = fetch_data_byte(destoffset); 10006 TRACE_AND_STEP(); 10007 idiv_byte(destval); 10008 break; 10009 } 10010 break; /* end mod==00 */ 10011 case 1: /* mod=01 */ 10012 switch (rh) { 10013 case 0: /* test byte imm */ 10014 DECODE_PRINTF("TEST\tBYTE PTR "); 10015 destoffset = decode_rm01_address(rl); 10016 DECODE_PRINTF(","); 10017 srcval = fetch_byte_imm(); 10018 DECODE_PRINTF2("%02x\n", srcval); 10019 destval = fetch_data_byte(destoffset); 10020 TRACE_AND_STEP(); 10021 test_byte(destval, srcval); 10022 break; 10023 case 1: 10024 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10025 HALT_SYS(); 10026 break; 10027 case 2: 10028 DECODE_PRINTF("NOT\tBYTE PTR "); 10029 destoffset = decode_rm01_address(rl); 10030 DECODE_PRINTF("\n"); 10031 destval = fetch_data_byte(destoffset); 10032 TRACE_AND_STEP(); 10033 destval = not_byte(destval); 10034 store_data_byte(destoffset, destval); 10035 break; 10036 case 3: 10037 DECODE_PRINTF("NEG\tBYTE PTR "); 10038 destoffset = decode_rm01_address(rl); 10039 DECODE_PRINTF("\n"); 10040 destval = fetch_data_byte(destoffset); 10041 TRACE_AND_STEP(); 10042 destval = neg_byte(destval); 10043 store_data_byte(destoffset, destval); 10044 break; 10045 case 4: 10046 DECODE_PRINTF("MUL\tBYTE PTR "); 10047 destoffset = decode_rm01_address(rl); 10048 DECODE_PRINTF("\n"); 10049 destval = fetch_data_byte(destoffset); 10050 TRACE_AND_STEP(); 10051 mul_byte(destval); 10052 break; 10053 case 5: 10054 DECODE_PRINTF("IMUL\tBYTE PTR "); 10055 destoffset = decode_rm01_address(rl); 10056 DECODE_PRINTF("\n"); 10057 destval = fetch_data_byte(destoffset); 10058 TRACE_AND_STEP(); 10059 imul_byte(destval); 10060 break; 10061 case 6: 10062 DECODE_PRINTF("DIV\tBYTE PTR "); 10063 destoffset = decode_rm01_address(rl); 10064 DECODE_PRINTF("\n"); 10065 destval = fetch_data_byte(destoffset); 10066 TRACE_AND_STEP(); 10067 div_byte(destval); 10068 break; 10069 case 7: 10070 DECODE_PRINTF("IDIV\tBYTE PTR "); 10071 destoffset = decode_rm01_address(rl); 10072 DECODE_PRINTF("\n"); 10073 destval = fetch_data_byte(destoffset); 10074 TRACE_AND_STEP(); 10075 idiv_byte(destval); 10076 break; 10077 } 10078 break; /* end mod==01 */ 10079 case 2: /* mod=10 */ 10080 switch (rh) { 10081 case 0: /* test byte imm */ 10082 DECODE_PRINTF("TEST\tBYTE PTR "); 10083 destoffset = decode_rm10_address(rl); 10084 DECODE_PRINTF(","); 10085 srcval = fetch_byte_imm(); 10086 DECODE_PRINTF2("%02x\n", srcval); 10087 destval = fetch_data_byte(destoffset); 10088 TRACE_AND_STEP(); 10089 test_byte(destval, srcval); 10090 break; 10091 case 1: 10092 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10093 HALT_SYS(); 10094 break; 10095 case 2: 10096 DECODE_PRINTF("NOT\tBYTE PTR "); 10097 destoffset = decode_rm10_address(rl); 10098 DECODE_PRINTF("\n"); 10099 destval = fetch_data_byte(destoffset); 10100 TRACE_AND_STEP(); 10101 destval = not_byte(destval); 10102 store_data_byte(destoffset, destval); 10103 break; 10104 case 3: 10105 DECODE_PRINTF("NEG\tBYTE PTR "); 10106 destoffset = decode_rm10_address(rl); 10107 DECODE_PRINTF("\n"); 10108 destval = fetch_data_byte(destoffset); 10109 TRACE_AND_STEP(); 10110 destval = neg_byte(destval); 10111 store_data_byte(destoffset, destval); 10112 break; 10113 case 4: 10114 DECODE_PRINTF("MUL\tBYTE PTR "); 10115 destoffset = decode_rm10_address(rl); 10116 DECODE_PRINTF("\n"); 10117 destval = fetch_data_byte(destoffset); 10118 TRACE_AND_STEP(); 10119 mul_byte(destval); 10120 break; 10121 case 5: 10122 DECODE_PRINTF("IMUL\tBYTE PTR "); 10123 destoffset = decode_rm10_address(rl); 10124 DECODE_PRINTF("\n"); 10125 destval = fetch_data_byte(destoffset); 10126 TRACE_AND_STEP(); 10127 imul_byte(destval); 10128 break; 10129 case 6: 10130 DECODE_PRINTF("DIV\tBYTE PTR "); 10131 destoffset = decode_rm10_address(rl); 10132 DECODE_PRINTF("\n"); 10133 destval = fetch_data_byte(destoffset); 10134 TRACE_AND_STEP(); 10135 div_byte(destval); 10136 break; 10137 case 7: 10138 DECODE_PRINTF("IDIV\tBYTE PTR "); 10139 destoffset = decode_rm10_address(rl); 10140 DECODE_PRINTF("\n"); 10141 destval = fetch_data_byte(destoffset); 10142 TRACE_AND_STEP(); 10143 idiv_byte(destval); 10144 break; 10145 } 10146 break; /* end mod==10 */ 10147 case 3: /* mod=11 */ 10148 switch (rh) { 10149 case 0: /* test byte imm */ 10150 DECODE_PRINTF("TEST\t"); 10151 destreg = DECODE_RM_BYTE_REGISTER(rl); 10152 DECODE_PRINTF(","); 10153 srcval = fetch_byte_imm(); 10154 DECODE_PRINTF2("%02x\n", srcval); 10155 TRACE_AND_STEP(); 10156 test_byte(*destreg, srcval); 10157 break; 10158 case 1: 10159 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10160 HALT_SYS(); 10161 break; 10162 case 2: 10163 DECODE_PRINTF("NOT\t"); 10164 destreg = DECODE_RM_BYTE_REGISTER(rl); 10165 DECODE_PRINTF("\n"); 10166 TRACE_AND_STEP(); 10167 *destreg = not_byte(*destreg); 10168 break; 10169 case 3: 10170 DECODE_PRINTF("NEG\t"); 10171 destreg = DECODE_RM_BYTE_REGISTER(rl); 10172 DECODE_PRINTF("\n"); 10173 TRACE_AND_STEP(); 10174 *destreg = neg_byte(*destreg); 10175 break; 10176 case 4: 10177 DECODE_PRINTF("MUL\t"); 10178 destreg = DECODE_RM_BYTE_REGISTER(rl); 10179 DECODE_PRINTF("\n"); 10180 TRACE_AND_STEP(); 10181 mul_byte(*destreg); /*!!! */ 10182 break; 10183 case 5: 10184 DECODE_PRINTF("IMUL\t"); 10185 destreg = DECODE_RM_BYTE_REGISTER(rl); 10186 DECODE_PRINTF("\n"); 10187 TRACE_AND_STEP(); 10188 imul_byte(*destreg); 10189 break; 10190 case 6: 10191 DECODE_PRINTF("DIV\t"); 10192 destreg = DECODE_RM_BYTE_REGISTER(rl); 10193 DECODE_PRINTF("\n"); 10194 TRACE_AND_STEP(); 10195 div_byte(*destreg); 10196 break; 10197 case 7: 10198 DECODE_PRINTF("IDIV\t"); 10199 destreg = DECODE_RM_BYTE_REGISTER(rl); 10200 DECODE_PRINTF("\n"); 10201 TRACE_AND_STEP(); 10202 idiv_byte(*destreg); 10203 break; 10204 } 10205 break; /* end mod==11 */ 10206 } 10207 DECODE_CLEAR_SEGOVR(); 10208 END_OF_INSTR(); 10209} 10210 10211/**************************************************************************** 10212REMARKS: 10213Handles opcode 0xf7 10214****************************************************************************/ 10215static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 10216{ 10217 int mod, rl, rh; 10218 uint destoffset; 10219 10220 /* long, drawn out code follows. Double switch for a total 10221 of 32 cases. */ 10222 START_OF_INSTR(); 10223 FETCH_DECODE_MODRM(mod, rh, rl); 10224 switch (mod) { 10225 case 0: /* mod=00 */ 10226 switch (rh) { 10227 case 0: /* test word imm */ 10228 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10229 u32 destval,srcval; 10230 10231 DECODE_PRINTF("TEST\tDWORD PTR "); 10232 destoffset = decode_rm00_address(rl); 10233 DECODE_PRINTF(","); 10234 srcval = fetch_long_imm(); 10235 DECODE_PRINTF2("%x\n", srcval); 10236 destval = fetch_data_long(destoffset); 10237 TRACE_AND_STEP(); 10238 test_long(destval, srcval); 10239 } else { 10240 u16 destval,srcval; 10241 10242 DECODE_PRINTF("TEST\tWORD PTR "); 10243 destoffset = decode_rm00_address(rl); 10244 DECODE_PRINTF(","); 10245 srcval = fetch_word_imm(); 10246 DECODE_PRINTF2("%x\n", srcval); 10247 destval = fetch_data_word(destoffset); 10248 TRACE_AND_STEP(); 10249 test_word(destval, srcval); 10250 } 10251 break; 10252 case 1: 10253 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 10254 HALT_SYS(); 10255 break; 10256 case 2: 10257 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10258 u32 destval; 10259 10260 DECODE_PRINTF("NOT\tDWORD PTR "); 10261 destoffset = decode_rm00_address(rl); 10262 DECODE_PRINTF("\n"); 10263 destval = fetch_data_long(destoffset); 10264 TRACE_AND_STEP(); 10265 destval = not_long(destval); 10266 store_data_long(destoffset, destval); 10267 } else { 10268 u16 destval; 10269 10270 DECODE_PRINTF("NOT\tWORD PTR "); 10271 destoffset = decode_rm00_address(rl); 10272 DECODE_PRINTF("\n"); 10273 destval = fetch_data_word(destoffset); 10274 TRACE_AND_STEP(); 10275 destval = not_word(destval); 10276 store_data_word(destoffset, destval); 10277 } 10278 break; 10279 case 3: 10280 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10281 u32 destval; 10282 10283 DECODE_PRINTF("NEG\tDWORD PTR "); 10284 destoffset = decode_rm00_address(rl); 10285 DECODE_PRINTF("\n"); 10286 destval = fetch_data_long(destoffset); 10287 TRACE_AND_STEP(); 10288 destval = neg_long(destval); 10289 store_data_long(destoffset, destval); 10290 } else { 10291 u16 destval; 10292 10293 DECODE_PRINTF("NEG\tWORD PTR "); 10294 destoffset = decode_rm00_address(rl); 10295 DECODE_PRINTF("\n"); 10296 destval = fetch_data_word(destoffset); 10297 TRACE_AND_STEP(); 10298 destval = neg_word(destval); 10299 store_data_word(destoffset, destval); 10300 } 10301 break; 10302 case 4: 10303 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10304 u32 destval; 10305 10306 DECODE_PRINTF("MUL\tDWORD PTR "); 10307 destoffset = decode_rm00_address(rl); 10308 DECODE_PRINTF("\n"); 10309 destval = fetch_data_long(destoffset); 10310 TRACE_AND_STEP(); 10311 mul_long(destval); 10312 } else { 10313 u16 destval; 10314 10315 DECODE_PRINTF("MUL\tWORD PTR "); 10316 destoffset = decode_rm00_address(rl); 10317 DECODE_PRINTF("\n"); 10318 destval = fetch_data_word(destoffset); 10319 TRACE_AND_STEP(); 10320 mul_word(destval); 10321 } 10322 break; 10323 case 5: 10324 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10325 u32 destval; 10326 10327 DECODE_PRINTF("IMUL\tDWORD PTR "); 10328 destoffset = decode_rm00_address(rl); 10329 DECODE_PRINTF("\n"); 10330 destval = fetch_data_long(destoffset); 10331 TRACE_AND_STEP(); 10332 imul_long(destval); 10333 } else { 10334 u16 destval; 10335 10336 DECODE_PRINTF("IMUL\tWORD PTR "); 10337 destoffset = decode_rm00_address(rl); 10338 DECODE_PRINTF("\n"); 10339 destval = fetch_data_word(destoffset); 10340 TRACE_AND_STEP(); 10341 imul_word(destval); 10342 } 10343 break; 10344 case 6: 10345 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10346 u32 destval; 10347 10348 DECODE_PRINTF("DIV\tDWORD PTR "); 10349 destoffset = decode_rm00_address(rl); 10350 DECODE_PRINTF("\n"); 10351 destval = fetch_data_long(destoffset); 10352 TRACE_AND_STEP(); 10353 div_long(destval); 10354 } else { 10355 u16 destval; 10356 10357 DECODE_PRINTF("DIV\tWORD PTR "); 10358 destoffset = decode_rm00_address(rl); 10359 DECODE_PRINTF("\n"); 10360 destval = fetch_data_word(destoffset); 10361 TRACE_AND_STEP(); 10362 div_word(destval); 10363 } 10364 break; 10365 case 7: 10366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10367 u32 destval; 10368 10369 DECODE_PRINTF("IDIV\tDWORD PTR "); 10370 destoffset = decode_rm00_address(rl); 10371 DECODE_PRINTF("\n"); 10372 destval = fetch_data_long(destoffset); 10373 TRACE_AND_STEP(); 10374 idiv_long(destval); 10375 } else { 10376 u16 destval; 10377 10378 DECODE_PRINTF("IDIV\tWORD PTR "); 10379 destoffset = decode_rm00_address(rl); 10380 DECODE_PRINTF("\n"); 10381 destval = fetch_data_word(destoffset); 10382 TRACE_AND_STEP(); 10383 idiv_word(destval); 10384 } 10385 break; 10386 } 10387 break; /* end mod==00 */ 10388 case 1: /* mod=01 */ 10389 switch (rh) { 10390 case 0: /* test word imm */ 10391 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10392 u32 destval,srcval; 10393 10394 DECODE_PRINTF("TEST\tDWORD PTR "); 10395 destoffset = decode_rm01_address(rl); 10396 DECODE_PRINTF(","); 10397 srcval = fetch_long_imm(); 10398 DECODE_PRINTF2("%x\n", srcval); 10399 destval = fetch_data_long(destoffset); 10400 TRACE_AND_STEP(); 10401 test_long(destval, srcval); 10402 } else { 10403 u16 destval,srcval; 10404 10405 DECODE_PRINTF("TEST\tWORD PTR "); 10406 destoffset = decode_rm01_address(rl); 10407 DECODE_PRINTF(","); 10408 srcval = fetch_word_imm(); 10409 DECODE_PRINTF2("%x\n", srcval); 10410 destval = fetch_data_word(destoffset); 10411 TRACE_AND_STEP(); 10412 test_word(destval, srcval); 10413 } 10414 break; 10415 case 1: 10416 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10417 HALT_SYS(); 10418 break; 10419 case 2: 10420 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10421 u32 destval; 10422 10423 DECODE_PRINTF("NOT\tDWORD PTR "); 10424 destoffset = decode_rm01_address(rl); 10425 DECODE_PRINTF("\n"); 10426 destval = fetch_data_long(destoffset); 10427 TRACE_AND_STEP(); 10428 destval = not_long(destval); 10429 store_data_long(destoffset, destval); 10430 } else { 10431 u16 destval; 10432 10433 DECODE_PRINTF("NOT\tWORD PTR "); 10434 destoffset = decode_rm01_address(rl); 10435 DECODE_PRINTF("\n"); 10436 destval = fetch_data_word(destoffset); 10437 TRACE_AND_STEP(); 10438 destval = not_word(destval); 10439 store_data_word(destoffset, destval); 10440 } 10441 break; 10442 case 3: 10443 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10444 u32 destval; 10445 10446 DECODE_PRINTF("NEG\tDWORD PTR "); 10447 destoffset = decode_rm01_address(rl); 10448 DECODE_PRINTF("\n"); 10449 destval = fetch_data_long(destoffset); 10450 TRACE_AND_STEP(); 10451 destval = neg_long(destval); 10452 store_data_long(destoffset, destval); 10453 } else { 10454 u16 destval; 10455 10456 DECODE_PRINTF("NEG\tWORD PTR "); 10457 destoffset = decode_rm01_address(rl); 10458 DECODE_PRINTF("\n"); 10459 destval = fetch_data_word(destoffset); 10460 TRACE_AND_STEP(); 10461 destval = neg_word(destval); 10462 store_data_word(destoffset, destval); 10463 } 10464 break; 10465 case 4: 10466 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10467 u32 destval; 10468 10469 DECODE_PRINTF("MUL\tDWORD PTR "); 10470 destoffset = decode_rm01_address(rl); 10471 DECODE_PRINTF("\n"); 10472 destval = fetch_data_long(destoffset); 10473 TRACE_AND_STEP(); 10474 mul_long(destval); 10475 } else { 10476 u16 destval; 10477 10478 DECODE_PRINTF("MUL\tWORD PTR "); 10479 destoffset = decode_rm01_address(rl); 10480 DECODE_PRINTF("\n"); 10481 destval = fetch_data_word(destoffset); 10482 TRACE_AND_STEP(); 10483 mul_word(destval); 10484 } 10485 break; 10486 case 5: 10487 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10488 u32 destval; 10489 10490 DECODE_PRINTF("IMUL\tDWORD PTR "); 10491 destoffset = decode_rm01_address(rl); 10492 DECODE_PRINTF("\n"); 10493 destval = fetch_data_long(destoffset); 10494 TRACE_AND_STEP(); 10495 imul_long(destval); 10496 } else { 10497 u16 destval; 10498 10499 DECODE_PRINTF("IMUL\tWORD PTR "); 10500 destoffset = decode_rm01_address(rl); 10501 DECODE_PRINTF("\n"); 10502 destval = fetch_data_word(destoffset); 10503 TRACE_AND_STEP(); 10504 imul_word(destval); 10505 } 10506 break; 10507 case 6: 10508 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10509 u32 destval; 10510 10511 DECODE_PRINTF("DIV\tDWORD PTR "); 10512 destoffset = decode_rm01_address(rl); 10513 DECODE_PRINTF("\n"); 10514 destval = fetch_data_long(destoffset); 10515 TRACE_AND_STEP(); 10516 div_long(destval); 10517 } else { 10518 u16 destval; 10519 10520 DECODE_PRINTF("DIV\tWORD PTR "); 10521 destoffset = decode_rm01_address(rl); 10522 DECODE_PRINTF("\n"); 10523 destval = fetch_data_word(destoffset); 10524 TRACE_AND_STEP(); 10525 div_word(destval); 10526 } 10527 break; 10528 case 7: 10529 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10530 u32 destval; 10531 10532 DECODE_PRINTF("IDIV\tDWORD PTR "); 10533 destoffset = decode_rm01_address(rl); 10534 DECODE_PRINTF("\n"); 10535 destval = fetch_data_long(destoffset); 10536 TRACE_AND_STEP(); 10537 idiv_long(destval); 10538 } else { 10539 u16 destval; 10540 10541 DECODE_PRINTF("IDIV\tWORD PTR "); 10542 destoffset = decode_rm01_address(rl); 10543 DECODE_PRINTF("\n"); 10544 destval = fetch_data_word(destoffset); 10545 TRACE_AND_STEP(); 10546 idiv_word(destval); 10547 } 10548 break; 10549 } 10550 break; /* end mod==01 */ 10551 case 2: /* mod=10 */ 10552 switch (rh) { 10553 case 0: /* test word imm */ 10554 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10555 u32 destval,srcval; 10556 10557 DECODE_PRINTF("TEST\tDWORD PTR "); 10558 destoffset = decode_rm10_address(rl); 10559 DECODE_PRINTF(","); 10560 srcval = fetch_long_imm(); 10561 DECODE_PRINTF2("%x\n", srcval); 10562 destval = fetch_data_long(destoffset); 10563 TRACE_AND_STEP(); 10564 test_long(destval, srcval); 10565 } else { 10566 u16 destval,srcval; 10567 10568 DECODE_PRINTF("TEST\tWORD PTR "); 10569 destoffset = decode_rm10_address(rl); 10570 DECODE_PRINTF(","); 10571 srcval = fetch_word_imm(); 10572 DECODE_PRINTF2("%x\n", srcval); 10573 destval = fetch_data_word(destoffset); 10574 TRACE_AND_STEP(); 10575 test_word(destval, srcval); 10576 } 10577 break; 10578 case 1: 10579 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10580 HALT_SYS(); 10581 break; 10582 case 2: 10583 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10584 u32 destval; 10585 10586 DECODE_PRINTF("NOT\tDWORD PTR "); 10587 destoffset = decode_rm10_address(rl); 10588 DECODE_PRINTF("\n"); 10589 destval = fetch_data_long(destoffset); 10590 TRACE_AND_STEP(); 10591 destval = not_long(destval); 10592 store_data_long(destoffset, destval); 10593 } else { 10594 u16 destval; 10595 10596 DECODE_PRINTF("NOT\tWORD PTR "); 10597 destoffset = decode_rm10_address(rl); 10598 DECODE_PRINTF("\n"); 10599 destval = fetch_data_word(destoffset); 10600 TRACE_AND_STEP(); 10601 destval = not_word(destval); 10602 store_data_word(destoffset, destval); 10603 } 10604 break; 10605 case 3: 10606 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10607 u32 destval; 10608 10609 DECODE_PRINTF("NEG\tDWORD PTR "); 10610 destoffset = decode_rm10_address(rl); 10611 DECODE_PRINTF("\n"); 10612 destval = fetch_data_long(destoffset); 10613 TRACE_AND_STEP(); 10614 destval = neg_long(destval); 10615 store_data_long(destoffset, destval); 10616 } else { 10617 u16 destval; 10618 10619 DECODE_PRINTF("NEG\tWORD PTR "); 10620 destoffset = decode_rm10_address(rl); 10621 DECODE_PRINTF("\n"); 10622 destval = fetch_data_word(destoffset); 10623 TRACE_AND_STEP(); 10624 destval = neg_word(destval); 10625 store_data_word(destoffset, destval); 10626 } 10627 break; 10628 case 4: 10629 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10630 u32 destval; 10631 10632 DECODE_PRINTF("MUL\tDWORD PTR "); 10633 destoffset = decode_rm10_address(rl); 10634 DECODE_PRINTF("\n"); 10635 destval = fetch_data_long(destoffset); 10636 TRACE_AND_STEP(); 10637 mul_long(destval); 10638 } else { 10639 u16 destval; 10640 10641 DECODE_PRINTF("MUL\tWORD PTR "); 10642 destoffset = decode_rm10_address(rl); 10643 DECODE_PRINTF("\n"); 10644 destval = fetch_data_word(destoffset); 10645 TRACE_AND_STEP(); 10646 mul_word(destval); 10647 } 10648 break; 10649 case 5: 10650 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10651 u32 destval; 10652 10653 DECODE_PRINTF("IMUL\tDWORD PTR "); 10654 destoffset = decode_rm10_address(rl); 10655 DECODE_PRINTF("\n"); 10656 destval = fetch_data_long(destoffset); 10657 TRACE_AND_STEP(); 10658 imul_long(destval); 10659 } else { 10660 u16 destval; 10661 10662 DECODE_PRINTF("IMUL\tWORD PTR "); 10663 destoffset = decode_rm10_address(rl); 10664 DECODE_PRINTF("\n"); 10665 destval = fetch_data_word(destoffset); 10666 TRACE_AND_STEP(); 10667 imul_word(destval); 10668 } 10669 break; 10670 case 6: 10671 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10672 u32 destval; 10673 10674 DECODE_PRINTF("DIV\tDWORD PTR "); 10675 destoffset = decode_rm10_address(rl); 10676 DECODE_PRINTF("\n"); 10677 destval = fetch_data_long(destoffset); 10678 TRACE_AND_STEP(); 10679 div_long(destval); 10680 } else { 10681 u16 destval; 10682 10683 DECODE_PRINTF("DIV\tWORD PTR "); 10684 destoffset = decode_rm10_address(rl); 10685 DECODE_PRINTF("\n"); 10686 destval = fetch_data_word(destoffset); 10687 TRACE_AND_STEP(); 10688 div_word(destval); 10689 } 10690 break; 10691 case 7: 10692 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10693 u32 destval; 10694 10695 DECODE_PRINTF("IDIV\tDWORD PTR "); 10696 destoffset = decode_rm10_address(rl); 10697 DECODE_PRINTF("\n"); 10698 destval = fetch_data_long(destoffset); 10699 TRACE_AND_STEP(); 10700 idiv_long(destval); 10701 } else { 10702 u16 destval; 10703 10704 DECODE_PRINTF("IDIV\tWORD PTR "); 10705 destoffset = decode_rm10_address(rl); 10706 DECODE_PRINTF("\n"); 10707 destval = fetch_data_word(destoffset); 10708 TRACE_AND_STEP(); 10709 idiv_word(destval); 10710 } 10711 break; 10712 } 10713 break; /* end mod==10 */ 10714 case 3: /* mod=11 */ 10715 switch (rh) { 10716 case 0: /* test word imm */ 10717 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10718 u32 *destreg; 10719 u32 srcval; 10720 10721 DECODE_PRINTF("TEST\t"); 10722 destreg = DECODE_RM_LONG_REGISTER(rl); 10723 DECODE_PRINTF(","); 10724 srcval = fetch_long_imm(); 10725 DECODE_PRINTF2("%x\n", srcval); 10726 TRACE_AND_STEP(); 10727 test_long(*destreg, srcval); 10728 } else { 10729 u16 *destreg; 10730 u16 srcval; 10731 10732 DECODE_PRINTF("TEST\t"); 10733 destreg = DECODE_RM_WORD_REGISTER(rl); 10734 DECODE_PRINTF(","); 10735 srcval = fetch_word_imm(); 10736 DECODE_PRINTF2("%x\n", srcval); 10737 TRACE_AND_STEP(); 10738 test_word(*destreg, srcval); 10739 } 10740 break; 10741 case 1: 10742 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10743 HALT_SYS(); 10744 break; 10745 case 2: 10746 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10747 u32 *destreg; 10748 10749 DECODE_PRINTF("NOT\t"); 10750 destreg = DECODE_RM_LONG_REGISTER(rl); 10751 DECODE_PRINTF("\n"); 10752 TRACE_AND_STEP(); 10753 *destreg = not_long(*destreg); 10754 } else { 10755 u16 *destreg; 10756 10757 DECODE_PRINTF("NOT\t"); 10758 destreg = DECODE_RM_WORD_REGISTER(rl); 10759 DECODE_PRINTF("\n"); 10760 TRACE_AND_STEP(); 10761 *destreg = not_word(*destreg); 10762 } 10763 break; 10764 case 3: 10765 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10766 u32 *destreg; 10767 10768 DECODE_PRINTF("NEG\t"); 10769 destreg = DECODE_RM_LONG_REGISTER(rl); 10770 DECODE_PRINTF("\n"); 10771 TRACE_AND_STEP(); 10772 *destreg = neg_long(*destreg); 10773 } else { 10774 u16 *destreg; 10775 10776 DECODE_PRINTF("NEG\t"); 10777 destreg = DECODE_RM_WORD_REGISTER(rl); 10778 DECODE_PRINTF("\n"); 10779 TRACE_AND_STEP(); 10780 *destreg = neg_word(*destreg); 10781 } 10782 break; 10783 case 4: 10784 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10785 u32 *destreg; 10786 10787 DECODE_PRINTF("MUL\t"); 10788 destreg = DECODE_RM_LONG_REGISTER(rl); 10789 DECODE_PRINTF("\n"); 10790 TRACE_AND_STEP(); 10791 mul_long(*destreg); /*!!! */ 10792 } else { 10793 u16 *destreg; 10794 10795 DECODE_PRINTF("MUL\t"); 10796 destreg = DECODE_RM_WORD_REGISTER(rl); 10797 DECODE_PRINTF("\n"); 10798 TRACE_AND_STEP(); 10799 mul_word(*destreg); /*!!! */ 10800 } 10801 break; 10802 case 5: 10803 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10804 u32 *destreg; 10805 10806 DECODE_PRINTF("IMUL\t"); 10807 destreg = DECODE_RM_LONG_REGISTER(rl); 10808 DECODE_PRINTF("\n"); 10809 TRACE_AND_STEP(); 10810 imul_long(*destreg); 10811 } else { 10812 u16 *destreg; 10813 10814 DECODE_PRINTF("IMUL\t"); 10815 destreg = DECODE_RM_WORD_REGISTER(rl); 10816 DECODE_PRINTF("\n"); 10817 TRACE_AND_STEP(); 10818 imul_word(*destreg); 10819 } 10820 break; 10821 case 6: 10822 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10823 u32 *destreg; 10824 10825 DECODE_PRINTF("DIV\t"); 10826 destreg = DECODE_RM_LONG_REGISTER(rl); 10827 DECODE_PRINTF("\n"); 10828 TRACE_AND_STEP(); 10829 div_long(*destreg); 10830 } else { 10831 u16 *destreg; 10832 10833 DECODE_PRINTF("DIV\t"); 10834 destreg = DECODE_RM_WORD_REGISTER(rl); 10835 DECODE_PRINTF("\n"); 10836 TRACE_AND_STEP(); 10837 div_word(*destreg); 10838 } 10839 break; 10840 case 7: 10841 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10842 u32 *destreg; 10843 10844 DECODE_PRINTF("IDIV\t"); 10845 destreg = DECODE_RM_LONG_REGISTER(rl); 10846 DECODE_PRINTF("\n"); 10847 TRACE_AND_STEP(); 10848 idiv_long(*destreg); 10849 } else { 10850 u16 *destreg; 10851 10852 DECODE_PRINTF("IDIV\t"); 10853 destreg = DECODE_RM_WORD_REGISTER(rl); 10854 DECODE_PRINTF("\n"); 10855 TRACE_AND_STEP(); 10856 idiv_word(*destreg); 10857 } 10858 break; 10859 } 10860 break; /* end mod==11 */ 10861 } 10862 DECODE_CLEAR_SEGOVR(); 10863 END_OF_INSTR(); 10864} 10865 10866/**************************************************************************** 10867REMARKS: 10868Handles opcode 0xf8 10869****************************************************************************/ 10870static void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 10871{ 10872 /* clear the carry flag. */ 10873 START_OF_INSTR(); 10874 DECODE_PRINTF("CLC\n"); 10875 TRACE_AND_STEP(); 10876 CLEAR_FLAG(F_CF); 10877 DECODE_CLEAR_SEGOVR(); 10878 END_OF_INSTR(); 10879} 10880 10881/**************************************************************************** 10882REMARKS: 10883Handles opcode 0xf9 10884****************************************************************************/ 10885static void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 10886{ 10887 /* set the carry flag. */ 10888 START_OF_INSTR(); 10889 DECODE_PRINTF("STC\n"); 10890 TRACE_AND_STEP(); 10891 SET_FLAG(F_CF); 10892 DECODE_CLEAR_SEGOVR(); 10893 END_OF_INSTR(); 10894} 10895 10896/**************************************************************************** 10897REMARKS: 10898Handles opcode 0xfa 10899****************************************************************************/ 10900static void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 10901{ 10902 /* clear interrupts. */ 10903 START_OF_INSTR(); 10904 DECODE_PRINTF("CLI\n"); 10905 TRACE_AND_STEP(); 10906 CLEAR_FLAG(F_IF); 10907 DECODE_CLEAR_SEGOVR(); 10908 END_OF_INSTR(); 10909} 10910 10911/**************************************************************************** 10912REMARKS: 10913Handles opcode 0xfb 10914****************************************************************************/ 10915static void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 10916{ 10917 /* enable interrupts. */ 10918 START_OF_INSTR(); 10919 DECODE_PRINTF("STI\n"); 10920 TRACE_AND_STEP(); 10921 SET_FLAG(F_IF); 10922 DECODE_CLEAR_SEGOVR(); 10923 END_OF_INSTR(); 10924} 10925 10926/**************************************************************************** 10927REMARKS: 10928Handles opcode 0xfc 10929****************************************************************************/ 10930static void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 10931{ 10932 /* clear interrupts. */ 10933 START_OF_INSTR(); 10934 DECODE_PRINTF("CLD\n"); 10935 TRACE_AND_STEP(); 10936 CLEAR_FLAG(F_DF); 10937 DECODE_CLEAR_SEGOVR(); 10938 END_OF_INSTR(); 10939} 10940 10941/**************************************************************************** 10942REMARKS: 10943Handles opcode 0xfd 10944****************************************************************************/ 10945static void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 10946{ 10947 /* clear interrupts. */ 10948 START_OF_INSTR(); 10949 DECODE_PRINTF("STD\n"); 10950 TRACE_AND_STEP(); 10951 SET_FLAG(F_DF); 10952 DECODE_CLEAR_SEGOVR(); 10953 END_OF_INSTR(); 10954} 10955 10956/**************************************************************************** 10957REMARKS: 10958Handles opcode 0xfe 10959****************************************************************************/ 10960static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 10961{ 10962 int mod, rh, rl; 10963 u8 destval; 10964 uint destoffset; 10965 u8 *destreg; 10966 10967 /* Yet another special case instruction. */ 10968 START_OF_INSTR(); 10969 FETCH_DECODE_MODRM(mod, rh, rl); 10970#ifdef DEBUG 10971 if (DEBUG_DECODE()) { 10972 /* XXX DECODE_PRINTF may be changed to something more 10973 general, so that it is important to leave the strings 10974 in the same format, even though the result is that the 10975 above test is done twice. */ 10976 10977 switch (rh) { 10978 case 0: 10979 DECODE_PRINTF("INC\t"); 10980 break; 10981 case 1: 10982 DECODE_PRINTF("DEC\t"); 10983 break; 10984 case 2: 10985 case 3: 10986 case 4: 10987 case 5: 10988 case 6: 10989 case 7: 10990 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 10991 HALT_SYS(); 10992 break; 10993 } 10994 } 10995#endif 10996 switch (mod) { 10997 case 0: 10998 DECODE_PRINTF("BYTE PTR "); 10999 destoffset = decode_rm00_address(rl); 11000 DECODE_PRINTF("\n"); 11001 switch (rh) { 11002 case 0: /* inc word ptr ... */ 11003 destval = fetch_data_byte(destoffset); 11004 TRACE_AND_STEP(); 11005 destval = inc_byte(destval); 11006 store_data_byte(destoffset, destval); 11007 break; 11008 case 1: /* dec word ptr ... */ 11009 destval = fetch_data_byte(destoffset); 11010 TRACE_AND_STEP(); 11011 destval = dec_byte(destval); 11012 store_data_byte(destoffset, destval); 11013 break; 11014 } 11015 break; 11016 case 1: 11017 DECODE_PRINTF("BYTE PTR "); 11018 destoffset = decode_rm01_address(rl); 11019 DECODE_PRINTF("\n"); 11020 switch (rh) { 11021 case 0: 11022 destval = fetch_data_byte(destoffset); 11023 TRACE_AND_STEP(); 11024 destval = inc_byte(destval); 11025 store_data_byte(destoffset, destval); 11026 break; 11027 case 1: 11028 destval = fetch_data_byte(destoffset); 11029 TRACE_AND_STEP(); 11030 destval = dec_byte(destval); 11031 store_data_byte(destoffset, destval); 11032 break; 11033 } 11034 break; 11035 case 2: 11036 DECODE_PRINTF("BYTE PTR "); 11037 destoffset = decode_rm10_address(rl); 11038 DECODE_PRINTF("\n"); 11039 switch (rh) { 11040 case 0: 11041 destval = fetch_data_byte(destoffset); 11042 TRACE_AND_STEP(); 11043 destval = inc_byte(destval); 11044 store_data_byte(destoffset, destval); 11045 break; 11046 case 1: 11047 destval = fetch_data_byte(destoffset); 11048 TRACE_AND_STEP(); 11049 destval = dec_byte(destval); 11050 store_data_byte(destoffset, destval); 11051 break; 11052 } 11053 break; 11054 case 3: 11055 destreg = DECODE_RM_BYTE_REGISTER(rl); 11056 DECODE_PRINTF("\n"); 11057 switch (rh) { 11058 case 0: 11059 TRACE_AND_STEP(); 11060 *destreg = inc_byte(*destreg); 11061 break; 11062 case 1: 11063 TRACE_AND_STEP(); 11064 *destreg = dec_byte(*destreg); 11065 break; 11066 } 11067 break; 11068 } 11069 DECODE_CLEAR_SEGOVR(); 11070 END_OF_INSTR(); 11071} 11072 11073/**************************************************************************** 11074REMARKS: 11075Handles opcode 0xff 11076****************************************************************************/ 11077static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 11078{ 11079 int mod, rh, rl; 11080 uint destoffset = 0; 11081 u16 *destreg; 11082 u16 destval,destval2; 11083 11084 /* Yet another special case instruction. */ 11085 START_OF_INSTR(); 11086 FETCH_DECODE_MODRM(mod, rh, rl); 11087#ifdef DEBUG 11088 if (DEBUG_DECODE()) { 11089 /* XXX DECODE_PRINTF may be changed to something more 11090 general, so that it is important to leave the strings 11091 in the same format, even though the result is that the 11092 above test is done twice. */ 11093 11094 switch (rh) { 11095 case 0: 11096 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11097 DECODE_PRINTF("INC\tDWORD PTR "); 11098 } else { 11099 DECODE_PRINTF("INC\tWORD PTR "); 11100 } 11101 break; 11102 case 1: 11103 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11104 DECODE_PRINTF("DEC\tDWORD PTR "); 11105 } else { 11106 DECODE_PRINTF("DEC\tWORD PTR "); 11107 } 11108 break; 11109 case 2: 11110 DECODE_PRINTF("CALL\t"); 11111 break; 11112 case 3: 11113 DECODE_PRINTF("CALL\tFAR "); 11114 break; 11115 case 4: 11116 DECODE_PRINTF("JMP\t"); 11117 break; 11118 case 5: 11119 DECODE_PRINTF("JMP\tFAR "); 11120 break; 11121 case 6: 11122 DECODE_PRINTF("PUSH\t"); 11123 break; 11124 case 7: 11125 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 11126 HALT_SYS(); 11127 break; 11128 } 11129 } 11130#endif 11131 switch (mod) { 11132 case 0: 11133 destoffset = decode_rm00_address(rl); 11134 DECODE_PRINTF("\n"); 11135 switch (rh) { 11136 case 0: /* inc word ptr ... */ 11137 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11138 u32 destval; 11139 11140 destval = fetch_data_long(destoffset); 11141 TRACE_AND_STEP(); 11142 destval = inc_long(destval); 11143 store_data_long(destoffset, destval); 11144 } else { 11145 u16 destval; 11146 11147 destval = fetch_data_word(destoffset); 11148 TRACE_AND_STEP(); 11149 destval = inc_word(destval); 11150 store_data_word(destoffset, destval); 11151 } 11152 break; 11153 case 1: /* dec word ptr ... */ 11154 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11155 u32 destval; 11156 11157 destval = fetch_data_long(destoffset); 11158 TRACE_AND_STEP(); 11159 destval = dec_long(destval); 11160 store_data_long(destoffset, destval); 11161 } else { 11162 u16 destval; 11163 11164 destval = fetch_data_word(destoffset); 11165 TRACE_AND_STEP(); 11166 destval = dec_word(destval); 11167 store_data_word(destoffset, destval); 11168 } 11169 break; 11170 case 2: /* call word ptr ... */ 11171 destval = fetch_data_word(destoffset); 11172 TRACE_AND_STEP(); 11173 push_word(M.x86.R_IP); 11174 M.x86.R_IP = destval; 11175 break; 11176 case 3: /* call far ptr ... */ 11177 destval = fetch_data_word(destoffset); 11178 destval2 = fetch_data_word(destoffset + 2); 11179 TRACE_AND_STEP(); 11180 push_word(M.x86.R_CS); 11181 M.x86.R_CS = destval2; 11182 push_word(M.x86.R_IP); 11183 M.x86.R_IP = destval; 11184 break; 11185 case 4: /* jmp word ptr ... */ 11186 destval = fetch_data_word(destoffset); 11187 TRACE_AND_STEP(); 11188 M.x86.R_IP = destval; 11189 break; 11190 case 5: /* jmp far ptr ... */ 11191 destval = fetch_data_word(destoffset); 11192 destval2 = fetch_data_word(destoffset + 2); 11193 TRACE_AND_STEP(); 11194 M.x86.R_IP = destval; 11195 M.x86.R_CS = destval2; 11196 break; 11197 case 6: /* push word ptr ... */ 11198 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11199 u32 destval; 11200 11201 destval = fetch_data_long(destoffset); 11202 TRACE_AND_STEP(); 11203 push_long(destval); 11204 } else { 11205 u16 destval; 11206 11207 destval = fetch_data_word(destoffset); 11208 TRACE_AND_STEP(); 11209 push_word(destval); 11210 } 11211 break; 11212 } 11213 break; 11214 case 1: 11215 destoffset = decode_rm01_address(rl); 11216 DECODE_PRINTF("\n"); 11217 switch (rh) { 11218 case 0: 11219 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11220 u32 destval; 11221 11222 destval = fetch_data_long(destoffset); 11223 TRACE_AND_STEP(); 11224 destval = inc_long(destval); 11225 store_data_long(destoffset, destval); 11226 } else { 11227 u16 destval; 11228 11229 destval = fetch_data_word(destoffset); 11230 TRACE_AND_STEP(); 11231 destval = inc_word(destval); 11232 store_data_word(destoffset, destval); 11233 } 11234 break; 11235 case 1: 11236 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11237 u32 destval; 11238 11239 destval = fetch_data_long(destoffset); 11240 TRACE_AND_STEP(); 11241 destval = dec_long(destval); 11242 store_data_long(destoffset, destval); 11243 } else { 11244 u16 destval; 11245 11246 destval = fetch_data_word(destoffset); 11247 TRACE_AND_STEP(); 11248 destval = dec_word(destval); 11249 store_data_word(destoffset, destval); 11250 } 11251 break; 11252 case 2: /* call word ptr ... */ 11253 destval = fetch_data_word(destoffset); 11254 TRACE_AND_STEP(); 11255 push_word(M.x86.R_IP); 11256 M.x86.R_IP = destval; 11257 break; 11258 case 3: /* call far ptr ... */ 11259 destval = fetch_data_word(destoffset); 11260 destval2 = fetch_data_word(destoffset + 2); 11261 TRACE_AND_STEP(); 11262 push_word(M.x86.R_CS); 11263 M.x86.R_CS = destval2; 11264 push_word(M.x86.R_IP); 11265 M.x86.R_IP = destval; 11266 break; 11267 case 4: /* jmp word ptr ... */ 11268 destval = fetch_data_word(destoffset); 11269 TRACE_AND_STEP(); 11270 M.x86.R_IP = destval; 11271 break; 11272 case 5: /* jmp far ptr ... */ 11273 destval = fetch_data_word(destoffset); 11274 destval2 = fetch_data_word(destoffset + 2); 11275 TRACE_AND_STEP(); 11276 M.x86.R_IP = destval; 11277 M.x86.R_CS = destval2; 11278 break; 11279 case 6: /* push word ptr ... */ 11280 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11281 u32 destval; 11282 11283 destval = fetch_data_long(destoffset); 11284 TRACE_AND_STEP(); 11285 push_long(destval); 11286 } else { 11287 u16 destval; 11288 11289 destval = fetch_data_word(destoffset); 11290 TRACE_AND_STEP(); 11291 push_word(destval); 11292 } 11293 break; 11294 } 11295 break; 11296 case 2: 11297 destoffset = decode_rm10_address(rl); 11298 DECODE_PRINTF("\n"); 11299 switch (rh) { 11300 case 0: 11301 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11302 u32 destval; 11303 11304 destval = fetch_data_long(destoffset); 11305 TRACE_AND_STEP(); 11306 destval = inc_long(destval); 11307 store_data_long(destoffset, destval); 11308 } else { 11309 u16 destval; 11310 11311 destval = fetch_data_word(destoffset); 11312 TRACE_AND_STEP(); 11313 destval = inc_word(destval); 11314 store_data_word(destoffset, destval); 11315 } 11316 break; 11317 case 1: 11318 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11319 u32 destval; 11320 11321 destval = fetch_data_long(destoffset); 11322 TRACE_AND_STEP(); 11323 destval = dec_long(destval); 11324 store_data_long(destoffset, destval); 11325 } else { 11326 u16 destval; 11327 11328 destval = fetch_data_word(destoffset); 11329 TRACE_AND_STEP(); 11330 destval = dec_word(destval); 11331 store_data_word(destoffset, destval); 11332 } 11333 break; 11334 case 2: /* call word ptr ... */ 11335 destval = fetch_data_word(destoffset); 11336 TRACE_AND_STEP(); 11337 push_word(M.x86.R_IP); 11338 M.x86.R_IP = destval; 11339 break; 11340 case 3: /* call far ptr ... */ 11341 destval = fetch_data_word(destoffset); 11342 destval2 = fetch_data_word(destoffset + 2); 11343 TRACE_AND_STEP(); 11344 push_word(M.x86.R_CS); 11345 M.x86.R_CS = destval2; 11346 push_word(M.x86.R_IP); 11347 M.x86.R_IP = destval; 11348 break; 11349 case 4: /* jmp word ptr ... */ 11350 destval = fetch_data_word(destoffset); 11351 TRACE_AND_STEP(); 11352 M.x86.R_IP = destval; 11353 break; 11354 case 5: /* jmp far ptr ... */ 11355 destval = fetch_data_word(destoffset); 11356 destval2 = fetch_data_word(destoffset + 2); 11357 TRACE_AND_STEP(); 11358 M.x86.R_IP = destval; 11359 M.x86.R_CS = destval2; 11360 break; 11361 case 6: /* push word ptr ... */ 11362 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11363 u32 destval; 11364 11365 destval = fetch_data_long(destoffset); 11366 TRACE_AND_STEP(); 11367 push_long(destval); 11368 } else { 11369 u16 destval; 11370 11371 destval = fetch_data_word(destoffset); 11372 TRACE_AND_STEP(); 11373 push_word(destval); 11374 } 11375 break; 11376 } 11377 break; 11378 case 3: 11379 switch (rh) { 11380 case 0: 11381 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11382 u32 *destreg; 11383 11384 destreg = DECODE_RM_LONG_REGISTER(rl); 11385 DECODE_PRINTF("\n"); 11386 TRACE_AND_STEP(); 11387 *destreg = inc_long(*destreg); 11388 } else { 11389 u16 *destreg; 11390 11391 destreg = DECODE_RM_WORD_REGISTER(rl); 11392 DECODE_PRINTF("\n"); 11393 TRACE_AND_STEP(); 11394 *destreg = inc_word(*destreg); 11395 } 11396 break; 11397 case 1: 11398 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11399 u32 *destreg; 11400 11401 destreg = DECODE_RM_LONG_REGISTER(rl); 11402 DECODE_PRINTF("\n"); 11403 TRACE_AND_STEP(); 11404 *destreg = dec_long(*destreg); 11405 } else { 11406 u16 *destreg; 11407 11408 destreg = DECODE_RM_WORD_REGISTER(rl); 11409 DECODE_PRINTF("\n"); 11410 TRACE_AND_STEP(); 11411 *destreg = dec_word(*destreg); 11412 } 11413 break; 11414 case 2: /* call word ptr ... */ 11415 destreg = DECODE_RM_WORD_REGISTER(rl); 11416 DECODE_PRINTF("\n"); 11417 TRACE_AND_STEP(); 11418 push_word(M.x86.R_IP); 11419 M.x86.R_IP = *destreg; 11420 break; 11421 case 3: /* jmp far ptr ... */ 11422 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11423 TRACE_AND_STEP(); 11424 HALT_SYS(); 11425 break; 11426 11427 case 4: /* jmp ... */ 11428 destreg = DECODE_RM_WORD_REGISTER(rl); 11429 DECODE_PRINTF("\n"); 11430 TRACE_AND_STEP(); 11431 M.x86.R_IP = (u16) (*destreg); 11432 break; 11433 case 5: /* jmp far ptr ... */ 11434 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11435 TRACE_AND_STEP(); 11436 HALT_SYS(); 11437 break; 11438 case 6: 11439 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11440 u32 *destreg; 11441 11442 destreg = DECODE_RM_LONG_REGISTER(rl); 11443 DECODE_PRINTF("\n"); 11444 TRACE_AND_STEP(); 11445 push_long(*destreg); 11446 } else { 11447 u16 *destreg; 11448 11449 destreg = DECODE_RM_WORD_REGISTER(rl); 11450 DECODE_PRINTF("\n"); 11451 TRACE_AND_STEP(); 11452 push_word(*destreg); 11453 } 11454 break; 11455 } 11456 break; 11457 } 11458 DECODE_CLEAR_SEGOVR(); 11459 END_OF_INSTR(); 11460} 11461 11462/*************************************************************************** 11463 * Single byte operation code table: 11464 **************************************************************************/ 11465void (*x86emu_optab[256])(u8) = 11466{ 11467/* 0x00 */ x86emuOp_add_byte_RM_R, 11468/* 0x01 */ x86emuOp_add_word_RM_R, 11469/* 0x02 */ x86emuOp_add_byte_R_RM, 11470/* 0x03 */ x86emuOp_add_word_R_RM, 11471/* 0x04 */ x86emuOp_add_byte_AL_IMM, 11472/* 0x05 */ x86emuOp_add_word_AX_IMM, 11473/* 0x06 */ x86emuOp_push_ES, 11474/* 0x07 */ x86emuOp_pop_ES, 11475 11476/* 0x08 */ x86emuOp_or_byte_RM_R, 11477/* 0x09 */ x86emuOp_or_word_RM_R, 11478/* 0x0a */ x86emuOp_or_byte_R_RM, 11479/* 0x0b */ x86emuOp_or_word_R_RM, 11480/* 0x0c */ x86emuOp_or_byte_AL_IMM, 11481/* 0x0d */ x86emuOp_or_word_AX_IMM, 11482/* 0x0e */ x86emuOp_push_CS, 11483/* 0x0f */ x86emuOp_two_byte, 11484 11485/* 0x10 */ x86emuOp_adc_byte_RM_R, 11486/* 0x11 */ x86emuOp_adc_word_RM_R, 11487/* 0x12 */ x86emuOp_adc_byte_R_RM, 11488/* 0x13 */ x86emuOp_adc_word_R_RM, 11489/* 0x14 */ x86emuOp_adc_byte_AL_IMM, 11490/* 0x15 */ x86emuOp_adc_word_AX_IMM, 11491/* 0x16 */ x86emuOp_push_SS, 11492/* 0x17 */ x86emuOp_pop_SS, 11493 11494/* 0x18 */ x86emuOp_sbb_byte_RM_R, 11495/* 0x19 */ x86emuOp_sbb_word_RM_R, 11496/* 0x1a */ x86emuOp_sbb_byte_R_RM, 11497/* 0x1b */ x86emuOp_sbb_word_R_RM, 11498/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, 11499/* 0x1d */ x86emuOp_sbb_word_AX_IMM, 11500/* 0x1e */ x86emuOp_push_DS, 11501/* 0x1f */ x86emuOp_pop_DS, 11502 11503/* 0x20 */ x86emuOp_and_byte_RM_R, 11504/* 0x21 */ x86emuOp_and_word_RM_R, 11505/* 0x22 */ x86emuOp_and_byte_R_RM, 11506/* 0x23 */ x86emuOp_and_word_R_RM, 11507/* 0x24 */ x86emuOp_and_byte_AL_IMM, 11508/* 0x25 */ x86emuOp_and_word_AX_IMM, 11509/* 0x26 */ x86emuOp_segovr_ES, 11510/* 0x27 */ x86emuOp_daa, 11511 11512/* 0x28 */ x86emuOp_sub_byte_RM_R, 11513/* 0x29 */ x86emuOp_sub_word_RM_R, 11514/* 0x2a */ x86emuOp_sub_byte_R_RM, 11515/* 0x2b */ x86emuOp_sub_word_R_RM, 11516/* 0x2c */ x86emuOp_sub_byte_AL_IMM, 11517/* 0x2d */ x86emuOp_sub_word_AX_IMM, 11518/* 0x2e */ x86emuOp_segovr_CS, 11519/* 0x2f */ x86emuOp_das, 11520 11521/* 0x30 */ x86emuOp_xor_byte_RM_R, 11522/* 0x31 */ x86emuOp_xor_word_RM_R, 11523/* 0x32 */ x86emuOp_xor_byte_R_RM, 11524/* 0x33 */ x86emuOp_xor_word_R_RM, 11525/* 0x34 */ x86emuOp_xor_byte_AL_IMM, 11526/* 0x35 */ x86emuOp_xor_word_AX_IMM, 11527/* 0x36 */ x86emuOp_segovr_SS, 11528/* 0x37 */ x86emuOp_aaa, 11529 11530/* 0x38 */ x86emuOp_cmp_byte_RM_R, 11531/* 0x39 */ x86emuOp_cmp_word_RM_R, 11532/* 0x3a */ x86emuOp_cmp_byte_R_RM, 11533/* 0x3b */ x86emuOp_cmp_word_R_RM, 11534/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, 11535/* 0x3d */ x86emuOp_cmp_word_AX_IMM, 11536/* 0x3e */ x86emuOp_segovr_DS, 11537/* 0x3f */ x86emuOp_aas, 11538 11539/* 0x40 */ x86emuOp_inc_AX, 11540/* 0x41 */ x86emuOp_inc_CX, 11541/* 0x42 */ x86emuOp_inc_DX, 11542/* 0x43 */ x86emuOp_inc_BX, 11543/* 0x44 */ x86emuOp_inc_SP, 11544/* 0x45 */ x86emuOp_inc_BP, 11545/* 0x46 */ x86emuOp_inc_SI, 11546/* 0x47 */ x86emuOp_inc_DI, 11547 11548/* 0x48 */ x86emuOp_dec_AX, 11549/* 0x49 */ x86emuOp_dec_CX, 11550/* 0x4a */ x86emuOp_dec_DX, 11551/* 0x4b */ x86emuOp_dec_BX, 11552/* 0x4c */ x86emuOp_dec_SP, 11553/* 0x4d */ x86emuOp_dec_BP, 11554/* 0x4e */ x86emuOp_dec_SI, 11555/* 0x4f */ x86emuOp_dec_DI, 11556 11557/* 0x50 */ x86emuOp_push_AX, 11558/* 0x51 */ x86emuOp_push_CX, 11559/* 0x52 */ x86emuOp_push_DX, 11560/* 0x53 */ x86emuOp_push_BX, 11561/* 0x54 */ x86emuOp_push_SP, 11562/* 0x55 */ x86emuOp_push_BP, 11563/* 0x56 */ x86emuOp_push_SI, 11564/* 0x57 */ x86emuOp_push_DI, 11565 11566/* 0x58 */ x86emuOp_pop_AX, 11567/* 0x59 */ x86emuOp_pop_CX, 11568/* 0x5a */ x86emuOp_pop_DX, 11569/* 0x5b */ x86emuOp_pop_BX, 11570/* 0x5c */ x86emuOp_pop_SP, 11571/* 0x5d */ x86emuOp_pop_BP, 11572/* 0x5e */ x86emuOp_pop_SI, 11573/* 0x5f */ x86emuOp_pop_DI, 11574 11575/* 0x60 */ x86emuOp_push_all, 11576/* 0x61 */ x86emuOp_pop_all, 11577/* 0x62 */ x86emuOp_illegal_op, /* bound */ 11578/* 0x63 */ x86emuOp_illegal_op, /* arpl */ 11579/* 0x64 */ x86emuOp_segovr_FS, 11580/* 0x65 */ x86emuOp_segovr_GS, 11581/* 0x66 */ x86emuOp_prefix_data, 11582/* 0x67 */ x86emuOp_prefix_addr, 11583 11584/* 0x68 */ x86emuOp_push_word_IMM, 11585/* 0x69 */ x86emuOp_imul_word_IMM, 11586/* 0x6a */ x86emuOp_push_byte_IMM, 11587/* 0x6b */ x86emuOp_imul_byte_IMM, 11588/* 0x6c */ x86emuOp_ins_byte, 11589/* 0x6d */ x86emuOp_ins_word, 11590/* 0x6e */ x86emuOp_outs_byte, 11591/* 0x6f */ x86emuOp_outs_word, 11592 11593/* 0x70 */ x86emuOp_jump_near_O, 11594/* 0x71 */ x86emuOp_jump_near_NO, 11595/* 0x72 */ x86emuOp_jump_near_B, 11596/* 0x73 */ x86emuOp_jump_near_NB, 11597/* 0x74 */ x86emuOp_jump_near_Z, 11598/* 0x75 */ x86emuOp_jump_near_NZ, 11599/* 0x76 */ x86emuOp_jump_near_BE, 11600/* 0x77 */ x86emuOp_jump_near_NBE, 11601 11602/* 0x78 */ x86emuOp_jump_near_S, 11603/* 0x79 */ x86emuOp_jump_near_NS, 11604/* 0x7a */ x86emuOp_jump_near_P, 11605/* 0x7b */ x86emuOp_jump_near_NP, 11606/* 0x7c */ x86emuOp_jump_near_L, 11607/* 0x7d */ x86emuOp_jump_near_NL, 11608/* 0x7e */ x86emuOp_jump_near_LE, 11609/* 0x7f */ x86emuOp_jump_near_NLE, 11610 11611/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 11612/* 0x81 */ x86emuOp_opc81_word_RM_IMM, 11613/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 11614/* 0x83 */ x86emuOp_opc83_word_RM_IMM, 11615/* 0x84 */ x86emuOp_test_byte_RM_R, 11616/* 0x85 */ x86emuOp_test_word_RM_R, 11617/* 0x86 */ x86emuOp_xchg_byte_RM_R, 11618/* 0x87 */ x86emuOp_xchg_word_RM_R, 11619 11620/* 0x88 */ x86emuOp_mov_byte_RM_R, 11621/* 0x89 */ x86emuOp_mov_word_RM_R, 11622/* 0x8a */ x86emuOp_mov_byte_R_RM, 11623/* 0x8b */ x86emuOp_mov_word_R_RM, 11624/* 0x8c */ x86emuOp_mov_word_RM_SR, 11625/* 0x8d */ x86emuOp_lea_word_R_M, 11626/* 0x8e */ x86emuOp_mov_word_SR_RM, 11627/* 0x8f */ x86emuOp_pop_RM, 11628 11629/* 0x90 */ x86emuOp_nop, 11630/* 0x91 */ x86emuOp_xchg_word_AX_CX, 11631/* 0x92 */ x86emuOp_xchg_word_AX_DX, 11632/* 0x93 */ x86emuOp_xchg_word_AX_BX, 11633/* 0x94 */ x86emuOp_xchg_word_AX_SP, 11634/* 0x95 */ x86emuOp_xchg_word_AX_BP, 11635/* 0x96 */ x86emuOp_xchg_word_AX_SI, 11636/* 0x97 */ x86emuOp_xchg_word_AX_DI, 11637 11638/* 0x98 */ x86emuOp_cbw, 11639/* 0x99 */ x86emuOp_cwd, 11640/* 0x9a */ x86emuOp_call_far_IMM, 11641/* 0x9b */ x86emuOp_wait, 11642/* 0x9c */ x86emuOp_pushf_word, 11643/* 0x9d */ x86emuOp_popf_word, 11644/* 0x9e */ x86emuOp_sahf, 11645/* 0x9f */ x86emuOp_lahf, 11646 11647/* 0xa0 */ x86emuOp_mov_AL_M_IMM, 11648/* 0xa1 */ x86emuOp_mov_AX_M_IMM, 11649/* 0xa2 */ x86emuOp_mov_M_AL_IMM, 11650/* 0xa3 */ x86emuOp_mov_M_AX_IMM, 11651/* 0xa4 */ x86emuOp_movs_byte, 11652/* 0xa5 */ x86emuOp_movs_word, 11653/* 0xa6 */ x86emuOp_cmps_byte, 11654/* 0xa7 */ x86emuOp_cmps_word, 11655/* 0xa8 */ x86emuOp_test_AL_IMM, 11656/* 0xa9 */ x86emuOp_test_AX_IMM, 11657/* 0xaa */ x86emuOp_stos_byte, 11658/* 0xab */ x86emuOp_stos_word, 11659/* 0xac */ x86emuOp_lods_byte, 11660/* 0xad */ x86emuOp_lods_word, 11661/* 0xac */ x86emuOp_scas_byte, 11662/* 0xad */ x86emuOp_scas_word, 11663 11664 11665/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, 11666/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, 11667/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, 11668/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, 11669/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, 11670/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, 11671/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, 11672/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, 11673 11674/* 0xb8 */ x86emuOp_mov_word_AX_IMM, 11675/* 0xb9 */ x86emuOp_mov_word_CX_IMM, 11676/* 0xba */ x86emuOp_mov_word_DX_IMM, 11677/* 0xbb */ x86emuOp_mov_word_BX_IMM, 11678/* 0xbc */ x86emuOp_mov_word_SP_IMM, 11679/* 0xbd */ x86emuOp_mov_word_BP_IMM, 11680/* 0xbe */ x86emuOp_mov_word_SI_IMM, 11681/* 0xbf */ x86emuOp_mov_word_DI_IMM, 11682 11683/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 11684/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 11685/* 0xc2 */ x86emuOp_ret_near_IMM, 11686/* 0xc3 */ x86emuOp_ret_near, 11687/* 0xc4 */ x86emuOp_les_R_IMM, 11688/* 0xc5 */ x86emuOp_lds_R_IMM, 11689/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 11690/* 0xc7 */ x86emuOp_mov_word_RM_IMM, 11691/* 0xc8 */ x86emuOp_enter, 11692/* 0xc9 */ x86emuOp_leave, 11693/* 0xca */ x86emuOp_ret_far_IMM, 11694/* 0xcb */ x86emuOp_ret_far, 11695/* 0xcc */ x86emuOp_int3, 11696/* 0xcd */ x86emuOp_int_IMM, 11697/* 0xce */ x86emuOp_into, 11698/* 0xcf */ x86emuOp_iret, 11699 11700/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 11701/* 0xd1 */ x86emuOp_opcD1_word_RM_1, 11702/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 11703/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 11704/* 0xd4 */ x86emuOp_aam, 11705/* 0xd5 */ x86emuOp_aad, 11706/* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 11707/* 0xd7 */ x86emuOp_xlat, 11708/* 0xd8 */ x86emuOp_esc_coprocess_d8, 11709/* 0xd9 */ x86emuOp_esc_coprocess_d9, 11710/* 0xda */ x86emuOp_esc_coprocess_da, 11711/* 0xdb */ x86emuOp_esc_coprocess_db, 11712/* 0xdc */ x86emuOp_esc_coprocess_dc, 11713/* 0xdd */ x86emuOp_esc_coprocess_dd, 11714/* 0xde */ x86emuOp_esc_coprocess_de, 11715/* 0xdf */ x86emuOp_esc_coprocess_df, 11716 11717/* 0xe0 */ x86emuOp_loopne, 11718/* 0xe1 */ x86emuOp_loope, 11719/* 0xe2 */ x86emuOp_loop, 11720/* 0xe3 */ x86emuOp_jcxz, 11721/* 0xe4 */ x86emuOp_in_byte_AL_IMM, 11722/* 0xe5 */ x86emuOp_in_word_AX_IMM, 11723/* 0xe6 */ x86emuOp_out_byte_IMM_AL, 11724/* 0xe7 */ x86emuOp_out_word_IMM_AX, 11725 11726/* 0xe8 */ x86emuOp_call_near_IMM, 11727/* 0xe9 */ x86emuOp_jump_near_IMM, 11728/* 0xea */ x86emuOp_jump_far_IMM, 11729/* 0xeb */ x86emuOp_jump_byte_IMM, 11730/* 0xec */ x86emuOp_in_byte_AL_DX, 11731/* 0xed */ x86emuOp_in_word_AX_DX, 11732/* 0xee */ x86emuOp_out_byte_DX_AL, 11733/* 0xef */ x86emuOp_out_word_DX_AX, 11734 11735/* 0xf0 */ x86emuOp_lock, 11736/* 0xf1 */ x86emuOp_illegal_op, 11737/* 0xf2 */ x86emuOp_repne, 11738/* 0xf3 */ x86emuOp_repe, 11739/* 0xf4 */ x86emuOp_halt, 11740/* 0xf5 */ x86emuOp_cmc, 11741/* 0xf6 */ x86emuOp_opcF6_byte_RM, 11742/* 0xf7 */ x86emuOp_opcF7_word_RM, 11743 11744/* 0xf8 */ x86emuOp_clc, 11745/* 0xf9 */ x86emuOp_stc, 11746/* 0xfa */ x86emuOp_cli, 11747/* 0xfb */ x86emuOp_sti, 11748/* 0xfc */ x86emuOp_cld, 11749/* 0xfd */ x86emuOp_std, 11750/* 0xfe */ x86emuOp_opcFE_byte_RM, 11751/* 0xff */ x86emuOp_opcFF_word_RM, 11752}; 11753