ops.c revision 6747b715
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 u16 farseg, faroff; 7069 7070 START_OF_INSTR(); 7071 DECODE_PRINTF("CALL\t"); 7072 faroff = fetch_word_imm(); 7073 farseg = fetch_word_imm(); 7074 DECODE_PRINTF2("%04x:", farseg); 7075 DECODE_PRINTF2("%04x\n", faroff); 7076 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 7077 7078 /* XXX 7079 * 7080 * Hooked interrupt vectors calling into our "BIOS" will cause 7081 * problems unless all intersegment stuff is checked for BIOS 7082 * access. Check needed here. For moment, let it alone. 7083 */ 7084 TRACE_AND_STEP(); 7085 push_word(M.x86.R_CS); 7086 M.x86.R_CS = farseg; 7087 push_word(M.x86.R_IP); 7088 M.x86.R_IP = faroff; 7089 DECODE_CLEAR_SEGOVR(); 7090 END_OF_INSTR(); 7091} 7092 7093/**************************************************************************** 7094REMARKS: 7095Handles opcode 0x9b 7096****************************************************************************/ 7097static void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 7098{ 7099 START_OF_INSTR(); 7100 DECODE_PRINTF("WAIT"); 7101 TRACE_AND_STEP(); 7102 /* NADA. */ 7103 DECODE_CLEAR_SEGOVR(); 7104 END_OF_INSTR(); 7105} 7106 7107/**************************************************************************** 7108REMARKS: 7109Handles opcode 0x9c 7110****************************************************************************/ 7111static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 7112{ 7113 u32 flags; 7114 7115 START_OF_INSTR(); 7116 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7117 DECODE_PRINTF("PUSHFD\n"); 7118 } else { 7119 DECODE_PRINTF("PUSHF\n"); 7120 } 7121 TRACE_AND_STEP(); 7122 7123 /* clear out *all* bits not representing flags, and turn on real bits */ 7124 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 7125 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7126 push_long(flags); 7127 } else { 7128 push_word((u16)flags); 7129 } 7130 DECODE_CLEAR_SEGOVR(); 7131 END_OF_INSTR(); 7132} 7133 7134/**************************************************************************** 7135REMARKS: 7136Handles opcode 0x9d 7137****************************************************************************/ 7138static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 7139{ 7140 START_OF_INSTR(); 7141 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7142 DECODE_PRINTF("POPFD\n"); 7143 } else { 7144 DECODE_PRINTF("POPF\n"); 7145 } 7146 TRACE_AND_STEP(); 7147 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7148 M.x86.R_EFLG = pop_long(); 7149 } else { 7150 M.x86.R_FLG = pop_word(); 7151 } 7152 DECODE_CLEAR_SEGOVR(); 7153 END_OF_INSTR(); 7154} 7155 7156/**************************************************************************** 7157REMARKS: 7158Handles opcode 0x9e 7159****************************************************************************/ 7160static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 7161{ 7162 START_OF_INSTR(); 7163 DECODE_PRINTF("SAHF\n"); 7164 TRACE_AND_STEP(); 7165 /* clear the lower bits of the flag register */ 7166 M.x86.R_FLG &= 0xffffff00; 7167 /* or in the AH register into the flags register */ 7168 M.x86.R_FLG |= M.x86.R_AH; 7169 DECODE_CLEAR_SEGOVR(); 7170 END_OF_INSTR(); 7171} 7172 7173/**************************************************************************** 7174REMARKS: 7175Handles opcode 0x9f 7176****************************************************************************/ 7177static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 7178{ 7179 START_OF_INSTR(); 7180 DECODE_PRINTF("LAHF\n"); 7181 TRACE_AND_STEP(); 7182 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 7183 /*undocumented TC++ behavior??? Nope. It's documented, but 7184 you have too look real hard to notice it. */ 7185 M.x86.R_AH |= 0x2; 7186 DECODE_CLEAR_SEGOVR(); 7187 END_OF_INSTR(); 7188} 7189 7190/**************************************************************************** 7191REMARKS: 7192Handles opcode 0xa0 7193****************************************************************************/ 7194static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 7195{ 7196 u16 offset; 7197 7198 START_OF_INSTR(); 7199 DECODE_PRINTF("MOV\tAL,"); 7200 offset = fetch_word_imm(); 7201 DECODE_PRINTF2("[%04x]\n", offset); 7202 TRACE_AND_STEP(); 7203 M.x86.R_AL = fetch_data_byte(offset); 7204 DECODE_CLEAR_SEGOVR(); 7205 END_OF_INSTR(); 7206} 7207 7208/**************************************************************************** 7209REMARKS: 7210Handles opcode 0xa1 7211****************************************************************************/ 7212static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 7213{ 7214 u16 offset; 7215 7216 START_OF_INSTR(); 7217 offset = fetch_word_imm(); 7218 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7219 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 7220 } else { 7221 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 7222 } 7223 TRACE_AND_STEP(); 7224 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7225 M.x86.R_EAX = fetch_data_long(offset); 7226 } else { 7227 M.x86.R_AX = fetch_data_word(offset); 7228 } 7229 DECODE_CLEAR_SEGOVR(); 7230 END_OF_INSTR(); 7231} 7232 7233/**************************************************************************** 7234REMARKS: 7235Handles opcode 0xa2 7236****************************************************************************/ 7237static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 7238{ 7239 u16 offset; 7240 7241 START_OF_INSTR(); 7242 DECODE_PRINTF("MOV\t"); 7243 offset = fetch_word_imm(); 7244 DECODE_PRINTF2("[%04x],AL\n", offset); 7245 TRACE_AND_STEP(); 7246 store_data_byte(offset, M.x86.R_AL); 7247 DECODE_CLEAR_SEGOVR(); 7248 END_OF_INSTR(); 7249} 7250 7251/**************************************************************************** 7252REMARKS: 7253Handles opcode 0xa3 7254****************************************************************************/ 7255static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 7256{ 7257 u16 offset; 7258 7259 START_OF_INSTR(); 7260 offset = fetch_word_imm(); 7261 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7262 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 7263 } else { 7264 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 7265 } 7266 TRACE_AND_STEP(); 7267 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7268 store_data_long(offset, M.x86.R_EAX); 7269 } else { 7270 store_data_word(offset, M.x86.R_AX); 7271 } 7272 DECODE_CLEAR_SEGOVR(); 7273 END_OF_INSTR(); 7274} 7275 7276/**************************************************************************** 7277REMARKS: 7278Handles opcode 0xa4 7279****************************************************************************/ 7280static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 7281{ 7282 u8 val; 7283 u32 count; 7284 int inc; 7285 7286 START_OF_INSTR(); 7287 DECODE_PRINTF("MOVS\tBYTE\n"); 7288 if (ACCESS_FLAG(F_DF)) /* down */ 7289 inc = -1; 7290 else 7291 inc = 1; 7292 TRACE_AND_STEP(); 7293 count = 1; 7294 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7295 /* dont care whether REPE or REPNE */ 7296 /* move them until CX is ZERO. */ 7297 count = M.x86.R_CX; 7298 M.x86.R_CX = 0; 7299 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7300 } 7301 while (count--) { 7302 val = fetch_data_byte(M.x86.R_SI); 7303 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 7304 M.x86.R_SI += inc; 7305 M.x86.R_DI += inc; 7306 } 7307 DECODE_CLEAR_SEGOVR(); 7308 END_OF_INSTR(); 7309} 7310 7311/**************************************************************************** 7312REMARKS: 7313Handles opcode 0xa5 7314****************************************************************************/ 7315static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 7316{ 7317 u32 val; 7318 int inc; 7319 u32 count; 7320 7321 START_OF_INSTR(); 7322 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7323 DECODE_PRINTF("MOVS\tDWORD\n"); 7324 if (ACCESS_FLAG(F_DF)) /* down */ 7325 inc = -4; 7326 else 7327 inc = 4; 7328 } else { 7329 DECODE_PRINTF("MOVS\tWORD\n"); 7330 if (ACCESS_FLAG(F_DF)) /* down */ 7331 inc = -2; 7332 else 7333 inc = 2; 7334 } 7335 TRACE_AND_STEP(); 7336 count = 1; 7337 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7338 /* dont care whether REPE or REPNE */ 7339 /* move them until CX is ZERO. */ 7340 count = M.x86.R_CX; 7341 M.x86.R_CX = 0; 7342 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7343 } 7344 while (count--) { 7345 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7346 val = fetch_data_long(M.x86.R_SI); 7347 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 7348 } else { 7349 val = fetch_data_word(M.x86.R_SI); 7350 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 7351 } 7352 M.x86.R_SI += inc; 7353 M.x86.R_DI += inc; 7354 } 7355 DECODE_CLEAR_SEGOVR(); 7356 END_OF_INSTR(); 7357} 7358 7359/**************************************************************************** 7360REMARKS: 7361Handles opcode 0xa6 7362****************************************************************************/ 7363static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 7364{ 7365 s8 val1, val2; 7366 int inc; 7367 7368 START_OF_INSTR(); 7369 DECODE_PRINTF("CMPS\tBYTE\n"); 7370 TRACE_AND_STEP(); 7371 if (ACCESS_FLAG(F_DF)) /* down */ 7372 inc = -1; 7373 else 7374 inc = 1; 7375 7376 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7377 /* REPE */ 7378 /* move them until CX is ZERO. */ 7379 while (M.x86.R_CX != 0) { 7380 val1 = fetch_data_byte(M.x86.R_SI); 7381 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7382 cmp_byte(val1, val2); 7383 M.x86.R_CX -= 1; 7384 M.x86.R_SI += inc; 7385 M.x86.R_DI += inc; 7386 if (ACCESS_FLAG(F_ZF) == 0) 7387 break; 7388 } 7389 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7390 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7391 /* REPNE */ 7392 /* move them until CX is ZERO. */ 7393 while (M.x86.R_CX != 0) { 7394 val1 = fetch_data_byte(M.x86.R_SI); 7395 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7396 cmp_byte(val1, val2); 7397 M.x86.R_CX -= 1; 7398 M.x86.R_SI += inc; 7399 M.x86.R_DI += inc; 7400 if (ACCESS_FLAG(F_ZF)) 7401 break; /* zero flag set means equal */ 7402 } 7403 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7404 } else { 7405 val1 = fetch_data_byte(M.x86.R_SI); 7406 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7407 cmp_byte(val1, val2); 7408 M.x86.R_SI += inc; 7409 M.x86.R_DI += inc; 7410 } 7411 DECODE_CLEAR_SEGOVR(); 7412 END_OF_INSTR(); 7413} 7414 7415/**************************************************************************** 7416REMARKS: 7417Handles opcode 0xa7 7418****************************************************************************/ 7419static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 7420{ 7421 u32 val1,val2; 7422 int inc; 7423 7424 START_OF_INSTR(); 7425 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7426 DECODE_PRINTF("CMPS\tDWORD\n"); 7427 if (ACCESS_FLAG(F_DF)) /* down */ 7428 inc = -4; 7429 else 7430 inc = 4; 7431 } else { 7432 DECODE_PRINTF("CMPS\tWORD\n"); 7433 if (ACCESS_FLAG(F_DF)) /* down */ 7434 inc = -2; 7435 else 7436 inc = 2; 7437 } 7438 TRACE_AND_STEP(); 7439 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7440 /* REPE */ 7441 /* move them until CX is ZERO. */ 7442 while (M.x86.R_CX != 0) { 7443 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7444 val1 = fetch_data_long(M.x86.R_SI); 7445 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7446 cmp_long(val1, val2); 7447 } else { 7448 val1 = fetch_data_word(M.x86.R_SI); 7449 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7450 cmp_word((u16)val1, (u16)val2); 7451 } 7452 M.x86.R_CX -= 1; 7453 M.x86.R_SI += inc; 7454 M.x86.R_DI += inc; 7455 if (ACCESS_FLAG(F_ZF) == 0) 7456 break; 7457 } 7458 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7459 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7460 /* REPNE */ 7461 /* move them until CX is ZERO. */ 7462 while (M.x86.R_CX != 0) { 7463 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7464 val1 = fetch_data_long(M.x86.R_SI); 7465 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7466 cmp_long(val1, val2); 7467 } else { 7468 val1 = fetch_data_word(M.x86.R_SI); 7469 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7470 cmp_word((u16)val1, (u16)val2); 7471 } 7472 M.x86.R_CX -= 1; 7473 M.x86.R_SI += inc; 7474 M.x86.R_DI += inc; 7475 if (ACCESS_FLAG(F_ZF)) 7476 break; /* zero flag set means equal */ 7477 } 7478 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7479 } else { 7480 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7481 val1 = fetch_data_long(M.x86.R_SI); 7482 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7483 cmp_long(val1, val2); 7484 } else { 7485 val1 = fetch_data_word(M.x86.R_SI); 7486 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7487 cmp_word((u16)val1, (u16)val2); 7488 } 7489 M.x86.R_SI += inc; 7490 M.x86.R_DI += inc; 7491 } 7492 DECODE_CLEAR_SEGOVR(); 7493 END_OF_INSTR(); 7494} 7495 7496/**************************************************************************** 7497REMARKS: 7498Handles opcode 0xa8 7499****************************************************************************/ 7500static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 7501{ 7502 int imm; 7503 7504 START_OF_INSTR(); 7505 DECODE_PRINTF("TEST\tAL,"); 7506 imm = fetch_byte_imm(); 7507 DECODE_PRINTF2("%04x\n", imm); 7508 TRACE_AND_STEP(); 7509 test_byte(M.x86.R_AL, (u8)imm); 7510 DECODE_CLEAR_SEGOVR(); 7511 END_OF_INSTR(); 7512} 7513 7514/**************************************************************************** 7515REMARKS: 7516Handles opcode 0xa9 7517****************************************************************************/ 7518static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 7519{ 7520 u32 srcval; 7521 7522 START_OF_INSTR(); 7523 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7524 DECODE_PRINTF("TEST\tEAX,"); 7525 srcval = fetch_long_imm(); 7526 } else { 7527 DECODE_PRINTF("TEST\tAX,"); 7528 srcval = fetch_word_imm(); 7529 } 7530 DECODE_PRINTF2("%x\n", srcval); 7531 TRACE_AND_STEP(); 7532 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7533 test_long(M.x86.R_EAX, srcval); 7534 } else { 7535 test_word(M.x86.R_AX, (u16)srcval); 7536 } 7537 DECODE_CLEAR_SEGOVR(); 7538 END_OF_INSTR(); 7539} 7540 7541/**************************************************************************** 7542REMARKS: 7543Handles opcode 0xaa 7544****************************************************************************/ 7545static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 7546{ 7547 int inc; 7548 7549 START_OF_INSTR(); 7550 DECODE_PRINTF("STOS\tBYTE\n"); 7551 if (ACCESS_FLAG(F_DF)) /* down */ 7552 inc = -1; 7553 else 7554 inc = 1; 7555 TRACE_AND_STEP(); 7556 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7557 /* dont care whether REPE or REPNE */ 7558 /* move them until CX is ZERO. */ 7559 while (M.x86.R_CX != 0) { 7560 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7561 M.x86.R_CX -= 1; 7562 M.x86.R_DI += inc; 7563 } 7564 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7565 } else { 7566 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7567 M.x86.R_DI += inc; 7568 } 7569 DECODE_CLEAR_SEGOVR(); 7570 END_OF_INSTR(); 7571} 7572 7573/**************************************************************************** 7574REMARKS: 7575Handles opcode 0xab 7576****************************************************************************/ 7577static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 7578{ 7579 int inc; 7580 u32 count; 7581 7582 START_OF_INSTR(); 7583 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7584 DECODE_PRINTF("STOS\tDWORD\n"); 7585 if (ACCESS_FLAG(F_DF)) /* down */ 7586 inc = -4; 7587 else 7588 inc = 4; 7589 } else { 7590 DECODE_PRINTF("STOS\tWORD\n"); 7591 if (ACCESS_FLAG(F_DF)) /* down */ 7592 inc = -2; 7593 else 7594 inc = 2; 7595 } 7596 TRACE_AND_STEP(); 7597 count = 1; 7598 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7599 /* dont care whether REPE or REPNE */ 7600 /* move them until CX is ZERO. */ 7601 count = M.x86.R_CX; 7602 M.x86.R_CX = 0; 7603 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7604 } 7605 while (count--) { 7606 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7607 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 7608 } else { 7609 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 7610 } 7611 M.x86.R_DI += inc; 7612 } 7613 DECODE_CLEAR_SEGOVR(); 7614 END_OF_INSTR(); 7615} 7616 7617/**************************************************************************** 7618REMARKS: 7619Handles opcode 0xac 7620****************************************************************************/ 7621static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 7622{ 7623 int inc; 7624 7625 START_OF_INSTR(); 7626 DECODE_PRINTF("LODS\tBYTE\n"); 7627 TRACE_AND_STEP(); 7628 if (ACCESS_FLAG(F_DF)) /* down */ 7629 inc = -1; 7630 else 7631 inc = 1; 7632 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7633 /* dont care whether REPE or REPNE */ 7634 /* move them until CX is ZERO. */ 7635 while (M.x86.R_CX != 0) { 7636 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7637 M.x86.R_CX -= 1; 7638 M.x86.R_SI += inc; 7639 } 7640 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7641 } else { 7642 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7643 M.x86.R_SI += inc; 7644 } 7645 DECODE_CLEAR_SEGOVR(); 7646 END_OF_INSTR(); 7647} 7648 7649/**************************************************************************** 7650REMARKS: 7651Handles opcode 0xad 7652****************************************************************************/ 7653static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 7654{ 7655 int inc; 7656 u32 count; 7657 7658 START_OF_INSTR(); 7659 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7660 DECODE_PRINTF("LODS\tDWORD\n"); 7661 if (ACCESS_FLAG(F_DF)) /* down */ 7662 inc = -4; 7663 else 7664 inc = 4; 7665 } else { 7666 DECODE_PRINTF("LODS\tWORD\n"); 7667 if (ACCESS_FLAG(F_DF)) /* down */ 7668 inc = -2; 7669 else 7670 inc = 2; 7671 } 7672 TRACE_AND_STEP(); 7673 count = 1; 7674 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7675 /* dont care whether REPE or REPNE */ 7676 /* move them until CX is ZERO. */ 7677 count = M.x86.R_CX; 7678 M.x86.R_CX = 0; 7679 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7680 } 7681 while (count--) { 7682 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7683 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 7684 } else { 7685 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 7686 } 7687 M.x86.R_SI += inc; 7688 } 7689 DECODE_CLEAR_SEGOVR(); 7690 END_OF_INSTR(); 7691} 7692 7693/**************************************************************************** 7694REMARKS: 7695Handles opcode 0xae 7696****************************************************************************/ 7697static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 7698{ 7699 s8 val2; 7700 int inc; 7701 7702 START_OF_INSTR(); 7703 DECODE_PRINTF("SCAS\tBYTE\n"); 7704 TRACE_AND_STEP(); 7705 if (ACCESS_FLAG(F_DF)) /* down */ 7706 inc = -1; 7707 else 7708 inc = 1; 7709 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7710 /* REPE */ 7711 /* move them until CX is ZERO. */ 7712 while (M.x86.R_CX != 0) { 7713 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7714 cmp_byte(M.x86.R_AL, val2); 7715 M.x86.R_CX -= 1; 7716 M.x86.R_DI += inc; 7717 if (ACCESS_FLAG(F_ZF) == 0) 7718 break; 7719 } 7720 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7721 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7722 /* REPNE */ 7723 /* move them until CX is ZERO. */ 7724 while (M.x86.R_CX != 0) { 7725 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7726 cmp_byte(M.x86.R_AL, val2); 7727 M.x86.R_CX -= 1; 7728 M.x86.R_DI += inc; 7729 if (ACCESS_FLAG(F_ZF)) 7730 break; /* zero flag set means equal */ 7731 } 7732 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7733 } else { 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_DI += inc; 7737 } 7738 DECODE_CLEAR_SEGOVR(); 7739 END_OF_INSTR(); 7740} 7741 7742/**************************************************************************** 7743REMARKS: 7744Handles opcode 0xaf 7745****************************************************************************/ 7746static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 7747{ 7748 int inc; 7749 u32 val; 7750 7751 START_OF_INSTR(); 7752 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7753 DECODE_PRINTF("SCAS\tDWORD\n"); 7754 if (ACCESS_FLAG(F_DF)) /* down */ 7755 inc = -4; 7756 else 7757 inc = 4; 7758 } else { 7759 DECODE_PRINTF("SCAS\tWORD\n"); 7760 if (ACCESS_FLAG(F_DF)) /* down */ 7761 inc = -2; 7762 else 7763 inc = 2; 7764 } 7765 TRACE_AND_STEP(); 7766 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7767 /* REPE */ 7768 /* move them until CX is ZERO. */ 7769 while (M.x86.R_CX != 0) { 7770 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7771 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7772 cmp_long(M.x86.R_EAX, val); 7773 } else { 7774 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7775 cmp_word(M.x86.R_AX, (u16)val); 7776 } 7777 M.x86.R_CX -= 1; 7778 M.x86.R_DI += inc; 7779 if (ACCESS_FLAG(F_ZF) == 0) 7780 break; 7781 } 7782 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7783 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7784 /* REPNE */ 7785 /* move them until CX is ZERO. */ 7786 while (M.x86.R_CX != 0) { 7787 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7788 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7789 cmp_long(M.x86.R_EAX, val); 7790 } else { 7791 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7792 cmp_word(M.x86.R_AX, (u16)val); 7793 } 7794 M.x86.R_CX -= 1; 7795 M.x86.R_DI += inc; 7796 if (ACCESS_FLAG(F_ZF)) 7797 break; /* zero flag set means equal */ 7798 } 7799 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7800 } else { 7801 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7802 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7803 cmp_long(M.x86.R_EAX, val); 7804 } else { 7805 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7806 cmp_word(M.x86.R_AX, (u16)val); 7807 } 7808 M.x86.R_DI += inc; 7809 } 7810 DECODE_CLEAR_SEGOVR(); 7811 END_OF_INSTR(); 7812} 7813 7814/**************************************************************************** 7815REMARKS: 7816Handles opcode 0xb0 7817****************************************************************************/ 7818static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 7819{ 7820 u8 imm; 7821 7822 START_OF_INSTR(); 7823 DECODE_PRINTF("MOV\tAL,"); 7824 imm = fetch_byte_imm(); 7825 DECODE_PRINTF2("%x\n", imm); 7826 TRACE_AND_STEP(); 7827 M.x86.R_AL = imm; 7828 DECODE_CLEAR_SEGOVR(); 7829 END_OF_INSTR(); 7830} 7831 7832/**************************************************************************** 7833REMARKS: 7834Handles opcode 0xb1 7835****************************************************************************/ 7836static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) 7837{ 7838 u8 imm; 7839 7840 START_OF_INSTR(); 7841 DECODE_PRINTF("MOV\tCL,"); 7842 imm = fetch_byte_imm(); 7843 DECODE_PRINTF2("%x\n", imm); 7844 TRACE_AND_STEP(); 7845 M.x86.R_CL = imm; 7846 DECODE_CLEAR_SEGOVR(); 7847 END_OF_INSTR(); 7848} 7849 7850/**************************************************************************** 7851REMARKS: 7852Handles opcode 0xb2 7853****************************************************************************/ 7854static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) 7855{ 7856 u8 imm; 7857 7858 START_OF_INSTR(); 7859 DECODE_PRINTF("MOV\tDL,"); 7860 imm = fetch_byte_imm(); 7861 DECODE_PRINTF2("%x\n", imm); 7862 TRACE_AND_STEP(); 7863 M.x86.R_DL = imm; 7864 DECODE_CLEAR_SEGOVR(); 7865 END_OF_INSTR(); 7866} 7867 7868/**************************************************************************** 7869REMARKS: 7870Handles opcode 0xb3 7871****************************************************************************/ 7872static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) 7873{ 7874 u8 imm; 7875 7876 START_OF_INSTR(); 7877 DECODE_PRINTF("MOV\tBL,"); 7878 imm = fetch_byte_imm(); 7879 DECODE_PRINTF2("%x\n", imm); 7880 TRACE_AND_STEP(); 7881 M.x86.R_BL = imm; 7882 DECODE_CLEAR_SEGOVR(); 7883 END_OF_INSTR(); 7884} 7885 7886/**************************************************************************** 7887REMARKS: 7888Handles opcode 0xb4 7889****************************************************************************/ 7890static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) 7891{ 7892 u8 imm; 7893 7894 START_OF_INSTR(); 7895 DECODE_PRINTF("MOV\tAH,"); 7896 imm = fetch_byte_imm(); 7897 DECODE_PRINTF2("%x\n", imm); 7898 TRACE_AND_STEP(); 7899 M.x86.R_AH = imm; 7900 DECODE_CLEAR_SEGOVR(); 7901 END_OF_INSTR(); 7902} 7903 7904/**************************************************************************** 7905REMARKS: 7906Handles opcode 0xb5 7907****************************************************************************/ 7908static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) 7909{ 7910 u8 imm; 7911 7912 START_OF_INSTR(); 7913 DECODE_PRINTF("MOV\tCH,"); 7914 imm = fetch_byte_imm(); 7915 DECODE_PRINTF2("%x\n", imm); 7916 TRACE_AND_STEP(); 7917 M.x86.R_CH = imm; 7918 DECODE_CLEAR_SEGOVR(); 7919 END_OF_INSTR(); 7920} 7921 7922/**************************************************************************** 7923REMARKS: 7924Handles opcode 0xb6 7925****************************************************************************/ 7926static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) 7927{ 7928 u8 imm; 7929 7930 START_OF_INSTR(); 7931 DECODE_PRINTF("MOV\tDH,"); 7932 imm = fetch_byte_imm(); 7933 DECODE_PRINTF2("%x\n", imm); 7934 TRACE_AND_STEP(); 7935 M.x86.R_DH = imm; 7936 DECODE_CLEAR_SEGOVR(); 7937 END_OF_INSTR(); 7938} 7939 7940/**************************************************************************** 7941REMARKS: 7942Handles opcode 0xb7 7943****************************************************************************/ 7944static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) 7945{ 7946 u8 imm; 7947 7948 START_OF_INSTR(); 7949 DECODE_PRINTF("MOV\tBH,"); 7950 imm = fetch_byte_imm(); 7951 DECODE_PRINTF2("%x\n", imm); 7952 TRACE_AND_STEP(); 7953 M.x86.R_BH = imm; 7954 DECODE_CLEAR_SEGOVR(); 7955 END_OF_INSTR(); 7956} 7957 7958/**************************************************************************** 7959REMARKS: 7960Handles opcode 0xb8 7961****************************************************************************/ 7962static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 7963{ 7964 u32 srcval; 7965 7966 START_OF_INSTR(); 7967 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7968 DECODE_PRINTF("MOV\tEAX,"); 7969 srcval = fetch_long_imm(); 7970 } else { 7971 DECODE_PRINTF("MOV\tAX,"); 7972 srcval = fetch_word_imm(); 7973 } 7974 DECODE_PRINTF2("%x\n", srcval); 7975 TRACE_AND_STEP(); 7976 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7977 M.x86.R_EAX = srcval; 7978 } else { 7979 M.x86.R_AX = (u16)srcval; 7980 } 7981 DECODE_CLEAR_SEGOVR(); 7982 END_OF_INSTR(); 7983} 7984 7985/**************************************************************************** 7986REMARKS: 7987Handles opcode 0xb9 7988****************************************************************************/ 7989static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) 7990{ 7991 u32 srcval; 7992 7993 START_OF_INSTR(); 7994 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7995 DECODE_PRINTF("MOV\tECX,"); 7996 srcval = fetch_long_imm(); 7997 } else { 7998 DECODE_PRINTF("MOV\tCX,"); 7999 srcval = fetch_word_imm(); 8000 } 8001 DECODE_PRINTF2("%x\n", srcval); 8002 TRACE_AND_STEP(); 8003 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8004 M.x86.R_ECX = srcval; 8005 } else { 8006 M.x86.R_CX = (u16)srcval; 8007 } 8008 DECODE_CLEAR_SEGOVR(); 8009 END_OF_INSTR(); 8010} 8011 8012/**************************************************************************** 8013REMARKS: 8014Handles opcode 0xba 8015****************************************************************************/ 8016static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) 8017{ 8018 u32 srcval; 8019 8020 START_OF_INSTR(); 8021 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8022 DECODE_PRINTF("MOV\tEDX,"); 8023 srcval = fetch_long_imm(); 8024 } else { 8025 DECODE_PRINTF("MOV\tDX,"); 8026 srcval = fetch_word_imm(); 8027 } 8028 DECODE_PRINTF2("%x\n", srcval); 8029 TRACE_AND_STEP(); 8030 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8031 M.x86.R_EDX = srcval; 8032 } else { 8033 M.x86.R_DX = (u16)srcval; 8034 } 8035 DECODE_CLEAR_SEGOVR(); 8036 END_OF_INSTR(); 8037} 8038 8039/**************************************************************************** 8040REMARKS: 8041Handles opcode 0xbb 8042****************************************************************************/ 8043static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) 8044{ 8045 u32 srcval; 8046 8047 START_OF_INSTR(); 8048 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8049 DECODE_PRINTF("MOV\tEBX,"); 8050 srcval = fetch_long_imm(); 8051 } else { 8052 DECODE_PRINTF("MOV\tBX,"); 8053 srcval = fetch_word_imm(); 8054 } 8055 DECODE_PRINTF2("%x\n", srcval); 8056 TRACE_AND_STEP(); 8057 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8058 M.x86.R_EBX = srcval; 8059 } else { 8060 M.x86.R_BX = (u16)srcval; 8061 } 8062 DECODE_CLEAR_SEGOVR(); 8063 END_OF_INSTR(); 8064} 8065 8066/**************************************************************************** 8067REMARKS: 8068Handles opcode 0xbc 8069****************************************************************************/ 8070static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) 8071{ 8072 u32 srcval; 8073 8074 START_OF_INSTR(); 8075 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8076 DECODE_PRINTF("MOV\tESP,"); 8077 srcval = fetch_long_imm(); 8078 } else { 8079 DECODE_PRINTF("MOV\tSP,"); 8080 srcval = fetch_word_imm(); 8081 } 8082 DECODE_PRINTF2("%x\n", srcval); 8083 TRACE_AND_STEP(); 8084 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8085 M.x86.R_ESP = srcval; 8086 } else { 8087 M.x86.R_SP = (u16)srcval; 8088 } 8089 DECODE_CLEAR_SEGOVR(); 8090 END_OF_INSTR(); 8091} 8092 8093/**************************************************************************** 8094REMARKS: 8095Handles opcode 0xbd 8096****************************************************************************/ 8097static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) 8098{ 8099 u32 srcval; 8100 8101 START_OF_INSTR(); 8102 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8103 DECODE_PRINTF("MOV\tEBP,"); 8104 srcval = fetch_long_imm(); 8105 } else { 8106 DECODE_PRINTF("MOV\tBP,"); 8107 srcval = fetch_word_imm(); 8108 } 8109 DECODE_PRINTF2("%x\n", srcval); 8110 TRACE_AND_STEP(); 8111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8112 M.x86.R_EBP = srcval; 8113 } else { 8114 M.x86.R_BP = (u16)srcval; 8115 } 8116 DECODE_CLEAR_SEGOVR(); 8117 END_OF_INSTR(); 8118} 8119 8120/**************************************************************************** 8121REMARKS: 8122Handles opcode 0xbe 8123****************************************************************************/ 8124static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) 8125{ 8126 u32 srcval; 8127 8128 START_OF_INSTR(); 8129 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8130 DECODE_PRINTF("MOV\tESI,"); 8131 srcval = fetch_long_imm(); 8132 } else { 8133 DECODE_PRINTF("MOV\tSI,"); 8134 srcval = fetch_word_imm(); 8135 } 8136 DECODE_PRINTF2("%x\n", srcval); 8137 TRACE_AND_STEP(); 8138 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8139 M.x86.R_ESI = srcval; 8140 } else { 8141 M.x86.R_SI = (u16)srcval; 8142 } 8143 DECODE_CLEAR_SEGOVR(); 8144 END_OF_INSTR(); 8145} 8146 8147/**************************************************************************** 8148REMARKS: 8149Handles opcode 0xbf 8150****************************************************************************/ 8151static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) 8152{ 8153 u32 srcval; 8154 8155 START_OF_INSTR(); 8156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8157 DECODE_PRINTF("MOV\tEDI,"); 8158 srcval = fetch_long_imm(); 8159 } else { 8160 DECODE_PRINTF("MOV\tDI,"); 8161 srcval = fetch_word_imm(); 8162 } 8163 DECODE_PRINTF2("%x\n", srcval); 8164 TRACE_AND_STEP(); 8165 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8166 M.x86.R_EDI = srcval; 8167 } else { 8168 M.x86.R_DI = (u16)srcval; 8169 } 8170 DECODE_CLEAR_SEGOVR(); 8171 END_OF_INSTR(); 8172} 8173 8174/* used by opcodes c0, d0, and d2. */ 8175static u8(*opcD0_byte_operation[])(u8 d, u8 s) = 8176{ 8177 rol_byte, 8178 ror_byte, 8179 rcl_byte, 8180 rcr_byte, 8181 shl_byte, 8182 shr_byte, 8183 shl_byte, /* sal_byte === shl_byte by definition */ 8184 sar_byte, 8185}; 8186 8187/**************************************************************************** 8188REMARKS: 8189Handles opcode 0xc0 8190****************************************************************************/ 8191static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 8192{ 8193 int mod, rl, rh; 8194 u8 *destreg; 8195 uint destoffset; 8196 u8 destval; 8197 u8 amt; 8198 8199 /* 8200 * Yet another weirdo special case instruction format. Part of 8201 * the opcode held below in "RH". Doubly nested case would 8202 * result, except that the decoded instruction 8203 */ 8204 START_OF_INSTR(); 8205 FETCH_DECODE_MODRM(mod, rh, rl); 8206#ifdef DEBUG 8207 if (DEBUG_DECODE()) { 8208 /* XXX DECODE_PRINTF may be changed to something more 8209 general, so that it is important to leave the strings 8210 in the same format, even though the result is that the 8211 above test is done twice. */ 8212 8213 switch (rh) { 8214 case 0: 8215 DECODE_PRINTF("ROL\t"); 8216 break; 8217 case 1: 8218 DECODE_PRINTF("ROR\t"); 8219 break; 8220 case 2: 8221 DECODE_PRINTF("RCL\t"); 8222 break; 8223 case 3: 8224 DECODE_PRINTF("RCR\t"); 8225 break; 8226 case 4: 8227 DECODE_PRINTF("SHL\t"); 8228 break; 8229 case 5: 8230 DECODE_PRINTF("SHR\t"); 8231 break; 8232 case 6: 8233 DECODE_PRINTF("SAL\t"); 8234 break; 8235 case 7: 8236 DECODE_PRINTF("SAR\t"); 8237 break; 8238 } 8239 } 8240#endif 8241 /* know operation, decode the mod byte to find the addressing 8242 mode. */ 8243 switch (mod) { 8244 case 0: 8245 DECODE_PRINTF("BYTE PTR "); 8246 destoffset = decode_rm00_address(rl); 8247 amt = fetch_byte_imm(); 8248 DECODE_PRINTF2(",%x\n", amt); 8249 destval = fetch_data_byte(destoffset); 8250 TRACE_AND_STEP(); 8251 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8252 store_data_byte(destoffset, destval); 8253 break; 8254 case 1: 8255 DECODE_PRINTF("BYTE PTR "); 8256 destoffset = decode_rm01_address(rl); 8257 amt = fetch_byte_imm(); 8258 DECODE_PRINTF2(",%x\n", amt); 8259 destval = fetch_data_byte(destoffset); 8260 TRACE_AND_STEP(); 8261 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8262 store_data_byte(destoffset, destval); 8263 break; 8264 case 2: 8265 DECODE_PRINTF("BYTE PTR "); 8266 destoffset = decode_rm10_address(rl); 8267 amt = fetch_byte_imm(); 8268 DECODE_PRINTF2(",%x\n", amt); 8269 destval = fetch_data_byte(destoffset); 8270 TRACE_AND_STEP(); 8271 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8272 store_data_byte(destoffset, destval); 8273 break; 8274 case 3: /* register to register */ 8275 destreg = DECODE_RM_BYTE_REGISTER(rl); 8276 amt = fetch_byte_imm(); 8277 DECODE_PRINTF2(",%x\n", amt); 8278 TRACE_AND_STEP(); 8279 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 8280 *destreg = destval; 8281 break; 8282 } 8283 DECODE_CLEAR_SEGOVR(); 8284 END_OF_INSTR(); 8285} 8286 8287/* used by opcodes c1, d1, and d3. */ 8288static u16(*opcD1_word_operation[])(u16 s, u8 d) = 8289{ 8290 rol_word, 8291 ror_word, 8292 rcl_word, 8293 rcr_word, 8294 shl_word, 8295 shr_word, 8296 shl_word, /* sal_byte === shl_byte by definition */ 8297 sar_word, 8298}; 8299 8300/* used by opcodes c1, d1, and d3. */ 8301static u32 (*opcD1_long_operation[])(u32 s, u8 d) = 8302{ 8303 rol_long, 8304 ror_long, 8305 rcl_long, 8306 rcr_long, 8307 shl_long, 8308 shr_long, 8309 shl_long, /* sal_byte === shl_byte by definition */ 8310 sar_long, 8311}; 8312 8313/**************************************************************************** 8314REMARKS: 8315Handles opcode 0xc1 8316****************************************************************************/ 8317static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 8318{ 8319 int mod, rl, rh; 8320 uint destoffset; 8321 u8 amt; 8322 8323 /* 8324 * Yet another weirdo special case instruction format. Part of 8325 * the opcode held below in "RH". Doubly nested case would 8326 * result, except that the decoded instruction 8327 */ 8328 START_OF_INSTR(); 8329 FETCH_DECODE_MODRM(mod, rh, rl); 8330#ifdef DEBUG 8331 if (DEBUG_DECODE()) { 8332 /* XXX DECODE_PRINTF may be changed to something more 8333 general, so that it is important to leave the strings 8334 in the same format, even though the result is that the 8335 above test is done twice. */ 8336 8337 switch (rh) { 8338 case 0: 8339 DECODE_PRINTF("ROL\t"); 8340 break; 8341 case 1: 8342 DECODE_PRINTF("ROR\t"); 8343 break; 8344 case 2: 8345 DECODE_PRINTF("RCL\t"); 8346 break; 8347 case 3: 8348 DECODE_PRINTF("RCR\t"); 8349 break; 8350 case 4: 8351 DECODE_PRINTF("SHL\t"); 8352 break; 8353 case 5: 8354 DECODE_PRINTF("SHR\t"); 8355 break; 8356 case 6: 8357 DECODE_PRINTF("SAL\t"); 8358 break; 8359 case 7: 8360 DECODE_PRINTF("SAR\t"); 8361 break; 8362 } 8363 } 8364#endif 8365 /* know operation, decode the mod byte to find the addressing 8366 mode. */ 8367 switch (mod) { 8368 case 0: 8369 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8370 u32 destval; 8371 8372 DECODE_PRINTF("DWORD PTR "); 8373 destoffset = decode_rm00_address(rl); 8374 amt = fetch_byte_imm(); 8375 DECODE_PRINTF2(",%x\n", amt); 8376 destval = fetch_data_long(destoffset); 8377 TRACE_AND_STEP(); 8378 destval = (*opcD1_long_operation[rh]) (destval, amt); 8379 store_data_long(destoffset, destval); 8380 } else { 8381 u16 destval; 8382 8383 DECODE_PRINTF("WORD PTR "); 8384 destoffset = decode_rm00_address(rl); 8385 amt = fetch_byte_imm(); 8386 DECODE_PRINTF2(",%x\n", amt); 8387 destval = fetch_data_word(destoffset); 8388 TRACE_AND_STEP(); 8389 destval = (*opcD1_word_operation[rh]) (destval, amt); 8390 store_data_word(destoffset, destval); 8391 } 8392 break; 8393 case 1: 8394 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8395 u32 destval; 8396 8397 DECODE_PRINTF("DWORD PTR "); 8398 destoffset = decode_rm01_address(rl); 8399 amt = fetch_byte_imm(); 8400 DECODE_PRINTF2(",%x\n", amt); 8401 destval = fetch_data_long(destoffset); 8402 TRACE_AND_STEP(); 8403 destval = (*opcD1_long_operation[rh]) (destval, amt); 8404 store_data_long(destoffset, destval); 8405 } else { 8406 u16 destval; 8407 8408 DECODE_PRINTF("WORD PTR "); 8409 destoffset = decode_rm01_address(rl); 8410 amt = fetch_byte_imm(); 8411 DECODE_PRINTF2(",%x\n", amt); 8412 destval = fetch_data_word(destoffset); 8413 TRACE_AND_STEP(); 8414 destval = (*opcD1_word_operation[rh]) (destval, amt); 8415 store_data_word(destoffset, destval); 8416 } 8417 break; 8418 case 2: 8419 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8420 u32 destval; 8421 8422 DECODE_PRINTF("DWORD PTR "); 8423 destoffset = decode_rm10_address(rl); 8424 amt = fetch_byte_imm(); 8425 DECODE_PRINTF2(",%x\n", amt); 8426 destval = fetch_data_long(destoffset); 8427 TRACE_AND_STEP(); 8428 destval = (*opcD1_long_operation[rh]) (destval, amt); 8429 store_data_long(destoffset, destval); 8430 } else { 8431 u16 destval; 8432 8433 DECODE_PRINTF("WORD PTR "); 8434 destoffset = decode_rm10_address(rl); 8435 amt = fetch_byte_imm(); 8436 DECODE_PRINTF2(",%x\n", amt); 8437 destval = fetch_data_word(destoffset); 8438 TRACE_AND_STEP(); 8439 destval = (*opcD1_word_operation[rh]) (destval, amt); 8440 store_data_word(destoffset, destval); 8441 } 8442 break; 8443 case 3: /* register to register */ 8444 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8445 u32 *destreg; 8446 8447 destreg = DECODE_RM_LONG_REGISTER(rl); 8448 amt = fetch_byte_imm(); 8449 DECODE_PRINTF2(",%x\n", amt); 8450 TRACE_AND_STEP(); 8451 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 8452 } else { 8453 u16 *destreg; 8454 8455 destreg = DECODE_RM_WORD_REGISTER(rl); 8456 amt = fetch_byte_imm(); 8457 DECODE_PRINTF2(",%x\n", amt); 8458 TRACE_AND_STEP(); 8459 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 8460 } 8461 break; 8462 } 8463 DECODE_CLEAR_SEGOVR(); 8464 END_OF_INSTR(); 8465} 8466 8467/**************************************************************************** 8468REMARKS: 8469Handles opcode 0xc2 8470****************************************************************************/ 8471static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 8472{ 8473 u16 imm; 8474 8475 START_OF_INSTR(); 8476 DECODE_PRINTF("RET\t"); 8477 imm = fetch_word_imm(); 8478 DECODE_PRINTF2("%x\n", imm); 8479 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8480 TRACE_AND_STEP(); 8481 M.x86.R_IP = pop_word(); 8482 M.x86.R_SP += imm; 8483 DECODE_CLEAR_SEGOVR(); 8484 END_OF_INSTR(); 8485} 8486 8487/**************************************************************************** 8488REMARKS: 8489Handles opcode 0xc3 8490****************************************************************************/ 8491static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 8492{ 8493 START_OF_INSTR(); 8494 DECODE_PRINTF("RET\n"); 8495 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8496 TRACE_AND_STEP(); 8497 M.x86.R_IP = pop_word(); 8498 DECODE_CLEAR_SEGOVR(); 8499 END_OF_INSTR(); 8500} 8501 8502/**************************************************************************** 8503REMARKS: 8504Handles opcode 0xc4 8505****************************************************************************/ 8506static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 8507{ 8508 int mod, rh, rl; 8509 u16 *dstreg; 8510 uint srcoffset; 8511 8512 START_OF_INSTR(); 8513 DECODE_PRINTF("LES\t"); 8514 FETCH_DECODE_MODRM(mod, rh, rl); 8515 switch (mod) { 8516 case 0: 8517 dstreg = DECODE_RM_WORD_REGISTER(rh); 8518 DECODE_PRINTF(","); 8519 srcoffset = decode_rm00_address(rl); 8520 DECODE_PRINTF("\n"); 8521 TRACE_AND_STEP(); 8522 *dstreg = fetch_data_word(srcoffset); 8523 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8524 break; 8525 case 1: 8526 dstreg = DECODE_RM_WORD_REGISTER(rh); 8527 DECODE_PRINTF(","); 8528 srcoffset = decode_rm01_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 2: 8535 dstreg = DECODE_RM_WORD_REGISTER(rh); 8536 DECODE_PRINTF(","); 8537 srcoffset = decode_rm10_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 3: /* register to register */ 8544 /* UNDEFINED! */ 8545 TRACE_AND_STEP(); 8546 } 8547 DECODE_CLEAR_SEGOVR(); 8548 END_OF_INSTR(); 8549} 8550 8551/**************************************************************************** 8552REMARKS: 8553Handles opcode 0xc5 8554****************************************************************************/ 8555static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 8556{ 8557 int mod, rh, rl; 8558 u16 *dstreg; 8559 uint srcoffset; 8560 8561 START_OF_INSTR(); 8562 DECODE_PRINTF("LDS\t"); 8563 FETCH_DECODE_MODRM(mod, rh, rl); 8564 switch (mod) { 8565 case 0: 8566 dstreg = DECODE_RM_WORD_REGISTER(rh); 8567 DECODE_PRINTF(","); 8568 srcoffset = decode_rm00_address(rl); 8569 DECODE_PRINTF("\n"); 8570 TRACE_AND_STEP(); 8571 *dstreg = fetch_data_word(srcoffset); 8572 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8573 break; 8574 case 1: 8575 dstreg = DECODE_RM_WORD_REGISTER(rh); 8576 DECODE_PRINTF(","); 8577 srcoffset = decode_rm01_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 2: 8584 dstreg = DECODE_RM_WORD_REGISTER(rh); 8585 DECODE_PRINTF(","); 8586 srcoffset = decode_rm10_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 3: /* register to register */ 8593 /* UNDEFINED! */ 8594 TRACE_AND_STEP(); 8595 } 8596 DECODE_CLEAR_SEGOVR(); 8597 END_OF_INSTR(); 8598} 8599 8600/**************************************************************************** 8601REMARKS: 8602Handles opcode 0xc6 8603****************************************************************************/ 8604static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 8605{ 8606 int mod, rl, rh; 8607 u8 *destreg; 8608 uint destoffset; 8609 u8 imm; 8610 8611 START_OF_INSTR(); 8612 DECODE_PRINTF("MOV\t"); 8613 FETCH_DECODE_MODRM(mod, rh, rl); 8614 if (rh != 0) { 8615 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 8616 HALT_SYS(); 8617 } 8618 switch (mod) { 8619 case 0: 8620 DECODE_PRINTF("BYTE PTR "); 8621 destoffset = decode_rm00_address(rl); 8622 imm = fetch_byte_imm(); 8623 DECODE_PRINTF2(",%2x\n", imm); 8624 TRACE_AND_STEP(); 8625 store_data_byte(destoffset, imm); 8626 break; 8627 case 1: 8628 DECODE_PRINTF("BYTE PTR "); 8629 destoffset = decode_rm01_address(rl); 8630 imm = fetch_byte_imm(); 8631 DECODE_PRINTF2(",%2x\n", imm); 8632 TRACE_AND_STEP(); 8633 store_data_byte(destoffset, imm); 8634 break; 8635 case 2: 8636 DECODE_PRINTF("BYTE PTR "); 8637 destoffset = decode_rm10_address(rl); 8638 imm = fetch_byte_imm(); 8639 DECODE_PRINTF2(",%2x\n", imm); 8640 TRACE_AND_STEP(); 8641 store_data_byte(destoffset, imm); 8642 break; 8643 case 3: /* register to register */ 8644 destreg = DECODE_RM_BYTE_REGISTER(rl); 8645 imm = fetch_byte_imm(); 8646 DECODE_PRINTF2(",%2x\n", imm); 8647 TRACE_AND_STEP(); 8648 *destreg = imm; 8649 break; 8650 } 8651 DECODE_CLEAR_SEGOVR(); 8652 END_OF_INSTR(); 8653} 8654 8655/**************************************************************************** 8656REMARKS: 8657Handles opcode 0xc7 8658****************************************************************************/ 8659static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 8660{ 8661 int mod, rl, rh; 8662 uint destoffset; 8663 8664 START_OF_INSTR(); 8665 DECODE_PRINTF("MOV\t"); 8666 FETCH_DECODE_MODRM(mod, rh, rl); 8667 if (rh != 0) { 8668 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 8669 HALT_SYS(); 8670 } 8671 switch (mod) { 8672 case 0: 8673 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8674 u32 imm; 8675 8676 DECODE_PRINTF("DWORD PTR "); 8677 destoffset = decode_rm00_address(rl); 8678 imm = fetch_long_imm(); 8679 DECODE_PRINTF2(",%x\n", imm); 8680 TRACE_AND_STEP(); 8681 store_data_long(destoffset, imm); 8682 } else { 8683 u16 imm; 8684 8685 DECODE_PRINTF("WORD PTR "); 8686 destoffset = decode_rm00_address(rl); 8687 imm = fetch_word_imm(); 8688 DECODE_PRINTF2(",%x\n", imm); 8689 TRACE_AND_STEP(); 8690 store_data_word(destoffset, imm); 8691 } 8692 break; 8693 case 1: 8694 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8695 u32 imm; 8696 8697 DECODE_PRINTF("DWORD PTR "); 8698 destoffset = decode_rm01_address(rl); 8699 imm = fetch_long_imm(); 8700 DECODE_PRINTF2(",%x\n", imm); 8701 TRACE_AND_STEP(); 8702 store_data_long(destoffset, imm); 8703 } else { 8704 u16 imm; 8705 8706 DECODE_PRINTF("WORD PTR "); 8707 destoffset = decode_rm01_address(rl); 8708 imm = fetch_word_imm(); 8709 DECODE_PRINTF2(",%x\n", imm); 8710 TRACE_AND_STEP(); 8711 store_data_word(destoffset, imm); 8712 } 8713 break; 8714 case 2: 8715 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8716 u32 imm; 8717 8718 DECODE_PRINTF("DWORD PTR "); 8719 destoffset = decode_rm10_address(rl); 8720 imm = fetch_long_imm(); 8721 DECODE_PRINTF2(",%x\n", imm); 8722 TRACE_AND_STEP(); 8723 store_data_long(destoffset, imm); 8724 } else { 8725 u16 imm; 8726 8727 DECODE_PRINTF("WORD PTR "); 8728 destoffset = decode_rm10_address(rl); 8729 imm = fetch_word_imm(); 8730 DECODE_PRINTF2(",%x\n", imm); 8731 TRACE_AND_STEP(); 8732 store_data_word(destoffset, imm); 8733 } 8734 break; 8735 case 3: /* register to register */ 8736 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8737 u32 *destreg; 8738 u32 imm; 8739 8740 destreg = DECODE_RM_LONG_REGISTER(rl); 8741 imm = fetch_long_imm(); 8742 DECODE_PRINTF2(",%x\n", imm); 8743 TRACE_AND_STEP(); 8744 *destreg = imm; 8745 } else { 8746 u16 *destreg; 8747 u16 imm; 8748 8749 destreg = DECODE_RM_WORD_REGISTER(rl); 8750 imm = fetch_word_imm(); 8751 DECODE_PRINTF2(",%x\n", imm); 8752 TRACE_AND_STEP(); 8753 *destreg = imm; 8754 } 8755 break; 8756 } 8757 DECODE_CLEAR_SEGOVR(); 8758 END_OF_INSTR(); 8759} 8760 8761/**************************************************************************** 8762REMARKS: 8763Handles opcode 0xc8 8764****************************************************************************/ 8765static void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 8766{ 8767 u16 local,frame_pointer; 8768 u8 nesting; 8769 int i; 8770 8771 START_OF_INSTR(); 8772 local = fetch_word_imm(); 8773 nesting = fetch_byte_imm(); 8774 DECODE_PRINTF2("ENTER %x\n", local); 8775 DECODE_PRINTF2(",%x\n", nesting); 8776 TRACE_AND_STEP(); 8777 push_word(M.x86.R_BP); 8778 frame_pointer = M.x86.R_SP; 8779 if (nesting > 0) { 8780 for (i = 1; i < nesting; i++) { 8781 M.x86.R_BP -= 2; 8782 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 8783 } 8784 push_word(frame_pointer); 8785 } 8786 M.x86.R_BP = frame_pointer; 8787 M.x86.R_SP = (u16)(M.x86.R_SP - local); 8788 DECODE_CLEAR_SEGOVR(); 8789 END_OF_INSTR(); 8790} 8791 8792/**************************************************************************** 8793REMARKS: 8794Handles opcode 0xc9 8795****************************************************************************/ 8796static void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 8797{ 8798 START_OF_INSTR(); 8799 DECODE_PRINTF("LEAVE\n"); 8800 TRACE_AND_STEP(); 8801 M.x86.R_SP = M.x86.R_BP; 8802 M.x86.R_BP = pop_word(); 8803 DECODE_CLEAR_SEGOVR(); 8804 END_OF_INSTR(); 8805} 8806 8807/**************************************************************************** 8808REMARKS: 8809Handles opcode 0xca 8810****************************************************************************/ 8811static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 8812{ 8813 u16 imm; 8814 8815 START_OF_INSTR(); 8816 DECODE_PRINTF("RETF\t"); 8817 imm = fetch_word_imm(); 8818 DECODE_PRINTF2("%x\n", imm); 8819 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8820 TRACE_AND_STEP(); 8821 M.x86.R_IP = pop_word(); 8822 M.x86.R_CS = pop_word(); 8823 M.x86.R_SP += imm; 8824 DECODE_CLEAR_SEGOVR(); 8825 END_OF_INSTR(); 8826} 8827 8828/**************************************************************************** 8829REMARKS: 8830Handles opcode 0xcb 8831****************************************************************************/ 8832static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 8833{ 8834 START_OF_INSTR(); 8835 DECODE_PRINTF("RETF\n"); 8836 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8837 TRACE_AND_STEP(); 8838 M.x86.R_IP = pop_word(); 8839 M.x86.R_CS = pop_word(); 8840 DECODE_CLEAR_SEGOVR(); 8841 END_OF_INSTR(); 8842} 8843 8844/**************************************************************************** 8845REMARKS: 8846Handles opcode 0xcc 8847****************************************************************************/ 8848static void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 8849{ 8850 START_OF_INSTR(); 8851 DECODE_PRINTF("INT 3\n"); 8852 TRACE_AND_STEP(); 8853 if (_X86EMU_intrTab[3]) { 8854 (*_X86EMU_intrTab[3])(3); 8855 } else { 8856 push_word((u16)M.x86.R_FLG); 8857 CLEAR_FLAG(F_IF); 8858 CLEAR_FLAG(F_TF); 8859 push_word(M.x86.R_CS); 8860 M.x86.R_CS = mem_access_word(3 * 4 + 2); 8861 push_word(M.x86.R_IP); 8862 M.x86.R_IP = mem_access_word(3 * 4); 8863 } 8864 DECODE_CLEAR_SEGOVR(); 8865 END_OF_INSTR(); 8866} 8867 8868/**************************************************************************** 8869REMARKS: 8870Handles opcode 0xcd 8871****************************************************************************/ 8872static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 8873{ 8874 u8 intnum; 8875 8876 START_OF_INSTR(); 8877 DECODE_PRINTF("INT\t"); 8878 intnum = fetch_byte_imm(); 8879 DECODE_PRINTF2("%x\n", intnum); 8880 TRACE_AND_STEP(); 8881 if (_X86EMU_intrTab[intnum]) { 8882 (*_X86EMU_intrTab[intnum])(intnum); 8883 } else { 8884 push_word((u16)M.x86.R_FLG); 8885 CLEAR_FLAG(F_IF); 8886 CLEAR_FLAG(F_TF); 8887 push_word(M.x86.R_CS); 8888 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 8889 push_word(M.x86.R_IP); 8890 M.x86.R_IP = mem_access_word(intnum * 4); 8891 } 8892 DECODE_CLEAR_SEGOVR(); 8893 END_OF_INSTR(); 8894} 8895 8896/**************************************************************************** 8897REMARKS: 8898Handles opcode 0xce 8899****************************************************************************/ 8900static void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 8901{ 8902 START_OF_INSTR(); 8903 DECODE_PRINTF("INTO\n"); 8904 TRACE_AND_STEP(); 8905 if (ACCESS_FLAG(F_OF)) { 8906 if (_X86EMU_intrTab[4]) { 8907 (*_X86EMU_intrTab[4])(4); 8908 } else { 8909 push_word((u16)M.x86.R_FLG); 8910 CLEAR_FLAG(F_IF); 8911 CLEAR_FLAG(F_TF); 8912 push_word(M.x86.R_CS); 8913 M.x86.R_CS = mem_access_word(4 * 4 + 2); 8914 push_word(M.x86.R_IP); 8915 M.x86.R_IP = mem_access_word(4 * 4); 8916 } 8917 } 8918 DECODE_CLEAR_SEGOVR(); 8919 END_OF_INSTR(); 8920} 8921 8922/**************************************************************************** 8923REMARKS: 8924Handles opcode 0xcf 8925****************************************************************************/ 8926static void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 8927{ 8928 START_OF_INSTR(); 8929 DECODE_PRINTF("IRET\n"); 8930 8931 TRACE_AND_STEP(); 8932 8933 M.x86.R_IP = pop_word(); 8934 M.x86.R_CS = pop_word(); 8935 M.x86.R_FLG = pop_word(); 8936 DECODE_CLEAR_SEGOVR(); 8937 END_OF_INSTR(); 8938} 8939 8940/**************************************************************************** 8941REMARKS: 8942Handles opcode 0xd0 8943****************************************************************************/ 8944static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 8945{ 8946 int mod, rl, rh; 8947 u8 *destreg; 8948 uint destoffset; 8949 u8 destval; 8950 8951 /* 8952 * Yet another weirdo special case instruction format. Part of 8953 * the opcode held below in "RH". Doubly nested case would 8954 * result, except that the decoded instruction 8955 */ 8956 START_OF_INSTR(); 8957 FETCH_DECODE_MODRM(mod, rh, rl); 8958#ifdef DEBUG 8959 if (DEBUG_DECODE()) { 8960 /* XXX DECODE_PRINTF may be changed to something more 8961 general, so that it is important to leave the strings 8962 in the same format, even though the result is that the 8963 above test is done twice. */ 8964 switch (rh) { 8965 case 0: 8966 DECODE_PRINTF("ROL\t"); 8967 break; 8968 case 1: 8969 DECODE_PRINTF("ROR\t"); 8970 break; 8971 case 2: 8972 DECODE_PRINTF("RCL\t"); 8973 break; 8974 case 3: 8975 DECODE_PRINTF("RCR\t"); 8976 break; 8977 case 4: 8978 DECODE_PRINTF("SHL\t"); 8979 break; 8980 case 5: 8981 DECODE_PRINTF("SHR\t"); 8982 break; 8983 case 6: 8984 DECODE_PRINTF("SAL\t"); 8985 break; 8986 case 7: 8987 DECODE_PRINTF("SAR\t"); 8988 break; 8989 } 8990 } 8991#endif 8992 /* know operation, decode the mod byte to find the addressing 8993 mode. */ 8994 switch (mod) { 8995 case 0: 8996 DECODE_PRINTF("BYTE PTR "); 8997 destoffset = decode_rm00_address(rl); 8998 DECODE_PRINTF(",1\n"); 8999 destval = fetch_data_byte(destoffset); 9000 TRACE_AND_STEP(); 9001 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9002 store_data_byte(destoffset, destval); 9003 break; 9004 case 1: 9005 DECODE_PRINTF("BYTE PTR "); 9006 destoffset = decode_rm01_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 2: 9014 DECODE_PRINTF("BYTE PTR "); 9015 destoffset = decode_rm10_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 3: /* register to register */ 9023 destreg = DECODE_RM_BYTE_REGISTER(rl); 9024 DECODE_PRINTF(",1\n"); 9025 TRACE_AND_STEP(); 9026 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 9027 *destreg = destval; 9028 break; 9029 } 9030 DECODE_CLEAR_SEGOVR(); 9031 END_OF_INSTR(); 9032} 9033 9034/**************************************************************************** 9035REMARKS: 9036Handles opcode 0xd1 9037****************************************************************************/ 9038static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 9039{ 9040 int mod, rl, rh; 9041 uint destoffset; 9042 9043 /* 9044 * Yet another weirdo special case instruction format. Part of 9045 * the opcode held below in "RH". Doubly nested case would 9046 * result, except that the decoded instruction 9047 */ 9048 START_OF_INSTR(); 9049 FETCH_DECODE_MODRM(mod, rh, rl); 9050#ifdef DEBUG 9051 if (DEBUG_DECODE()) { 9052 /* XXX DECODE_PRINTF may be changed to something more 9053 general, so that it is important to leave the strings 9054 in the same format, even though the result is that the 9055 above test is done twice. */ 9056 switch (rh) { 9057 case 0: 9058 DECODE_PRINTF("ROL\t"); 9059 break; 9060 case 1: 9061 DECODE_PRINTF("ROR\t"); 9062 break; 9063 case 2: 9064 DECODE_PRINTF("RCL\t"); 9065 break; 9066 case 3: 9067 DECODE_PRINTF("RCR\t"); 9068 break; 9069 case 4: 9070 DECODE_PRINTF("SHL\t"); 9071 break; 9072 case 5: 9073 DECODE_PRINTF("SHR\t"); 9074 break; 9075 case 6: 9076 DECODE_PRINTF("SAL\t"); 9077 break; 9078 case 7: 9079 DECODE_PRINTF("SAR\t"); 9080 break; 9081 } 9082 } 9083#endif 9084 /* know operation, decode the mod byte to find the addressing 9085 mode. */ 9086 switch (mod) { 9087 case 0: 9088 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9089 u32 destval; 9090 9091 DECODE_PRINTF("DWORD PTR "); 9092 destoffset = decode_rm00_address(rl); 9093 DECODE_PRINTF(",1\n"); 9094 destval = fetch_data_long(destoffset); 9095 TRACE_AND_STEP(); 9096 destval = (*opcD1_long_operation[rh]) (destval, 1); 9097 store_data_long(destoffset, destval); 9098 } else { 9099 u16 destval; 9100 9101 DECODE_PRINTF("WORD PTR "); 9102 destoffset = decode_rm00_address(rl); 9103 DECODE_PRINTF(",1\n"); 9104 destval = fetch_data_word(destoffset); 9105 TRACE_AND_STEP(); 9106 destval = (*opcD1_word_operation[rh]) (destval, 1); 9107 store_data_word(destoffset, destval); 9108 } 9109 break; 9110 case 1: 9111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9112 u32 destval; 9113 9114 DECODE_PRINTF("DWORD PTR "); 9115 destoffset = decode_rm01_address(rl); 9116 DECODE_PRINTF(",1\n"); 9117 destval = fetch_data_long(destoffset); 9118 TRACE_AND_STEP(); 9119 destval = (*opcD1_long_operation[rh]) (destval, 1); 9120 store_data_long(destoffset, destval); 9121 } else { 9122 u16 destval; 9123 9124 DECODE_PRINTF("WORD PTR "); 9125 destoffset = decode_rm01_address(rl); 9126 DECODE_PRINTF(",1\n"); 9127 destval = fetch_data_word(destoffset); 9128 TRACE_AND_STEP(); 9129 destval = (*opcD1_word_operation[rh]) (destval, 1); 9130 store_data_word(destoffset, destval); 9131 } 9132 break; 9133 case 2: 9134 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9135 u32 destval; 9136 9137 DECODE_PRINTF("DWORD PTR "); 9138 destoffset = decode_rm10_address(rl); 9139 DECODE_PRINTF(",1\n"); 9140 destval = fetch_data_long(destoffset); 9141 TRACE_AND_STEP(); 9142 destval = (*opcD1_long_operation[rh]) (destval, 1); 9143 store_data_long(destoffset, destval); 9144 } else { 9145 u16 destval; 9146 9147 DECODE_PRINTF("BYTE PTR "); 9148 destoffset = decode_rm10_address(rl); 9149 DECODE_PRINTF(",1\n"); 9150 destval = fetch_data_word(destoffset); 9151 TRACE_AND_STEP(); 9152 destval = (*opcD1_word_operation[rh]) (destval, 1); 9153 store_data_word(destoffset, destval); 9154 } 9155 break; 9156 case 3: /* register to register */ 9157 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9158 u32 destval; 9159 u32 *destreg; 9160 9161 destreg = DECODE_RM_LONG_REGISTER(rl); 9162 DECODE_PRINTF(",1\n"); 9163 TRACE_AND_STEP(); 9164 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 9165 *destreg = destval; 9166 } else { 9167 u16 destval; 9168 u16 *destreg; 9169 9170 destreg = DECODE_RM_WORD_REGISTER(rl); 9171 DECODE_PRINTF(",1\n"); 9172 TRACE_AND_STEP(); 9173 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 9174 *destreg = destval; 9175 } 9176 break; 9177 } 9178 DECODE_CLEAR_SEGOVR(); 9179 END_OF_INSTR(); 9180} 9181 9182/**************************************************************************** 9183REMARKS: 9184Handles opcode 0xd2 9185****************************************************************************/ 9186static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 9187{ 9188 int mod, rl, rh; 9189 u8 *destreg; 9190 uint destoffset; 9191 u8 destval; 9192 u8 amt; 9193 9194 /* 9195 * Yet another weirdo special case instruction format. Part of 9196 * the opcode held below in "RH". Doubly nested case would 9197 * result, except that the decoded instruction 9198 */ 9199 START_OF_INSTR(); 9200 FETCH_DECODE_MODRM(mod, rh, rl); 9201#ifdef DEBUG 9202 if (DEBUG_DECODE()) { 9203 /* XXX DECODE_PRINTF may be changed to something more 9204 general, so that it is important to leave the strings 9205 in the same format, even though the result is that the 9206 above test is done twice. */ 9207 switch (rh) { 9208 case 0: 9209 DECODE_PRINTF("ROL\t"); 9210 break; 9211 case 1: 9212 DECODE_PRINTF("ROR\t"); 9213 break; 9214 case 2: 9215 DECODE_PRINTF("RCL\t"); 9216 break; 9217 case 3: 9218 DECODE_PRINTF("RCR\t"); 9219 break; 9220 case 4: 9221 DECODE_PRINTF("SHL\t"); 9222 break; 9223 case 5: 9224 DECODE_PRINTF("SHR\t"); 9225 break; 9226 case 6: 9227 DECODE_PRINTF("SAL\t"); 9228 break; 9229 case 7: 9230 DECODE_PRINTF("SAR\t"); 9231 break; 9232 } 9233 } 9234#endif 9235 /* know operation, decode the mod byte to find the addressing 9236 mode. */ 9237 amt = M.x86.R_CL; 9238 switch (mod) { 9239 case 0: 9240 DECODE_PRINTF("BYTE PTR "); 9241 destoffset = decode_rm00_address(rl); 9242 DECODE_PRINTF(",CL\n"); 9243 destval = fetch_data_byte(destoffset); 9244 TRACE_AND_STEP(); 9245 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9246 store_data_byte(destoffset, destval); 9247 break; 9248 case 1: 9249 DECODE_PRINTF("BYTE PTR "); 9250 destoffset = decode_rm01_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 2: 9258 DECODE_PRINTF("BYTE PTR "); 9259 destoffset = decode_rm10_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 3: /* register to register */ 9267 destreg = DECODE_RM_BYTE_REGISTER(rl); 9268 DECODE_PRINTF(",CL\n"); 9269 TRACE_AND_STEP(); 9270 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 9271 *destreg = destval; 9272 break; 9273 } 9274 DECODE_CLEAR_SEGOVR(); 9275 END_OF_INSTR(); 9276} 9277 9278/**************************************************************************** 9279REMARKS: 9280Handles opcode 0xd3 9281****************************************************************************/ 9282static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 9283{ 9284 int mod, rl, rh; 9285 uint destoffset; 9286 u8 amt; 9287 9288 /* 9289 * Yet another weirdo special case instruction format. Part of 9290 * the opcode held below in "RH". Doubly nested case would 9291 * result, except that the decoded instruction 9292 */ 9293 START_OF_INSTR(); 9294 FETCH_DECODE_MODRM(mod, rh, rl); 9295#ifdef DEBUG 9296 if (DEBUG_DECODE()) { 9297 /* XXX DECODE_PRINTF may be changed to something more 9298 general, so that it is important to leave the strings 9299 in the same format, even though the result is that the 9300 above test is done twice. */ 9301 switch (rh) { 9302 case 0: 9303 DECODE_PRINTF("ROL\t"); 9304 break; 9305 case 1: 9306 DECODE_PRINTF("ROR\t"); 9307 break; 9308 case 2: 9309 DECODE_PRINTF("RCL\t"); 9310 break; 9311 case 3: 9312 DECODE_PRINTF("RCR\t"); 9313 break; 9314 case 4: 9315 DECODE_PRINTF("SHL\t"); 9316 break; 9317 case 5: 9318 DECODE_PRINTF("SHR\t"); 9319 break; 9320 case 6: 9321 DECODE_PRINTF("SAL\t"); 9322 break; 9323 case 7: 9324 DECODE_PRINTF("SAR\t"); 9325 break; 9326 } 9327 } 9328#endif 9329 /* know operation, decode the mod byte to find the addressing 9330 mode. */ 9331 amt = M.x86.R_CL; 9332 switch (mod) { 9333 case 0: 9334 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9335 u32 destval; 9336 9337 DECODE_PRINTF("DWORD PTR "); 9338 destoffset = decode_rm00_address(rl); 9339 DECODE_PRINTF(",CL\n"); 9340 destval = fetch_data_long(destoffset); 9341 TRACE_AND_STEP(); 9342 destval = (*opcD1_long_operation[rh]) (destval, amt); 9343 store_data_long(destoffset, destval); 9344 } else { 9345 u16 destval; 9346 9347 DECODE_PRINTF("WORD PTR "); 9348 destoffset = decode_rm00_address(rl); 9349 DECODE_PRINTF(",CL\n"); 9350 destval = fetch_data_word(destoffset); 9351 TRACE_AND_STEP(); 9352 destval = (*opcD1_word_operation[rh]) (destval, amt); 9353 store_data_word(destoffset, destval); 9354 } 9355 break; 9356 case 1: 9357 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9358 u32 destval; 9359 9360 DECODE_PRINTF("DWORD PTR "); 9361 destoffset = decode_rm01_address(rl); 9362 DECODE_PRINTF(",CL\n"); 9363 destval = fetch_data_long(destoffset); 9364 TRACE_AND_STEP(); 9365 destval = (*opcD1_long_operation[rh]) (destval, amt); 9366 store_data_long(destoffset, destval); 9367 } else { 9368 u16 destval; 9369 9370 DECODE_PRINTF("WORD PTR "); 9371 destoffset = decode_rm01_address(rl); 9372 DECODE_PRINTF(",CL\n"); 9373 destval = fetch_data_word(destoffset); 9374 TRACE_AND_STEP(); 9375 destval = (*opcD1_word_operation[rh]) (destval, amt); 9376 store_data_word(destoffset, destval); 9377 } 9378 break; 9379 case 2: 9380 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9381 u32 destval; 9382 9383 DECODE_PRINTF("DWORD PTR "); 9384 destoffset = decode_rm10_address(rl); 9385 DECODE_PRINTF(",CL\n"); 9386 destval = fetch_data_long(destoffset); 9387 TRACE_AND_STEP(); 9388 destval = (*opcD1_long_operation[rh]) (destval, amt); 9389 store_data_long(destoffset, destval); 9390 } else { 9391 u16 destval; 9392 9393 DECODE_PRINTF("WORD PTR "); 9394 destoffset = decode_rm10_address(rl); 9395 DECODE_PRINTF(",CL\n"); 9396 destval = fetch_data_word(destoffset); 9397 TRACE_AND_STEP(); 9398 destval = (*opcD1_word_operation[rh]) (destval, amt); 9399 store_data_word(destoffset, destval); 9400 } 9401 break; 9402 case 3: /* register to register */ 9403 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9404 u32 *destreg; 9405 9406 destreg = DECODE_RM_LONG_REGISTER(rl); 9407 DECODE_PRINTF(",CL\n"); 9408 TRACE_AND_STEP(); 9409 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 9410 } else { 9411 u16 *destreg; 9412 9413 destreg = DECODE_RM_WORD_REGISTER(rl); 9414 DECODE_PRINTF(",CL\n"); 9415 TRACE_AND_STEP(); 9416 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 9417 } 9418 break; 9419 } 9420 DECODE_CLEAR_SEGOVR(); 9421 END_OF_INSTR(); 9422} 9423 9424/**************************************************************************** 9425REMARKS: 9426Handles opcode 0xd4 9427****************************************************************************/ 9428static void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 9429{ 9430 u8 a; 9431 9432 START_OF_INSTR(); 9433 DECODE_PRINTF("AAM\n"); 9434 a = fetch_byte_imm(); /* this is a stupid encoding. */ 9435 if (a != 10) { 9436 /* fix: add base decoding 9437 aam_word(u8 val, int base a) */ 9438 DECODE_PRINTF("ERROR DECODING AAM\n"); 9439 TRACE_REGS(); 9440 HALT_SYS(); 9441 } 9442 TRACE_AND_STEP(); 9443 /* note the type change here --- returning AL and AH in AX. */ 9444 M.x86.R_AX = aam_word(M.x86.R_AL); 9445 DECODE_CLEAR_SEGOVR(); 9446 END_OF_INSTR(); 9447} 9448 9449/**************************************************************************** 9450REMARKS: 9451Handles opcode 0xd5 9452****************************************************************************/ 9453static void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 9454{ 9455 u8 a; 9456 9457 START_OF_INSTR(); 9458 DECODE_PRINTF("AAD\n"); 9459 a = fetch_byte_imm(); 9460 if (a != 10) { 9461 /* fix: add base decoding 9462 aad_word(u16 val, int base a) */ 9463 DECODE_PRINTF("ERROR DECODING AAM\n"); 9464 TRACE_REGS(); 9465 HALT_SYS(); 9466 } 9467 TRACE_AND_STEP(); 9468 M.x86.R_AX = aad_word(M.x86.R_AX); 9469 DECODE_CLEAR_SEGOVR(); 9470 END_OF_INSTR(); 9471} 9472 9473/* opcode 0xd6 ILLEGAL OPCODE */ 9474 9475/**************************************************************************** 9476REMARKS: 9477Handles opcode 0xd7 9478****************************************************************************/ 9479static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 9480{ 9481 u16 addr; 9482 9483 START_OF_INSTR(); 9484 DECODE_PRINTF("XLAT\n"); 9485 TRACE_AND_STEP(); 9486 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 9487 M.x86.R_AL = fetch_data_byte(addr); 9488 DECODE_CLEAR_SEGOVR(); 9489 END_OF_INSTR(); 9490} 9491 9492/* instuctions D8 .. DF are in i87_ops.c */ 9493 9494/**************************************************************************** 9495REMARKS: 9496Handles opcode 0xe0 9497****************************************************************************/ 9498static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 9499{ 9500 s16 ip; 9501 9502 START_OF_INSTR(); 9503 DECODE_PRINTF("LOOPNE\t"); 9504 ip = (s8) fetch_byte_imm(); 9505 ip += (s16) M.x86.R_IP; 9506 DECODE_PRINTF2("%04x\n", ip); 9507 TRACE_AND_STEP(); 9508 M.x86.R_CX -= 1; 9509 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 9510 M.x86.R_IP = ip; 9511 DECODE_CLEAR_SEGOVR(); 9512 END_OF_INSTR(); 9513} 9514 9515/**************************************************************************** 9516REMARKS: 9517Handles opcode 0xe1 9518****************************************************************************/ 9519static void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 9520{ 9521 s16 ip; 9522 9523 START_OF_INSTR(); 9524 DECODE_PRINTF("LOOPE\t"); 9525 ip = (s8) fetch_byte_imm(); 9526 ip += (s16) M.x86.R_IP; 9527 DECODE_PRINTF2("%04x\n", ip); 9528 TRACE_AND_STEP(); 9529 M.x86.R_CX -= 1; 9530 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 9531 M.x86.R_IP = ip; 9532 DECODE_CLEAR_SEGOVR(); 9533 END_OF_INSTR(); 9534} 9535 9536/**************************************************************************** 9537REMARKS: 9538Handles opcode 0xe2 9539****************************************************************************/ 9540static void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 9541{ 9542 s16 ip; 9543 9544 START_OF_INSTR(); 9545 DECODE_PRINTF("LOOP\t"); 9546 ip = (s8) fetch_byte_imm(); 9547 ip += (s16) M.x86.R_IP; 9548 DECODE_PRINTF2("%04x\n", ip); 9549 TRACE_AND_STEP(); 9550 M.x86.R_CX -= 1; 9551 if (M.x86.R_CX != 0) 9552 M.x86.R_IP = ip; 9553 DECODE_CLEAR_SEGOVR(); 9554 END_OF_INSTR(); 9555} 9556 9557/**************************************************************************** 9558REMARKS: 9559Handles opcode 0xe3 9560****************************************************************************/ 9561static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 9562{ 9563 u16 target; 9564 s8 offset; 9565 9566 /* jump to byte offset if overflow flag is set */ 9567 START_OF_INSTR(); 9568 DECODE_PRINTF("JCXZ\t"); 9569 offset = (s8)fetch_byte_imm(); 9570 target = (u16)(M.x86.R_IP + offset); 9571 DECODE_PRINTF2("%x\n", target); 9572 TRACE_AND_STEP(); 9573 if (M.x86.R_CX == 0) 9574 M.x86.R_IP = target; 9575 DECODE_CLEAR_SEGOVR(); 9576 END_OF_INSTR(); 9577} 9578 9579/**************************************************************************** 9580REMARKS: 9581Handles opcode 0xe4 9582****************************************************************************/ 9583static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 9584{ 9585 u8 port; 9586 9587 START_OF_INSTR(); 9588 DECODE_PRINTF("IN\t"); 9589 port = (u8) fetch_byte_imm(); 9590 DECODE_PRINTF2("%x,AL\n", port); 9591 TRACE_AND_STEP(); 9592 M.x86.R_AL = (*sys_inb)(port); 9593 DECODE_CLEAR_SEGOVR(); 9594 END_OF_INSTR(); 9595} 9596 9597/**************************************************************************** 9598REMARKS: 9599Handles opcode 0xe5 9600****************************************************************************/ 9601static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 9602{ 9603 u8 port; 9604 9605 START_OF_INSTR(); 9606 DECODE_PRINTF("IN\t"); 9607 port = (u8) fetch_byte_imm(); 9608 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9609 DECODE_PRINTF2("EAX,%x\n", port); 9610 } else { 9611 DECODE_PRINTF2("AX,%x\n", port); 9612 } 9613 TRACE_AND_STEP(); 9614 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9615 M.x86.R_EAX = (*sys_inl)(port); 9616 } else { 9617 M.x86.R_AX = (*sys_inw)(port); 9618 } 9619 DECODE_CLEAR_SEGOVR(); 9620 END_OF_INSTR(); 9621} 9622 9623/**************************************************************************** 9624REMARKS: 9625Handles opcode 0xe6 9626****************************************************************************/ 9627static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 9628{ 9629 u8 port; 9630 9631 START_OF_INSTR(); 9632 DECODE_PRINTF("OUT\t"); 9633 port = (u8) fetch_byte_imm(); 9634 DECODE_PRINTF2("%x,AL\n", port); 9635 TRACE_AND_STEP(); 9636 (*sys_outb)(port, M.x86.R_AL); 9637 DECODE_CLEAR_SEGOVR(); 9638 END_OF_INSTR(); 9639} 9640 9641/**************************************************************************** 9642REMARKS: 9643Handles opcode 0xe7 9644****************************************************************************/ 9645static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 9646{ 9647 u8 port; 9648 9649 START_OF_INSTR(); 9650 DECODE_PRINTF("OUT\t"); 9651 port = (u8) fetch_byte_imm(); 9652 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9653 DECODE_PRINTF2("%x,EAX\n", port); 9654 } else { 9655 DECODE_PRINTF2("%x,AX\n", port); 9656 } 9657 TRACE_AND_STEP(); 9658 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9659 (*sys_outl)(port, M.x86.R_EAX); 9660 } else { 9661 (*sys_outw)(port, M.x86.R_AX); 9662 } 9663 DECODE_CLEAR_SEGOVR(); 9664 END_OF_INSTR(); 9665} 9666 9667/**************************************************************************** 9668REMARKS: 9669Handles opcode 0xe8 9670****************************************************************************/ 9671static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 9672{ 9673 s16 ip; 9674 9675 START_OF_INSTR(); 9676 DECODE_PRINTF("CALL\t"); 9677 ip = (s16) fetch_word_imm(); 9678 ip += (s16) M.x86.R_IP; /* CHECK SIGN */ 9679 DECODE_PRINTF2("%04x\n", (u16)ip); 9680 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, ""); 9681 TRACE_AND_STEP(); 9682 push_word(M.x86.R_IP); 9683 M.x86.R_IP = ip; 9684 DECODE_CLEAR_SEGOVR(); 9685 END_OF_INSTR(); 9686} 9687 9688/**************************************************************************** 9689REMARKS: 9690Handles opcode 0xe9 9691****************************************************************************/ 9692static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 9693{ 9694 int ip; 9695 9696 START_OF_INSTR(); 9697 DECODE_PRINTF("JMP\t"); 9698 ip = (s16)fetch_word_imm(); 9699 ip += (s16)M.x86.R_IP; 9700 DECODE_PRINTF2("%04x\n", (u16)ip); 9701 TRACE_AND_STEP(); 9702 M.x86.R_IP = (u16)ip; 9703 DECODE_CLEAR_SEGOVR(); 9704 END_OF_INSTR(); 9705} 9706 9707/**************************************************************************** 9708REMARKS: 9709Handles opcode 0xea 9710****************************************************************************/ 9711static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 9712{ 9713 u16 cs, ip; 9714 9715 START_OF_INSTR(); 9716 DECODE_PRINTF("JMP\tFAR "); 9717 ip = fetch_word_imm(); 9718 cs = fetch_word_imm(); 9719 DECODE_PRINTF2("%04x:", cs); 9720 DECODE_PRINTF2("%04x\n", ip); 9721 TRACE_AND_STEP(); 9722 M.x86.R_IP = ip; 9723 M.x86.R_CS = cs; 9724 DECODE_CLEAR_SEGOVR(); 9725 END_OF_INSTR(); 9726} 9727 9728/**************************************************************************** 9729REMARKS: 9730Handles opcode 0xeb 9731****************************************************************************/ 9732static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 9733{ 9734 u16 target; 9735 s8 offset; 9736 9737 START_OF_INSTR(); 9738 DECODE_PRINTF("JMP\t"); 9739 offset = (s8)fetch_byte_imm(); 9740 target = (u16)(M.x86.R_IP + offset); 9741 DECODE_PRINTF2("%x\n", target); 9742 TRACE_AND_STEP(); 9743 M.x86.R_IP = target; 9744 DECODE_CLEAR_SEGOVR(); 9745 END_OF_INSTR(); 9746} 9747 9748/**************************************************************************** 9749REMARKS: 9750Handles opcode 0xec 9751****************************************************************************/ 9752static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 9753{ 9754 START_OF_INSTR(); 9755 DECODE_PRINTF("IN\tAL,DX\n"); 9756 TRACE_AND_STEP(); 9757 M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 9758 DECODE_CLEAR_SEGOVR(); 9759 END_OF_INSTR(); 9760} 9761 9762/**************************************************************************** 9763REMARKS: 9764Handles opcode 0xed 9765****************************************************************************/ 9766static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 9767{ 9768 START_OF_INSTR(); 9769 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9770 DECODE_PRINTF("IN\tEAX,DX\n"); 9771 } else { 9772 DECODE_PRINTF("IN\tAX,DX\n"); 9773 } 9774 TRACE_AND_STEP(); 9775 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9776 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 9777 } else { 9778 M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 9779 } 9780 DECODE_CLEAR_SEGOVR(); 9781 END_OF_INSTR(); 9782} 9783 9784/**************************************************************************** 9785REMARKS: 9786Handles opcode 0xee 9787****************************************************************************/ 9788static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 9789{ 9790 START_OF_INSTR(); 9791 DECODE_PRINTF("OUT\tDX,AL\n"); 9792 TRACE_AND_STEP(); 9793 (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 9794 DECODE_CLEAR_SEGOVR(); 9795 END_OF_INSTR(); 9796} 9797 9798/**************************************************************************** 9799REMARKS: 9800Handles opcode 0xef 9801****************************************************************************/ 9802static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 9803{ 9804 START_OF_INSTR(); 9805 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9806 DECODE_PRINTF("OUT\tDX,EAX\n"); 9807 } else { 9808 DECODE_PRINTF("OUT\tDX,AX\n"); 9809 } 9810 TRACE_AND_STEP(); 9811 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9812 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 9813 } else { 9814 (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 9815 } 9816 DECODE_CLEAR_SEGOVR(); 9817 END_OF_INSTR(); 9818} 9819 9820/**************************************************************************** 9821REMARKS: 9822Handles opcode 0xf0 9823****************************************************************************/ 9824static void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 9825{ 9826 START_OF_INSTR(); 9827 DECODE_PRINTF("LOCK:\n"); 9828 TRACE_AND_STEP(); 9829 DECODE_CLEAR_SEGOVR(); 9830 END_OF_INSTR(); 9831} 9832 9833/*opcode 0xf1 ILLEGAL OPERATION */ 9834 9835/**************************************************************************** 9836REMARKS: 9837Handles opcode 0xf2 9838****************************************************************************/ 9839static void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 9840{ 9841 START_OF_INSTR(); 9842 DECODE_PRINTF("REPNE\n"); 9843 TRACE_AND_STEP(); 9844 M.x86.mode |= SYSMODE_PREFIX_REPNE; 9845 DECODE_CLEAR_SEGOVR(); 9846 END_OF_INSTR(); 9847} 9848 9849/**************************************************************************** 9850REMARKS: 9851Handles opcode 0xf3 9852****************************************************************************/ 9853static void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 9854{ 9855 START_OF_INSTR(); 9856 DECODE_PRINTF("REPE\n"); 9857 TRACE_AND_STEP(); 9858 M.x86.mode |= SYSMODE_PREFIX_REPE; 9859 DECODE_CLEAR_SEGOVR(); 9860 END_OF_INSTR(); 9861} 9862 9863/**************************************************************************** 9864REMARKS: 9865Handles opcode 0xf4 9866****************************************************************************/ 9867static void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 9868{ 9869 START_OF_INSTR(); 9870 DECODE_PRINTF("HALT\n"); 9871 TRACE_AND_STEP(); 9872 HALT_SYS(); 9873 DECODE_CLEAR_SEGOVR(); 9874 END_OF_INSTR(); 9875} 9876 9877/**************************************************************************** 9878REMARKS: 9879Handles opcode 0xf5 9880****************************************************************************/ 9881static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 9882{ 9883 /* complement the carry flag. */ 9884 START_OF_INSTR(); 9885 DECODE_PRINTF("CMC\n"); 9886 TRACE_AND_STEP(); 9887 TOGGLE_FLAG(F_CF); 9888 DECODE_CLEAR_SEGOVR(); 9889 END_OF_INSTR(); 9890} 9891 9892/**************************************************************************** 9893REMARKS: 9894Handles opcode 0xf6 9895****************************************************************************/ 9896static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 9897{ 9898 int mod, rl, rh; 9899 u8 *destreg; 9900 uint destoffset; 9901 u8 destval, srcval; 9902 9903 /* long, drawn out code follows. Double switch for a total 9904 of 32 cases. */ 9905 START_OF_INSTR(); 9906 FETCH_DECODE_MODRM(mod, rh, rl); 9907 switch (mod) { 9908 case 0: /* mod=00 */ 9909 switch (rh) { 9910 case 0: /* test byte imm */ 9911 DECODE_PRINTF("TEST\tBYTE PTR "); 9912 destoffset = decode_rm00_address(rl); 9913 DECODE_PRINTF(","); 9914 srcval = fetch_byte_imm(); 9915 DECODE_PRINTF2("%02x\n", srcval); 9916 destval = fetch_data_byte(destoffset); 9917 TRACE_AND_STEP(); 9918 test_byte(destval, srcval); 9919 break; 9920 case 1: 9921 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 9922 HALT_SYS(); 9923 break; 9924 case 2: 9925 DECODE_PRINTF("NOT\tBYTE PTR "); 9926 destoffset = decode_rm00_address(rl); 9927 DECODE_PRINTF("\n"); 9928 destval = fetch_data_byte(destoffset); 9929 TRACE_AND_STEP(); 9930 destval = not_byte(destval); 9931 store_data_byte(destoffset, destval); 9932 break; 9933 case 3: 9934 DECODE_PRINTF("NEG\tBYTE PTR "); 9935 destoffset = decode_rm00_address(rl); 9936 DECODE_PRINTF("\n"); 9937 destval = fetch_data_byte(destoffset); 9938 TRACE_AND_STEP(); 9939 destval = neg_byte(destval); 9940 store_data_byte(destoffset, destval); 9941 break; 9942 case 4: 9943 DECODE_PRINTF("MUL\tBYTE PTR "); 9944 destoffset = decode_rm00_address(rl); 9945 DECODE_PRINTF("\n"); 9946 destval = fetch_data_byte(destoffset); 9947 TRACE_AND_STEP(); 9948 mul_byte(destval); 9949 break; 9950 case 5: 9951 DECODE_PRINTF("IMUL\tBYTE PTR "); 9952 destoffset = decode_rm00_address(rl); 9953 DECODE_PRINTF("\n"); 9954 destval = fetch_data_byte(destoffset); 9955 TRACE_AND_STEP(); 9956 imul_byte(destval); 9957 break; 9958 case 6: 9959 DECODE_PRINTF("DIV\tBYTE PTR "); 9960 destoffset = decode_rm00_address(rl); 9961 DECODE_PRINTF("\n"); 9962 destval = fetch_data_byte(destoffset); 9963 TRACE_AND_STEP(); 9964 div_byte(destval); 9965 break; 9966 case 7: 9967 DECODE_PRINTF("IDIV\tBYTE PTR "); 9968 destoffset = decode_rm00_address(rl); 9969 DECODE_PRINTF("\n"); 9970 destval = fetch_data_byte(destoffset); 9971 TRACE_AND_STEP(); 9972 idiv_byte(destval); 9973 break; 9974 } 9975 break; /* end mod==00 */ 9976 case 1: /* mod=01 */ 9977 switch (rh) { 9978 case 0: /* test byte imm */ 9979 DECODE_PRINTF("TEST\tBYTE PTR "); 9980 destoffset = decode_rm01_address(rl); 9981 DECODE_PRINTF(","); 9982 srcval = fetch_byte_imm(); 9983 DECODE_PRINTF2("%02x\n", srcval); 9984 destval = fetch_data_byte(destoffset); 9985 TRACE_AND_STEP(); 9986 test_byte(destval, srcval); 9987 break; 9988 case 1: 9989 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 9990 HALT_SYS(); 9991 break; 9992 case 2: 9993 DECODE_PRINTF("NOT\tBYTE PTR "); 9994 destoffset = decode_rm01_address(rl); 9995 DECODE_PRINTF("\n"); 9996 destval = fetch_data_byte(destoffset); 9997 TRACE_AND_STEP(); 9998 destval = not_byte(destval); 9999 store_data_byte(destoffset, destval); 10000 break; 10001 case 3: 10002 DECODE_PRINTF("NEG\tBYTE PTR "); 10003 destoffset = decode_rm01_address(rl); 10004 DECODE_PRINTF("\n"); 10005 destval = fetch_data_byte(destoffset); 10006 TRACE_AND_STEP(); 10007 destval = neg_byte(destval); 10008 store_data_byte(destoffset, destval); 10009 break; 10010 case 4: 10011 DECODE_PRINTF("MUL\tBYTE PTR "); 10012 destoffset = decode_rm01_address(rl); 10013 DECODE_PRINTF("\n"); 10014 destval = fetch_data_byte(destoffset); 10015 TRACE_AND_STEP(); 10016 mul_byte(destval); 10017 break; 10018 case 5: 10019 DECODE_PRINTF("IMUL\tBYTE PTR "); 10020 destoffset = decode_rm01_address(rl); 10021 DECODE_PRINTF("\n"); 10022 destval = fetch_data_byte(destoffset); 10023 TRACE_AND_STEP(); 10024 imul_byte(destval); 10025 break; 10026 case 6: 10027 DECODE_PRINTF("DIV\tBYTE PTR "); 10028 destoffset = decode_rm01_address(rl); 10029 DECODE_PRINTF("\n"); 10030 destval = fetch_data_byte(destoffset); 10031 TRACE_AND_STEP(); 10032 div_byte(destval); 10033 break; 10034 case 7: 10035 DECODE_PRINTF("IDIV\tBYTE PTR "); 10036 destoffset = decode_rm01_address(rl); 10037 DECODE_PRINTF("\n"); 10038 destval = fetch_data_byte(destoffset); 10039 TRACE_AND_STEP(); 10040 idiv_byte(destval); 10041 break; 10042 } 10043 break; /* end mod==01 */ 10044 case 2: /* mod=10 */ 10045 switch (rh) { 10046 case 0: /* test byte imm */ 10047 DECODE_PRINTF("TEST\tBYTE PTR "); 10048 destoffset = decode_rm10_address(rl); 10049 DECODE_PRINTF(","); 10050 srcval = fetch_byte_imm(); 10051 DECODE_PRINTF2("%02x\n", srcval); 10052 destval = fetch_data_byte(destoffset); 10053 TRACE_AND_STEP(); 10054 test_byte(destval, srcval); 10055 break; 10056 case 1: 10057 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10058 HALT_SYS(); 10059 break; 10060 case 2: 10061 DECODE_PRINTF("NOT\tBYTE PTR "); 10062 destoffset = decode_rm10_address(rl); 10063 DECODE_PRINTF("\n"); 10064 destval = fetch_data_byte(destoffset); 10065 TRACE_AND_STEP(); 10066 destval = not_byte(destval); 10067 store_data_byte(destoffset, destval); 10068 break; 10069 case 3: 10070 DECODE_PRINTF("NEG\tBYTE PTR "); 10071 destoffset = decode_rm10_address(rl); 10072 DECODE_PRINTF("\n"); 10073 destval = fetch_data_byte(destoffset); 10074 TRACE_AND_STEP(); 10075 destval = neg_byte(destval); 10076 store_data_byte(destoffset, destval); 10077 break; 10078 case 4: 10079 DECODE_PRINTF("MUL\tBYTE PTR "); 10080 destoffset = decode_rm10_address(rl); 10081 DECODE_PRINTF("\n"); 10082 destval = fetch_data_byte(destoffset); 10083 TRACE_AND_STEP(); 10084 mul_byte(destval); 10085 break; 10086 case 5: 10087 DECODE_PRINTF("IMUL\tBYTE PTR "); 10088 destoffset = decode_rm10_address(rl); 10089 DECODE_PRINTF("\n"); 10090 destval = fetch_data_byte(destoffset); 10091 TRACE_AND_STEP(); 10092 imul_byte(destval); 10093 break; 10094 case 6: 10095 DECODE_PRINTF("DIV\tBYTE PTR "); 10096 destoffset = decode_rm10_address(rl); 10097 DECODE_PRINTF("\n"); 10098 destval = fetch_data_byte(destoffset); 10099 TRACE_AND_STEP(); 10100 div_byte(destval); 10101 break; 10102 case 7: 10103 DECODE_PRINTF("IDIV\tBYTE PTR "); 10104 destoffset = decode_rm10_address(rl); 10105 DECODE_PRINTF("\n"); 10106 destval = fetch_data_byte(destoffset); 10107 TRACE_AND_STEP(); 10108 idiv_byte(destval); 10109 break; 10110 } 10111 break; /* end mod==10 */ 10112 case 3: /* mod=11 */ 10113 switch (rh) { 10114 case 0: /* test byte imm */ 10115 DECODE_PRINTF("TEST\t"); 10116 destreg = DECODE_RM_BYTE_REGISTER(rl); 10117 DECODE_PRINTF(","); 10118 srcval = fetch_byte_imm(); 10119 DECODE_PRINTF2("%02x\n", srcval); 10120 TRACE_AND_STEP(); 10121 test_byte(*destreg, srcval); 10122 break; 10123 case 1: 10124 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10125 HALT_SYS(); 10126 break; 10127 case 2: 10128 DECODE_PRINTF("NOT\t"); 10129 destreg = DECODE_RM_BYTE_REGISTER(rl); 10130 DECODE_PRINTF("\n"); 10131 TRACE_AND_STEP(); 10132 *destreg = not_byte(*destreg); 10133 break; 10134 case 3: 10135 DECODE_PRINTF("NEG\t"); 10136 destreg = DECODE_RM_BYTE_REGISTER(rl); 10137 DECODE_PRINTF("\n"); 10138 TRACE_AND_STEP(); 10139 *destreg = neg_byte(*destreg); 10140 break; 10141 case 4: 10142 DECODE_PRINTF("MUL\t"); 10143 destreg = DECODE_RM_BYTE_REGISTER(rl); 10144 DECODE_PRINTF("\n"); 10145 TRACE_AND_STEP(); 10146 mul_byte(*destreg); /*!!! */ 10147 break; 10148 case 5: 10149 DECODE_PRINTF("IMUL\t"); 10150 destreg = DECODE_RM_BYTE_REGISTER(rl); 10151 DECODE_PRINTF("\n"); 10152 TRACE_AND_STEP(); 10153 imul_byte(*destreg); 10154 break; 10155 case 6: 10156 DECODE_PRINTF("DIV\t"); 10157 destreg = DECODE_RM_BYTE_REGISTER(rl); 10158 DECODE_PRINTF("\n"); 10159 TRACE_AND_STEP(); 10160 div_byte(*destreg); 10161 break; 10162 case 7: 10163 DECODE_PRINTF("IDIV\t"); 10164 destreg = DECODE_RM_BYTE_REGISTER(rl); 10165 DECODE_PRINTF("\n"); 10166 TRACE_AND_STEP(); 10167 idiv_byte(*destreg); 10168 break; 10169 } 10170 break; /* end mod==11 */ 10171 } 10172 DECODE_CLEAR_SEGOVR(); 10173 END_OF_INSTR(); 10174} 10175 10176/**************************************************************************** 10177REMARKS: 10178Handles opcode 0xf7 10179****************************************************************************/ 10180static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 10181{ 10182 int mod, rl, rh; 10183 uint destoffset; 10184 10185 /* long, drawn out code follows. Double switch for a total 10186 of 32 cases. */ 10187 START_OF_INSTR(); 10188 FETCH_DECODE_MODRM(mod, rh, rl); 10189 switch (mod) { 10190 case 0: /* mod=00 */ 10191 switch (rh) { 10192 case 0: /* test word imm */ 10193 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10194 u32 destval,srcval; 10195 10196 DECODE_PRINTF("TEST\tDWORD PTR "); 10197 destoffset = decode_rm00_address(rl); 10198 DECODE_PRINTF(","); 10199 srcval = fetch_long_imm(); 10200 DECODE_PRINTF2("%x\n", srcval); 10201 destval = fetch_data_long(destoffset); 10202 TRACE_AND_STEP(); 10203 test_long(destval, srcval); 10204 } else { 10205 u16 destval,srcval; 10206 10207 DECODE_PRINTF("TEST\tWORD PTR "); 10208 destoffset = decode_rm00_address(rl); 10209 DECODE_PRINTF(","); 10210 srcval = fetch_word_imm(); 10211 DECODE_PRINTF2("%x\n", srcval); 10212 destval = fetch_data_word(destoffset); 10213 TRACE_AND_STEP(); 10214 test_word(destval, srcval); 10215 } 10216 break; 10217 case 1: 10218 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 10219 HALT_SYS(); 10220 break; 10221 case 2: 10222 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10223 u32 destval; 10224 10225 DECODE_PRINTF("NOT\tDWORD PTR "); 10226 destoffset = decode_rm00_address(rl); 10227 DECODE_PRINTF("\n"); 10228 destval = fetch_data_long(destoffset); 10229 TRACE_AND_STEP(); 10230 destval = not_long(destval); 10231 store_data_long(destoffset, destval); 10232 } else { 10233 u16 destval; 10234 10235 DECODE_PRINTF("NOT\tWORD PTR "); 10236 destoffset = decode_rm00_address(rl); 10237 DECODE_PRINTF("\n"); 10238 destval = fetch_data_word(destoffset); 10239 TRACE_AND_STEP(); 10240 destval = not_word(destval); 10241 store_data_word(destoffset, destval); 10242 } 10243 break; 10244 case 3: 10245 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10246 u32 destval; 10247 10248 DECODE_PRINTF("NEG\tDWORD PTR "); 10249 destoffset = decode_rm00_address(rl); 10250 DECODE_PRINTF("\n"); 10251 destval = fetch_data_long(destoffset); 10252 TRACE_AND_STEP(); 10253 destval = neg_long(destval); 10254 store_data_long(destoffset, destval); 10255 } else { 10256 u16 destval; 10257 10258 DECODE_PRINTF("NEG\tWORD PTR "); 10259 destoffset = decode_rm00_address(rl); 10260 DECODE_PRINTF("\n"); 10261 destval = fetch_data_word(destoffset); 10262 TRACE_AND_STEP(); 10263 destval = neg_word(destval); 10264 store_data_word(destoffset, destval); 10265 } 10266 break; 10267 case 4: 10268 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10269 u32 destval; 10270 10271 DECODE_PRINTF("MUL\tDWORD PTR "); 10272 destoffset = decode_rm00_address(rl); 10273 DECODE_PRINTF("\n"); 10274 destval = fetch_data_long(destoffset); 10275 TRACE_AND_STEP(); 10276 mul_long(destval); 10277 } else { 10278 u16 destval; 10279 10280 DECODE_PRINTF("MUL\tWORD PTR "); 10281 destoffset = decode_rm00_address(rl); 10282 DECODE_PRINTF("\n"); 10283 destval = fetch_data_word(destoffset); 10284 TRACE_AND_STEP(); 10285 mul_word(destval); 10286 } 10287 break; 10288 case 5: 10289 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10290 u32 destval; 10291 10292 DECODE_PRINTF("IMUL\tDWORD PTR "); 10293 destoffset = decode_rm00_address(rl); 10294 DECODE_PRINTF("\n"); 10295 destval = fetch_data_long(destoffset); 10296 TRACE_AND_STEP(); 10297 imul_long(destval); 10298 } else { 10299 u16 destval; 10300 10301 DECODE_PRINTF("IMUL\tWORD PTR "); 10302 destoffset = decode_rm00_address(rl); 10303 DECODE_PRINTF("\n"); 10304 destval = fetch_data_word(destoffset); 10305 TRACE_AND_STEP(); 10306 imul_word(destval); 10307 } 10308 break; 10309 case 6: 10310 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10311 u32 destval; 10312 10313 DECODE_PRINTF("DIV\tDWORD PTR "); 10314 destoffset = decode_rm00_address(rl); 10315 DECODE_PRINTF("\n"); 10316 destval = fetch_data_long(destoffset); 10317 TRACE_AND_STEP(); 10318 div_long(destval); 10319 } else { 10320 u16 destval; 10321 10322 DECODE_PRINTF("DIV\tWORD PTR "); 10323 destoffset = decode_rm00_address(rl); 10324 DECODE_PRINTF("\n"); 10325 destval = fetch_data_word(destoffset); 10326 TRACE_AND_STEP(); 10327 div_word(destval); 10328 } 10329 break; 10330 case 7: 10331 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10332 u32 destval; 10333 10334 DECODE_PRINTF("IDIV\tDWORD PTR "); 10335 destoffset = decode_rm00_address(rl); 10336 DECODE_PRINTF("\n"); 10337 destval = fetch_data_long(destoffset); 10338 TRACE_AND_STEP(); 10339 idiv_long(destval); 10340 } else { 10341 u16 destval; 10342 10343 DECODE_PRINTF("IDIV\tWORD PTR "); 10344 destoffset = decode_rm00_address(rl); 10345 DECODE_PRINTF("\n"); 10346 destval = fetch_data_word(destoffset); 10347 TRACE_AND_STEP(); 10348 idiv_word(destval); 10349 } 10350 break; 10351 } 10352 break; /* end mod==00 */ 10353 case 1: /* mod=01 */ 10354 switch (rh) { 10355 case 0: /* test word imm */ 10356 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10357 u32 destval,srcval; 10358 10359 DECODE_PRINTF("TEST\tDWORD PTR "); 10360 destoffset = decode_rm01_address(rl); 10361 DECODE_PRINTF(","); 10362 srcval = fetch_long_imm(); 10363 DECODE_PRINTF2("%x\n", srcval); 10364 destval = fetch_data_long(destoffset); 10365 TRACE_AND_STEP(); 10366 test_long(destval, srcval); 10367 } else { 10368 u16 destval,srcval; 10369 10370 DECODE_PRINTF("TEST\tWORD PTR "); 10371 destoffset = decode_rm01_address(rl); 10372 DECODE_PRINTF(","); 10373 srcval = fetch_word_imm(); 10374 DECODE_PRINTF2("%x\n", srcval); 10375 destval = fetch_data_word(destoffset); 10376 TRACE_AND_STEP(); 10377 test_word(destval, srcval); 10378 } 10379 break; 10380 case 1: 10381 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10382 HALT_SYS(); 10383 break; 10384 case 2: 10385 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10386 u32 destval; 10387 10388 DECODE_PRINTF("NOT\tDWORD PTR "); 10389 destoffset = decode_rm01_address(rl); 10390 DECODE_PRINTF("\n"); 10391 destval = fetch_data_long(destoffset); 10392 TRACE_AND_STEP(); 10393 destval = not_long(destval); 10394 store_data_long(destoffset, destval); 10395 } else { 10396 u16 destval; 10397 10398 DECODE_PRINTF("NOT\tWORD PTR "); 10399 destoffset = decode_rm01_address(rl); 10400 DECODE_PRINTF("\n"); 10401 destval = fetch_data_word(destoffset); 10402 TRACE_AND_STEP(); 10403 destval = not_word(destval); 10404 store_data_word(destoffset, destval); 10405 } 10406 break; 10407 case 3: 10408 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10409 u32 destval; 10410 10411 DECODE_PRINTF("NEG\tDWORD PTR "); 10412 destoffset = decode_rm01_address(rl); 10413 DECODE_PRINTF("\n"); 10414 destval = fetch_data_long(destoffset); 10415 TRACE_AND_STEP(); 10416 destval = neg_long(destval); 10417 store_data_long(destoffset, destval); 10418 } else { 10419 u16 destval; 10420 10421 DECODE_PRINTF("NEG\tWORD PTR "); 10422 destoffset = decode_rm01_address(rl); 10423 DECODE_PRINTF("\n"); 10424 destval = fetch_data_word(destoffset); 10425 TRACE_AND_STEP(); 10426 destval = neg_word(destval); 10427 store_data_word(destoffset, destval); 10428 } 10429 break; 10430 case 4: 10431 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10432 u32 destval; 10433 10434 DECODE_PRINTF("MUL\tDWORD PTR "); 10435 destoffset = decode_rm01_address(rl); 10436 DECODE_PRINTF("\n"); 10437 destval = fetch_data_long(destoffset); 10438 TRACE_AND_STEP(); 10439 mul_long(destval); 10440 } else { 10441 u16 destval; 10442 10443 DECODE_PRINTF("MUL\tWORD PTR "); 10444 destoffset = decode_rm01_address(rl); 10445 DECODE_PRINTF("\n"); 10446 destval = fetch_data_word(destoffset); 10447 TRACE_AND_STEP(); 10448 mul_word(destval); 10449 } 10450 break; 10451 case 5: 10452 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10453 u32 destval; 10454 10455 DECODE_PRINTF("IMUL\tDWORD PTR "); 10456 destoffset = decode_rm01_address(rl); 10457 DECODE_PRINTF("\n"); 10458 destval = fetch_data_long(destoffset); 10459 TRACE_AND_STEP(); 10460 imul_long(destval); 10461 } else { 10462 u16 destval; 10463 10464 DECODE_PRINTF("IMUL\tWORD PTR "); 10465 destoffset = decode_rm01_address(rl); 10466 DECODE_PRINTF("\n"); 10467 destval = fetch_data_word(destoffset); 10468 TRACE_AND_STEP(); 10469 imul_word(destval); 10470 } 10471 break; 10472 case 6: 10473 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10474 u32 destval; 10475 10476 DECODE_PRINTF("DIV\tDWORD PTR "); 10477 destoffset = decode_rm01_address(rl); 10478 DECODE_PRINTF("\n"); 10479 destval = fetch_data_long(destoffset); 10480 TRACE_AND_STEP(); 10481 div_long(destval); 10482 } else { 10483 u16 destval; 10484 10485 DECODE_PRINTF("DIV\tWORD PTR "); 10486 destoffset = decode_rm01_address(rl); 10487 DECODE_PRINTF("\n"); 10488 destval = fetch_data_word(destoffset); 10489 TRACE_AND_STEP(); 10490 div_word(destval); 10491 } 10492 break; 10493 case 7: 10494 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10495 u32 destval; 10496 10497 DECODE_PRINTF("IDIV\tDWORD PTR "); 10498 destoffset = decode_rm01_address(rl); 10499 DECODE_PRINTF("\n"); 10500 destval = fetch_data_long(destoffset); 10501 TRACE_AND_STEP(); 10502 idiv_long(destval); 10503 } else { 10504 u16 destval; 10505 10506 DECODE_PRINTF("IDIV\tWORD PTR "); 10507 destoffset = decode_rm01_address(rl); 10508 DECODE_PRINTF("\n"); 10509 destval = fetch_data_word(destoffset); 10510 TRACE_AND_STEP(); 10511 idiv_word(destval); 10512 } 10513 break; 10514 } 10515 break; /* end mod==01 */ 10516 case 2: /* mod=10 */ 10517 switch (rh) { 10518 case 0: /* test word imm */ 10519 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10520 u32 destval,srcval; 10521 10522 DECODE_PRINTF("TEST\tDWORD PTR "); 10523 destoffset = decode_rm10_address(rl); 10524 DECODE_PRINTF(","); 10525 srcval = fetch_long_imm(); 10526 DECODE_PRINTF2("%x\n", srcval); 10527 destval = fetch_data_long(destoffset); 10528 TRACE_AND_STEP(); 10529 test_long(destval, srcval); 10530 } else { 10531 u16 destval,srcval; 10532 10533 DECODE_PRINTF("TEST\tWORD PTR "); 10534 destoffset = decode_rm10_address(rl); 10535 DECODE_PRINTF(","); 10536 srcval = fetch_word_imm(); 10537 DECODE_PRINTF2("%x\n", srcval); 10538 destval = fetch_data_word(destoffset); 10539 TRACE_AND_STEP(); 10540 test_word(destval, srcval); 10541 } 10542 break; 10543 case 1: 10544 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10545 HALT_SYS(); 10546 break; 10547 case 2: 10548 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10549 u32 destval; 10550 10551 DECODE_PRINTF("NOT\tDWORD PTR "); 10552 destoffset = decode_rm10_address(rl); 10553 DECODE_PRINTF("\n"); 10554 destval = fetch_data_long(destoffset); 10555 TRACE_AND_STEP(); 10556 destval = not_long(destval); 10557 store_data_long(destoffset, destval); 10558 } else { 10559 u16 destval; 10560 10561 DECODE_PRINTF("NOT\tWORD PTR "); 10562 destoffset = decode_rm10_address(rl); 10563 DECODE_PRINTF("\n"); 10564 destval = fetch_data_word(destoffset); 10565 TRACE_AND_STEP(); 10566 destval = not_word(destval); 10567 store_data_word(destoffset, destval); 10568 } 10569 break; 10570 case 3: 10571 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10572 u32 destval; 10573 10574 DECODE_PRINTF("NEG\tDWORD PTR "); 10575 destoffset = decode_rm10_address(rl); 10576 DECODE_PRINTF("\n"); 10577 destval = fetch_data_long(destoffset); 10578 TRACE_AND_STEP(); 10579 destval = neg_long(destval); 10580 store_data_long(destoffset, destval); 10581 } else { 10582 u16 destval; 10583 10584 DECODE_PRINTF("NEG\tWORD PTR "); 10585 destoffset = decode_rm10_address(rl); 10586 DECODE_PRINTF("\n"); 10587 destval = fetch_data_word(destoffset); 10588 TRACE_AND_STEP(); 10589 destval = neg_word(destval); 10590 store_data_word(destoffset, destval); 10591 } 10592 break; 10593 case 4: 10594 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10595 u32 destval; 10596 10597 DECODE_PRINTF("MUL\tDWORD PTR "); 10598 destoffset = decode_rm10_address(rl); 10599 DECODE_PRINTF("\n"); 10600 destval = fetch_data_long(destoffset); 10601 TRACE_AND_STEP(); 10602 mul_long(destval); 10603 } else { 10604 u16 destval; 10605 10606 DECODE_PRINTF("MUL\tWORD PTR "); 10607 destoffset = decode_rm10_address(rl); 10608 DECODE_PRINTF("\n"); 10609 destval = fetch_data_word(destoffset); 10610 TRACE_AND_STEP(); 10611 mul_word(destval); 10612 } 10613 break; 10614 case 5: 10615 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10616 u32 destval; 10617 10618 DECODE_PRINTF("IMUL\tDWORD PTR "); 10619 destoffset = decode_rm10_address(rl); 10620 DECODE_PRINTF("\n"); 10621 destval = fetch_data_long(destoffset); 10622 TRACE_AND_STEP(); 10623 imul_long(destval); 10624 } else { 10625 u16 destval; 10626 10627 DECODE_PRINTF("IMUL\tWORD PTR "); 10628 destoffset = decode_rm10_address(rl); 10629 DECODE_PRINTF("\n"); 10630 destval = fetch_data_word(destoffset); 10631 TRACE_AND_STEP(); 10632 imul_word(destval); 10633 } 10634 break; 10635 case 6: 10636 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10637 u32 destval; 10638 10639 DECODE_PRINTF("DIV\tDWORD PTR "); 10640 destoffset = decode_rm10_address(rl); 10641 DECODE_PRINTF("\n"); 10642 destval = fetch_data_long(destoffset); 10643 TRACE_AND_STEP(); 10644 div_long(destval); 10645 } else { 10646 u16 destval; 10647 10648 DECODE_PRINTF("DIV\tWORD PTR "); 10649 destoffset = decode_rm10_address(rl); 10650 DECODE_PRINTF("\n"); 10651 destval = fetch_data_word(destoffset); 10652 TRACE_AND_STEP(); 10653 div_word(destval); 10654 } 10655 break; 10656 case 7: 10657 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10658 u32 destval; 10659 10660 DECODE_PRINTF("IDIV\tDWORD PTR "); 10661 destoffset = decode_rm10_address(rl); 10662 DECODE_PRINTF("\n"); 10663 destval = fetch_data_long(destoffset); 10664 TRACE_AND_STEP(); 10665 idiv_long(destval); 10666 } else { 10667 u16 destval; 10668 10669 DECODE_PRINTF("IDIV\tWORD PTR "); 10670 destoffset = decode_rm10_address(rl); 10671 DECODE_PRINTF("\n"); 10672 destval = fetch_data_word(destoffset); 10673 TRACE_AND_STEP(); 10674 idiv_word(destval); 10675 } 10676 break; 10677 } 10678 break; /* end mod==10 */ 10679 case 3: /* mod=11 */ 10680 switch (rh) { 10681 case 0: /* test word imm */ 10682 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10683 u32 *destreg; 10684 u32 srcval; 10685 10686 DECODE_PRINTF("TEST\t"); 10687 destreg = DECODE_RM_LONG_REGISTER(rl); 10688 DECODE_PRINTF(","); 10689 srcval = fetch_long_imm(); 10690 DECODE_PRINTF2("%x\n", srcval); 10691 TRACE_AND_STEP(); 10692 test_long(*destreg, srcval); 10693 } else { 10694 u16 *destreg; 10695 u16 srcval; 10696 10697 DECODE_PRINTF("TEST\t"); 10698 destreg = DECODE_RM_WORD_REGISTER(rl); 10699 DECODE_PRINTF(","); 10700 srcval = fetch_word_imm(); 10701 DECODE_PRINTF2("%x\n", srcval); 10702 TRACE_AND_STEP(); 10703 test_word(*destreg, srcval); 10704 } 10705 break; 10706 case 1: 10707 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10708 HALT_SYS(); 10709 break; 10710 case 2: 10711 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10712 u32 *destreg; 10713 10714 DECODE_PRINTF("NOT\t"); 10715 destreg = DECODE_RM_LONG_REGISTER(rl); 10716 DECODE_PRINTF("\n"); 10717 TRACE_AND_STEP(); 10718 *destreg = not_long(*destreg); 10719 } else { 10720 u16 *destreg; 10721 10722 DECODE_PRINTF("NOT\t"); 10723 destreg = DECODE_RM_WORD_REGISTER(rl); 10724 DECODE_PRINTF("\n"); 10725 TRACE_AND_STEP(); 10726 *destreg = not_word(*destreg); 10727 } 10728 break; 10729 case 3: 10730 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10731 u32 *destreg; 10732 10733 DECODE_PRINTF("NEG\t"); 10734 destreg = DECODE_RM_LONG_REGISTER(rl); 10735 DECODE_PRINTF("\n"); 10736 TRACE_AND_STEP(); 10737 *destreg = neg_long(*destreg); 10738 } else { 10739 u16 *destreg; 10740 10741 DECODE_PRINTF("NEG\t"); 10742 destreg = DECODE_RM_WORD_REGISTER(rl); 10743 DECODE_PRINTF("\n"); 10744 TRACE_AND_STEP(); 10745 *destreg = neg_word(*destreg); 10746 } 10747 break; 10748 case 4: 10749 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10750 u32 *destreg; 10751 10752 DECODE_PRINTF("MUL\t"); 10753 destreg = DECODE_RM_LONG_REGISTER(rl); 10754 DECODE_PRINTF("\n"); 10755 TRACE_AND_STEP(); 10756 mul_long(*destreg); /*!!! */ 10757 } else { 10758 u16 *destreg; 10759 10760 DECODE_PRINTF("MUL\t"); 10761 destreg = DECODE_RM_WORD_REGISTER(rl); 10762 DECODE_PRINTF("\n"); 10763 TRACE_AND_STEP(); 10764 mul_word(*destreg); /*!!! */ 10765 } 10766 break; 10767 case 5: 10768 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10769 u32 *destreg; 10770 10771 DECODE_PRINTF("IMUL\t"); 10772 destreg = DECODE_RM_LONG_REGISTER(rl); 10773 DECODE_PRINTF("\n"); 10774 TRACE_AND_STEP(); 10775 imul_long(*destreg); 10776 } else { 10777 u16 *destreg; 10778 10779 DECODE_PRINTF("IMUL\t"); 10780 destreg = DECODE_RM_WORD_REGISTER(rl); 10781 DECODE_PRINTF("\n"); 10782 TRACE_AND_STEP(); 10783 imul_word(*destreg); 10784 } 10785 break; 10786 case 6: 10787 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10788 u32 *destreg; 10789 10790 DECODE_PRINTF("DIV\t"); 10791 destreg = DECODE_RM_LONG_REGISTER(rl); 10792 DECODE_PRINTF("\n"); 10793 TRACE_AND_STEP(); 10794 div_long(*destreg); 10795 } else { 10796 u16 *destreg; 10797 10798 DECODE_PRINTF("DIV\t"); 10799 destreg = DECODE_RM_WORD_REGISTER(rl); 10800 DECODE_PRINTF("\n"); 10801 TRACE_AND_STEP(); 10802 div_word(*destreg); 10803 } 10804 break; 10805 case 7: 10806 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10807 u32 *destreg; 10808 10809 DECODE_PRINTF("IDIV\t"); 10810 destreg = DECODE_RM_LONG_REGISTER(rl); 10811 DECODE_PRINTF("\n"); 10812 TRACE_AND_STEP(); 10813 idiv_long(*destreg); 10814 } else { 10815 u16 *destreg; 10816 10817 DECODE_PRINTF("IDIV\t"); 10818 destreg = DECODE_RM_WORD_REGISTER(rl); 10819 DECODE_PRINTF("\n"); 10820 TRACE_AND_STEP(); 10821 idiv_word(*destreg); 10822 } 10823 break; 10824 } 10825 break; /* end mod==11 */ 10826 } 10827 DECODE_CLEAR_SEGOVR(); 10828 END_OF_INSTR(); 10829} 10830 10831/**************************************************************************** 10832REMARKS: 10833Handles opcode 0xf8 10834****************************************************************************/ 10835static void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 10836{ 10837 /* clear the carry flag. */ 10838 START_OF_INSTR(); 10839 DECODE_PRINTF("CLC\n"); 10840 TRACE_AND_STEP(); 10841 CLEAR_FLAG(F_CF); 10842 DECODE_CLEAR_SEGOVR(); 10843 END_OF_INSTR(); 10844} 10845 10846/**************************************************************************** 10847REMARKS: 10848Handles opcode 0xf9 10849****************************************************************************/ 10850static void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 10851{ 10852 /* set the carry flag. */ 10853 START_OF_INSTR(); 10854 DECODE_PRINTF("STC\n"); 10855 TRACE_AND_STEP(); 10856 SET_FLAG(F_CF); 10857 DECODE_CLEAR_SEGOVR(); 10858 END_OF_INSTR(); 10859} 10860 10861/**************************************************************************** 10862REMARKS: 10863Handles opcode 0xfa 10864****************************************************************************/ 10865static void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 10866{ 10867 /* clear interrupts. */ 10868 START_OF_INSTR(); 10869 DECODE_PRINTF("CLI\n"); 10870 TRACE_AND_STEP(); 10871 CLEAR_FLAG(F_IF); 10872 DECODE_CLEAR_SEGOVR(); 10873 END_OF_INSTR(); 10874} 10875 10876/**************************************************************************** 10877REMARKS: 10878Handles opcode 0xfb 10879****************************************************************************/ 10880static void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 10881{ 10882 /* enable interrupts. */ 10883 START_OF_INSTR(); 10884 DECODE_PRINTF("STI\n"); 10885 TRACE_AND_STEP(); 10886 SET_FLAG(F_IF); 10887 DECODE_CLEAR_SEGOVR(); 10888 END_OF_INSTR(); 10889} 10890 10891/**************************************************************************** 10892REMARKS: 10893Handles opcode 0xfc 10894****************************************************************************/ 10895static void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 10896{ 10897 /* clear interrupts. */ 10898 START_OF_INSTR(); 10899 DECODE_PRINTF("CLD\n"); 10900 TRACE_AND_STEP(); 10901 CLEAR_FLAG(F_DF); 10902 DECODE_CLEAR_SEGOVR(); 10903 END_OF_INSTR(); 10904} 10905 10906/**************************************************************************** 10907REMARKS: 10908Handles opcode 0xfd 10909****************************************************************************/ 10910static void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 10911{ 10912 /* clear interrupts. */ 10913 START_OF_INSTR(); 10914 DECODE_PRINTF("STD\n"); 10915 TRACE_AND_STEP(); 10916 SET_FLAG(F_DF); 10917 DECODE_CLEAR_SEGOVR(); 10918 END_OF_INSTR(); 10919} 10920 10921/**************************************************************************** 10922REMARKS: 10923Handles opcode 0xfe 10924****************************************************************************/ 10925static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 10926{ 10927 int mod, rh, rl; 10928 u8 destval; 10929 uint destoffset; 10930 u8 *destreg; 10931 10932 /* Yet another special case instruction. */ 10933 START_OF_INSTR(); 10934 FETCH_DECODE_MODRM(mod, rh, rl); 10935#ifdef DEBUG 10936 if (DEBUG_DECODE()) { 10937 /* XXX DECODE_PRINTF may be changed to something more 10938 general, so that it is important to leave the strings 10939 in the same format, even though the result is that the 10940 above test is done twice. */ 10941 10942 switch (rh) { 10943 case 0: 10944 DECODE_PRINTF("INC\t"); 10945 break; 10946 case 1: 10947 DECODE_PRINTF("DEC\t"); 10948 break; 10949 case 2: 10950 case 3: 10951 case 4: 10952 case 5: 10953 case 6: 10954 case 7: 10955 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 10956 HALT_SYS(); 10957 break; 10958 } 10959 } 10960#endif 10961 switch (mod) { 10962 case 0: 10963 DECODE_PRINTF("BYTE PTR "); 10964 destoffset = decode_rm00_address(rl); 10965 DECODE_PRINTF("\n"); 10966 switch (rh) { 10967 case 0: /* inc word ptr ... */ 10968 destval = fetch_data_byte(destoffset); 10969 TRACE_AND_STEP(); 10970 destval = inc_byte(destval); 10971 store_data_byte(destoffset, destval); 10972 break; 10973 case 1: /* dec word ptr ... */ 10974 destval = fetch_data_byte(destoffset); 10975 TRACE_AND_STEP(); 10976 destval = dec_byte(destval); 10977 store_data_byte(destoffset, destval); 10978 break; 10979 } 10980 break; 10981 case 1: 10982 DECODE_PRINTF("BYTE PTR "); 10983 destoffset = decode_rm01_address(rl); 10984 DECODE_PRINTF("\n"); 10985 switch (rh) { 10986 case 0: 10987 destval = fetch_data_byte(destoffset); 10988 TRACE_AND_STEP(); 10989 destval = inc_byte(destval); 10990 store_data_byte(destoffset, destval); 10991 break; 10992 case 1: 10993 destval = fetch_data_byte(destoffset); 10994 TRACE_AND_STEP(); 10995 destval = dec_byte(destval); 10996 store_data_byte(destoffset, destval); 10997 break; 10998 } 10999 break; 11000 case 2: 11001 DECODE_PRINTF("BYTE PTR "); 11002 destoffset = decode_rm10_address(rl); 11003 DECODE_PRINTF("\n"); 11004 switch (rh) { 11005 case 0: 11006 destval = fetch_data_byte(destoffset); 11007 TRACE_AND_STEP(); 11008 destval = inc_byte(destval); 11009 store_data_byte(destoffset, destval); 11010 break; 11011 case 1: 11012 destval = fetch_data_byte(destoffset); 11013 TRACE_AND_STEP(); 11014 destval = dec_byte(destval); 11015 store_data_byte(destoffset, destval); 11016 break; 11017 } 11018 break; 11019 case 3: 11020 destreg = DECODE_RM_BYTE_REGISTER(rl); 11021 DECODE_PRINTF("\n"); 11022 switch (rh) { 11023 case 0: 11024 TRACE_AND_STEP(); 11025 *destreg = inc_byte(*destreg); 11026 break; 11027 case 1: 11028 TRACE_AND_STEP(); 11029 *destreg = dec_byte(*destreg); 11030 break; 11031 } 11032 break; 11033 } 11034 DECODE_CLEAR_SEGOVR(); 11035 END_OF_INSTR(); 11036} 11037 11038/**************************************************************************** 11039REMARKS: 11040Handles opcode 0xff 11041****************************************************************************/ 11042static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 11043{ 11044 int mod, rh, rl; 11045 uint destoffset = 0; 11046 u16 *destreg; 11047 u16 destval,destval2; 11048 11049 /* Yet another special case instruction. */ 11050 START_OF_INSTR(); 11051 FETCH_DECODE_MODRM(mod, rh, rl); 11052#ifdef DEBUG 11053 if (DEBUG_DECODE()) { 11054 /* XXX DECODE_PRINTF may be changed to something more 11055 general, so that it is important to leave the strings 11056 in the same format, even though the result is that the 11057 above test is done twice. */ 11058 11059 switch (rh) { 11060 case 0: 11061 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11062 DECODE_PRINTF("INC\tDWORD PTR "); 11063 } else { 11064 DECODE_PRINTF("INC\tWORD PTR "); 11065 } 11066 break; 11067 case 1: 11068 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11069 DECODE_PRINTF("DEC\tDWORD PTR "); 11070 } else { 11071 DECODE_PRINTF("DEC\tWORD PTR "); 11072 } 11073 break; 11074 case 2: 11075 DECODE_PRINTF("CALL\t"); 11076 break; 11077 case 3: 11078 DECODE_PRINTF("CALL\tFAR "); 11079 break; 11080 case 4: 11081 DECODE_PRINTF("JMP\t"); 11082 break; 11083 case 5: 11084 DECODE_PRINTF("JMP\tFAR "); 11085 break; 11086 case 6: 11087 DECODE_PRINTF("PUSH\t"); 11088 break; 11089 case 7: 11090 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 11091 HALT_SYS(); 11092 break; 11093 } 11094 } 11095#endif 11096 switch (mod) { 11097 case 0: 11098 destoffset = decode_rm00_address(rl); 11099 DECODE_PRINTF("\n"); 11100 switch (rh) { 11101 case 0: /* inc word ptr ... */ 11102 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11103 u32 destval; 11104 11105 destval = fetch_data_long(destoffset); 11106 TRACE_AND_STEP(); 11107 destval = inc_long(destval); 11108 store_data_long(destoffset, destval); 11109 } else { 11110 u16 destval; 11111 11112 destval = fetch_data_word(destoffset); 11113 TRACE_AND_STEP(); 11114 destval = inc_word(destval); 11115 store_data_word(destoffset, destval); 11116 } 11117 break; 11118 case 1: /* dec word ptr ... */ 11119 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11120 u32 destval; 11121 11122 destval = fetch_data_long(destoffset); 11123 TRACE_AND_STEP(); 11124 destval = dec_long(destval); 11125 store_data_long(destoffset, destval); 11126 } else { 11127 u16 destval; 11128 11129 destval = fetch_data_word(destoffset); 11130 TRACE_AND_STEP(); 11131 destval = dec_word(destval); 11132 store_data_word(destoffset, destval); 11133 } 11134 break; 11135 case 2: /* call word ptr ... */ 11136 destval = fetch_data_word(destoffset); 11137 TRACE_AND_STEP(); 11138 push_word(M.x86.R_IP); 11139 M.x86.R_IP = destval; 11140 break; 11141 case 3: /* call far ptr ... */ 11142 destval = fetch_data_word(destoffset); 11143 destval2 = fetch_data_word(destoffset + 2); 11144 TRACE_AND_STEP(); 11145 push_word(M.x86.R_CS); 11146 M.x86.R_CS = destval2; 11147 push_word(M.x86.R_IP); 11148 M.x86.R_IP = destval; 11149 break; 11150 case 4: /* jmp word ptr ... */ 11151 destval = fetch_data_word(destoffset); 11152 TRACE_AND_STEP(); 11153 M.x86.R_IP = destval; 11154 break; 11155 case 5: /* jmp far ptr ... */ 11156 destval = fetch_data_word(destoffset); 11157 destval2 = fetch_data_word(destoffset + 2); 11158 TRACE_AND_STEP(); 11159 M.x86.R_IP = destval; 11160 M.x86.R_CS = destval2; 11161 break; 11162 case 6: /* push word ptr ... */ 11163 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11164 u32 destval; 11165 11166 destval = fetch_data_long(destoffset); 11167 TRACE_AND_STEP(); 11168 push_long(destval); 11169 } else { 11170 u16 destval; 11171 11172 destval = fetch_data_word(destoffset); 11173 TRACE_AND_STEP(); 11174 push_word(destval); 11175 } 11176 break; 11177 } 11178 break; 11179 case 1: 11180 destoffset = decode_rm01_address(rl); 11181 DECODE_PRINTF("\n"); 11182 switch (rh) { 11183 case 0: 11184 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11185 u32 destval; 11186 11187 destval = fetch_data_long(destoffset); 11188 TRACE_AND_STEP(); 11189 destval = inc_long(destval); 11190 store_data_long(destoffset, destval); 11191 } else { 11192 u16 destval; 11193 11194 destval = fetch_data_word(destoffset); 11195 TRACE_AND_STEP(); 11196 destval = inc_word(destval); 11197 store_data_word(destoffset, destval); 11198 } 11199 break; 11200 case 1: 11201 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11202 u32 destval; 11203 11204 destval = fetch_data_long(destoffset); 11205 TRACE_AND_STEP(); 11206 destval = dec_long(destval); 11207 store_data_long(destoffset, destval); 11208 } else { 11209 u16 destval; 11210 11211 destval = fetch_data_word(destoffset); 11212 TRACE_AND_STEP(); 11213 destval = dec_word(destval); 11214 store_data_word(destoffset, destval); 11215 } 11216 break; 11217 case 2: /* call word ptr ... */ 11218 destval = fetch_data_word(destoffset); 11219 TRACE_AND_STEP(); 11220 push_word(M.x86.R_IP); 11221 M.x86.R_IP = destval; 11222 break; 11223 case 3: /* call far ptr ... */ 11224 destval = fetch_data_word(destoffset); 11225 destval2 = fetch_data_word(destoffset + 2); 11226 TRACE_AND_STEP(); 11227 push_word(M.x86.R_CS); 11228 M.x86.R_CS = destval2; 11229 push_word(M.x86.R_IP); 11230 M.x86.R_IP = destval; 11231 break; 11232 case 4: /* jmp word ptr ... */ 11233 destval = fetch_data_word(destoffset); 11234 TRACE_AND_STEP(); 11235 M.x86.R_IP = destval; 11236 break; 11237 case 5: /* jmp far ptr ... */ 11238 destval = fetch_data_word(destoffset); 11239 destval2 = fetch_data_word(destoffset + 2); 11240 TRACE_AND_STEP(); 11241 M.x86.R_IP = destval; 11242 M.x86.R_CS = destval2; 11243 break; 11244 case 6: /* push word ptr ... */ 11245 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11246 u32 destval; 11247 11248 destval = fetch_data_long(destoffset); 11249 TRACE_AND_STEP(); 11250 push_long(destval); 11251 } else { 11252 u16 destval; 11253 11254 destval = fetch_data_word(destoffset); 11255 TRACE_AND_STEP(); 11256 push_word(destval); 11257 } 11258 break; 11259 } 11260 break; 11261 case 2: 11262 destoffset = decode_rm10_address(rl); 11263 DECODE_PRINTF("\n"); 11264 switch (rh) { 11265 case 0: 11266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11267 u32 destval; 11268 11269 destval = fetch_data_long(destoffset); 11270 TRACE_AND_STEP(); 11271 destval = inc_long(destval); 11272 store_data_long(destoffset, destval); 11273 } else { 11274 u16 destval; 11275 11276 destval = fetch_data_word(destoffset); 11277 TRACE_AND_STEP(); 11278 destval = inc_word(destval); 11279 store_data_word(destoffset, destval); 11280 } 11281 break; 11282 case 1: 11283 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11284 u32 destval; 11285 11286 destval = fetch_data_long(destoffset); 11287 TRACE_AND_STEP(); 11288 destval = dec_long(destval); 11289 store_data_long(destoffset, destval); 11290 } else { 11291 u16 destval; 11292 11293 destval = fetch_data_word(destoffset); 11294 TRACE_AND_STEP(); 11295 destval = dec_word(destval); 11296 store_data_word(destoffset, destval); 11297 } 11298 break; 11299 case 2: /* call word ptr ... */ 11300 destval = fetch_data_word(destoffset); 11301 TRACE_AND_STEP(); 11302 push_word(M.x86.R_IP); 11303 M.x86.R_IP = destval; 11304 break; 11305 case 3: /* call far ptr ... */ 11306 destval = fetch_data_word(destoffset); 11307 destval2 = fetch_data_word(destoffset + 2); 11308 TRACE_AND_STEP(); 11309 push_word(M.x86.R_CS); 11310 M.x86.R_CS = destval2; 11311 push_word(M.x86.R_IP); 11312 M.x86.R_IP = destval; 11313 break; 11314 case 4: /* jmp word ptr ... */ 11315 destval = fetch_data_word(destoffset); 11316 TRACE_AND_STEP(); 11317 M.x86.R_IP = destval; 11318 break; 11319 case 5: /* jmp far ptr ... */ 11320 destval = fetch_data_word(destoffset); 11321 destval2 = fetch_data_word(destoffset + 2); 11322 TRACE_AND_STEP(); 11323 M.x86.R_IP = destval; 11324 M.x86.R_CS = destval2; 11325 break; 11326 case 6: /* push word ptr ... */ 11327 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11328 u32 destval; 11329 11330 destval = fetch_data_long(destoffset); 11331 TRACE_AND_STEP(); 11332 push_long(destval); 11333 } else { 11334 u16 destval; 11335 11336 destval = fetch_data_word(destoffset); 11337 TRACE_AND_STEP(); 11338 push_word(destval); 11339 } 11340 break; 11341 } 11342 break; 11343 case 3: 11344 switch (rh) { 11345 case 0: 11346 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11347 u32 *destreg; 11348 11349 destreg = DECODE_RM_LONG_REGISTER(rl); 11350 DECODE_PRINTF("\n"); 11351 TRACE_AND_STEP(); 11352 *destreg = inc_long(*destreg); 11353 } else { 11354 u16 *destreg; 11355 11356 destreg = DECODE_RM_WORD_REGISTER(rl); 11357 DECODE_PRINTF("\n"); 11358 TRACE_AND_STEP(); 11359 *destreg = inc_word(*destreg); 11360 } 11361 break; 11362 case 1: 11363 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11364 u32 *destreg; 11365 11366 destreg = DECODE_RM_LONG_REGISTER(rl); 11367 DECODE_PRINTF("\n"); 11368 TRACE_AND_STEP(); 11369 *destreg = dec_long(*destreg); 11370 } else { 11371 u16 *destreg; 11372 11373 destreg = DECODE_RM_WORD_REGISTER(rl); 11374 DECODE_PRINTF("\n"); 11375 TRACE_AND_STEP(); 11376 *destreg = dec_word(*destreg); 11377 } 11378 break; 11379 case 2: /* call word ptr ... */ 11380 destreg = DECODE_RM_WORD_REGISTER(rl); 11381 DECODE_PRINTF("\n"); 11382 TRACE_AND_STEP(); 11383 push_word(M.x86.R_IP); 11384 M.x86.R_IP = *destreg; 11385 break; 11386 case 3: /* jmp far ptr ... */ 11387 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11388 TRACE_AND_STEP(); 11389 HALT_SYS(); 11390 break; 11391 11392 case 4: /* jmp ... */ 11393 destreg = DECODE_RM_WORD_REGISTER(rl); 11394 DECODE_PRINTF("\n"); 11395 TRACE_AND_STEP(); 11396 M.x86.R_IP = (u16) (*destreg); 11397 break; 11398 case 5: /* jmp far ptr ... */ 11399 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11400 TRACE_AND_STEP(); 11401 HALT_SYS(); 11402 break; 11403 case 6: 11404 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11405 u32 *destreg; 11406 11407 destreg = DECODE_RM_LONG_REGISTER(rl); 11408 DECODE_PRINTF("\n"); 11409 TRACE_AND_STEP(); 11410 push_long(*destreg); 11411 } else { 11412 u16 *destreg; 11413 11414 destreg = DECODE_RM_WORD_REGISTER(rl); 11415 DECODE_PRINTF("\n"); 11416 TRACE_AND_STEP(); 11417 push_word(*destreg); 11418 } 11419 break; 11420 } 11421 break; 11422 } 11423 DECODE_CLEAR_SEGOVR(); 11424 END_OF_INSTR(); 11425} 11426 11427/*************************************************************************** 11428 * Single byte operation code table: 11429 **************************************************************************/ 11430void (*x86emu_optab[256])(u8) = 11431{ 11432/* 0x00 */ x86emuOp_add_byte_RM_R, 11433/* 0x01 */ x86emuOp_add_word_RM_R, 11434/* 0x02 */ x86emuOp_add_byte_R_RM, 11435/* 0x03 */ x86emuOp_add_word_R_RM, 11436/* 0x04 */ x86emuOp_add_byte_AL_IMM, 11437/* 0x05 */ x86emuOp_add_word_AX_IMM, 11438/* 0x06 */ x86emuOp_push_ES, 11439/* 0x07 */ x86emuOp_pop_ES, 11440 11441/* 0x08 */ x86emuOp_or_byte_RM_R, 11442/* 0x09 */ x86emuOp_or_word_RM_R, 11443/* 0x0a */ x86emuOp_or_byte_R_RM, 11444/* 0x0b */ x86emuOp_or_word_R_RM, 11445/* 0x0c */ x86emuOp_or_byte_AL_IMM, 11446/* 0x0d */ x86emuOp_or_word_AX_IMM, 11447/* 0x0e */ x86emuOp_push_CS, 11448/* 0x0f */ x86emuOp_two_byte, 11449 11450/* 0x10 */ x86emuOp_adc_byte_RM_R, 11451/* 0x11 */ x86emuOp_adc_word_RM_R, 11452/* 0x12 */ x86emuOp_adc_byte_R_RM, 11453/* 0x13 */ x86emuOp_adc_word_R_RM, 11454/* 0x14 */ x86emuOp_adc_byte_AL_IMM, 11455/* 0x15 */ x86emuOp_adc_word_AX_IMM, 11456/* 0x16 */ x86emuOp_push_SS, 11457/* 0x17 */ x86emuOp_pop_SS, 11458 11459/* 0x18 */ x86emuOp_sbb_byte_RM_R, 11460/* 0x19 */ x86emuOp_sbb_word_RM_R, 11461/* 0x1a */ x86emuOp_sbb_byte_R_RM, 11462/* 0x1b */ x86emuOp_sbb_word_R_RM, 11463/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, 11464/* 0x1d */ x86emuOp_sbb_word_AX_IMM, 11465/* 0x1e */ x86emuOp_push_DS, 11466/* 0x1f */ x86emuOp_pop_DS, 11467 11468/* 0x20 */ x86emuOp_and_byte_RM_R, 11469/* 0x21 */ x86emuOp_and_word_RM_R, 11470/* 0x22 */ x86emuOp_and_byte_R_RM, 11471/* 0x23 */ x86emuOp_and_word_R_RM, 11472/* 0x24 */ x86emuOp_and_byte_AL_IMM, 11473/* 0x25 */ x86emuOp_and_word_AX_IMM, 11474/* 0x26 */ x86emuOp_segovr_ES, 11475/* 0x27 */ x86emuOp_daa, 11476 11477/* 0x28 */ x86emuOp_sub_byte_RM_R, 11478/* 0x29 */ x86emuOp_sub_word_RM_R, 11479/* 0x2a */ x86emuOp_sub_byte_R_RM, 11480/* 0x2b */ x86emuOp_sub_word_R_RM, 11481/* 0x2c */ x86emuOp_sub_byte_AL_IMM, 11482/* 0x2d */ x86emuOp_sub_word_AX_IMM, 11483/* 0x2e */ x86emuOp_segovr_CS, 11484/* 0x2f */ x86emuOp_das, 11485 11486/* 0x30 */ x86emuOp_xor_byte_RM_R, 11487/* 0x31 */ x86emuOp_xor_word_RM_R, 11488/* 0x32 */ x86emuOp_xor_byte_R_RM, 11489/* 0x33 */ x86emuOp_xor_word_R_RM, 11490/* 0x34 */ x86emuOp_xor_byte_AL_IMM, 11491/* 0x35 */ x86emuOp_xor_word_AX_IMM, 11492/* 0x36 */ x86emuOp_segovr_SS, 11493/* 0x37 */ x86emuOp_aaa, 11494 11495/* 0x38 */ x86emuOp_cmp_byte_RM_R, 11496/* 0x39 */ x86emuOp_cmp_word_RM_R, 11497/* 0x3a */ x86emuOp_cmp_byte_R_RM, 11498/* 0x3b */ x86emuOp_cmp_word_R_RM, 11499/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, 11500/* 0x3d */ x86emuOp_cmp_word_AX_IMM, 11501/* 0x3e */ x86emuOp_segovr_DS, 11502/* 0x3f */ x86emuOp_aas, 11503 11504/* 0x40 */ x86emuOp_inc_AX, 11505/* 0x41 */ x86emuOp_inc_CX, 11506/* 0x42 */ x86emuOp_inc_DX, 11507/* 0x43 */ x86emuOp_inc_BX, 11508/* 0x44 */ x86emuOp_inc_SP, 11509/* 0x45 */ x86emuOp_inc_BP, 11510/* 0x46 */ x86emuOp_inc_SI, 11511/* 0x47 */ x86emuOp_inc_DI, 11512 11513/* 0x48 */ x86emuOp_dec_AX, 11514/* 0x49 */ x86emuOp_dec_CX, 11515/* 0x4a */ x86emuOp_dec_DX, 11516/* 0x4b */ x86emuOp_dec_BX, 11517/* 0x4c */ x86emuOp_dec_SP, 11518/* 0x4d */ x86emuOp_dec_BP, 11519/* 0x4e */ x86emuOp_dec_SI, 11520/* 0x4f */ x86emuOp_dec_DI, 11521 11522/* 0x50 */ x86emuOp_push_AX, 11523/* 0x51 */ x86emuOp_push_CX, 11524/* 0x52 */ x86emuOp_push_DX, 11525/* 0x53 */ x86emuOp_push_BX, 11526/* 0x54 */ x86emuOp_push_SP, 11527/* 0x55 */ x86emuOp_push_BP, 11528/* 0x56 */ x86emuOp_push_SI, 11529/* 0x57 */ x86emuOp_push_DI, 11530 11531/* 0x58 */ x86emuOp_pop_AX, 11532/* 0x59 */ x86emuOp_pop_CX, 11533/* 0x5a */ x86emuOp_pop_DX, 11534/* 0x5b */ x86emuOp_pop_BX, 11535/* 0x5c */ x86emuOp_pop_SP, 11536/* 0x5d */ x86emuOp_pop_BP, 11537/* 0x5e */ x86emuOp_pop_SI, 11538/* 0x5f */ x86emuOp_pop_DI, 11539 11540/* 0x60 */ x86emuOp_push_all, 11541/* 0x61 */ x86emuOp_pop_all, 11542/* 0x62 */ x86emuOp_illegal_op, /* bound */ 11543/* 0x63 */ x86emuOp_illegal_op, /* arpl */ 11544/* 0x64 */ x86emuOp_segovr_FS, 11545/* 0x65 */ x86emuOp_segovr_GS, 11546/* 0x66 */ x86emuOp_prefix_data, 11547/* 0x67 */ x86emuOp_prefix_addr, 11548 11549/* 0x68 */ x86emuOp_push_word_IMM, 11550/* 0x69 */ x86emuOp_imul_word_IMM, 11551/* 0x6a */ x86emuOp_push_byte_IMM, 11552/* 0x6b */ x86emuOp_imul_byte_IMM, 11553/* 0x6c */ x86emuOp_ins_byte, 11554/* 0x6d */ x86emuOp_ins_word, 11555/* 0x6e */ x86emuOp_outs_byte, 11556/* 0x6f */ x86emuOp_outs_word, 11557 11558/* 0x70 */ x86emuOp_jump_near_O, 11559/* 0x71 */ x86emuOp_jump_near_NO, 11560/* 0x72 */ x86emuOp_jump_near_B, 11561/* 0x73 */ x86emuOp_jump_near_NB, 11562/* 0x74 */ x86emuOp_jump_near_Z, 11563/* 0x75 */ x86emuOp_jump_near_NZ, 11564/* 0x76 */ x86emuOp_jump_near_BE, 11565/* 0x77 */ x86emuOp_jump_near_NBE, 11566 11567/* 0x78 */ x86emuOp_jump_near_S, 11568/* 0x79 */ x86emuOp_jump_near_NS, 11569/* 0x7a */ x86emuOp_jump_near_P, 11570/* 0x7b */ x86emuOp_jump_near_NP, 11571/* 0x7c */ x86emuOp_jump_near_L, 11572/* 0x7d */ x86emuOp_jump_near_NL, 11573/* 0x7e */ x86emuOp_jump_near_LE, 11574/* 0x7f */ x86emuOp_jump_near_NLE, 11575 11576/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 11577/* 0x81 */ x86emuOp_opc81_word_RM_IMM, 11578/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 11579/* 0x83 */ x86emuOp_opc83_word_RM_IMM, 11580/* 0x84 */ x86emuOp_test_byte_RM_R, 11581/* 0x85 */ x86emuOp_test_word_RM_R, 11582/* 0x86 */ x86emuOp_xchg_byte_RM_R, 11583/* 0x87 */ x86emuOp_xchg_word_RM_R, 11584 11585/* 0x88 */ x86emuOp_mov_byte_RM_R, 11586/* 0x89 */ x86emuOp_mov_word_RM_R, 11587/* 0x8a */ x86emuOp_mov_byte_R_RM, 11588/* 0x8b */ x86emuOp_mov_word_R_RM, 11589/* 0x8c */ x86emuOp_mov_word_RM_SR, 11590/* 0x8d */ x86emuOp_lea_word_R_M, 11591/* 0x8e */ x86emuOp_mov_word_SR_RM, 11592/* 0x8f */ x86emuOp_pop_RM, 11593 11594/* 0x90 */ x86emuOp_nop, 11595/* 0x91 */ x86emuOp_xchg_word_AX_CX, 11596/* 0x92 */ x86emuOp_xchg_word_AX_DX, 11597/* 0x93 */ x86emuOp_xchg_word_AX_BX, 11598/* 0x94 */ x86emuOp_xchg_word_AX_SP, 11599/* 0x95 */ x86emuOp_xchg_word_AX_BP, 11600/* 0x96 */ x86emuOp_xchg_word_AX_SI, 11601/* 0x97 */ x86emuOp_xchg_word_AX_DI, 11602 11603/* 0x98 */ x86emuOp_cbw, 11604/* 0x99 */ x86emuOp_cwd, 11605/* 0x9a */ x86emuOp_call_far_IMM, 11606/* 0x9b */ x86emuOp_wait, 11607/* 0x9c */ x86emuOp_pushf_word, 11608/* 0x9d */ x86emuOp_popf_word, 11609/* 0x9e */ x86emuOp_sahf, 11610/* 0x9f */ x86emuOp_lahf, 11611 11612/* 0xa0 */ x86emuOp_mov_AL_M_IMM, 11613/* 0xa1 */ x86emuOp_mov_AX_M_IMM, 11614/* 0xa2 */ x86emuOp_mov_M_AL_IMM, 11615/* 0xa3 */ x86emuOp_mov_M_AX_IMM, 11616/* 0xa4 */ x86emuOp_movs_byte, 11617/* 0xa5 */ x86emuOp_movs_word, 11618/* 0xa6 */ x86emuOp_cmps_byte, 11619/* 0xa7 */ x86emuOp_cmps_word, 11620/* 0xa8 */ x86emuOp_test_AL_IMM, 11621/* 0xa9 */ x86emuOp_test_AX_IMM, 11622/* 0xaa */ x86emuOp_stos_byte, 11623/* 0xab */ x86emuOp_stos_word, 11624/* 0xac */ x86emuOp_lods_byte, 11625/* 0xad */ x86emuOp_lods_word, 11626/* 0xac */ x86emuOp_scas_byte, 11627/* 0xad */ x86emuOp_scas_word, 11628 11629 11630/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, 11631/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, 11632/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, 11633/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, 11634/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, 11635/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, 11636/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, 11637/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, 11638 11639/* 0xb8 */ x86emuOp_mov_word_AX_IMM, 11640/* 0xb9 */ x86emuOp_mov_word_CX_IMM, 11641/* 0xba */ x86emuOp_mov_word_DX_IMM, 11642/* 0xbb */ x86emuOp_mov_word_BX_IMM, 11643/* 0xbc */ x86emuOp_mov_word_SP_IMM, 11644/* 0xbd */ x86emuOp_mov_word_BP_IMM, 11645/* 0xbe */ x86emuOp_mov_word_SI_IMM, 11646/* 0xbf */ x86emuOp_mov_word_DI_IMM, 11647 11648/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 11649/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 11650/* 0xc2 */ x86emuOp_ret_near_IMM, 11651/* 0xc3 */ x86emuOp_ret_near, 11652/* 0xc4 */ x86emuOp_les_R_IMM, 11653/* 0xc5 */ x86emuOp_lds_R_IMM, 11654/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 11655/* 0xc7 */ x86emuOp_mov_word_RM_IMM, 11656/* 0xc8 */ x86emuOp_enter, 11657/* 0xc9 */ x86emuOp_leave, 11658/* 0xca */ x86emuOp_ret_far_IMM, 11659/* 0xcb */ x86emuOp_ret_far, 11660/* 0xcc */ x86emuOp_int3, 11661/* 0xcd */ x86emuOp_int_IMM, 11662/* 0xce */ x86emuOp_into, 11663/* 0xcf */ x86emuOp_iret, 11664 11665/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 11666/* 0xd1 */ x86emuOp_opcD1_word_RM_1, 11667/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 11668/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 11669/* 0xd4 */ x86emuOp_aam, 11670/* 0xd5 */ x86emuOp_aad, 11671/* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 11672/* 0xd7 */ x86emuOp_xlat, 11673/* 0xd8 */ x86emuOp_esc_coprocess_d8, 11674/* 0xd9 */ x86emuOp_esc_coprocess_d9, 11675/* 0xda */ x86emuOp_esc_coprocess_da, 11676/* 0xdb */ x86emuOp_esc_coprocess_db, 11677/* 0xdc */ x86emuOp_esc_coprocess_dc, 11678/* 0xdd */ x86emuOp_esc_coprocess_dd, 11679/* 0xde */ x86emuOp_esc_coprocess_de, 11680/* 0xdf */ x86emuOp_esc_coprocess_df, 11681 11682/* 0xe0 */ x86emuOp_loopne, 11683/* 0xe1 */ x86emuOp_loope, 11684/* 0xe2 */ x86emuOp_loop, 11685/* 0xe3 */ x86emuOp_jcxz, 11686/* 0xe4 */ x86emuOp_in_byte_AL_IMM, 11687/* 0xe5 */ x86emuOp_in_word_AX_IMM, 11688/* 0xe6 */ x86emuOp_out_byte_IMM_AL, 11689/* 0xe7 */ x86emuOp_out_word_IMM_AX, 11690 11691/* 0xe8 */ x86emuOp_call_near_IMM, 11692/* 0xe9 */ x86emuOp_jump_near_IMM, 11693/* 0xea */ x86emuOp_jump_far_IMM, 11694/* 0xeb */ x86emuOp_jump_byte_IMM, 11695/* 0xec */ x86emuOp_in_byte_AL_DX, 11696/* 0xed */ x86emuOp_in_word_AX_DX, 11697/* 0xee */ x86emuOp_out_byte_DX_AL, 11698/* 0xef */ x86emuOp_out_word_DX_AX, 11699 11700/* 0xf0 */ x86emuOp_lock, 11701/* 0xf1 */ x86emuOp_illegal_op, 11702/* 0xf2 */ x86emuOp_repne, 11703/* 0xf3 */ x86emuOp_repe, 11704/* 0xf4 */ x86emuOp_halt, 11705/* 0xf5 */ x86emuOp_cmc, 11706/* 0xf6 */ x86emuOp_opcF6_byte_RM, 11707/* 0xf7 */ x86emuOp_opcF7_word_RM, 11708 11709/* 0xf8 */ x86emuOp_clc, 11710/* 0xf9 */ x86emuOp_stc, 11711/* 0xfa */ x86emuOp_cli, 11712/* 0xfb */ x86emuOp_sti, 11713/* 0xfc */ x86emuOp_cld, 11714/* 0xfd */ x86emuOp_std, 11715/* 0xfe */ x86emuOp_opcFE_byte_RM, 11716/* 0xff */ x86emuOp_opcFF_word_RM, 11717}; 11718