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 DECODE_CLEAR_SEGOVR(); 105 END_OF_INSTR(); 106} 107 108/**************************************************************************** 109REMARKS: 110Handles opcode 0x00 111****************************************************************************/ 112static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1)) 113{ 114 int mod, rl, rh; 115 uint destoffset; 116 u8 *destreg, *srcreg; 117 u8 destval; 118 119 START_OF_INSTR(); 120 DECODE_PRINTF("ADD\t"); 121 FETCH_DECODE_MODRM(mod, rh, rl); 122 switch (mod) { 123 case 0: 124 destoffset = decode_rm00_address(rl); 125 DECODE_PRINTF(","); 126 destval = fetch_data_byte(destoffset); 127 srcreg = DECODE_RM_BYTE_REGISTER(rh); 128 DECODE_PRINTF("\n"); 129 TRACE_AND_STEP(); 130 destval = add_byte(destval, *srcreg); 131 store_data_byte(destoffset, destval); 132 break; 133 case 1: 134 destoffset = decode_rm01_address(rl); 135 DECODE_PRINTF(","); 136 destval = fetch_data_byte(destoffset); 137 srcreg = DECODE_RM_BYTE_REGISTER(rh); 138 DECODE_PRINTF("\n"); 139 TRACE_AND_STEP(); 140 destval = add_byte(destval, *srcreg); 141 store_data_byte(destoffset, destval); 142 break; 143 case 2: 144 destoffset = decode_rm10_address(rl); 145 DECODE_PRINTF(","); 146 destval = fetch_data_byte(destoffset); 147 srcreg = DECODE_RM_BYTE_REGISTER(rh); 148 DECODE_PRINTF("\n"); 149 TRACE_AND_STEP(); 150 destval = add_byte(destval, *srcreg); 151 store_data_byte(destoffset, destval); 152 break; 153 case 3: /* register to register */ 154 destreg = DECODE_RM_BYTE_REGISTER(rl); 155 DECODE_PRINTF(","); 156 srcreg = DECODE_RM_BYTE_REGISTER(rh); 157 DECODE_PRINTF("\n"); 158 TRACE_AND_STEP(); 159 *destreg = add_byte(*destreg, *srcreg); 160 break; 161 } 162 DECODE_CLEAR_SEGOVR(); 163 END_OF_INSTR(); 164} 165 166/**************************************************************************** 167REMARKS: 168Handles opcode 0x01 169****************************************************************************/ 170static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1)) 171{ 172 int mod, rl, rh; 173 uint destoffset; 174 175 START_OF_INSTR(); 176 DECODE_PRINTF("ADD\t"); 177 FETCH_DECODE_MODRM(mod, rh, rl); 178 switch (mod) { 179 case 0: 180 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 181 u32 destval; 182 u32 *srcreg; 183 184 destoffset = decode_rm00_address(rl); 185 DECODE_PRINTF(","); 186 destval = fetch_data_long(destoffset); 187 srcreg = DECODE_RM_LONG_REGISTER(rh); 188 DECODE_PRINTF("\n"); 189 TRACE_AND_STEP(); 190 destval = add_long(destval, *srcreg); 191 store_data_long(destoffset, destval); 192 } else { 193 u16 destval; 194 u16 *srcreg; 195 196 destoffset = decode_rm00_address(rl); 197 DECODE_PRINTF(","); 198 destval = fetch_data_word(destoffset); 199 srcreg = DECODE_RM_WORD_REGISTER(rh); 200 DECODE_PRINTF("\n"); 201 TRACE_AND_STEP(); 202 destval = add_word(destval, *srcreg); 203 store_data_word(destoffset, destval); 204 } 205 break; 206 case 1: 207 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 208 u32 destval; 209 u32 *srcreg; 210 211 destoffset = decode_rm01_address(rl); 212 DECODE_PRINTF(","); 213 destval = fetch_data_long(destoffset); 214 srcreg = DECODE_RM_LONG_REGISTER(rh); 215 DECODE_PRINTF("\n"); 216 TRACE_AND_STEP(); 217 destval = add_long(destval, *srcreg); 218 store_data_long(destoffset, destval); 219 } else { 220 u16 destval; 221 u16 *srcreg; 222 223 destoffset = decode_rm01_address(rl); 224 DECODE_PRINTF(","); 225 destval = fetch_data_word(destoffset); 226 srcreg = DECODE_RM_WORD_REGISTER(rh); 227 DECODE_PRINTF("\n"); 228 TRACE_AND_STEP(); 229 destval = add_word(destval, *srcreg); 230 store_data_word(destoffset, destval); 231 } 232 break; 233 case 2: 234 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 235 u32 destval; 236 u32 *srcreg; 237 238 destoffset = decode_rm10_address(rl); 239 DECODE_PRINTF(","); 240 destval = fetch_data_long(destoffset); 241 srcreg = DECODE_RM_LONG_REGISTER(rh); 242 DECODE_PRINTF("\n"); 243 TRACE_AND_STEP(); 244 destval = add_long(destval, *srcreg); 245 store_data_long(destoffset, destval); 246 } else { 247 u16 destval; 248 u16 *srcreg; 249 250 destoffset = decode_rm10_address(rl); 251 DECODE_PRINTF(","); 252 destval = fetch_data_word(destoffset); 253 srcreg = DECODE_RM_WORD_REGISTER(rh); 254 DECODE_PRINTF("\n"); 255 TRACE_AND_STEP(); 256 destval = add_word(destval, *srcreg); 257 store_data_word(destoffset, destval); 258 } 259 break; 260 case 3: /* register to register */ 261 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 262 u32 *destreg,*srcreg; 263 264 destreg = DECODE_RM_LONG_REGISTER(rl); 265 DECODE_PRINTF(","); 266 srcreg = DECODE_RM_LONG_REGISTER(rh); 267 DECODE_PRINTF("\n"); 268 TRACE_AND_STEP(); 269 *destreg = add_long(*destreg, *srcreg); 270 } else { 271 u16 *destreg,*srcreg; 272 273 destreg = DECODE_RM_WORD_REGISTER(rl); 274 DECODE_PRINTF(","); 275 srcreg = DECODE_RM_WORD_REGISTER(rh); 276 DECODE_PRINTF("\n"); 277 TRACE_AND_STEP(); 278 *destreg = add_word(*destreg, *srcreg); 279 } 280 break; 281 } 282 DECODE_CLEAR_SEGOVR(); 283 END_OF_INSTR(); 284} 285 286/**************************************************************************** 287REMARKS: 288Handles opcode 0x02 289****************************************************************************/ 290static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1)) 291{ 292 int mod, rl, rh; 293 u8 *destreg, *srcreg; 294 uint srcoffset; 295 u8 srcval; 296 297 START_OF_INSTR(); 298 DECODE_PRINTF("ADD\t"); 299 FETCH_DECODE_MODRM(mod, rh, rl); 300 switch (mod) { 301 case 0: 302 destreg = DECODE_RM_BYTE_REGISTER(rh); 303 DECODE_PRINTF(","); 304 srcoffset = decode_rm00_address(rl); 305 srcval = fetch_data_byte(srcoffset); 306 DECODE_PRINTF("\n"); 307 TRACE_AND_STEP(); 308 *destreg = add_byte(*destreg, srcval); 309 break; 310 case 1: 311 destreg = DECODE_RM_BYTE_REGISTER(rh); 312 DECODE_PRINTF(","); 313 srcoffset = decode_rm01_address(rl); 314 srcval = fetch_data_byte(srcoffset); 315 DECODE_PRINTF("\n"); 316 TRACE_AND_STEP(); 317 *destreg = add_byte(*destreg, srcval); 318 break; 319 case 2: 320 destreg = DECODE_RM_BYTE_REGISTER(rh); 321 DECODE_PRINTF(","); 322 srcoffset = decode_rm10_address(rl); 323 srcval = fetch_data_byte(srcoffset); 324 DECODE_PRINTF("\n"); 325 TRACE_AND_STEP(); 326 *destreg = add_byte(*destreg, srcval); 327 break; 328 case 3: /* register to register */ 329 destreg = DECODE_RM_BYTE_REGISTER(rh); 330 DECODE_PRINTF(","); 331 srcreg = DECODE_RM_BYTE_REGISTER(rl); 332 DECODE_PRINTF("\n"); 333 TRACE_AND_STEP(); 334 *destreg = add_byte(*destreg, *srcreg); 335 break; 336 } 337 DECODE_CLEAR_SEGOVR(); 338 END_OF_INSTR(); 339} 340 341/**************************************************************************** 342REMARKS: 343Handles opcode 0x03 344****************************************************************************/ 345static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1)) 346{ 347 int mod, rl, rh; 348 uint srcoffset; 349 350 START_OF_INSTR(); 351 DECODE_PRINTF("ADD\t"); 352 FETCH_DECODE_MODRM(mod, rh, rl); 353 switch (mod) { 354 case 0: 355 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 356 u32 *destreg; 357 u32 srcval; 358 359 destreg = DECODE_RM_LONG_REGISTER(rh); 360 DECODE_PRINTF(","); 361 srcoffset = decode_rm00_address(rl); 362 srcval = fetch_data_long(srcoffset); 363 DECODE_PRINTF("\n"); 364 TRACE_AND_STEP(); 365 *destreg = add_long(*destreg, srcval); 366 } else { 367 u16 *destreg; 368 u16 srcval; 369 370 destreg = DECODE_RM_WORD_REGISTER(rh); 371 DECODE_PRINTF(","); 372 srcoffset = decode_rm00_address(rl); 373 srcval = fetch_data_word(srcoffset); 374 DECODE_PRINTF("\n"); 375 TRACE_AND_STEP(); 376 *destreg = add_word(*destreg, srcval); 377 } 378 break; 379 case 1: 380 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 381 u32 *destreg; 382 u32 srcval; 383 384 destreg = DECODE_RM_LONG_REGISTER(rh); 385 DECODE_PRINTF(","); 386 srcoffset = decode_rm01_address(rl); 387 srcval = fetch_data_long(srcoffset); 388 DECODE_PRINTF("\n"); 389 TRACE_AND_STEP(); 390 *destreg = add_long(*destreg, srcval); 391 } else { 392 u16 *destreg; 393 u16 srcval; 394 395 destreg = DECODE_RM_WORD_REGISTER(rh); 396 DECODE_PRINTF(","); 397 srcoffset = decode_rm01_address(rl); 398 srcval = fetch_data_word(srcoffset); 399 DECODE_PRINTF("\n"); 400 TRACE_AND_STEP(); 401 *destreg = add_word(*destreg, srcval); 402 } 403 break; 404 case 2: 405 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 406 u32 *destreg; 407 u32 srcval; 408 409 destreg = DECODE_RM_LONG_REGISTER(rh); 410 DECODE_PRINTF(","); 411 srcoffset = decode_rm10_address(rl); 412 srcval = fetch_data_long(srcoffset); 413 DECODE_PRINTF("\n"); 414 TRACE_AND_STEP(); 415 *destreg = add_long(*destreg, srcval); 416 } else { 417 u16 *destreg; 418 u16 srcval; 419 420 destreg = DECODE_RM_WORD_REGISTER(rh); 421 DECODE_PRINTF(","); 422 srcoffset = decode_rm10_address(rl); 423 srcval = fetch_data_word(srcoffset); 424 DECODE_PRINTF("\n"); 425 TRACE_AND_STEP(); 426 *destreg = add_word(*destreg, srcval); 427 } 428 break; 429 case 3: /* register to register */ 430 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 431 u32 *destreg,*srcreg; 432 433 destreg = DECODE_RM_LONG_REGISTER(rh); 434 DECODE_PRINTF(","); 435 srcreg = DECODE_RM_LONG_REGISTER(rl); 436 DECODE_PRINTF("\n"); 437 TRACE_AND_STEP(); 438 *destreg = add_long(*destreg, *srcreg); 439 } else { 440 u16 *destreg,*srcreg; 441 442 destreg = DECODE_RM_WORD_REGISTER(rh); 443 DECODE_PRINTF(","); 444 srcreg = DECODE_RM_WORD_REGISTER(rl); 445 DECODE_PRINTF("\n"); 446 TRACE_AND_STEP(); 447 *destreg = add_word(*destreg, *srcreg); 448 } 449 break; 450 } 451 DECODE_CLEAR_SEGOVR(); 452 END_OF_INSTR(); 453} 454 455/**************************************************************************** 456REMARKS: 457Handles opcode 0x04 458****************************************************************************/ 459static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 460{ 461 u8 srcval; 462 463 START_OF_INSTR(); 464 DECODE_PRINTF("ADD\tAL,"); 465 srcval = fetch_byte_imm(); 466 DECODE_PRINTF2("%x\n", srcval); 467 TRACE_AND_STEP(); 468 M.x86.R_AL = add_byte(M.x86.R_AL, srcval); 469 DECODE_CLEAR_SEGOVR(); 470 END_OF_INSTR(); 471} 472 473/**************************************************************************** 474REMARKS: 475Handles opcode 0x05 476****************************************************************************/ 477static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 478{ 479 u32 srcval; 480 481 START_OF_INSTR(); 482 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 483 DECODE_PRINTF("ADD\tEAX,"); 484 srcval = fetch_long_imm(); 485 } else { 486 DECODE_PRINTF("ADD\tAX,"); 487 srcval = fetch_word_imm(); 488 } 489 DECODE_PRINTF2("%x\n", srcval); 490 TRACE_AND_STEP(); 491 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 492 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval); 493 } else { 494 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval); 495 } 496 DECODE_CLEAR_SEGOVR(); 497 END_OF_INSTR(); 498} 499 500/**************************************************************************** 501REMARKS: 502Handles opcode 0x06 503****************************************************************************/ 504static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 505{ 506 START_OF_INSTR(); 507 DECODE_PRINTF("PUSH\tES\n"); 508 TRACE_AND_STEP(); 509 push_word(M.x86.R_ES); 510 DECODE_CLEAR_SEGOVR(); 511 END_OF_INSTR(); 512} 513 514/**************************************************************************** 515REMARKS: 516Handles opcode 0x07 517****************************************************************************/ 518static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 519{ 520 START_OF_INSTR(); 521 DECODE_PRINTF("POP\tES\n"); 522 TRACE_AND_STEP(); 523 M.x86.R_ES = pop_word(); 524 DECODE_CLEAR_SEGOVR(); 525 END_OF_INSTR(); 526} 527 528/**************************************************************************** 529REMARKS: 530Handles opcode 0x08 531****************************************************************************/ 532static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1)) 533{ 534 int mod, rl, rh; 535 u8 *destreg, *srcreg; 536 uint destoffset; 537 u8 destval; 538 539 START_OF_INSTR(); 540 DECODE_PRINTF("OR\t"); 541 FETCH_DECODE_MODRM(mod, rh, rl); 542 switch (mod) { 543 case 0: 544 destoffset = decode_rm00_address(rl); 545 DECODE_PRINTF(","); 546 destval = fetch_data_byte(destoffset); 547 srcreg = DECODE_RM_BYTE_REGISTER(rh); 548 DECODE_PRINTF("\n"); 549 TRACE_AND_STEP(); 550 destval = or_byte(destval, *srcreg); 551 store_data_byte(destoffset, destval); 552 break; 553 case 1: 554 destoffset = decode_rm01_address(rl); 555 DECODE_PRINTF(","); 556 destval = fetch_data_byte(destoffset); 557 srcreg = DECODE_RM_BYTE_REGISTER(rh); 558 DECODE_PRINTF("\n"); 559 TRACE_AND_STEP(); 560 destval = or_byte(destval, *srcreg); 561 store_data_byte(destoffset, destval); 562 break; 563 case 2: 564 destoffset = decode_rm10_address(rl); 565 DECODE_PRINTF(","); 566 destval = fetch_data_byte(destoffset); 567 srcreg = DECODE_RM_BYTE_REGISTER(rh); 568 DECODE_PRINTF("\n"); 569 TRACE_AND_STEP(); 570 destval = or_byte(destval, *srcreg); 571 store_data_byte(destoffset, destval); 572 break; 573 case 3: /* register to register */ 574 destreg = DECODE_RM_BYTE_REGISTER(rl); 575 DECODE_PRINTF(","); 576 srcreg = DECODE_RM_BYTE_REGISTER(rh); 577 DECODE_PRINTF("\n"); 578 TRACE_AND_STEP(); 579 *destreg = or_byte(*destreg, *srcreg); 580 break; 581 } 582 DECODE_CLEAR_SEGOVR(); 583 END_OF_INSTR(); 584} 585 586/**************************************************************************** 587REMARKS: 588Handles opcode 0x09 589****************************************************************************/ 590static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1)) 591{ 592 int mod, rl, rh; 593 uint destoffset; 594 595 START_OF_INSTR(); 596 DECODE_PRINTF("OR\t"); 597 FETCH_DECODE_MODRM(mod, rh, rl); 598 switch (mod) { 599 case 0: 600 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 601 u32 destval; 602 u32 *srcreg; 603 604 destoffset = decode_rm00_address(rl); 605 DECODE_PRINTF(","); 606 destval = fetch_data_long(destoffset); 607 srcreg = DECODE_RM_LONG_REGISTER(rh); 608 DECODE_PRINTF("\n"); 609 TRACE_AND_STEP(); 610 destval = or_long(destval, *srcreg); 611 store_data_long(destoffset, destval); 612 } else { 613 u16 destval; 614 u16 *srcreg; 615 616 destoffset = decode_rm00_address(rl); 617 DECODE_PRINTF(","); 618 destval = fetch_data_word(destoffset); 619 srcreg = DECODE_RM_WORD_REGISTER(rh); 620 DECODE_PRINTF("\n"); 621 TRACE_AND_STEP(); 622 destval = or_word(destval, *srcreg); 623 store_data_word(destoffset, destval); 624 } 625 break; 626 case 1: 627 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 628 u32 destval; 629 u32 *srcreg; 630 631 destoffset = decode_rm01_address(rl); 632 DECODE_PRINTF(","); 633 destval = fetch_data_long(destoffset); 634 srcreg = DECODE_RM_LONG_REGISTER(rh); 635 DECODE_PRINTF("\n"); 636 TRACE_AND_STEP(); 637 destval = or_long(destval, *srcreg); 638 store_data_long(destoffset, destval); 639 } else { 640 u16 destval; 641 u16 *srcreg; 642 643 destoffset = decode_rm01_address(rl); 644 DECODE_PRINTF(","); 645 destval = fetch_data_word(destoffset); 646 srcreg = DECODE_RM_WORD_REGISTER(rh); 647 DECODE_PRINTF("\n"); 648 TRACE_AND_STEP(); 649 destval = or_word(destval, *srcreg); 650 store_data_word(destoffset, destval); 651 } 652 break; 653 case 2: 654 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 655 u32 destval; 656 u32 *srcreg; 657 658 destoffset = decode_rm10_address(rl); 659 DECODE_PRINTF(","); 660 destval = fetch_data_long(destoffset); 661 srcreg = DECODE_RM_LONG_REGISTER(rh); 662 DECODE_PRINTF("\n"); 663 TRACE_AND_STEP(); 664 destval = or_long(destval, *srcreg); 665 store_data_long(destoffset, destval); 666 } else { 667 u16 destval; 668 u16 *srcreg; 669 670 destoffset = decode_rm10_address(rl); 671 DECODE_PRINTF(","); 672 destval = fetch_data_word(destoffset); 673 srcreg = DECODE_RM_WORD_REGISTER(rh); 674 DECODE_PRINTF("\n"); 675 TRACE_AND_STEP(); 676 destval = or_word(destval, *srcreg); 677 store_data_word(destoffset, destval); 678 } 679 break; 680 case 3: /* register to register */ 681 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 682 u32 *destreg,*srcreg; 683 684 destreg = DECODE_RM_LONG_REGISTER(rl); 685 DECODE_PRINTF(","); 686 srcreg = DECODE_RM_LONG_REGISTER(rh); 687 DECODE_PRINTF("\n"); 688 TRACE_AND_STEP(); 689 *destreg = or_long(*destreg, *srcreg); 690 } else { 691 u16 *destreg,*srcreg; 692 693 destreg = DECODE_RM_WORD_REGISTER(rl); 694 DECODE_PRINTF(","); 695 srcreg = DECODE_RM_WORD_REGISTER(rh); 696 DECODE_PRINTF("\n"); 697 TRACE_AND_STEP(); 698 *destreg = or_word(*destreg, *srcreg); 699 } 700 break; 701 } 702 DECODE_CLEAR_SEGOVR(); 703 END_OF_INSTR(); 704} 705 706/**************************************************************************** 707REMARKS: 708Handles opcode 0x0a 709****************************************************************************/ 710static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1)) 711{ 712 int mod, rl, rh; 713 u8 *destreg, *srcreg; 714 uint srcoffset; 715 u8 srcval; 716 717 START_OF_INSTR(); 718 DECODE_PRINTF("OR\t"); 719 FETCH_DECODE_MODRM(mod, rh, rl); 720 switch (mod) { 721 case 0: 722 destreg = DECODE_RM_BYTE_REGISTER(rh); 723 DECODE_PRINTF(","); 724 srcoffset = decode_rm00_address(rl); 725 srcval = fetch_data_byte(srcoffset); 726 DECODE_PRINTF("\n"); 727 TRACE_AND_STEP(); 728 *destreg = or_byte(*destreg, srcval); 729 break; 730 case 1: 731 destreg = DECODE_RM_BYTE_REGISTER(rh); 732 DECODE_PRINTF(","); 733 srcoffset = decode_rm01_address(rl); 734 srcval = fetch_data_byte(srcoffset); 735 DECODE_PRINTF("\n"); 736 TRACE_AND_STEP(); 737 *destreg = or_byte(*destreg, srcval); 738 break; 739 case 2: 740 destreg = DECODE_RM_BYTE_REGISTER(rh); 741 DECODE_PRINTF(","); 742 srcoffset = decode_rm10_address(rl); 743 srcval = fetch_data_byte(srcoffset); 744 DECODE_PRINTF("\n"); 745 TRACE_AND_STEP(); 746 *destreg = or_byte(*destreg, srcval); 747 break; 748 case 3: /* register to register */ 749 destreg = DECODE_RM_BYTE_REGISTER(rh); 750 DECODE_PRINTF(","); 751 srcreg = DECODE_RM_BYTE_REGISTER(rl); 752 DECODE_PRINTF("\n"); 753 TRACE_AND_STEP(); 754 *destreg = or_byte(*destreg, *srcreg); 755 break; 756 } 757 DECODE_CLEAR_SEGOVR(); 758 END_OF_INSTR(); 759} 760 761/**************************************************************************** 762REMARKS: 763Handles opcode 0x0b 764****************************************************************************/ 765static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1)) 766{ 767 int mod, rl, rh; 768 uint srcoffset; 769 770 START_OF_INSTR(); 771 DECODE_PRINTF("OR\t"); 772 FETCH_DECODE_MODRM(mod, rh, rl); 773 switch (mod) { 774 case 0: 775 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 776 u32 *destreg; 777 u32 srcval; 778 779 destreg = DECODE_RM_LONG_REGISTER(rh); 780 DECODE_PRINTF(","); 781 srcoffset = decode_rm00_address(rl); 782 srcval = fetch_data_long(srcoffset); 783 DECODE_PRINTF("\n"); 784 TRACE_AND_STEP(); 785 *destreg = or_long(*destreg, srcval); 786 } else { 787 u16 *destreg; 788 u16 srcval; 789 790 destreg = DECODE_RM_WORD_REGISTER(rh); 791 DECODE_PRINTF(","); 792 srcoffset = decode_rm00_address(rl); 793 srcval = fetch_data_word(srcoffset); 794 DECODE_PRINTF("\n"); 795 TRACE_AND_STEP(); 796 *destreg = or_word(*destreg, srcval); 797 } 798 break; 799 case 1: 800 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 801 u32 *destreg; 802 u32 srcval; 803 804 destreg = DECODE_RM_LONG_REGISTER(rh); 805 DECODE_PRINTF(","); 806 srcoffset = decode_rm01_address(rl); 807 srcval = fetch_data_long(srcoffset); 808 DECODE_PRINTF("\n"); 809 TRACE_AND_STEP(); 810 *destreg = or_long(*destreg, srcval); 811 } else { 812 u16 *destreg; 813 u16 srcval; 814 815 destreg = DECODE_RM_WORD_REGISTER(rh); 816 DECODE_PRINTF(","); 817 srcoffset = decode_rm01_address(rl); 818 srcval = fetch_data_word(srcoffset); 819 DECODE_PRINTF("\n"); 820 TRACE_AND_STEP(); 821 *destreg = or_word(*destreg, srcval); 822 } 823 break; 824 case 2: 825 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 826 u32 *destreg; 827 u32 srcval; 828 829 destreg = DECODE_RM_LONG_REGISTER(rh); 830 DECODE_PRINTF(","); 831 srcoffset = decode_rm10_address(rl); 832 srcval = fetch_data_long(srcoffset); 833 DECODE_PRINTF("\n"); 834 TRACE_AND_STEP(); 835 *destreg = or_long(*destreg, srcval); 836 } else { 837 u16 *destreg; 838 u16 srcval; 839 840 destreg = DECODE_RM_WORD_REGISTER(rh); 841 DECODE_PRINTF(","); 842 srcoffset = decode_rm10_address(rl); 843 srcval = fetch_data_word(srcoffset); 844 DECODE_PRINTF("\n"); 845 TRACE_AND_STEP(); 846 *destreg = or_word(*destreg, srcval); 847 } 848 break; 849 case 3: /* register to register */ 850 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 851 u32 *destreg,*srcreg; 852 853 destreg = DECODE_RM_LONG_REGISTER(rh); 854 DECODE_PRINTF(","); 855 srcreg = DECODE_RM_LONG_REGISTER(rl); 856 DECODE_PRINTF("\n"); 857 TRACE_AND_STEP(); 858 *destreg = or_long(*destreg, *srcreg); 859 } else { 860 u16 *destreg,*srcreg; 861 862 destreg = DECODE_RM_WORD_REGISTER(rh); 863 DECODE_PRINTF(","); 864 srcreg = DECODE_RM_WORD_REGISTER(rl); 865 DECODE_PRINTF("\n"); 866 TRACE_AND_STEP(); 867 *destreg = or_word(*destreg, *srcreg); 868 } 869 break; 870 } 871 DECODE_CLEAR_SEGOVR(); 872 END_OF_INSTR(); 873} 874 875/**************************************************************************** 876REMARKS: 877Handles opcode 0x0c 878****************************************************************************/ 879static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 880{ 881 u8 srcval; 882 883 START_OF_INSTR(); 884 DECODE_PRINTF("OR\tAL,"); 885 srcval = fetch_byte_imm(); 886 DECODE_PRINTF2("%x\n", srcval); 887 TRACE_AND_STEP(); 888 M.x86.R_AL = or_byte(M.x86.R_AL, srcval); 889 DECODE_CLEAR_SEGOVR(); 890 END_OF_INSTR(); 891} 892 893/**************************************************************************** 894REMARKS: 895Handles opcode 0x0d 896****************************************************************************/ 897static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 898{ 899 u32 srcval; 900 901 START_OF_INSTR(); 902 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 903 DECODE_PRINTF("OR\tEAX,"); 904 srcval = fetch_long_imm(); 905 } else { 906 DECODE_PRINTF("OR\tAX,"); 907 srcval = fetch_word_imm(); 908 } 909 DECODE_PRINTF2("%x\n", srcval); 910 TRACE_AND_STEP(); 911 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 912 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval); 913 } else { 914 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval); 915 } 916 DECODE_CLEAR_SEGOVR(); 917 END_OF_INSTR(); 918} 919 920/**************************************************************************** 921REMARKS: 922Handles opcode 0x0e 923****************************************************************************/ 924static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 925{ 926 START_OF_INSTR(); 927 DECODE_PRINTF("PUSH\tCS\n"); 928 TRACE_AND_STEP(); 929 push_word(M.x86.R_CS); 930 DECODE_CLEAR_SEGOVR(); 931 END_OF_INSTR(); 932} 933 934/**************************************************************************** 935REMARKS: 936Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 937****************************************************************************/ 938static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 939{ 940 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 941 INC_DECODED_INST_LEN(1); 942 (*x86emu_optab2[op2])(op2); 943} 944 945/**************************************************************************** 946REMARKS: 947Handles opcode 0x10 948****************************************************************************/ 949static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1)) 950{ 951 int mod, rl, rh; 952 u8 *destreg, *srcreg; 953 uint destoffset; 954 u8 destval; 955 956 START_OF_INSTR(); 957 DECODE_PRINTF("ADC\t"); 958 FETCH_DECODE_MODRM(mod, rh, rl); 959 switch (mod) { 960 case 0: 961 destoffset = decode_rm00_address(rl); 962 DECODE_PRINTF(","); 963 destval = fetch_data_byte(destoffset); 964 srcreg = DECODE_RM_BYTE_REGISTER(rh); 965 DECODE_PRINTF("\n"); 966 TRACE_AND_STEP(); 967 destval = adc_byte(destval, *srcreg); 968 store_data_byte(destoffset, destval); 969 break; 970 case 1: 971 destoffset = decode_rm01_address(rl); 972 DECODE_PRINTF(","); 973 destval = fetch_data_byte(destoffset); 974 srcreg = DECODE_RM_BYTE_REGISTER(rh); 975 DECODE_PRINTF("\n"); 976 TRACE_AND_STEP(); 977 destval = adc_byte(destval, *srcreg); 978 store_data_byte(destoffset, destval); 979 break; 980 case 2: 981 destoffset = decode_rm10_address(rl); 982 DECODE_PRINTF(","); 983 destval = fetch_data_byte(destoffset); 984 srcreg = DECODE_RM_BYTE_REGISTER(rh); 985 DECODE_PRINTF("\n"); 986 TRACE_AND_STEP(); 987 destval = adc_byte(destval, *srcreg); 988 store_data_byte(destoffset, destval); 989 break; 990 case 3: /* register to register */ 991 destreg = DECODE_RM_BYTE_REGISTER(rl); 992 DECODE_PRINTF(","); 993 srcreg = DECODE_RM_BYTE_REGISTER(rh); 994 DECODE_PRINTF("\n"); 995 TRACE_AND_STEP(); 996 *destreg = adc_byte(*destreg, *srcreg); 997 break; 998 } 999 DECODE_CLEAR_SEGOVR(); 1000 END_OF_INSTR(); 1001} 1002 1003/**************************************************************************** 1004REMARKS: 1005Handles opcode 0x11 1006****************************************************************************/ 1007static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1)) 1008{ 1009 int mod, rl, rh; 1010 uint destoffset; 1011 1012 START_OF_INSTR(); 1013 DECODE_PRINTF("ADC\t"); 1014 FETCH_DECODE_MODRM(mod, rh, rl); 1015 switch (mod) { 1016 case 0: 1017 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1018 u32 destval; 1019 u32 *srcreg; 1020 1021 destoffset = decode_rm00_address(rl); 1022 DECODE_PRINTF(","); 1023 destval = fetch_data_long(destoffset); 1024 srcreg = DECODE_RM_LONG_REGISTER(rh); 1025 DECODE_PRINTF("\n"); 1026 TRACE_AND_STEP(); 1027 destval = adc_long(destval, *srcreg); 1028 store_data_long(destoffset, destval); 1029 } else { 1030 u16 destval; 1031 u16 *srcreg; 1032 1033 destoffset = decode_rm00_address(rl); 1034 DECODE_PRINTF(","); 1035 destval = fetch_data_word(destoffset); 1036 srcreg = DECODE_RM_WORD_REGISTER(rh); 1037 DECODE_PRINTF("\n"); 1038 TRACE_AND_STEP(); 1039 destval = adc_word(destval, *srcreg); 1040 store_data_word(destoffset, destval); 1041 } 1042 break; 1043 case 1: 1044 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1045 u32 destval; 1046 u32 *srcreg; 1047 1048 destoffset = decode_rm01_address(rl); 1049 DECODE_PRINTF(","); 1050 destval = fetch_data_long(destoffset); 1051 srcreg = DECODE_RM_LONG_REGISTER(rh); 1052 DECODE_PRINTF("\n"); 1053 TRACE_AND_STEP(); 1054 destval = adc_long(destval, *srcreg); 1055 store_data_long(destoffset, destval); 1056 } else { 1057 u16 destval; 1058 u16 *srcreg; 1059 1060 destoffset = decode_rm01_address(rl); 1061 DECODE_PRINTF(","); 1062 destval = fetch_data_word(destoffset); 1063 srcreg = DECODE_RM_WORD_REGISTER(rh); 1064 DECODE_PRINTF("\n"); 1065 TRACE_AND_STEP(); 1066 destval = adc_word(destval, *srcreg); 1067 store_data_word(destoffset, destval); 1068 } 1069 break; 1070 case 2: 1071 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1072 u32 destval; 1073 u32 *srcreg; 1074 1075 destoffset = decode_rm10_address(rl); 1076 DECODE_PRINTF(","); 1077 destval = fetch_data_long(destoffset); 1078 srcreg = DECODE_RM_LONG_REGISTER(rh); 1079 DECODE_PRINTF("\n"); 1080 TRACE_AND_STEP(); 1081 destval = adc_long(destval, *srcreg); 1082 store_data_long(destoffset, destval); 1083 } else { 1084 u16 destval; 1085 u16 *srcreg; 1086 1087 destoffset = decode_rm10_address(rl); 1088 DECODE_PRINTF(","); 1089 destval = fetch_data_word(destoffset); 1090 srcreg = DECODE_RM_WORD_REGISTER(rh); 1091 DECODE_PRINTF("\n"); 1092 TRACE_AND_STEP(); 1093 destval = adc_word(destval, *srcreg); 1094 store_data_word(destoffset, destval); 1095 } 1096 break; 1097 case 3: /* register to register */ 1098 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1099 u32 *destreg,*srcreg; 1100 1101 destreg = DECODE_RM_LONG_REGISTER(rl); 1102 DECODE_PRINTF(","); 1103 srcreg = DECODE_RM_LONG_REGISTER(rh); 1104 DECODE_PRINTF("\n"); 1105 TRACE_AND_STEP(); 1106 *destreg = adc_long(*destreg, *srcreg); 1107 } else { 1108 u16 *destreg,*srcreg; 1109 1110 destreg = DECODE_RM_WORD_REGISTER(rl); 1111 DECODE_PRINTF(","); 1112 srcreg = DECODE_RM_WORD_REGISTER(rh); 1113 DECODE_PRINTF("\n"); 1114 TRACE_AND_STEP(); 1115 *destreg = adc_word(*destreg, *srcreg); 1116 } 1117 break; 1118 } 1119 DECODE_CLEAR_SEGOVR(); 1120 END_OF_INSTR(); 1121} 1122 1123/**************************************************************************** 1124REMARKS: 1125Handles opcode 0x12 1126****************************************************************************/ 1127static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1128{ 1129 int mod, rl, rh; 1130 u8 *destreg, *srcreg; 1131 uint srcoffset; 1132 u8 srcval; 1133 1134 START_OF_INSTR(); 1135 DECODE_PRINTF("ADC\t"); 1136 FETCH_DECODE_MODRM(mod, rh, rl); 1137 switch (mod) { 1138 case 0: 1139 destreg = DECODE_RM_BYTE_REGISTER(rh); 1140 DECODE_PRINTF(","); 1141 srcoffset = decode_rm00_address(rl); 1142 srcval = fetch_data_byte(srcoffset); 1143 DECODE_PRINTF("\n"); 1144 TRACE_AND_STEP(); 1145 *destreg = adc_byte(*destreg, srcval); 1146 break; 1147 case 1: 1148 destreg = DECODE_RM_BYTE_REGISTER(rh); 1149 DECODE_PRINTF(","); 1150 srcoffset = decode_rm01_address(rl); 1151 srcval = fetch_data_byte(srcoffset); 1152 DECODE_PRINTF("\n"); 1153 TRACE_AND_STEP(); 1154 *destreg = adc_byte(*destreg, srcval); 1155 break; 1156 case 2: 1157 destreg = DECODE_RM_BYTE_REGISTER(rh); 1158 DECODE_PRINTF(","); 1159 srcoffset = decode_rm10_address(rl); 1160 srcval = fetch_data_byte(srcoffset); 1161 DECODE_PRINTF("\n"); 1162 TRACE_AND_STEP(); 1163 *destreg = adc_byte(*destreg, srcval); 1164 break; 1165 case 3: /* register to register */ 1166 destreg = DECODE_RM_BYTE_REGISTER(rh); 1167 DECODE_PRINTF(","); 1168 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1169 DECODE_PRINTF("\n"); 1170 TRACE_AND_STEP(); 1171 *destreg = adc_byte(*destreg, *srcreg); 1172 break; 1173 } 1174 DECODE_CLEAR_SEGOVR(); 1175 END_OF_INSTR(); 1176} 1177 1178/**************************************************************************** 1179REMARKS: 1180Handles opcode 0x13 1181****************************************************************************/ 1182static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1)) 1183{ 1184 int mod, rl, rh; 1185 uint srcoffset; 1186 1187 START_OF_INSTR(); 1188 DECODE_PRINTF("ADC\t"); 1189 FETCH_DECODE_MODRM(mod, rh, rl); 1190 switch (mod) { 1191 case 0: 1192 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1193 u32 *destreg; 1194 u32 srcval; 1195 1196 destreg = DECODE_RM_LONG_REGISTER(rh); 1197 DECODE_PRINTF(","); 1198 srcoffset = decode_rm00_address(rl); 1199 srcval = fetch_data_long(srcoffset); 1200 DECODE_PRINTF("\n"); 1201 TRACE_AND_STEP(); 1202 *destreg = adc_long(*destreg, srcval); 1203 } else { 1204 u16 *destreg; 1205 u16 srcval; 1206 1207 destreg = DECODE_RM_WORD_REGISTER(rh); 1208 DECODE_PRINTF(","); 1209 srcoffset = decode_rm00_address(rl); 1210 srcval = fetch_data_word(srcoffset); 1211 DECODE_PRINTF("\n"); 1212 TRACE_AND_STEP(); 1213 *destreg = adc_word(*destreg, srcval); 1214 } 1215 break; 1216 case 1: 1217 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1218 u32 *destreg; 1219 u32 srcval; 1220 1221 destreg = DECODE_RM_LONG_REGISTER(rh); 1222 DECODE_PRINTF(","); 1223 srcoffset = decode_rm01_address(rl); 1224 srcval = fetch_data_long(srcoffset); 1225 DECODE_PRINTF("\n"); 1226 TRACE_AND_STEP(); 1227 *destreg = adc_long(*destreg, srcval); 1228 } else { 1229 u16 *destreg; 1230 u16 srcval; 1231 1232 destreg = DECODE_RM_WORD_REGISTER(rh); 1233 DECODE_PRINTF(","); 1234 srcoffset = decode_rm01_address(rl); 1235 srcval = fetch_data_word(srcoffset); 1236 DECODE_PRINTF("\n"); 1237 TRACE_AND_STEP(); 1238 *destreg = adc_word(*destreg, srcval); 1239 } 1240 break; 1241 case 2: 1242 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1243 u32 *destreg; 1244 u32 srcval; 1245 1246 destreg = DECODE_RM_LONG_REGISTER(rh); 1247 DECODE_PRINTF(","); 1248 srcoffset = decode_rm10_address(rl); 1249 srcval = fetch_data_long(srcoffset); 1250 DECODE_PRINTF("\n"); 1251 TRACE_AND_STEP(); 1252 *destreg = adc_long(*destreg, srcval); 1253 } else { 1254 u16 *destreg; 1255 u16 srcval; 1256 1257 destreg = DECODE_RM_WORD_REGISTER(rh); 1258 DECODE_PRINTF(","); 1259 srcoffset = decode_rm10_address(rl); 1260 srcval = fetch_data_word(srcoffset); 1261 DECODE_PRINTF("\n"); 1262 TRACE_AND_STEP(); 1263 *destreg = adc_word(*destreg, srcval); 1264 } 1265 break; 1266 case 3: /* register to register */ 1267 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1268 u32 *destreg,*srcreg; 1269 1270 destreg = DECODE_RM_LONG_REGISTER(rh); 1271 DECODE_PRINTF(","); 1272 srcreg = DECODE_RM_LONG_REGISTER(rl); 1273 DECODE_PRINTF("\n"); 1274 TRACE_AND_STEP(); 1275 *destreg = adc_long(*destreg, *srcreg); 1276 } else { 1277 u16 *destreg,*srcreg; 1278 1279 destreg = DECODE_RM_WORD_REGISTER(rh); 1280 DECODE_PRINTF(","); 1281 srcreg = DECODE_RM_WORD_REGISTER(rl); 1282 DECODE_PRINTF("\n"); 1283 TRACE_AND_STEP(); 1284 *destreg = adc_word(*destreg, *srcreg); 1285 } 1286 break; 1287 } 1288 DECODE_CLEAR_SEGOVR(); 1289 END_OF_INSTR(); 1290} 1291 1292/**************************************************************************** 1293REMARKS: 1294Handles opcode 0x14 1295****************************************************************************/ 1296static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1297{ 1298 u8 srcval; 1299 1300 START_OF_INSTR(); 1301 DECODE_PRINTF("ADC\tAL,"); 1302 srcval = fetch_byte_imm(); 1303 DECODE_PRINTF2("%x\n", srcval); 1304 TRACE_AND_STEP(); 1305 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval); 1306 DECODE_CLEAR_SEGOVR(); 1307 END_OF_INSTR(); 1308} 1309 1310/**************************************************************************** 1311REMARKS: 1312Handles opcode 0x15 1313****************************************************************************/ 1314static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1315{ 1316 u32 srcval; 1317 1318 START_OF_INSTR(); 1319 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1320 DECODE_PRINTF("ADC\tEAX,"); 1321 srcval = fetch_long_imm(); 1322 } else { 1323 DECODE_PRINTF("ADC\tAX,"); 1324 srcval = fetch_word_imm(); 1325 } 1326 DECODE_PRINTF2("%x\n", srcval); 1327 TRACE_AND_STEP(); 1328 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1329 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval); 1330 } else { 1331 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval); 1332 } 1333 DECODE_CLEAR_SEGOVR(); 1334 END_OF_INSTR(); 1335} 1336 1337/**************************************************************************** 1338REMARKS: 1339Handles opcode 0x16 1340****************************************************************************/ 1341static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 1342{ 1343 START_OF_INSTR(); 1344 DECODE_PRINTF("PUSH\tSS\n"); 1345 TRACE_AND_STEP(); 1346 push_word(M.x86.R_SS); 1347 DECODE_CLEAR_SEGOVR(); 1348 END_OF_INSTR(); 1349} 1350 1351/**************************************************************************** 1352REMARKS: 1353Handles opcode 0x17 1354****************************************************************************/ 1355static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 1356{ 1357 START_OF_INSTR(); 1358 DECODE_PRINTF("POP\tSS\n"); 1359 TRACE_AND_STEP(); 1360 M.x86.R_SS = pop_word(); 1361 DECODE_CLEAR_SEGOVR(); 1362 END_OF_INSTR(); 1363} 1364 1365/**************************************************************************** 1366REMARKS: 1367Handles opcode 0x18 1368****************************************************************************/ 1369static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1370{ 1371 int mod, rl, rh; 1372 u8 *destreg, *srcreg; 1373 uint destoffset; 1374 u8 destval; 1375 1376 START_OF_INSTR(); 1377 DECODE_PRINTF("SBB\t"); 1378 FETCH_DECODE_MODRM(mod, rh, rl); 1379 switch (mod) { 1380 case 0: 1381 destoffset = decode_rm00_address(rl); 1382 DECODE_PRINTF(","); 1383 destval = fetch_data_byte(destoffset); 1384 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1385 DECODE_PRINTF("\n"); 1386 TRACE_AND_STEP(); 1387 destval = sbb_byte(destval, *srcreg); 1388 store_data_byte(destoffset, destval); 1389 break; 1390 case 1: 1391 destoffset = decode_rm01_address(rl); 1392 DECODE_PRINTF(","); 1393 destval = fetch_data_byte(destoffset); 1394 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1395 DECODE_PRINTF("\n"); 1396 TRACE_AND_STEP(); 1397 destval = sbb_byte(destval, *srcreg); 1398 store_data_byte(destoffset, destval); 1399 break; 1400 case 2: 1401 destoffset = decode_rm10_address(rl); 1402 DECODE_PRINTF(","); 1403 destval = fetch_data_byte(destoffset); 1404 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1405 DECODE_PRINTF("\n"); 1406 TRACE_AND_STEP(); 1407 destval = sbb_byte(destval, *srcreg); 1408 store_data_byte(destoffset, destval); 1409 break; 1410 case 3: /* register to register */ 1411 destreg = DECODE_RM_BYTE_REGISTER(rl); 1412 DECODE_PRINTF(","); 1413 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1414 DECODE_PRINTF("\n"); 1415 TRACE_AND_STEP(); 1416 *destreg = sbb_byte(*destreg, *srcreg); 1417 break; 1418 } 1419 DECODE_CLEAR_SEGOVR(); 1420 END_OF_INSTR(); 1421} 1422 1423/**************************************************************************** 1424REMARKS: 1425Handles opcode 0x19 1426****************************************************************************/ 1427static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1)) 1428{ 1429 int mod, rl, rh; 1430 uint destoffset; 1431 1432 START_OF_INSTR(); 1433 DECODE_PRINTF("SBB\t"); 1434 FETCH_DECODE_MODRM(mod, rh, rl); 1435 switch (mod) { 1436 case 0: 1437 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1438 u32 destval; 1439 u32 *srcreg; 1440 1441 destoffset = decode_rm00_address(rl); 1442 DECODE_PRINTF(","); 1443 destval = fetch_data_long(destoffset); 1444 srcreg = DECODE_RM_LONG_REGISTER(rh); 1445 DECODE_PRINTF("\n"); 1446 TRACE_AND_STEP(); 1447 destval = sbb_long(destval, *srcreg); 1448 store_data_long(destoffset, destval); 1449 } else { 1450 u16 destval; 1451 u16 *srcreg; 1452 1453 destoffset = decode_rm00_address(rl); 1454 DECODE_PRINTF(","); 1455 destval = fetch_data_word(destoffset); 1456 srcreg = DECODE_RM_WORD_REGISTER(rh); 1457 DECODE_PRINTF("\n"); 1458 TRACE_AND_STEP(); 1459 destval = sbb_word(destval, *srcreg); 1460 store_data_word(destoffset, destval); 1461 } 1462 break; 1463 case 1: 1464 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1465 u32 destval; 1466 u32 *srcreg; 1467 1468 destoffset = decode_rm01_address(rl); 1469 DECODE_PRINTF(","); 1470 destval = fetch_data_long(destoffset); 1471 srcreg = DECODE_RM_LONG_REGISTER(rh); 1472 DECODE_PRINTF("\n"); 1473 TRACE_AND_STEP(); 1474 destval = sbb_long(destval, *srcreg); 1475 store_data_long(destoffset, destval); 1476 } else { 1477 u16 destval; 1478 u16 *srcreg; 1479 1480 destoffset = decode_rm01_address(rl); 1481 DECODE_PRINTF(","); 1482 destval = fetch_data_word(destoffset); 1483 srcreg = DECODE_RM_WORD_REGISTER(rh); 1484 DECODE_PRINTF("\n"); 1485 TRACE_AND_STEP(); 1486 destval = sbb_word(destval, *srcreg); 1487 store_data_word(destoffset, destval); 1488 } 1489 break; 1490 case 2: 1491 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1492 u32 destval; 1493 u32 *srcreg; 1494 1495 destoffset = decode_rm10_address(rl); 1496 DECODE_PRINTF(","); 1497 destval = fetch_data_long(destoffset); 1498 srcreg = DECODE_RM_LONG_REGISTER(rh); 1499 DECODE_PRINTF("\n"); 1500 TRACE_AND_STEP(); 1501 destval = sbb_long(destval, *srcreg); 1502 store_data_long(destoffset, destval); 1503 } else { 1504 u16 destval; 1505 u16 *srcreg; 1506 1507 destoffset = decode_rm10_address(rl); 1508 DECODE_PRINTF(","); 1509 destval = fetch_data_word(destoffset); 1510 srcreg = DECODE_RM_WORD_REGISTER(rh); 1511 DECODE_PRINTF("\n"); 1512 TRACE_AND_STEP(); 1513 destval = sbb_word(destval, *srcreg); 1514 store_data_word(destoffset, destval); 1515 } 1516 break; 1517 case 3: /* register to register */ 1518 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1519 u32 *destreg,*srcreg; 1520 1521 destreg = DECODE_RM_LONG_REGISTER(rl); 1522 DECODE_PRINTF(","); 1523 srcreg = DECODE_RM_LONG_REGISTER(rh); 1524 DECODE_PRINTF("\n"); 1525 TRACE_AND_STEP(); 1526 *destreg = sbb_long(*destreg, *srcreg); 1527 } else { 1528 u16 *destreg,*srcreg; 1529 1530 destreg = DECODE_RM_WORD_REGISTER(rl); 1531 DECODE_PRINTF(","); 1532 srcreg = DECODE_RM_WORD_REGISTER(rh); 1533 DECODE_PRINTF("\n"); 1534 TRACE_AND_STEP(); 1535 *destreg = sbb_word(*destreg, *srcreg); 1536 } 1537 break; 1538 } 1539 DECODE_CLEAR_SEGOVR(); 1540 END_OF_INSTR(); 1541} 1542 1543/**************************************************************************** 1544REMARKS: 1545Handles opcode 0x1a 1546****************************************************************************/ 1547static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1548{ 1549 int mod, rl, rh; 1550 u8 *destreg, *srcreg; 1551 uint srcoffset; 1552 u8 srcval; 1553 1554 START_OF_INSTR(); 1555 DECODE_PRINTF("SBB\t"); 1556 FETCH_DECODE_MODRM(mod, rh, rl); 1557 switch (mod) { 1558 case 0: 1559 destreg = DECODE_RM_BYTE_REGISTER(rh); 1560 DECODE_PRINTF(","); 1561 srcoffset = decode_rm00_address(rl); 1562 srcval = fetch_data_byte(srcoffset); 1563 DECODE_PRINTF("\n"); 1564 TRACE_AND_STEP(); 1565 *destreg = sbb_byte(*destreg, srcval); 1566 break; 1567 case 1: 1568 destreg = DECODE_RM_BYTE_REGISTER(rh); 1569 DECODE_PRINTF(","); 1570 srcoffset = decode_rm01_address(rl); 1571 srcval = fetch_data_byte(srcoffset); 1572 DECODE_PRINTF("\n"); 1573 TRACE_AND_STEP(); 1574 *destreg = sbb_byte(*destreg, srcval); 1575 break; 1576 case 2: 1577 destreg = DECODE_RM_BYTE_REGISTER(rh); 1578 DECODE_PRINTF(","); 1579 srcoffset = decode_rm10_address(rl); 1580 srcval = fetch_data_byte(srcoffset); 1581 DECODE_PRINTF("\n"); 1582 TRACE_AND_STEP(); 1583 *destreg = sbb_byte(*destreg, srcval); 1584 break; 1585 case 3: /* register to register */ 1586 destreg = DECODE_RM_BYTE_REGISTER(rh); 1587 DECODE_PRINTF(","); 1588 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1589 DECODE_PRINTF("\n"); 1590 TRACE_AND_STEP(); 1591 *destreg = sbb_byte(*destreg, *srcreg); 1592 break; 1593 } 1594 DECODE_CLEAR_SEGOVR(); 1595 END_OF_INSTR(); 1596} 1597 1598/**************************************************************************** 1599REMARKS: 1600Handles opcode 0x1b 1601****************************************************************************/ 1602static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1)) 1603{ 1604 int mod, rl, rh; 1605 uint srcoffset; 1606 1607 START_OF_INSTR(); 1608 DECODE_PRINTF("SBB\t"); 1609 FETCH_DECODE_MODRM(mod, rh, rl); 1610 switch (mod) { 1611 case 0: 1612 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1613 u32 *destreg; 1614 u32 srcval; 1615 1616 destreg = DECODE_RM_LONG_REGISTER(rh); 1617 DECODE_PRINTF(","); 1618 srcoffset = decode_rm00_address(rl); 1619 srcval = fetch_data_long(srcoffset); 1620 DECODE_PRINTF("\n"); 1621 TRACE_AND_STEP(); 1622 *destreg = sbb_long(*destreg, srcval); 1623 } else { 1624 u16 *destreg; 1625 u16 srcval; 1626 1627 destreg = DECODE_RM_WORD_REGISTER(rh); 1628 DECODE_PRINTF(","); 1629 srcoffset = decode_rm00_address(rl); 1630 srcval = fetch_data_word(srcoffset); 1631 DECODE_PRINTF("\n"); 1632 TRACE_AND_STEP(); 1633 *destreg = sbb_word(*destreg, srcval); 1634 } 1635 break; 1636 case 1: 1637 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1638 u32 *destreg; 1639 u32 srcval; 1640 1641 destreg = DECODE_RM_LONG_REGISTER(rh); 1642 DECODE_PRINTF(","); 1643 srcoffset = decode_rm01_address(rl); 1644 srcval = fetch_data_long(srcoffset); 1645 DECODE_PRINTF("\n"); 1646 TRACE_AND_STEP(); 1647 *destreg = sbb_long(*destreg, srcval); 1648 } else { 1649 u16 *destreg; 1650 u16 srcval; 1651 1652 destreg = DECODE_RM_WORD_REGISTER(rh); 1653 DECODE_PRINTF(","); 1654 srcoffset = decode_rm01_address(rl); 1655 srcval = fetch_data_word(srcoffset); 1656 DECODE_PRINTF("\n"); 1657 TRACE_AND_STEP(); 1658 *destreg = sbb_word(*destreg, srcval); 1659 } 1660 break; 1661 case 2: 1662 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1663 u32 *destreg; 1664 u32 srcval; 1665 1666 destreg = DECODE_RM_LONG_REGISTER(rh); 1667 DECODE_PRINTF(","); 1668 srcoffset = decode_rm10_address(rl); 1669 srcval = fetch_data_long(srcoffset); 1670 DECODE_PRINTF("\n"); 1671 TRACE_AND_STEP(); 1672 *destreg = sbb_long(*destreg, srcval); 1673 } else { 1674 u16 *destreg; 1675 u16 srcval; 1676 1677 destreg = DECODE_RM_WORD_REGISTER(rh); 1678 DECODE_PRINTF(","); 1679 srcoffset = decode_rm10_address(rl); 1680 srcval = fetch_data_word(srcoffset); 1681 DECODE_PRINTF("\n"); 1682 TRACE_AND_STEP(); 1683 *destreg = sbb_word(*destreg, srcval); 1684 } 1685 break; 1686 case 3: /* register to register */ 1687 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1688 u32 *destreg,*srcreg; 1689 1690 destreg = DECODE_RM_LONG_REGISTER(rh); 1691 DECODE_PRINTF(","); 1692 srcreg = DECODE_RM_LONG_REGISTER(rl); 1693 DECODE_PRINTF("\n"); 1694 TRACE_AND_STEP(); 1695 *destreg = sbb_long(*destreg, *srcreg); 1696 } else { 1697 u16 *destreg,*srcreg; 1698 1699 destreg = DECODE_RM_WORD_REGISTER(rh); 1700 DECODE_PRINTF(","); 1701 srcreg = DECODE_RM_WORD_REGISTER(rl); 1702 DECODE_PRINTF("\n"); 1703 TRACE_AND_STEP(); 1704 *destreg = sbb_word(*destreg, *srcreg); 1705 } 1706 break; 1707 } 1708 DECODE_CLEAR_SEGOVR(); 1709 END_OF_INSTR(); 1710} 1711 1712/**************************************************************************** 1713REMARKS: 1714Handles opcode 0x1c 1715****************************************************************************/ 1716static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1717{ 1718 u8 srcval; 1719 1720 START_OF_INSTR(); 1721 DECODE_PRINTF("SBB\tAL,"); 1722 srcval = fetch_byte_imm(); 1723 DECODE_PRINTF2("%x\n", srcval); 1724 TRACE_AND_STEP(); 1725 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval); 1726 DECODE_CLEAR_SEGOVR(); 1727 END_OF_INSTR(); 1728} 1729 1730/**************************************************************************** 1731REMARKS: 1732Handles opcode 0x1d 1733****************************************************************************/ 1734static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1735{ 1736 u32 srcval; 1737 1738 START_OF_INSTR(); 1739 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1740 DECODE_PRINTF("SBB\tEAX,"); 1741 srcval = fetch_long_imm(); 1742 } else { 1743 DECODE_PRINTF("SBB\tAX,"); 1744 srcval = fetch_word_imm(); 1745 } 1746 DECODE_PRINTF2("%x\n", srcval); 1747 TRACE_AND_STEP(); 1748 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1749 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval); 1750 } else { 1751 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval); 1752 } 1753 DECODE_CLEAR_SEGOVR(); 1754 END_OF_INSTR(); 1755} 1756 1757/**************************************************************************** 1758REMARKS: 1759Handles opcode 0x1e 1760****************************************************************************/ 1761static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 1762{ 1763 START_OF_INSTR(); 1764 DECODE_PRINTF("PUSH\tDS\n"); 1765 TRACE_AND_STEP(); 1766 push_word(M.x86.R_DS); 1767 DECODE_CLEAR_SEGOVR(); 1768 END_OF_INSTR(); 1769} 1770 1771/**************************************************************************** 1772REMARKS: 1773Handles opcode 0x1f 1774****************************************************************************/ 1775static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 1776{ 1777 START_OF_INSTR(); 1778 DECODE_PRINTF("POP\tDS\n"); 1779 TRACE_AND_STEP(); 1780 M.x86.R_DS = pop_word(); 1781 DECODE_CLEAR_SEGOVR(); 1782 END_OF_INSTR(); 1783} 1784 1785/**************************************************************************** 1786REMARKS: 1787Handles opcode 0x20 1788****************************************************************************/ 1789static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1790{ 1791 int mod, rl, rh; 1792 u8 *destreg, *srcreg; 1793 uint destoffset; 1794 u8 destval; 1795 1796 START_OF_INSTR(); 1797 DECODE_PRINTF("AND\t"); 1798 FETCH_DECODE_MODRM(mod, rh, rl); 1799 1800 switch (mod) { 1801 case 0: 1802 destoffset = decode_rm00_address(rl); 1803 DECODE_PRINTF(","); 1804 destval = fetch_data_byte(destoffset); 1805 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1806 DECODE_PRINTF("\n"); 1807 TRACE_AND_STEP(); 1808 destval = and_byte(destval, *srcreg); 1809 store_data_byte(destoffset, destval); 1810 break; 1811 1812 case 1: 1813 destoffset = decode_rm01_address(rl); 1814 DECODE_PRINTF(","); 1815 destval = fetch_data_byte(destoffset); 1816 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1817 DECODE_PRINTF("\n"); 1818 TRACE_AND_STEP(); 1819 destval = and_byte(destval, *srcreg); 1820 store_data_byte(destoffset, destval); 1821 break; 1822 1823 case 2: 1824 destoffset = decode_rm10_address(rl); 1825 DECODE_PRINTF(","); 1826 destval = fetch_data_byte(destoffset); 1827 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1828 DECODE_PRINTF("\n"); 1829 TRACE_AND_STEP(); 1830 destval = and_byte(destval, *srcreg); 1831 store_data_byte(destoffset, destval); 1832 break; 1833 1834 case 3: /* register to register */ 1835 destreg = DECODE_RM_BYTE_REGISTER(rl); 1836 DECODE_PRINTF(","); 1837 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1838 DECODE_PRINTF("\n"); 1839 TRACE_AND_STEP(); 1840 *destreg = and_byte(*destreg, *srcreg); 1841 break; 1842 } 1843 DECODE_CLEAR_SEGOVR(); 1844 END_OF_INSTR(); 1845} 1846 1847/**************************************************************************** 1848REMARKS: 1849Handles opcode 0x21 1850****************************************************************************/ 1851static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1)) 1852{ 1853 int mod, rl, rh; 1854 uint destoffset; 1855 1856 START_OF_INSTR(); 1857 DECODE_PRINTF("AND\t"); 1858 FETCH_DECODE_MODRM(mod, rh, rl); 1859 switch (mod) { 1860 case 0: 1861 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1862 u32 destval; 1863 u32 *srcreg; 1864 1865 destoffset = decode_rm00_address(rl); 1866 DECODE_PRINTF(","); 1867 destval = fetch_data_long(destoffset); 1868 srcreg = DECODE_RM_LONG_REGISTER(rh); 1869 DECODE_PRINTF("\n"); 1870 TRACE_AND_STEP(); 1871 destval = and_long(destval, *srcreg); 1872 store_data_long(destoffset, destval); 1873 } else { 1874 u16 destval; 1875 u16 *srcreg; 1876 1877 destoffset = decode_rm00_address(rl); 1878 DECODE_PRINTF(","); 1879 destval = fetch_data_word(destoffset); 1880 srcreg = DECODE_RM_WORD_REGISTER(rh); 1881 DECODE_PRINTF("\n"); 1882 TRACE_AND_STEP(); 1883 destval = and_word(destval, *srcreg); 1884 store_data_word(destoffset, destval); 1885 } 1886 break; 1887 case 1: 1888 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1889 u32 destval; 1890 u32 *srcreg; 1891 1892 destoffset = decode_rm01_address(rl); 1893 DECODE_PRINTF(","); 1894 destval = fetch_data_long(destoffset); 1895 srcreg = DECODE_RM_LONG_REGISTER(rh); 1896 DECODE_PRINTF("\n"); 1897 TRACE_AND_STEP(); 1898 destval = and_long(destval, *srcreg); 1899 store_data_long(destoffset, destval); 1900 } else { 1901 u16 destval; 1902 u16 *srcreg; 1903 1904 destoffset = decode_rm01_address(rl); 1905 DECODE_PRINTF(","); 1906 destval = fetch_data_word(destoffset); 1907 srcreg = DECODE_RM_WORD_REGISTER(rh); 1908 DECODE_PRINTF("\n"); 1909 TRACE_AND_STEP(); 1910 destval = and_word(destval, *srcreg); 1911 store_data_word(destoffset, destval); 1912 } 1913 break; 1914 case 2: 1915 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1916 u32 destval; 1917 u32 *srcreg; 1918 1919 destoffset = decode_rm10_address(rl); 1920 DECODE_PRINTF(","); 1921 destval = fetch_data_long(destoffset); 1922 srcreg = DECODE_RM_LONG_REGISTER(rh); 1923 DECODE_PRINTF("\n"); 1924 TRACE_AND_STEP(); 1925 destval = and_long(destval, *srcreg); 1926 store_data_long(destoffset, destval); 1927 } else { 1928 u16 destval; 1929 u16 *srcreg; 1930 1931 destoffset = decode_rm10_address(rl); 1932 DECODE_PRINTF(","); 1933 destval = fetch_data_word(destoffset); 1934 srcreg = DECODE_RM_WORD_REGISTER(rh); 1935 DECODE_PRINTF("\n"); 1936 TRACE_AND_STEP(); 1937 destval = and_word(destval, *srcreg); 1938 store_data_word(destoffset, destval); 1939 } 1940 break; 1941 case 3: /* register to register */ 1942 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1943 u32 *destreg,*srcreg; 1944 1945 destreg = DECODE_RM_LONG_REGISTER(rl); 1946 DECODE_PRINTF(","); 1947 srcreg = DECODE_RM_LONG_REGISTER(rh); 1948 DECODE_PRINTF("\n"); 1949 TRACE_AND_STEP(); 1950 *destreg = and_long(*destreg, *srcreg); 1951 } else { 1952 u16 *destreg,*srcreg; 1953 1954 destreg = DECODE_RM_WORD_REGISTER(rl); 1955 DECODE_PRINTF(","); 1956 srcreg = DECODE_RM_WORD_REGISTER(rh); 1957 DECODE_PRINTF("\n"); 1958 TRACE_AND_STEP(); 1959 *destreg = and_word(*destreg, *srcreg); 1960 } 1961 break; 1962 } 1963 DECODE_CLEAR_SEGOVR(); 1964 END_OF_INSTR(); 1965} 1966 1967/**************************************************************************** 1968REMARKS: 1969Handles opcode 0x22 1970****************************************************************************/ 1971static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1972{ 1973 int mod, rl, rh; 1974 u8 *destreg, *srcreg; 1975 uint srcoffset; 1976 u8 srcval; 1977 1978 START_OF_INSTR(); 1979 DECODE_PRINTF("AND\t"); 1980 FETCH_DECODE_MODRM(mod, rh, rl); 1981 switch (mod) { 1982 case 0: 1983 destreg = DECODE_RM_BYTE_REGISTER(rh); 1984 DECODE_PRINTF(","); 1985 srcoffset = decode_rm00_address(rl); 1986 srcval = fetch_data_byte(srcoffset); 1987 DECODE_PRINTF("\n"); 1988 TRACE_AND_STEP(); 1989 *destreg = and_byte(*destreg, srcval); 1990 break; 1991 case 1: 1992 destreg = DECODE_RM_BYTE_REGISTER(rh); 1993 DECODE_PRINTF(","); 1994 srcoffset = decode_rm01_address(rl); 1995 srcval = fetch_data_byte(srcoffset); 1996 DECODE_PRINTF("\n"); 1997 TRACE_AND_STEP(); 1998 *destreg = and_byte(*destreg, srcval); 1999 break; 2000 case 2: 2001 destreg = DECODE_RM_BYTE_REGISTER(rh); 2002 DECODE_PRINTF(","); 2003 srcoffset = decode_rm10_address(rl); 2004 srcval = fetch_data_byte(srcoffset); 2005 DECODE_PRINTF("\n"); 2006 TRACE_AND_STEP(); 2007 *destreg = and_byte(*destreg, srcval); 2008 break; 2009 case 3: /* register to register */ 2010 destreg = DECODE_RM_BYTE_REGISTER(rh); 2011 DECODE_PRINTF(","); 2012 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2013 DECODE_PRINTF("\n"); 2014 TRACE_AND_STEP(); 2015 *destreg = and_byte(*destreg, *srcreg); 2016 break; 2017 } 2018 DECODE_CLEAR_SEGOVR(); 2019 END_OF_INSTR(); 2020} 2021 2022/**************************************************************************** 2023REMARKS: 2024Handles opcode 0x23 2025****************************************************************************/ 2026static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1)) 2027{ 2028 int mod, rl, rh; 2029 uint srcoffset; 2030 2031 START_OF_INSTR(); 2032 DECODE_PRINTF("AND\t"); 2033 FETCH_DECODE_MODRM(mod, rh, rl); 2034 switch (mod) { 2035 case 0: 2036 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2037 u32 *destreg; 2038 u32 srcval; 2039 2040 destreg = DECODE_RM_LONG_REGISTER(rh); 2041 DECODE_PRINTF(","); 2042 srcoffset = decode_rm00_address(rl); 2043 srcval = fetch_data_long(srcoffset); 2044 DECODE_PRINTF("\n"); 2045 TRACE_AND_STEP(); 2046 *destreg = and_long(*destreg, srcval); 2047 } else { 2048 u16 *destreg; 2049 u16 srcval; 2050 2051 destreg = DECODE_RM_WORD_REGISTER(rh); 2052 DECODE_PRINTF(","); 2053 srcoffset = decode_rm00_address(rl); 2054 srcval = fetch_data_word(srcoffset); 2055 DECODE_PRINTF("\n"); 2056 TRACE_AND_STEP(); 2057 *destreg = and_word(*destreg, srcval); 2058 } 2059 break; 2060 case 1: 2061 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2062 u32 *destreg; 2063 u32 srcval; 2064 2065 destreg = DECODE_RM_LONG_REGISTER(rh); 2066 DECODE_PRINTF(","); 2067 srcoffset = decode_rm01_address(rl); 2068 srcval = fetch_data_long(srcoffset); 2069 DECODE_PRINTF("\n"); 2070 TRACE_AND_STEP(); 2071 *destreg = and_long(*destreg, srcval); 2072 break; 2073 } else { 2074 u16 *destreg; 2075 u16 srcval; 2076 2077 destreg = DECODE_RM_WORD_REGISTER(rh); 2078 DECODE_PRINTF(","); 2079 srcoffset = decode_rm01_address(rl); 2080 srcval = fetch_data_word(srcoffset); 2081 DECODE_PRINTF("\n"); 2082 TRACE_AND_STEP(); 2083 *destreg = and_word(*destreg, srcval); 2084 break; 2085 } 2086 case 2: 2087 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2088 u32 *destreg; 2089 u32 srcval; 2090 2091 destreg = DECODE_RM_LONG_REGISTER(rh); 2092 DECODE_PRINTF(","); 2093 srcoffset = decode_rm10_address(rl); 2094 srcval = fetch_data_long(srcoffset); 2095 DECODE_PRINTF("\n"); 2096 TRACE_AND_STEP(); 2097 *destreg = and_long(*destreg, srcval); 2098 } else { 2099 u16 *destreg; 2100 u16 srcval; 2101 2102 destreg = DECODE_RM_WORD_REGISTER(rh); 2103 DECODE_PRINTF(","); 2104 srcoffset = decode_rm10_address(rl); 2105 srcval = fetch_data_word(srcoffset); 2106 DECODE_PRINTF("\n"); 2107 TRACE_AND_STEP(); 2108 *destreg = and_word(*destreg, srcval); 2109 } 2110 break; 2111 case 3: /* register to register */ 2112 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2113 u32 *destreg,*srcreg; 2114 2115 destreg = DECODE_RM_LONG_REGISTER(rh); 2116 DECODE_PRINTF(","); 2117 srcreg = DECODE_RM_LONG_REGISTER(rl); 2118 DECODE_PRINTF("\n"); 2119 TRACE_AND_STEP(); 2120 *destreg = and_long(*destreg, *srcreg); 2121 } else { 2122 u16 *destreg,*srcreg; 2123 2124 destreg = DECODE_RM_WORD_REGISTER(rh); 2125 DECODE_PRINTF(","); 2126 srcreg = DECODE_RM_WORD_REGISTER(rl); 2127 DECODE_PRINTF("\n"); 2128 TRACE_AND_STEP(); 2129 *destreg = and_word(*destreg, *srcreg); 2130 } 2131 break; 2132 } 2133 DECODE_CLEAR_SEGOVR(); 2134 END_OF_INSTR(); 2135} 2136 2137/**************************************************************************** 2138REMARKS: 2139Handles opcode 0x24 2140****************************************************************************/ 2141static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2142{ 2143 u8 srcval; 2144 2145 START_OF_INSTR(); 2146 DECODE_PRINTF("AND\tAL,"); 2147 srcval = fetch_byte_imm(); 2148 DECODE_PRINTF2("%x\n", srcval); 2149 TRACE_AND_STEP(); 2150 M.x86.R_AL = and_byte(M.x86.R_AL, srcval); 2151 DECODE_CLEAR_SEGOVR(); 2152 END_OF_INSTR(); 2153} 2154 2155/**************************************************************************** 2156REMARKS: 2157Handles opcode 0x25 2158****************************************************************************/ 2159static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2160{ 2161 u32 srcval; 2162 2163 START_OF_INSTR(); 2164 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2165 DECODE_PRINTF("AND\tEAX,"); 2166 srcval = fetch_long_imm(); 2167 } else { 2168 DECODE_PRINTF("AND\tAX,"); 2169 srcval = fetch_word_imm(); 2170 } 2171 DECODE_PRINTF2("%x\n", srcval); 2172 TRACE_AND_STEP(); 2173 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2174 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval); 2175 } else { 2176 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval); 2177 } 2178 DECODE_CLEAR_SEGOVR(); 2179 END_OF_INSTR(); 2180} 2181 2182/**************************************************************************** 2183REMARKS: 2184Handles opcode 0x26 2185****************************************************************************/ 2186static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 2187{ 2188 START_OF_INSTR(); 2189 DECODE_PRINTF("ES:\n"); 2190 TRACE_AND_STEP(); 2191 M.x86.mode |= SYSMODE_SEGOVR_ES; 2192 /* 2193 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 2194 * opcode subroutines we do not want to do this. 2195 */ 2196 END_OF_INSTR(); 2197} 2198 2199/**************************************************************************** 2200REMARKS: 2201Handles opcode 0x27 2202****************************************************************************/ 2203static void x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 2204{ 2205 START_OF_INSTR(); 2206 DECODE_PRINTF("DAA\n"); 2207 TRACE_AND_STEP(); 2208 M.x86.R_AL = daa_byte(M.x86.R_AL); 2209 DECODE_CLEAR_SEGOVR(); 2210 END_OF_INSTR(); 2211} 2212 2213/**************************************************************************** 2214REMARKS: 2215Handles opcode 0x28 2216****************************************************************************/ 2217static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2218{ 2219 int mod, rl, rh; 2220 u8 *destreg, *srcreg; 2221 uint destoffset; 2222 u8 destval; 2223 2224 START_OF_INSTR(); 2225 DECODE_PRINTF("SUB\t"); 2226 FETCH_DECODE_MODRM(mod, rh, rl); 2227 switch (mod) { 2228 case 0: 2229 destoffset = decode_rm00_address(rl); 2230 DECODE_PRINTF(","); 2231 destval = fetch_data_byte(destoffset); 2232 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2233 DECODE_PRINTF("\n"); 2234 TRACE_AND_STEP(); 2235 destval = sub_byte(destval, *srcreg); 2236 store_data_byte(destoffset, destval); 2237 break; 2238 case 1: 2239 destoffset = decode_rm01_address(rl); 2240 DECODE_PRINTF(","); 2241 destval = fetch_data_byte(destoffset); 2242 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2243 DECODE_PRINTF("\n"); 2244 TRACE_AND_STEP(); 2245 destval = sub_byte(destval, *srcreg); 2246 store_data_byte(destoffset, destval); 2247 break; 2248 case 2: 2249 destoffset = decode_rm10_address(rl); 2250 DECODE_PRINTF(","); 2251 destval = fetch_data_byte(destoffset); 2252 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2253 DECODE_PRINTF("\n"); 2254 TRACE_AND_STEP(); 2255 destval = sub_byte(destval, *srcreg); 2256 store_data_byte(destoffset, destval); 2257 break; 2258 case 3: /* register to register */ 2259 destreg = DECODE_RM_BYTE_REGISTER(rl); 2260 DECODE_PRINTF(","); 2261 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2262 DECODE_PRINTF("\n"); 2263 TRACE_AND_STEP(); 2264 *destreg = sub_byte(*destreg, *srcreg); 2265 break; 2266 } 2267 DECODE_CLEAR_SEGOVR(); 2268 END_OF_INSTR(); 2269} 2270 2271/**************************************************************************** 2272REMARKS: 2273Handles opcode 0x29 2274****************************************************************************/ 2275static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1)) 2276{ 2277 int mod, rl, rh; 2278 uint destoffset; 2279 2280 START_OF_INSTR(); 2281 DECODE_PRINTF("SUB\t"); 2282 FETCH_DECODE_MODRM(mod, rh, rl); 2283 switch (mod) { 2284 case 0: 2285 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2286 u32 destval; 2287 u32 *srcreg; 2288 2289 destoffset = decode_rm00_address(rl); 2290 DECODE_PRINTF(","); 2291 destval = fetch_data_long(destoffset); 2292 srcreg = DECODE_RM_LONG_REGISTER(rh); 2293 DECODE_PRINTF("\n"); 2294 TRACE_AND_STEP(); 2295 destval = sub_long(destval, *srcreg); 2296 store_data_long(destoffset, destval); 2297 } else { 2298 u16 destval; 2299 u16 *srcreg; 2300 2301 destoffset = decode_rm00_address(rl); 2302 DECODE_PRINTF(","); 2303 destval = fetch_data_word(destoffset); 2304 srcreg = DECODE_RM_WORD_REGISTER(rh); 2305 DECODE_PRINTF("\n"); 2306 TRACE_AND_STEP(); 2307 destval = sub_word(destval, *srcreg); 2308 store_data_word(destoffset, destval); 2309 } 2310 break; 2311 case 1: 2312 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2313 u32 destval; 2314 u32 *srcreg; 2315 2316 destoffset = decode_rm01_address(rl); 2317 DECODE_PRINTF(","); 2318 destval = fetch_data_long(destoffset); 2319 srcreg = DECODE_RM_LONG_REGISTER(rh); 2320 DECODE_PRINTF("\n"); 2321 TRACE_AND_STEP(); 2322 destval = sub_long(destval, *srcreg); 2323 store_data_long(destoffset, destval); 2324 } else { 2325 u16 destval; 2326 u16 *srcreg; 2327 2328 destoffset = decode_rm01_address(rl); 2329 DECODE_PRINTF(","); 2330 destval = fetch_data_word(destoffset); 2331 srcreg = DECODE_RM_WORD_REGISTER(rh); 2332 DECODE_PRINTF("\n"); 2333 TRACE_AND_STEP(); 2334 destval = sub_word(destval, *srcreg); 2335 store_data_word(destoffset, destval); 2336 } 2337 break; 2338 case 2: 2339 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2340 u32 destval; 2341 u32 *srcreg; 2342 2343 destoffset = decode_rm10_address(rl); 2344 DECODE_PRINTF(","); 2345 destval = fetch_data_long(destoffset); 2346 srcreg = DECODE_RM_LONG_REGISTER(rh); 2347 DECODE_PRINTF("\n"); 2348 TRACE_AND_STEP(); 2349 destval = sub_long(destval, *srcreg); 2350 store_data_long(destoffset, destval); 2351 } else { 2352 u16 destval; 2353 u16 *srcreg; 2354 2355 destoffset = decode_rm10_address(rl); 2356 DECODE_PRINTF(","); 2357 destval = fetch_data_word(destoffset); 2358 srcreg = DECODE_RM_WORD_REGISTER(rh); 2359 DECODE_PRINTF("\n"); 2360 TRACE_AND_STEP(); 2361 destval = sub_word(destval, *srcreg); 2362 store_data_word(destoffset, destval); 2363 } 2364 break; 2365 case 3: /* register to register */ 2366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2367 u32 *destreg,*srcreg; 2368 2369 destreg = DECODE_RM_LONG_REGISTER(rl); 2370 DECODE_PRINTF(","); 2371 srcreg = DECODE_RM_LONG_REGISTER(rh); 2372 DECODE_PRINTF("\n"); 2373 TRACE_AND_STEP(); 2374 *destreg = sub_long(*destreg, *srcreg); 2375 } else { 2376 u16 *destreg,*srcreg; 2377 2378 destreg = DECODE_RM_WORD_REGISTER(rl); 2379 DECODE_PRINTF(","); 2380 srcreg = DECODE_RM_WORD_REGISTER(rh); 2381 DECODE_PRINTF("\n"); 2382 TRACE_AND_STEP(); 2383 *destreg = sub_word(*destreg, *srcreg); 2384 } 2385 break; 2386 } 2387 DECODE_CLEAR_SEGOVR(); 2388 END_OF_INSTR(); 2389} 2390 2391/**************************************************************************** 2392REMARKS: 2393Handles opcode 0x2a 2394****************************************************************************/ 2395static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2396{ 2397 int mod, rl, rh; 2398 u8 *destreg, *srcreg; 2399 uint srcoffset; 2400 u8 srcval; 2401 2402 START_OF_INSTR(); 2403 DECODE_PRINTF("SUB\t"); 2404 FETCH_DECODE_MODRM(mod, rh, rl); 2405 switch (mod) { 2406 case 0: 2407 destreg = DECODE_RM_BYTE_REGISTER(rh); 2408 DECODE_PRINTF(","); 2409 srcoffset = decode_rm00_address(rl); 2410 srcval = fetch_data_byte(srcoffset); 2411 DECODE_PRINTF("\n"); 2412 TRACE_AND_STEP(); 2413 *destreg = sub_byte(*destreg, srcval); 2414 break; 2415 case 1: 2416 destreg = DECODE_RM_BYTE_REGISTER(rh); 2417 DECODE_PRINTF(","); 2418 srcoffset = decode_rm01_address(rl); 2419 srcval = fetch_data_byte(srcoffset); 2420 DECODE_PRINTF("\n"); 2421 TRACE_AND_STEP(); 2422 *destreg = sub_byte(*destreg, srcval); 2423 break; 2424 case 2: 2425 destreg = DECODE_RM_BYTE_REGISTER(rh); 2426 DECODE_PRINTF(","); 2427 srcoffset = decode_rm10_address(rl); 2428 srcval = fetch_data_byte(srcoffset); 2429 DECODE_PRINTF("\n"); 2430 TRACE_AND_STEP(); 2431 *destreg = sub_byte(*destreg, srcval); 2432 break; 2433 case 3: /* register to register */ 2434 destreg = DECODE_RM_BYTE_REGISTER(rh); 2435 DECODE_PRINTF(","); 2436 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2437 DECODE_PRINTF("\n"); 2438 TRACE_AND_STEP(); 2439 *destreg = sub_byte(*destreg, *srcreg); 2440 break; 2441 } 2442 DECODE_CLEAR_SEGOVR(); 2443 END_OF_INSTR(); 2444} 2445 2446/**************************************************************************** 2447REMARKS: 2448Handles opcode 0x2b 2449****************************************************************************/ 2450static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1)) 2451{ 2452 int mod, rl, rh; 2453 uint srcoffset; 2454 2455 START_OF_INSTR(); 2456 DECODE_PRINTF("SUB\t"); 2457 FETCH_DECODE_MODRM(mod, rh, rl); 2458 switch (mod) { 2459 case 0: 2460 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2461 u32 *destreg; 2462 u32 srcval; 2463 2464 destreg = DECODE_RM_LONG_REGISTER(rh); 2465 DECODE_PRINTF(","); 2466 srcoffset = decode_rm00_address(rl); 2467 srcval = fetch_data_long(srcoffset); 2468 DECODE_PRINTF("\n"); 2469 TRACE_AND_STEP(); 2470 *destreg = sub_long(*destreg, srcval); 2471 } else { 2472 u16 *destreg; 2473 u16 srcval; 2474 2475 destreg = DECODE_RM_WORD_REGISTER(rh); 2476 DECODE_PRINTF(","); 2477 srcoffset = decode_rm00_address(rl); 2478 srcval = fetch_data_word(srcoffset); 2479 DECODE_PRINTF("\n"); 2480 TRACE_AND_STEP(); 2481 *destreg = sub_word(*destreg, srcval); 2482 } 2483 break; 2484 case 1: 2485 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2486 u32 *destreg; 2487 u32 srcval; 2488 2489 destreg = DECODE_RM_LONG_REGISTER(rh); 2490 DECODE_PRINTF(","); 2491 srcoffset = decode_rm01_address(rl); 2492 srcval = fetch_data_long(srcoffset); 2493 DECODE_PRINTF("\n"); 2494 TRACE_AND_STEP(); 2495 *destreg = sub_long(*destreg, srcval); 2496 } else { 2497 u16 *destreg; 2498 u16 srcval; 2499 2500 destreg = DECODE_RM_WORD_REGISTER(rh); 2501 DECODE_PRINTF(","); 2502 srcoffset = decode_rm01_address(rl); 2503 srcval = fetch_data_word(srcoffset); 2504 DECODE_PRINTF("\n"); 2505 TRACE_AND_STEP(); 2506 *destreg = sub_word(*destreg, srcval); 2507 } 2508 break; 2509 case 2: 2510 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2511 u32 *destreg; 2512 u32 srcval; 2513 2514 destreg = DECODE_RM_LONG_REGISTER(rh); 2515 DECODE_PRINTF(","); 2516 srcoffset = decode_rm10_address(rl); 2517 srcval = fetch_data_long(srcoffset); 2518 DECODE_PRINTF("\n"); 2519 TRACE_AND_STEP(); 2520 *destreg = sub_long(*destreg, srcval); 2521 } else { 2522 u16 *destreg; 2523 u16 srcval; 2524 2525 destreg = DECODE_RM_WORD_REGISTER(rh); 2526 DECODE_PRINTF(","); 2527 srcoffset = decode_rm10_address(rl); 2528 srcval = fetch_data_word(srcoffset); 2529 DECODE_PRINTF("\n"); 2530 TRACE_AND_STEP(); 2531 *destreg = sub_word(*destreg, srcval); 2532 } 2533 break; 2534 case 3: /* register to register */ 2535 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2536 u32 *destreg,*srcreg; 2537 2538 destreg = DECODE_RM_LONG_REGISTER(rh); 2539 DECODE_PRINTF(","); 2540 srcreg = DECODE_RM_LONG_REGISTER(rl); 2541 DECODE_PRINTF("\n"); 2542 TRACE_AND_STEP(); 2543 *destreg = sub_long(*destreg, *srcreg); 2544 } else { 2545 u16 *destreg,*srcreg; 2546 2547 destreg = DECODE_RM_WORD_REGISTER(rh); 2548 DECODE_PRINTF(","); 2549 srcreg = DECODE_RM_WORD_REGISTER(rl); 2550 DECODE_PRINTF("\n"); 2551 TRACE_AND_STEP(); 2552 *destreg = sub_word(*destreg, *srcreg); 2553 } 2554 break; 2555 } 2556 DECODE_CLEAR_SEGOVR(); 2557 END_OF_INSTR(); 2558} 2559 2560/**************************************************************************** 2561REMARKS: 2562Handles opcode 0x2c 2563****************************************************************************/ 2564static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2565{ 2566 u8 srcval; 2567 2568 START_OF_INSTR(); 2569 DECODE_PRINTF("SUB\tAL,"); 2570 srcval = fetch_byte_imm(); 2571 DECODE_PRINTF2("%x\n", srcval); 2572 TRACE_AND_STEP(); 2573 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval); 2574 DECODE_CLEAR_SEGOVR(); 2575 END_OF_INSTR(); 2576} 2577 2578/**************************************************************************** 2579REMARKS: 2580Handles opcode 0x2d 2581****************************************************************************/ 2582static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2583{ 2584 u32 srcval; 2585 2586 START_OF_INSTR(); 2587 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2588 DECODE_PRINTF("SUB\tEAX,"); 2589 srcval = fetch_long_imm(); 2590 } else { 2591 DECODE_PRINTF("SUB\tAX,"); 2592 srcval = fetch_word_imm(); 2593 } 2594 DECODE_PRINTF2("%x\n", srcval); 2595 TRACE_AND_STEP(); 2596 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2597 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval); 2598 } else { 2599 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval); 2600 } 2601 DECODE_CLEAR_SEGOVR(); 2602 END_OF_INSTR(); 2603} 2604 2605/**************************************************************************** 2606REMARKS: 2607Handles opcode 0x2e 2608****************************************************************************/ 2609static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 2610{ 2611 START_OF_INSTR(); 2612 DECODE_PRINTF("CS:\n"); 2613 TRACE_AND_STEP(); 2614 M.x86.mode |= SYSMODE_SEGOVR_CS; 2615 /* note no DECODE_CLEAR_SEGOVR here. */ 2616 END_OF_INSTR(); 2617} 2618 2619/**************************************************************************** 2620REMARKS: 2621Handles opcode 0x2f 2622****************************************************************************/ 2623static void x86emuOp_das(u8 X86EMU_UNUSED(op1)) 2624{ 2625 START_OF_INSTR(); 2626 DECODE_PRINTF("DAS\n"); 2627 TRACE_AND_STEP(); 2628 M.x86.R_AL = das_byte(M.x86.R_AL); 2629 DECODE_CLEAR_SEGOVR(); 2630 END_OF_INSTR(); 2631} 2632 2633/**************************************************************************** 2634REMARKS: 2635Handles opcode 0x30 2636****************************************************************************/ 2637static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2638{ 2639 int mod, rl, rh; 2640 u8 *destreg, *srcreg; 2641 uint destoffset; 2642 u8 destval; 2643 2644 START_OF_INSTR(); 2645 DECODE_PRINTF("XOR\t"); 2646 FETCH_DECODE_MODRM(mod, rh, rl); 2647 switch (mod) { 2648 case 0: 2649 destoffset = decode_rm00_address(rl); 2650 DECODE_PRINTF(","); 2651 destval = fetch_data_byte(destoffset); 2652 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2653 DECODE_PRINTF("\n"); 2654 TRACE_AND_STEP(); 2655 destval = xor_byte(destval, *srcreg); 2656 store_data_byte(destoffset, destval); 2657 break; 2658 case 1: 2659 destoffset = decode_rm01_address(rl); 2660 DECODE_PRINTF(","); 2661 destval = fetch_data_byte(destoffset); 2662 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2663 DECODE_PRINTF("\n"); 2664 TRACE_AND_STEP(); 2665 destval = xor_byte(destval, *srcreg); 2666 store_data_byte(destoffset, destval); 2667 break; 2668 case 2: 2669 destoffset = decode_rm10_address(rl); 2670 DECODE_PRINTF(","); 2671 destval = fetch_data_byte(destoffset); 2672 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2673 DECODE_PRINTF("\n"); 2674 TRACE_AND_STEP(); 2675 destval = xor_byte(destval, *srcreg); 2676 store_data_byte(destoffset, destval); 2677 break; 2678 case 3: /* register to register */ 2679 destreg = DECODE_RM_BYTE_REGISTER(rl); 2680 DECODE_PRINTF(","); 2681 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2682 DECODE_PRINTF("\n"); 2683 TRACE_AND_STEP(); 2684 *destreg = xor_byte(*destreg, *srcreg); 2685 break; 2686 } 2687 DECODE_CLEAR_SEGOVR(); 2688 END_OF_INSTR(); 2689} 2690 2691/**************************************************************************** 2692REMARKS: 2693Handles opcode 0x31 2694****************************************************************************/ 2695static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1)) 2696{ 2697 int mod, rl, rh; 2698 uint destoffset; 2699 2700 START_OF_INSTR(); 2701 DECODE_PRINTF("XOR\t"); 2702 FETCH_DECODE_MODRM(mod, rh, rl); 2703 switch (mod) { 2704 case 0: 2705 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2706 u32 destval; 2707 u32 *srcreg; 2708 2709 destoffset = decode_rm00_address(rl); 2710 DECODE_PRINTF(","); 2711 destval = fetch_data_long(destoffset); 2712 srcreg = DECODE_RM_LONG_REGISTER(rh); 2713 DECODE_PRINTF("\n"); 2714 TRACE_AND_STEP(); 2715 destval = xor_long(destval, *srcreg); 2716 store_data_long(destoffset, destval); 2717 } else { 2718 u16 destval; 2719 u16 *srcreg; 2720 2721 destoffset = decode_rm00_address(rl); 2722 DECODE_PRINTF(","); 2723 destval = fetch_data_word(destoffset); 2724 srcreg = DECODE_RM_WORD_REGISTER(rh); 2725 DECODE_PRINTF("\n"); 2726 TRACE_AND_STEP(); 2727 destval = xor_word(destval, *srcreg); 2728 store_data_word(destoffset, destval); 2729 } 2730 break; 2731 case 1: 2732 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2733 u32 destval; 2734 u32 *srcreg; 2735 2736 destoffset = decode_rm01_address(rl); 2737 DECODE_PRINTF(","); 2738 destval = fetch_data_long(destoffset); 2739 srcreg = DECODE_RM_LONG_REGISTER(rh); 2740 DECODE_PRINTF("\n"); 2741 TRACE_AND_STEP(); 2742 destval = xor_long(destval, *srcreg); 2743 store_data_long(destoffset, destval); 2744 } else { 2745 u16 destval; 2746 u16 *srcreg; 2747 2748 destoffset = decode_rm01_address(rl); 2749 DECODE_PRINTF(","); 2750 destval = fetch_data_word(destoffset); 2751 srcreg = DECODE_RM_WORD_REGISTER(rh); 2752 DECODE_PRINTF("\n"); 2753 TRACE_AND_STEP(); 2754 destval = xor_word(destval, *srcreg); 2755 store_data_word(destoffset, destval); 2756 } 2757 break; 2758 case 2: 2759 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2760 u32 destval; 2761 u32 *srcreg; 2762 2763 destoffset = decode_rm10_address(rl); 2764 DECODE_PRINTF(","); 2765 destval = fetch_data_long(destoffset); 2766 srcreg = DECODE_RM_LONG_REGISTER(rh); 2767 DECODE_PRINTF("\n"); 2768 TRACE_AND_STEP(); 2769 destval = xor_long(destval, *srcreg); 2770 store_data_long(destoffset, destval); 2771 } else { 2772 u16 destval; 2773 u16 *srcreg; 2774 2775 destoffset = decode_rm10_address(rl); 2776 DECODE_PRINTF(","); 2777 destval = fetch_data_word(destoffset); 2778 srcreg = DECODE_RM_WORD_REGISTER(rh); 2779 DECODE_PRINTF("\n"); 2780 TRACE_AND_STEP(); 2781 destval = xor_word(destval, *srcreg); 2782 store_data_word(destoffset, destval); 2783 } 2784 break; 2785 case 3: /* register to register */ 2786 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2787 u32 *destreg,*srcreg; 2788 2789 destreg = DECODE_RM_LONG_REGISTER(rl); 2790 DECODE_PRINTF(","); 2791 srcreg = DECODE_RM_LONG_REGISTER(rh); 2792 DECODE_PRINTF("\n"); 2793 TRACE_AND_STEP(); 2794 *destreg = xor_long(*destreg, *srcreg); 2795 } else { 2796 u16 *destreg,*srcreg; 2797 2798 destreg = DECODE_RM_WORD_REGISTER(rl); 2799 DECODE_PRINTF(","); 2800 srcreg = DECODE_RM_WORD_REGISTER(rh); 2801 DECODE_PRINTF("\n"); 2802 TRACE_AND_STEP(); 2803 *destreg = xor_word(*destreg, *srcreg); 2804 } 2805 break; 2806 } 2807 DECODE_CLEAR_SEGOVR(); 2808 END_OF_INSTR(); 2809} 2810 2811/**************************************************************************** 2812REMARKS: 2813Handles opcode 0x32 2814****************************************************************************/ 2815static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2816{ 2817 int mod, rl, rh; 2818 u8 *destreg, *srcreg; 2819 uint srcoffset; 2820 u8 srcval; 2821 2822 START_OF_INSTR(); 2823 DECODE_PRINTF("XOR\t"); 2824 FETCH_DECODE_MODRM(mod, rh, rl); 2825 switch (mod) { 2826 case 0: 2827 destreg = DECODE_RM_BYTE_REGISTER(rh); 2828 DECODE_PRINTF(","); 2829 srcoffset = decode_rm00_address(rl); 2830 srcval = fetch_data_byte(srcoffset); 2831 DECODE_PRINTF("\n"); 2832 TRACE_AND_STEP(); 2833 *destreg = xor_byte(*destreg, srcval); 2834 break; 2835 case 1: 2836 destreg = DECODE_RM_BYTE_REGISTER(rh); 2837 DECODE_PRINTF(","); 2838 srcoffset = decode_rm01_address(rl); 2839 srcval = fetch_data_byte(srcoffset); 2840 DECODE_PRINTF("\n"); 2841 TRACE_AND_STEP(); 2842 *destreg = xor_byte(*destreg, srcval); 2843 break; 2844 case 2: 2845 destreg = DECODE_RM_BYTE_REGISTER(rh); 2846 DECODE_PRINTF(","); 2847 srcoffset = decode_rm10_address(rl); 2848 srcval = fetch_data_byte(srcoffset); 2849 DECODE_PRINTF("\n"); 2850 TRACE_AND_STEP(); 2851 *destreg = xor_byte(*destreg, srcval); 2852 break; 2853 case 3: /* register to register */ 2854 destreg = DECODE_RM_BYTE_REGISTER(rh); 2855 DECODE_PRINTF(","); 2856 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2857 DECODE_PRINTF("\n"); 2858 TRACE_AND_STEP(); 2859 *destreg = xor_byte(*destreg, *srcreg); 2860 break; 2861 } 2862 DECODE_CLEAR_SEGOVR(); 2863 END_OF_INSTR(); 2864} 2865 2866/**************************************************************************** 2867REMARKS: 2868Handles opcode 0x33 2869****************************************************************************/ 2870static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1)) 2871{ 2872 int mod, rl, rh; 2873 uint srcoffset; 2874 2875 START_OF_INSTR(); 2876 DECODE_PRINTF("XOR\t"); 2877 FETCH_DECODE_MODRM(mod, rh, rl); 2878 switch (mod) { 2879 case 0: 2880 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2881 u32 *destreg; 2882 u32 srcval; 2883 2884 destreg = DECODE_RM_LONG_REGISTER(rh); 2885 DECODE_PRINTF(","); 2886 srcoffset = decode_rm00_address(rl); 2887 srcval = fetch_data_long(srcoffset); 2888 DECODE_PRINTF("\n"); 2889 TRACE_AND_STEP(); 2890 *destreg = xor_long(*destreg, srcval); 2891 } else { 2892 u16 *destreg; 2893 u16 srcval; 2894 2895 destreg = DECODE_RM_WORD_REGISTER(rh); 2896 DECODE_PRINTF(","); 2897 srcoffset = decode_rm00_address(rl); 2898 srcval = fetch_data_word(srcoffset); 2899 DECODE_PRINTF("\n"); 2900 TRACE_AND_STEP(); 2901 *destreg = xor_word(*destreg, srcval); 2902 } 2903 break; 2904 case 1: 2905 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2906 u32 *destreg; 2907 u32 srcval; 2908 2909 destreg = DECODE_RM_LONG_REGISTER(rh); 2910 DECODE_PRINTF(","); 2911 srcoffset = decode_rm01_address(rl); 2912 srcval = fetch_data_long(srcoffset); 2913 DECODE_PRINTF("\n"); 2914 TRACE_AND_STEP(); 2915 *destreg = xor_long(*destreg, srcval); 2916 } else { 2917 u16 *destreg; 2918 u16 srcval; 2919 2920 destreg = DECODE_RM_WORD_REGISTER(rh); 2921 DECODE_PRINTF(","); 2922 srcoffset = decode_rm01_address(rl); 2923 srcval = fetch_data_word(srcoffset); 2924 DECODE_PRINTF("\n"); 2925 TRACE_AND_STEP(); 2926 *destreg = xor_word(*destreg, srcval); 2927 } 2928 break; 2929 case 2: 2930 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2931 u32 *destreg; 2932 u32 srcval; 2933 2934 destreg = DECODE_RM_LONG_REGISTER(rh); 2935 DECODE_PRINTF(","); 2936 srcoffset = decode_rm10_address(rl); 2937 srcval = fetch_data_long(srcoffset); 2938 DECODE_PRINTF("\n"); 2939 TRACE_AND_STEP(); 2940 *destreg = xor_long(*destreg, srcval); 2941 } else { 2942 u16 *destreg; 2943 u16 srcval; 2944 2945 destreg = DECODE_RM_WORD_REGISTER(rh); 2946 DECODE_PRINTF(","); 2947 srcoffset = decode_rm10_address(rl); 2948 srcval = fetch_data_word(srcoffset); 2949 DECODE_PRINTF("\n"); 2950 TRACE_AND_STEP(); 2951 *destreg = xor_word(*destreg, srcval); 2952 } 2953 break; 2954 case 3: /* register to register */ 2955 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2956 u32 *destreg,*srcreg; 2957 2958 destreg = DECODE_RM_LONG_REGISTER(rh); 2959 DECODE_PRINTF(","); 2960 srcreg = DECODE_RM_LONG_REGISTER(rl); 2961 DECODE_PRINTF("\n"); 2962 TRACE_AND_STEP(); 2963 *destreg = xor_long(*destreg, *srcreg); 2964 } else { 2965 u16 *destreg,*srcreg; 2966 2967 destreg = DECODE_RM_WORD_REGISTER(rh); 2968 DECODE_PRINTF(","); 2969 srcreg = DECODE_RM_WORD_REGISTER(rl); 2970 DECODE_PRINTF("\n"); 2971 TRACE_AND_STEP(); 2972 *destreg = xor_word(*destreg, *srcreg); 2973 } 2974 break; 2975 } 2976 DECODE_CLEAR_SEGOVR(); 2977 END_OF_INSTR(); 2978} 2979 2980/**************************************************************************** 2981REMARKS: 2982Handles opcode 0x34 2983****************************************************************************/ 2984static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2985{ 2986 u8 srcval; 2987 2988 START_OF_INSTR(); 2989 DECODE_PRINTF("XOR\tAL,"); 2990 srcval = fetch_byte_imm(); 2991 DECODE_PRINTF2("%x\n", srcval); 2992 TRACE_AND_STEP(); 2993 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval); 2994 DECODE_CLEAR_SEGOVR(); 2995 END_OF_INSTR(); 2996} 2997 2998/**************************************************************************** 2999REMARKS: 3000Handles opcode 0x35 3001****************************************************************************/ 3002static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3003{ 3004 u32 srcval; 3005 3006 START_OF_INSTR(); 3007 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3008 DECODE_PRINTF("XOR\tEAX,"); 3009 srcval = fetch_long_imm(); 3010 } else { 3011 DECODE_PRINTF("XOR\tAX,"); 3012 srcval = fetch_word_imm(); 3013 } 3014 DECODE_PRINTF2("%x\n", srcval); 3015 TRACE_AND_STEP(); 3016 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3017 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval); 3018 } else { 3019 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval); 3020 } 3021 DECODE_CLEAR_SEGOVR(); 3022 END_OF_INSTR(); 3023} 3024 3025/**************************************************************************** 3026REMARKS: 3027Handles opcode 0x36 3028****************************************************************************/ 3029static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 3030{ 3031 START_OF_INSTR(); 3032 DECODE_PRINTF("SS:\n"); 3033 TRACE_AND_STEP(); 3034 M.x86.mode |= SYSMODE_SEGOVR_SS; 3035 /* no DECODE_CLEAR_SEGOVR ! */ 3036 END_OF_INSTR(); 3037} 3038 3039/**************************************************************************** 3040REMARKS: 3041Handles opcode 0x37 3042****************************************************************************/ 3043static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 3044{ 3045 START_OF_INSTR(); 3046 DECODE_PRINTF("AAA\n"); 3047 TRACE_AND_STEP(); 3048 M.x86.R_AX = aaa_word(M.x86.R_AX); 3049 DECODE_CLEAR_SEGOVR(); 3050 END_OF_INSTR(); 3051} 3052 3053/**************************************************************************** 3054REMARKS: 3055Handles opcode 0x38 3056****************************************************************************/ 3057static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1)) 3058{ 3059 int mod, rl, rh; 3060 uint destoffset; 3061 u8 *destreg, *srcreg; 3062 u8 destval; 3063 3064 START_OF_INSTR(); 3065 DECODE_PRINTF("CMP\t"); 3066 FETCH_DECODE_MODRM(mod, rh, rl); 3067 switch (mod) { 3068 case 0: 3069 destoffset = decode_rm00_address(rl); 3070 DECODE_PRINTF(","); 3071 destval = fetch_data_byte(destoffset); 3072 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3073 DECODE_PRINTF("\n"); 3074 TRACE_AND_STEP(); 3075 cmp_byte(destval, *srcreg); 3076 break; 3077 case 1: 3078 destoffset = decode_rm01_address(rl); 3079 DECODE_PRINTF(","); 3080 destval = fetch_data_byte(destoffset); 3081 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3082 DECODE_PRINTF("\n"); 3083 TRACE_AND_STEP(); 3084 cmp_byte(destval, *srcreg); 3085 break; 3086 case 2: 3087 destoffset = decode_rm10_address(rl); 3088 DECODE_PRINTF(","); 3089 destval = fetch_data_byte(destoffset); 3090 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3091 DECODE_PRINTF("\n"); 3092 TRACE_AND_STEP(); 3093 cmp_byte(destval, *srcreg); 3094 break; 3095 case 3: /* register to register */ 3096 destreg = DECODE_RM_BYTE_REGISTER(rl); 3097 DECODE_PRINTF(","); 3098 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3099 DECODE_PRINTF("\n"); 3100 TRACE_AND_STEP(); 3101 cmp_byte(*destreg, *srcreg); 3102 break; 3103 } 3104 DECODE_CLEAR_SEGOVR(); 3105 END_OF_INSTR(); 3106} 3107 3108/**************************************************************************** 3109REMARKS: 3110Handles opcode 0x39 3111****************************************************************************/ 3112static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1)) 3113{ 3114 int mod, rl, rh; 3115 uint destoffset; 3116 3117 START_OF_INSTR(); 3118 DECODE_PRINTF("CMP\t"); 3119 FETCH_DECODE_MODRM(mod, rh, rl); 3120 switch (mod) { 3121 case 0: 3122 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3123 u32 destval; 3124 u32 *srcreg; 3125 3126 destoffset = decode_rm00_address(rl); 3127 DECODE_PRINTF(","); 3128 destval = fetch_data_long(destoffset); 3129 srcreg = DECODE_RM_LONG_REGISTER(rh); 3130 DECODE_PRINTF("\n"); 3131 TRACE_AND_STEP(); 3132 cmp_long(destval, *srcreg); 3133 } else { 3134 u16 destval; 3135 u16 *srcreg; 3136 3137 destoffset = decode_rm00_address(rl); 3138 DECODE_PRINTF(","); 3139 destval = fetch_data_word(destoffset); 3140 srcreg = DECODE_RM_WORD_REGISTER(rh); 3141 DECODE_PRINTF("\n"); 3142 TRACE_AND_STEP(); 3143 cmp_word(destval, *srcreg); 3144 } 3145 break; 3146 case 1: 3147 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3148 u32 destval; 3149 u32 *srcreg; 3150 3151 destoffset = decode_rm01_address(rl); 3152 DECODE_PRINTF(","); 3153 destval = fetch_data_long(destoffset); 3154 srcreg = DECODE_RM_LONG_REGISTER(rh); 3155 DECODE_PRINTF("\n"); 3156 TRACE_AND_STEP(); 3157 cmp_long(destval, *srcreg); 3158 } else { 3159 u16 destval; 3160 u16 *srcreg; 3161 3162 destoffset = decode_rm01_address(rl); 3163 DECODE_PRINTF(","); 3164 destval = fetch_data_word(destoffset); 3165 srcreg = DECODE_RM_WORD_REGISTER(rh); 3166 DECODE_PRINTF("\n"); 3167 TRACE_AND_STEP(); 3168 cmp_word(destval, *srcreg); 3169 } 3170 break; 3171 case 2: 3172 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3173 u32 destval; 3174 u32 *srcreg; 3175 3176 destoffset = decode_rm10_address(rl); 3177 DECODE_PRINTF(","); 3178 destval = fetch_data_long(destoffset); 3179 srcreg = DECODE_RM_LONG_REGISTER(rh); 3180 DECODE_PRINTF("\n"); 3181 TRACE_AND_STEP(); 3182 cmp_long(destval, *srcreg); 3183 } else { 3184 u16 destval; 3185 u16 *srcreg; 3186 3187 destoffset = decode_rm10_address(rl); 3188 DECODE_PRINTF(","); 3189 destval = fetch_data_word(destoffset); 3190 srcreg = DECODE_RM_WORD_REGISTER(rh); 3191 DECODE_PRINTF("\n"); 3192 TRACE_AND_STEP(); 3193 cmp_word(destval, *srcreg); 3194 } 3195 break; 3196 case 3: /* register to register */ 3197 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3198 u32 *destreg,*srcreg; 3199 3200 destreg = DECODE_RM_LONG_REGISTER(rl); 3201 DECODE_PRINTF(","); 3202 srcreg = DECODE_RM_LONG_REGISTER(rh); 3203 DECODE_PRINTF("\n"); 3204 TRACE_AND_STEP(); 3205 cmp_long(*destreg, *srcreg); 3206 } else { 3207 u16 *destreg,*srcreg; 3208 3209 destreg = DECODE_RM_WORD_REGISTER(rl); 3210 DECODE_PRINTF(","); 3211 srcreg = DECODE_RM_WORD_REGISTER(rh); 3212 DECODE_PRINTF("\n"); 3213 TRACE_AND_STEP(); 3214 cmp_word(*destreg, *srcreg); 3215 } 3216 break; 3217 } 3218 DECODE_CLEAR_SEGOVR(); 3219 END_OF_INSTR(); 3220} 3221 3222/**************************************************************************** 3223REMARKS: 3224Handles opcode 0x3a 3225****************************************************************************/ 3226static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1)) 3227{ 3228 int mod, rl, rh; 3229 u8 *destreg, *srcreg; 3230 uint srcoffset; 3231 u8 srcval; 3232 3233 START_OF_INSTR(); 3234 DECODE_PRINTF("CMP\t"); 3235 FETCH_DECODE_MODRM(mod, rh, rl); 3236 switch (mod) { 3237 case 0: 3238 destreg = DECODE_RM_BYTE_REGISTER(rh); 3239 DECODE_PRINTF(","); 3240 srcoffset = decode_rm00_address(rl); 3241 srcval = fetch_data_byte(srcoffset); 3242 DECODE_PRINTF("\n"); 3243 TRACE_AND_STEP(); 3244 cmp_byte(*destreg, srcval); 3245 break; 3246 case 1: 3247 destreg = DECODE_RM_BYTE_REGISTER(rh); 3248 DECODE_PRINTF(","); 3249 srcoffset = decode_rm01_address(rl); 3250 srcval = fetch_data_byte(srcoffset); 3251 DECODE_PRINTF("\n"); 3252 TRACE_AND_STEP(); 3253 cmp_byte(*destreg, srcval); 3254 break; 3255 case 2: 3256 destreg = DECODE_RM_BYTE_REGISTER(rh); 3257 DECODE_PRINTF(","); 3258 srcoffset = decode_rm10_address(rl); 3259 srcval = fetch_data_byte(srcoffset); 3260 DECODE_PRINTF("\n"); 3261 TRACE_AND_STEP(); 3262 cmp_byte(*destreg, srcval); 3263 break; 3264 case 3: /* register to register */ 3265 destreg = DECODE_RM_BYTE_REGISTER(rh); 3266 DECODE_PRINTF(","); 3267 srcreg = DECODE_RM_BYTE_REGISTER(rl); 3268 DECODE_PRINTF("\n"); 3269 TRACE_AND_STEP(); 3270 cmp_byte(*destreg, *srcreg); 3271 break; 3272 } 3273 DECODE_CLEAR_SEGOVR(); 3274 END_OF_INSTR(); 3275} 3276 3277/**************************************************************************** 3278REMARKS: 3279Handles opcode 0x3b 3280****************************************************************************/ 3281static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1)) 3282{ 3283 int mod, rl, rh; 3284 uint srcoffset; 3285 3286 START_OF_INSTR(); 3287 DECODE_PRINTF("CMP\t"); 3288 FETCH_DECODE_MODRM(mod, rh, rl); 3289 switch (mod) { 3290 case 0: 3291 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3292 u32 *destreg; 3293 u32 srcval; 3294 3295 destreg = DECODE_RM_LONG_REGISTER(rh); 3296 DECODE_PRINTF(","); 3297 srcoffset = decode_rm00_address(rl); 3298 srcval = fetch_data_long(srcoffset); 3299 DECODE_PRINTF("\n"); 3300 TRACE_AND_STEP(); 3301 cmp_long(*destreg, srcval); 3302 } else { 3303 u16 *destreg; 3304 u16 srcval; 3305 3306 destreg = DECODE_RM_WORD_REGISTER(rh); 3307 DECODE_PRINTF(","); 3308 srcoffset = decode_rm00_address(rl); 3309 srcval = fetch_data_word(srcoffset); 3310 DECODE_PRINTF("\n"); 3311 TRACE_AND_STEP(); 3312 cmp_word(*destreg, srcval); 3313 } 3314 break; 3315 case 1: 3316 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3317 u32 *destreg; 3318 u32 srcval; 3319 3320 destreg = DECODE_RM_LONG_REGISTER(rh); 3321 DECODE_PRINTF(","); 3322 srcoffset = decode_rm01_address(rl); 3323 srcval = fetch_data_long(srcoffset); 3324 DECODE_PRINTF("\n"); 3325 TRACE_AND_STEP(); 3326 cmp_long(*destreg, srcval); 3327 } else { 3328 u16 *destreg; 3329 u16 srcval; 3330 3331 destreg = DECODE_RM_WORD_REGISTER(rh); 3332 DECODE_PRINTF(","); 3333 srcoffset = decode_rm01_address(rl); 3334 srcval = fetch_data_word(srcoffset); 3335 DECODE_PRINTF("\n"); 3336 TRACE_AND_STEP(); 3337 cmp_word(*destreg, srcval); 3338 } 3339 break; 3340 case 2: 3341 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3342 u32 *destreg; 3343 u32 srcval; 3344 3345 destreg = DECODE_RM_LONG_REGISTER(rh); 3346 DECODE_PRINTF(","); 3347 srcoffset = decode_rm10_address(rl); 3348 srcval = fetch_data_long(srcoffset); 3349 DECODE_PRINTF("\n"); 3350 TRACE_AND_STEP(); 3351 cmp_long(*destreg, srcval); 3352 } else { 3353 u16 *destreg; 3354 u16 srcval; 3355 3356 destreg = DECODE_RM_WORD_REGISTER(rh); 3357 DECODE_PRINTF(","); 3358 srcoffset = decode_rm10_address(rl); 3359 srcval = fetch_data_word(srcoffset); 3360 DECODE_PRINTF("\n"); 3361 TRACE_AND_STEP(); 3362 cmp_word(*destreg, srcval); 3363 } 3364 break; 3365 case 3: /* register to register */ 3366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3367 u32 *destreg,*srcreg; 3368 3369 destreg = DECODE_RM_LONG_REGISTER(rh); 3370 DECODE_PRINTF(","); 3371 srcreg = DECODE_RM_LONG_REGISTER(rl); 3372 DECODE_PRINTF("\n"); 3373 TRACE_AND_STEP(); 3374 cmp_long(*destreg, *srcreg); 3375 } else { 3376 u16 *destreg,*srcreg; 3377 3378 destreg = DECODE_RM_WORD_REGISTER(rh); 3379 DECODE_PRINTF(","); 3380 srcreg = DECODE_RM_WORD_REGISTER(rl); 3381 DECODE_PRINTF("\n"); 3382 TRACE_AND_STEP(); 3383 cmp_word(*destreg, *srcreg); 3384 } 3385 break; 3386 } 3387 DECODE_CLEAR_SEGOVR(); 3388 END_OF_INSTR(); 3389} 3390 3391/**************************************************************************** 3392REMARKS: 3393Handles opcode 0x3c 3394****************************************************************************/ 3395static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 3396{ 3397 u8 srcval; 3398 3399 START_OF_INSTR(); 3400 DECODE_PRINTF("CMP\tAL,"); 3401 srcval = fetch_byte_imm(); 3402 DECODE_PRINTF2("%x\n", srcval); 3403 TRACE_AND_STEP(); 3404 cmp_byte(M.x86.R_AL, srcval); 3405 DECODE_CLEAR_SEGOVR(); 3406 END_OF_INSTR(); 3407} 3408 3409/**************************************************************************** 3410REMARKS: 3411Handles opcode 0x3d 3412****************************************************************************/ 3413static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3414{ 3415 u32 srcval; 3416 3417 START_OF_INSTR(); 3418 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3419 DECODE_PRINTF("CMP\tEAX,"); 3420 srcval = fetch_long_imm(); 3421 } else { 3422 DECODE_PRINTF("CMP\tAX,"); 3423 srcval = fetch_word_imm(); 3424 } 3425 DECODE_PRINTF2("%x\n", srcval); 3426 TRACE_AND_STEP(); 3427 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3428 cmp_long(M.x86.R_EAX, srcval); 3429 } else { 3430 cmp_word(M.x86.R_AX, (u16)srcval); 3431 } 3432 DECODE_CLEAR_SEGOVR(); 3433 END_OF_INSTR(); 3434} 3435 3436/**************************************************************************** 3437REMARKS: 3438Handles opcode 0x3e 3439****************************************************************************/ 3440static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 3441{ 3442 START_OF_INSTR(); 3443 DECODE_PRINTF("DS:\n"); 3444 TRACE_AND_STEP(); 3445 M.x86.mode |= SYSMODE_SEGOVR_DS; 3446 /* NO DECODE_CLEAR_SEGOVR! */ 3447 END_OF_INSTR(); 3448} 3449 3450/**************************************************************************** 3451REMARKS: 3452Handles opcode 0x3f 3453****************************************************************************/ 3454static void x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 3455{ 3456 START_OF_INSTR(); 3457 DECODE_PRINTF("AAS\n"); 3458 TRACE_AND_STEP(); 3459 M.x86.R_AX = aas_word(M.x86.R_AX); 3460 DECODE_CLEAR_SEGOVR(); 3461 END_OF_INSTR(); 3462} 3463 3464/**************************************************************************** 3465REMARKS: 3466Handles opcode 0x40 3467****************************************************************************/ 3468static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1)) 3469{ 3470 START_OF_INSTR(); 3471 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3472 DECODE_PRINTF("INC\tEAX\n"); 3473 } else { 3474 DECODE_PRINTF("INC\tAX\n"); 3475 } 3476 TRACE_AND_STEP(); 3477 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3478 M.x86.R_EAX = inc_long(M.x86.R_EAX); 3479 } else { 3480 M.x86.R_AX = inc_word(M.x86.R_AX); 3481 } 3482 DECODE_CLEAR_SEGOVR(); 3483 END_OF_INSTR(); 3484} 3485 3486/**************************************************************************** 3487REMARKS: 3488Handles opcode 0x41 3489****************************************************************************/ 3490static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1)) 3491{ 3492 START_OF_INSTR(); 3493 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3494 DECODE_PRINTF("INC\tECX\n"); 3495 } else { 3496 DECODE_PRINTF("INC\tCX\n"); 3497 } 3498 TRACE_AND_STEP(); 3499 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3500 M.x86.R_ECX = inc_long(M.x86.R_ECX); 3501 } else { 3502 M.x86.R_CX = inc_word(M.x86.R_CX); 3503 } 3504 DECODE_CLEAR_SEGOVR(); 3505 END_OF_INSTR(); 3506} 3507 3508/**************************************************************************** 3509REMARKS: 3510Handles opcode 0x42 3511****************************************************************************/ 3512static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1)) 3513{ 3514 START_OF_INSTR(); 3515 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3516 DECODE_PRINTF("INC\tEDX\n"); 3517 } else { 3518 DECODE_PRINTF("INC\tDX\n"); 3519 } 3520 TRACE_AND_STEP(); 3521 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3522 M.x86.R_EDX = inc_long(M.x86.R_EDX); 3523 } else { 3524 M.x86.R_DX = inc_word(M.x86.R_DX); 3525 } 3526 DECODE_CLEAR_SEGOVR(); 3527 END_OF_INSTR(); 3528} 3529 3530/**************************************************************************** 3531REMARKS: 3532Handles opcode 0x43 3533****************************************************************************/ 3534static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1)) 3535{ 3536 START_OF_INSTR(); 3537 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3538 DECODE_PRINTF("INC\tEBX\n"); 3539 } else { 3540 DECODE_PRINTF("INC\tBX\n"); 3541 } 3542 TRACE_AND_STEP(); 3543 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3544 M.x86.R_EBX = inc_long(M.x86.R_EBX); 3545 } else { 3546 M.x86.R_BX = inc_word(M.x86.R_BX); 3547 } 3548 DECODE_CLEAR_SEGOVR(); 3549 END_OF_INSTR(); 3550} 3551 3552/**************************************************************************** 3553REMARKS: 3554Handles opcode 0x44 3555****************************************************************************/ 3556static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1)) 3557{ 3558 START_OF_INSTR(); 3559 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3560 DECODE_PRINTF("INC\tESP\n"); 3561 } else { 3562 DECODE_PRINTF("INC\tSP\n"); 3563 } 3564 TRACE_AND_STEP(); 3565 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3566 M.x86.R_ESP = inc_long(M.x86.R_ESP); 3567 } else { 3568 M.x86.R_SP = inc_word(M.x86.R_SP); 3569 } 3570 DECODE_CLEAR_SEGOVR(); 3571 END_OF_INSTR(); 3572} 3573 3574/**************************************************************************** 3575REMARKS: 3576Handles opcode 0x45 3577****************************************************************************/ 3578static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1)) 3579{ 3580 START_OF_INSTR(); 3581 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3582 DECODE_PRINTF("INC\tEBP\n"); 3583 } else { 3584 DECODE_PRINTF("INC\tBP\n"); 3585 } 3586 TRACE_AND_STEP(); 3587 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3588 M.x86.R_EBP = inc_long(M.x86.R_EBP); 3589 } else { 3590 M.x86.R_BP = inc_word(M.x86.R_BP); 3591 } 3592 DECODE_CLEAR_SEGOVR(); 3593 END_OF_INSTR(); 3594} 3595 3596/**************************************************************************** 3597REMARKS: 3598Handles opcode 0x46 3599****************************************************************************/ 3600static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1)) 3601{ 3602 START_OF_INSTR(); 3603 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3604 DECODE_PRINTF("INC\tESI\n"); 3605 } else { 3606 DECODE_PRINTF("INC\tSI\n"); 3607 } 3608 TRACE_AND_STEP(); 3609 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3610 M.x86.R_ESI = inc_long(M.x86.R_ESI); 3611 } else { 3612 M.x86.R_SI = inc_word(M.x86.R_SI); 3613 } 3614 DECODE_CLEAR_SEGOVR(); 3615 END_OF_INSTR(); 3616} 3617 3618/**************************************************************************** 3619REMARKS: 3620Handles opcode 0x47 3621****************************************************************************/ 3622static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1)) 3623{ 3624 START_OF_INSTR(); 3625 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3626 DECODE_PRINTF("INC\tEDI\n"); 3627 } else { 3628 DECODE_PRINTF("INC\tDI\n"); 3629 } 3630 TRACE_AND_STEP(); 3631 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3632 M.x86.R_EDI = inc_long(M.x86.R_EDI); 3633 } else { 3634 M.x86.R_DI = inc_word(M.x86.R_DI); 3635 } 3636 DECODE_CLEAR_SEGOVR(); 3637 END_OF_INSTR(); 3638} 3639 3640/**************************************************************************** 3641REMARKS: 3642Handles opcode 0x48 3643****************************************************************************/ 3644static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1)) 3645{ 3646 START_OF_INSTR(); 3647 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3648 DECODE_PRINTF("DEC\tEAX\n"); 3649 } else { 3650 DECODE_PRINTF("DEC\tAX\n"); 3651 } 3652 TRACE_AND_STEP(); 3653 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3654 M.x86.R_EAX = dec_long(M.x86.R_EAX); 3655 } else { 3656 M.x86.R_AX = dec_word(M.x86.R_AX); 3657 } 3658 DECODE_CLEAR_SEGOVR(); 3659 END_OF_INSTR(); 3660} 3661 3662/**************************************************************************** 3663REMARKS: 3664Handles opcode 0x49 3665****************************************************************************/ 3666static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1)) 3667{ 3668 START_OF_INSTR(); 3669 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3670 DECODE_PRINTF("DEC\tECX\n"); 3671 } else { 3672 DECODE_PRINTF("DEC\tCX\n"); 3673 } 3674 TRACE_AND_STEP(); 3675 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3676 M.x86.R_ECX = dec_long(M.x86.R_ECX); 3677 } else { 3678 M.x86.R_CX = dec_word(M.x86.R_CX); 3679 } 3680 DECODE_CLEAR_SEGOVR(); 3681 END_OF_INSTR(); 3682} 3683 3684/**************************************************************************** 3685REMARKS: 3686Handles opcode 0x4a 3687****************************************************************************/ 3688static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1)) 3689{ 3690 START_OF_INSTR(); 3691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3692 DECODE_PRINTF("DEC\tEDX\n"); 3693 } else { 3694 DECODE_PRINTF("DEC\tDX\n"); 3695 } 3696 TRACE_AND_STEP(); 3697 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3698 M.x86.R_EDX = dec_long(M.x86.R_EDX); 3699 } else { 3700 M.x86.R_DX = dec_word(M.x86.R_DX); 3701 } 3702 DECODE_CLEAR_SEGOVR(); 3703 END_OF_INSTR(); 3704} 3705 3706/**************************************************************************** 3707REMARKS: 3708Handles opcode 0x4b 3709****************************************************************************/ 3710static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1)) 3711{ 3712 START_OF_INSTR(); 3713 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3714 DECODE_PRINTF("DEC\tEBX\n"); 3715 } else { 3716 DECODE_PRINTF("DEC\tBX\n"); 3717 } 3718 TRACE_AND_STEP(); 3719 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3720 M.x86.R_EBX = dec_long(M.x86.R_EBX); 3721 } else { 3722 M.x86.R_BX = dec_word(M.x86.R_BX); 3723 } 3724 DECODE_CLEAR_SEGOVR(); 3725 END_OF_INSTR(); 3726} 3727 3728/**************************************************************************** 3729REMARKS: 3730Handles opcode 0x4c 3731****************************************************************************/ 3732static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1)) 3733{ 3734 START_OF_INSTR(); 3735 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3736 DECODE_PRINTF("DEC\tESP\n"); 3737 } else { 3738 DECODE_PRINTF("DEC\tSP\n"); 3739 } 3740 TRACE_AND_STEP(); 3741 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3742 M.x86.R_ESP = dec_long(M.x86.R_ESP); 3743 } else { 3744 M.x86.R_SP = dec_word(M.x86.R_SP); 3745 } 3746 DECODE_CLEAR_SEGOVR(); 3747 END_OF_INSTR(); 3748} 3749 3750/**************************************************************************** 3751REMARKS: 3752Handles opcode 0x4d 3753****************************************************************************/ 3754static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1)) 3755{ 3756 START_OF_INSTR(); 3757 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3758 DECODE_PRINTF("DEC\tEBP\n"); 3759 } else { 3760 DECODE_PRINTF("DEC\tBP\n"); 3761 } 3762 TRACE_AND_STEP(); 3763 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3764 M.x86.R_EBP = dec_long(M.x86.R_EBP); 3765 } else { 3766 M.x86.R_BP = dec_word(M.x86.R_BP); 3767 } 3768 DECODE_CLEAR_SEGOVR(); 3769 END_OF_INSTR(); 3770} 3771 3772/**************************************************************************** 3773REMARKS: 3774Handles opcode 0x4e 3775****************************************************************************/ 3776static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1)) 3777{ 3778 START_OF_INSTR(); 3779 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3780 DECODE_PRINTF("DEC\tESI\n"); 3781 } else { 3782 DECODE_PRINTF("DEC\tSI\n"); 3783 } 3784 TRACE_AND_STEP(); 3785 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3786 M.x86.R_ESI = dec_long(M.x86.R_ESI); 3787 } else { 3788 M.x86.R_SI = dec_word(M.x86.R_SI); 3789 } 3790 DECODE_CLEAR_SEGOVR(); 3791 END_OF_INSTR(); 3792} 3793 3794/**************************************************************************** 3795REMARKS: 3796Handles opcode 0x4f 3797****************************************************************************/ 3798static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1)) 3799{ 3800 START_OF_INSTR(); 3801 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3802 DECODE_PRINTF("DEC\tEDI\n"); 3803 } else { 3804 DECODE_PRINTF("DEC\tDI\n"); 3805 } 3806 TRACE_AND_STEP(); 3807 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3808 M.x86.R_EDI = dec_long(M.x86.R_EDI); 3809 } else { 3810 M.x86.R_DI = dec_word(M.x86.R_DI); 3811 } 3812 DECODE_CLEAR_SEGOVR(); 3813 END_OF_INSTR(); 3814} 3815 3816/**************************************************************************** 3817REMARKS: 3818Handles opcode 0x50 3819****************************************************************************/ 3820static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1)) 3821{ 3822 START_OF_INSTR(); 3823 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3824 DECODE_PRINTF("PUSH\tEAX\n"); 3825 } else { 3826 DECODE_PRINTF("PUSH\tAX\n"); 3827 } 3828 TRACE_AND_STEP(); 3829 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3830 push_long(M.x86.R_EAX); 3831 } else { 3832 push_word(M.x86.R_AX); 3833 } 3834 DECODE_CLEAR_SEGOVR(); 3835 END_OF_INSTR(); 3836} 3837 3838/**************************************************************************** 3839REMARKS: 3840Handles opcode 0x51 3841****************************************************************************/ 3842static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1)) 3843{ 3844 START_OF_INSTR(); 3845 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3846 DECODE_PRINTF("PUSH\tECX\n"); 3847 } else { 3848 DECODE_PRINTF("PUSH\tCX\n"); 3849 } 3850 TRACE_AND_STEP(); 3851 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3852 push_long(M.x86.R_ECX); 3853 } else { 3854 push_word(M.x86.R_CX); 3855 } 3856 DECODE_CLEAR_SEGOVR(); 3857 END_OF_INSTR(); 3858} 3859 3860/**************************************************************************** 3861REMARKS: 3862Handles opcode 0x52 3863****************************************************************************/ 3864static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1)) 3865{ 3866 START_OF_INSTR(); 3867 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3868 DECODE_PRINTF("PUSH\tEDX\n"); 3869 } else { 3870 DECODE_PRINTF("PUSH\tDX\n"); 3871 } 3872 TRACE_AND_STEP(); 3873 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3874 push_long(M.x86.R_EDX); 3875 } else { 3876 push_word(M.x86.R_DX); 3877 } 3878 DECODE_CLEAR_SEGOVR(); 3879 END_OF_INSTR(); 3880} 3881 3882/**************************************************************************** 3883REMARKS: 3884Handles opcode 0x53 3885****************************************************************************/ 3886static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1)) 3887{ 3888 START_OF_INSTR(); 3889 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3890 DECODE_PRINTF("PUSH\tEBX\n"); 3891 } else { 3892 DECODE_PRINTF("PUSH\tBX\n"); 3893 } 3894 TRACE_AND_STEP(); 3895 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3896 push_long(M.x86.R_EBX); 3897 } else { 3898 push_word(M.x86.R_BX); 3899 } 3900 DECODE_CLEAR_SEGOVR(); 3901 END_OF_INSTR(); 3902} 3903 3904/**************************************************************************** 3905REMARKS: 3906Handles opcode 0x54 3907****************************************************************************/ 3908static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1)) 3909{ 3910 START_OF_INSTR(); 3911 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3912 DECODE_PRINTF("PUSH\tESP\n"); 3913 } else { 3914 DECODE_PRINTF("PUSH\tSP\n"); 3915 } 3916 TRACE_AND_STEP(); 3917 /* Always push (E)SP, since we are emulating an i386 and above 3918 * processor. This is necessary as some BIOS'es use this to check 3919 * what type of processor is in the system. 3920 */ 3921 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3922 push_long(M.x86.R_ESP); 3923 } else { 3924 push_word((u16)(M.x86.R_SP)); 3925 } 3926 DECODE_CLEAR_SEGOVR(); 3927 END_OF_INSTR(); 3928} 3929 3930/**************************************************************************** 3931REMARKS: 3932Handles opcode 0x55 3933****************************************************************************/ 3934static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1)) 3935{ 3936 START_OF_INSTR(); 3937 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3938 DECODE_PRINTF("PUSH\tEBP\n"); 3939 } else { 3940 DECODE_PRINTF("PUSH\tBP\n"); 3941 } 3942 TRACE_AND_STEP(); 3943 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3944 push_long(M.x86.R_EBP); 3945 } else { 3946 push_word(M.x86.R_BP); 3947 } 3948 DECODE_CLEAR_SEGOVR(); 3949 END_OF_INSTR(); 3950} 3951 3952/**************************************************************************** 3953REMARKS: 3954Handles opcode 0x56 3955****************************************************************************/ 3956static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1)) 3957{ 3958 START_OF_INSTR(); 3959 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3960 DECODE_PRINTF("PUSH\tESI\n"); 3961 } else { 3962 DECODE_PRINTF("PUSH\tSI\n"); 3963 } 3964 TRACE_AND_STEP(); 3965 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3966 push_long(M.x86.R_ESI); 3967 } else { 3968 push_word(M.x86.R_SI); 3969 } 3970 DECODE_CLEAR_SEGOVR(); 3971 END_OF_INSTR(); 3972} 3973 3974/**************************************************************************** 3975REMARKS: 3976Handles opcode 0x57 3977****************************************************************************/ 3978static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1)) 3979{ 3980 START_OF_INSTR(); 3981 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3982 DECODE_PRINTF("PUSH\tEDI\n"); 3983 } else { 3984 DECODE_PRINTF("PUSH\tDI\n"); 3985 } 3986 TRACE_AND_STEP(); 3987 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3988 push_long(M.x86.R_EDI); 3989 } else { 3990 push_word(M.x86.R_DI); 3991 } 3992 DECODE_CLEAR_SEGOVR(); 3993 END_OF_INSTR(); 3994} 3995 3996/**************************************************************************** 3997REMARKS: 3998Handles opcode 0x58 3999****************************************************************************/ 4000static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1)) 4001{ 4002 START_OF_INSTR(); 4003 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4004 DECODE_PRINTF("POP\tEAX\n"); 4005 } else { 4006 DECODE_PRINTF("POP\tAX\n"); 4007 } 4008 TRACE_AND_STEP(); 4009 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4010 M.x86.R_EAX = pop_long(); 4011 } else { 4012 M.x86.R_AX = pop_word(); 4013 } 4014 DECODE_CLEAR_SEGOVR(); 4015 END_OF_INSTR(); 4016} 4017 4018/**************************************************************************** 4019REMARKS: 4020Handles opcode 0x59 4021****************************************************************************/ 4022static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1)) 4023{ 4024 START_OF_INSTR(); 4025 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4026 DECODE_PRINTF("POP\tECX\n"); 4027 } else { 4028 DECODE_PRINTF("POP\tCX\n"); 4029 } 4030 TRACE_AND_STEP(); 4031 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4032 M.x86.R_ECX = pop_long(); 4033 } else { 4034 M.x86.R_CX = pop_word(); 4035 } 4036 DECODE_CLEAR_SEGOVR(); 4037 END_OF_INSTR(); 4038} 4039 4040/**************************************************************************** 4041REMARKS: 4042Handles opcode 0x5a 4043****************************************************************************/ 4044static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1)) 4045{ 4046 START_OF_INSTR(); 4047 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4048 DECODE_PRINTF("POP\tEDX\n"); 4049 } else { 4050 DECODE_PRINTF("POP\tDX\n"); 4051 } 4052 TRACE_AND_STEP(); 4053 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4054 M.x86.R_EDX = pop_long(); 4055 } else { 4056 M.x86.R_DX = pop_word(); 4057 } 4058 DECODE_CLEAR_SEGOVR(); 4059 END_OF_INSTR(); 4060} 4061 4062/**************************************************************************** 4063REMARKS: 4064Handles opcode 0x5b 4065****************************************************************************/ 4066static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1)) 4067{ 4068 START_OF_INSTR(); 4069 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4070 DECODE_PRINTF("POP\tEBX\n"); 4071 } else { 4072 DECODE_PRINTF("POP\tBX\n"); 4073 } 4074 TRACE_AND_STEP(); 4075 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4076 M.x86.R_EBX = pop_long(); 4077 } else { 4078 M.x86.R_BX = pop_word(); 4079 } 4080 DECODE_CLEAR_SEGOVR(); 4081 END_OF_INSTR(); 4082} 4083 4084/**************************************************************************** 4085REMARKS: 4086Handles opcode 0x5c 4087****************************************************************************/ 4088static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1)) 4089{ 4090 START_OF_INSTR(); 4091 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4092 DECODE_PRINTF("POP\tESP\n"); 4093 } else { 4094 DECODE_PRINTF("POP\tSP\n"); 4095 } 4096 TRACE_AND_STEP(); 4097 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4098 M.x86.R_ESP = pop_long(); 4099 } else { 4100 M.x86.R_SP = pop_word(); 4101 } 4102 DECODE_CLEAR_SEGOVR(); 4103 END_OF_INSTR(); 4104} 4105 4106/**************************************************************************** 4107REMARKS: 4108Handles opcode 0x5d 4109****************************************************************************/ 4110static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1)) 4111{ 4112 START_OF_INSTR(); 4113 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4114 DECODE_PRINTF("POP\tEBP\n"); 4115 } else { 4116 DECODE_PRINTF("POP\tBP\n"); 4117 } 4118 TRACE_AND_STEP(); 4119 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4120 M.x86.R_EBP = pop_long(); 4121 } else { 4122 M.x86.R_BP = pop_word(); 4123 } 4124 DECODE_CLEAR_SEGOVR(); 4125 END_OF_INSTR(); 4126} 4127 4128/**************************************************************************** 4129REMARKS: 4130Handles opcode 0x5e 4131****************************************************************************/ 4132static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1)) 4133{ 4134 START_OF_INSTR(); 4135 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4136 DECODE_PRINTF("POP\tESI\n"); 4137 } else { 4138 DECODE_PRINTF("POP\tSI\n"); 4139 } 4140 TRACE_AND_STEP(); 4141 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4142 M.x86.R_ESI = pop_long(); 4143 } else { 4144 M.x86.R_SI = pop_word(); 4145 } 4146 DECODE_CLEAR_SEGOVR(); 4147 END_OF_INSTR(); 4148} 4149 4150/**************************************************************************** 4151REMARKS: 4152Handles opcode 0x5f 4153****************************************************************************/ 4154static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1)) 4155{ 4156 START_OF_INSTR(); 4157 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4158 DECODE_PRINTF("POP\tEDI\n"); 4159 } else { 4160 DECODE_PRINTF("POP\tDI\n"); 4161 } 4162 TRACE_AND_STEP(); 4163 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4164 M.x86.R_EDI = pop_long(); 4165 } else { 4166 M.x86.R_DI = pop_word(); 4167 } 4168 DECODE_CLEAR_SEGOVR(); 4169 END_OF_INSTR(); 4170} 4171 4172/**************************************************************************** 4173REMARKS: 4174Handles opcode 0x60 4175****************************************************************************/ 4176static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 4177{ 4178 START_OF_INSTR(); 4179 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4180 DECODE_PRINTF("PUSHAD\n"); 4181 } else { 4182 DECODE_PRINTF("PUSHA\n"); 4183 } 4184 TRACE_AND_STEP(); 4185 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4186 u32 old_sp = M.x86.R_ESP; 4187 4188 push_long(M.x86.R_EAX); 4189 push_long(M.x86.R_ECX); 4190 push_long(M.x86.R_EDX); 4191 push_long(M.x86.R_EBX); 4192 push_long(old_sp); 4193 push_long(M.x86.R_EBP); 4194 push_long(M.x86.R_ESI); 4195 push_long(M.x86.R_EDI); 4196 } else { 4197 u16 old_sp = M.x86.R_SP; 4198 4199 push_word(M.x86.R_AX); 4200 push_word(M.x86.R_CX); 4201 push_word(M.x86.R_DX); 4202 push_word(M.x86.R_BX); 4203 push_word(old_sp); 4204 push_word(M.x86.R_BP); 4205 push_word(M.x86.R_SI); 4206 push_word(M.x86.R_DI); 4207 } 4208 DECODE_CLEAR_SEGOVR(); 4209 END_OF_INSTR(); 4210} 4211 4212/**************************************************************************** 4213REMARKS: 4214Handles opcode 0x61 4215****************************************************************************/ 4216static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 4217{ 4218 START_OF_INSTR(); 4219 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4220 DECODE_PRINTF("POPAD\n"); 4221 } else { 4222 DECODE_PRINTF("POPA\n"); 4223 } 4224 TRACE_AND_STEP(); 4225 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4226 M.x86.R_EDI = pop_long(); 4227 M.x86.R_ESI = pop_long(); 4228 M.x86.R_EBP = pop_long(); 4229 M.x86.R_ESP += 4; /* skip ESP */ 4230 M.x86.R_EBX = pop_long(); 4231 M.x86.R_EDX = pop_long(); 4232 M.x86.R_ECX = pop_long(); 4233 M.x86.R_EAX = pop_long(); 4234 } else { 4235 M.x86.R_DI = pop_word(); 4236 M.x86.R_SI = pop_word(); 4237 M.x86.R_BP = pop_word(); 4238 M.x86.R_SP += 2; /* skip SP */ 4239 M.x86.R_BX = pop_word(); 4240 M.x86.R_DX = pop_word(); 4241 M.x86.R_CX = pop_word(); 4242 M.x86.R_AX = pop_word(); 4243 } 4244 DECODE_CLEAR_SEGOVR(); 4245 END_OF_INSTR(); 4246} 4247 4248/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4249/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4250 4251/**************************************************************************** 4252REMARKS: 4253Handles opcode 0x64 4254****************************************************************************/ 4255static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 4256{ 4257 START_OF_INSTR(); 4258 DECODE_PRINTF("FS:\n"); 4259 TRACE_AND_STEP(); 4260 M.x86.mode |= SYSMODE_SEGOVR_FS; 4261 /* 4262 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4263 * opcode subroutines we do not want to do this. 4264 */ 4265 END_OF_INSTR(); 4266} 4267 4268/**************************************************************************** 4269REMARKS: 4270Handles opcode 0x65 4271****************************************************************************/ 4272static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 4273{ 4274 START_OF_INSTR(); 4275 DECODE_PRINTF("GS:\n"); 4276 TRACE_AND_STEP(); 4277 M.x86.mode |= SYSMODE_SEGOVR_GS; 4278 /* 4279 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4280 * opcode subroutines we do not want to do this. 4281 */ 4282 END_OF_INSTR(); 4283} 4284 4285/**************************************************************************** 4286REMARKS: 4287Handles opcode 0x66 - prefix for 32-bit register 4288****************************************************************************/ 4289static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 4290{ 4291 START_OF_INSTR(); 4292 DECODE_PRINTF("DATA:\n"); 4293 TRACE_AND_STEP(); 4294 M.x86.mode |= SYSMODE_PREFIX_DATA; 4295 /* note no DECODE_CLEAR_SEGOVR here. */ 4296 END_OF_INSTR(); 4297} 4298 4299/**************************************************************************** 4300REMARKS: 4301Handles opcode 0x67 - prefix for 32-bit address 4302****************************************************************************/ 4303static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 4304{ 4305 START_OF_INSTR(); 4306 DECODE_PRINTF("ADDR:\n"); 4307 TRACE_AND_STEP(); 4308 M.x86.mode |= SYSMODE_PREFIX_ADDR; 4309 /* note no DECODE_CLEAR_SEGOVR here. */ 4310 END_OF_INSTR(); 4311} 4312 4313/**************************************************************************** 4314REMARKS: 4315Handles opcode 0x68 4316****************************************************************************/ 4317static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 4318{ 4319 u32 imm; 4320 4321 START_OF_INSTR(); 4322 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4323 imm = fetch_long_imm(); 4324 } else { 4325 imm = fetch_word_imm(); 4326 } 4327 DECODE_PRINTF2("PUSH\t%x\n", imm); 4328 TRACE_AND_STEP(); 4329 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4330 push_long(imm); 4331 } else { 4332 push_word((u16)imm); 4333 } 4334 DECODE_CLEAR_SEGOVR(); 4335 END_OF_INSTR(); 4336} 4337 4338/**************************************************************************** 4339REMARKS: 4340Handles opcode 0x69 4341****************************************************************************/ 4342static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 4343{ 4344 int mod, rl, rh; 4345 uint srcoffset; 4346 4347 START_OF_INSTR(); 4348 DECODE_PRINTF("IMUL\t"); 4349 FETCH_DECODE_MODRM(mod, rh, rl); 4350 switch (mod) { 4351 case 0: 4352 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4353 u32 *destreg; 4354 u32 srcval; 4355 u32 res_lo,res_hi; 4356 s32 imm; 4357 4358 destreg = DECODE_RM_LONG_REGISTER(rh); 4359 DECODE_PRINTF(","); 4360 srcoffset = decode_rm00_address(rl); 4361 srcval = fetch_data_long(srcoffset); 4362 imm = fetch_long_imm(); 4363 DECODE_PRINTF2(",%d\n", (s32)imm); 4364 TRACE_AND_STEP(); 4365 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4366 if (res_hi != 0) { 4367 SET_FLAG(F_CF); 4368 SET_FLAG(F_OF); 4369 } else { 4370 CLEAR_FLAG(F_CF); 4371 CLEAR_FLAG(F_OF); 4372 } 4373 *destreg = (u32)res_lo; 4374 } else { 4375 u16 *destreg; 4376 u16 srcval; 4377 u32 res; 4378 s16 imm; 4379 4380 destreg = DECODE_RM_WORD_REGISTER(rh); 4381 DECODE_PRINTF(","); 4382 srcoffset = decode_rm00_address(rl); 4383 srcval = fetch_data_word(srcoffset); 4384 imm = fetch_word_imm(); 4385 DECODE_PRINTF2(",%d\n", (s32)imm); 4386 TRACE_AND_STEP(); 4387 res = (s16)srcval * (s16)imm; 4388 if (res > 0xFFFF) { 4389 SET_FLAG(F_CF); 4390 SET_FLAG(F_OF); 4391 } else { 4392 CLEAR_FLAG(F_CF); 4393 CLEAR_FLAG(F_OF); 4394 } 4395 *destreg = (u16)res; 4396 } 4397 break; 4398 case 1: 4399 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4400 u32 *destreg; 4401 u32 srcval; 4402 u32 res_lo,res_hi; 4403 s32 imm; 4404 4405 destreg = DECODE_RM_LONG_REGISTER(rh); 4406 DECODE_PRINTF(","); 4407 srcoffset = decode_rm01_address(rl); 4408 srcval = fetch_data_long(srcoffset); 4409 imm = fetch_long_imm(); 4410 DECODE_PRINTF2(",%d\n", (s32)imm); 4411 TRACE_AND_STEP(); 4412 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4413 if (res_hi != 0) { 4414 SET_FLAG(F_CF); 4415 SET_FLAG(F_OF); 4416 } else { 4417 CLEAR_FLAG(F_CF); 4418 CLEAR_FLAG(F_OF); 4419 } 4420 *destreg = (u32)res_lo; 4421 } else { 4422 u16 *destreg; 4423 u16 srcval; 4424 u32 res; 4425 s16 imm; 4426 4427 destreg = DECODE_RM_WORD_REGISTER(rh); 4428 DECODE_PRINTF(","); 4429 srcoffset = decode_rm01_address(rl); 4430 srcval = fetch_data_word(srcoffset); 4431 imm = fetch_word_imm(); 4432 DECODE_PRINTF2(",%d\n", (s32)imm); 4433 TRACE_AND_STEP(); 4434 res = (s16)srcval * (s16)imm; 4435 if (res > 0xFFFF) { 4436 SET_FLAG(F_CF); 4437 SET_FLAG(F_OF); 4438 } else { 4439 CLEAR_FLAG(F_CF); 4440 CLEAR_FLAG(F_OF); 4441 } 4442 *destreg = (u16)res; 4443 } 4444 break; 4445 case 2: 4446 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4447 u32 *destreg; 4448 u32 srcval; 4449 u32 res_lo,res_hi; 4450 s32 imm; 4451 4452 destreg = DECODE_RM_LONG_REGISTER(rh); 4453 DECODE_PRINTF(","); 4454 srcoffset = decode_rm10_address(rl); 4455 srcval = fetch_data_long(srcoffset); 4456 imm = fetch_long_imm(); 4457 DECODE_PRINTF2(",%d\n", (s32)imm); 4458 TRACE_AND_STEP(); 4459 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4460 if (res_hi != 0) { 4461 SET_FLAG(F_CF); 4462 SET_FLAG(F_OF); 4463 } else { 4464 CLEAR_FLAG(F_CF); 4465 CLEAR_FLAG(F_OF); 4466 } 4467 *destreg = (u32)res_lo; 4468 } else { 4469 u16 *destreg; 4470 u16 srcval; 4471 u32 res; 4472 s16 imm; 4473 4474 destreg = DECODE_RM_WORD_REGISTER(rh); 4475 DECODE_PRINTF(","); 4476 srcoffset = decode_rm10_address(rl); 4477 srcval = fetch_data_word(srcoffset); 4478 imm = fetch_word_imm(); 4479 DECODE_PRINTF2(",%d\n", (s32)imm); 4480 TRACE_AND_STEP(); 4481 res = (s16)srcval * (s16)imm; 4482 if (res > 0xFFFF) { 4483 SET_FLAG(F_CF); 4484 SET_FLAG(F_OF); 4485 } else { 4486 CLEAR_FLAG(F_CF); 4487 CLEAR_FLAG(F_OF); 4488 } 4489 *destreg = (u16)res; 4490 } 4491 break; 4492 case 3: /* register to register */ 4493 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4494 u32 *destreg,*srcreg; 4495 u32 res_lo,res_hi; 4496 s32 imm; 4497 4498 destreg = DECODE_RM_LONG_REGISTER(rh); 4499 DECODE_PRINTF(","); 4500 srcreg = DECODE_RM_LONG_REGISTER(rl); 4501 imm = fetch_long_imm(); 4502 DECODE_PRINTF2(",%d\n", (s32)imm); 4503 TRACE_AND_STEP(); 4504 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4505 if (res_hi != 0) { 4506 SET_FLAG(F_CF); 4507 SET_FLAG(F_OF); 4508 } else { 4509 CLEAR_FLAG(F_CF); 4510 CLEAR_FLAG(F_OF); 4511 } 4512 *destreg = (u32)res_lo; 4513 } else { 4514 u16 *destreg,*srcreg; 4515 u32 res; 4516 s16 imm; 4517 4518 destreg = DECODE_RM_WORD_REGISTER(rh); 4519 DECODE_PRINTF(","); 4520 srcreg = DECODE_RM_WORD_REGISTER(rl); 4521 imm = fetch_word_imm(); 4522 DECODE_PRINTF2(",%d\n", (s32)imm); 4523 res = (s16)*srcreg * (s16)imm; 4524 if (res > 0xFFFF) { 4525 SET_FLAG(F_CF); 4526 SET_FLAG(F_OF); 4527 } else { 4528 CLEAR_FLAG(F_CF); 4529 CLEAR_FLAG(F_OF); 4530 } 4531 *destreg = (u16)res; 4532 } 4533 break; 4534 } 4535 DECODE_CLEAR_SEGOVR(); 4536 END_OF_INSTR(); 4537} 4538 4539/**************************************************************************** 4540REMARKS: 4541Handles opcode 0x6a 4542****************************************************************************/ 4543static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 4544{ 4545 s16 imm; 4546 4547 START_OF_INSTR(); 4548 imm = (s8)fetch_byte_imm(); 4549 DECODE_PRINTF2("PUSH\t%d\n", imm); 4550 TRACE_AND_STEP(); 4551 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4552 push_long((s32)imm); 4553 } else { 4554 push_word(imm); 4555 } 4556 DECODE_CLEAR_SEGOVR(); 4557 END_OF_INSTR(); 4558} 4559 4560/**************************************************************************** 4561REMARKS: 4562Handles opcode 0x6b 4563****************************************************************************/ 4564static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 4565{ 4566 int mod, rl, rh; 4567 uint srcoffset; 4568 s8 imm; 4569 4570 START_OF_INSTR(); 4571 DECODE_PRINTF("IMUL\t"); 4572 FETCH_DECODE_MODRM(mod, rh, rl); 4573 switch (mod) { 4574 case 0: 4575 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4576 u32 *destreg; 4577 u32 srcval; 4578 u32 res_lo,res_hi; 4579 4580 destreg = DECODE_RM_LONG_REGISTER(rh); 4581 DECODE_PRINTF(","); 4582 srcoffset = decode_rm00_address(rl); 4583 srcval = fetch_data_long(srcoffset); 4584 imm = fetch_byte_imm(); 4585 DECODE_PRINTF2(",%d\n", (s32)imm); 4586 TRACE_AND_STEP(); 4587 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4588 if (res_hi != 0) { 4589 SET_FLAG(F_CF); 4590 SET_FLAG(F_OF); 4591 } else { 4592 CLEAR_FLAG(F_CF); 4593 CLEAR_FLAG(F_OF); 4594 } 4595 *destreg = (u32)res_lo; 4596 } else { 4597 u16 *destreg; 4598 u16 srcval; 4599 u32 res; 4600 4601 destreg = DECODE_RM_WORD_REGISTER(rh); 4602 DECODE_PRINTF(","); 4603 srcoffset = decode_rm00_address(rl); 4604 srcval = fetch_data_word(srcoffset); 4605 imm = fetch_byte_imm(); 4606 DECODE_PRINTF2(",%d\n", (s32)imm); 4607 TRACE_AND_STEP(); 4608 res = (s16)srcval * (s16)imm; 4609 if (res > 0xFFFF) { 4610 SET_FLAG(F_CF); 4611 SET_FLAG(F_OF); 4612 } else { 4613 CLEAR_FLAG(F_CF); 4614 CLEAR_FLAG(F_OF); 4615 } 4616 *destreg = (u16)res; 4617 } 4618 break; 4619 case 1: 4620 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4621 u32 *destreg; 4622 u32 srcval; 4623 u32 res_lo,res_hi; 4624 4625 destreg = DECODE_RM_LONG_REGISTER(rh); 4626 DECODE_PRINTF(","); 4627 srcoffset = decode_rm01_address(rl); 4628 srcval = fetch_data_long(srcoffset); 4629 imm = fetch_byte_imm(); 4630 DECODE_PRINTF2(",%d\n", (s32)imm); 4631 TRACE_AND_STEP(); 4632 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4633 if (res_hi != 0) { 4634 SET_FLAG(F_CF); 4635 SET_FLAG(F_OF); 4636 } else { 4637 CLEAR_FLAG(F_CF); 4638 CLEAR_FLAG(F_OF); 4639 } 4640 *destreg = (u32)res_lo; 4641 } else { 4642 u16 *destreg; 4643 u16 srcval; 4644 u32 res; 4645 4646 destreg = DECODE_RM_WORD_REGISTER(rh); 4647 DECODE_PRINTF(","); 4648 srcoffset = decode_rm01_address(rl); 4649 srcval = fetch_data_word(srcoffset); 4650 imm = fetch_byte_imm(); 4651 DECODE_PRINTF2(",%d\n", (s32)imm); 4652 TRACE_AND_STEP(); 4653 res = (s16)srcval * (s16)imm; 4654 if (res > 0xFFFF) { 4655 SET_FLAG(F_CF); 4656 SET_FLAG(F_OF); 4657 } else { 4658 CLEAR_FLAG(F_CF); 4659 CLEAR_FLAG(F_OF); 4660 } 4661 *destreg = (u16)res; 4662 } 4663 break; 4664 case 2: 4665 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4666 u32 *destreg; 4667 u32 srcval; 4668 u32 res_lo,res_hi; 4669 4670 destreg = DECODE_RM_LONG_REGISTER(rh); 4671 DECODE_PRINTF(","); 4672 srcoffset = decode_rm10_address(rl); 4673 srcval = fetch_data_long(srcoffset); 4674 imm = fetch_byte_imm(); 4675 DECODE_PRINTF2(",%d\n", (s32)imm); 4676 TRACE_AND_STEP(); 4677 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4678 if (res_hi != 0) { 4679 SET_FLAG(F_CF); 4680 SET_FLAG(F_OF); 4681 } else { 4682 CLEAR_FLAG(F_CF); 4683 CLEAR_FLAG(F_OF); 4684 } 4685 *destreg = (u32)res_lo; 4686 } else { 4687 u16 *destreg; 4688 u16 srcval; 4689 u32 res; 4690 4691 destreg = DECODE_RM_WORD_REGISTER(rh); 4692 DECODE_PRINTF(","); 4693 srcoffset = decode_rm10_address(rl); 4694 srcval = fetch_data_word(srcoffset); 4695 imm = fetch_byte_imm(); 4696 DECODE_PRINTF2(",%d\n", (s32)imm); 4697 TRACE_AND_STEP(); 4698 res = (s16)srcval * (s16)imm; 4699 if (res > 0xFFFF) { 4700 SET_FLAG(F_CF); 4701 SET_FLAG(F_OF); 4702 } else { 4703 CLEAR_FLAG(F_CF); 4704 CLEAR_FLAG(F_OF); 4705 } 4706 *destreg = (u16)res; 4707 } 4708 break; 4709 case 3: /* register to register */ 4710 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4711 u32 *destreg,*srcreg; 4712 u32 res_lo,res_hi; 4713 4714 destreg = DECODE_RM_LONG_REGISTER(rh); 4715 DECODE_PRINTF(","); 4716 srcreg = DECODE_RM_LONG_REGISTER(rl); 4717 imm = fetch_byte_imm(); 4718 DECODE_PRINTF2(",%d\n", (s32)imm); 4719 TRACE_AND_STEP(); 4720 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4721 if (res_hi != 0) { 4722 SET_FLAG(F_CF); 4723 SET_FLAG(F_OF); 4724 } else { 4725 CLEAR_FLAG(F_CF); 4726 CLEAR_FLAG(F_OF); 4727 } 4728 *destreg = (u32)res_lo; 4729 } else { 4730 u16 *destreg,*srcreg; 4731 u32 res; 4732 4733 destreg = DECODE_RM_WORD_REGISTER(rh); 4734 DECODE_PRINTF(","); 4735 srcreg = DECODE_RM_WORD_REGISTER(rl); 4736 imm = fetch_byte_imm(); 4737 DECODE_PRINTF2(",%d\n", (s32)imm); 4738 res = (s16)*srcreg * (s16)imm; 4739 if (res > 0xFFFF) { 4740 SET_FLAG(F_CF); 4741 SET_FLAG(F_OF); 4742 } else { 4743 CLEAR_FLAG(F_CF); 4744 CLEAR_FLAG(F_OF); 4745 } 4746 *destreg = (u16)res; 4747 } 4748 break; 4749 } 4750 DECODE_CLEAR_SEGOVR(); 4751 END_OF_INSTR(); 4752} 4753 4754/**************************************************************************** 4755REMARKS: 4756Handles opcode 0x6c 4757****************************************************************************/ 4758static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 4759{ 4760 START_OF_INSTR(); 4761 DECODE_PRINTF("INSB\n"); 4762 ins(1); 4763 TRACE_AND_STEP(); 4764 DECODE_CLEAR_SEGOVR(); 4765 END_OF_INSTR(); 4766} 4767 4768/**************************************************************************** 4769REMARKS: 4770Handles opcode 0x6d 4771****************************************************************************/ 4772static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 4773{ 4774 START_OF_INSTR(); 4775 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4776 DECODE_PRINTF("INSD\n"); 4777 ins(4); 4778 } else { 4779 DECODE_PRINTF("INSW\n"); 4780 ins(2); 4781 } 4782 TRACE_AND_STEP(); 4783 DECODE_CLEAR_SEGOVR(); 4784 END_OF_INSTR(); 4785} 4786 4787/**************************************************************************** 4788REMARKS: 4789Handles opcode 0x6e 4790****************************************************************************/ 4791static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 4792{ 4793 START_OF_INSTR(); 4794 DECODE_PRINTF("OUTSB\n"); 4795 outs(1); 4796 TRACE_AND_STEP(); 4797 DECODE_CLEAR_SEGOVR(); 4798 END_OF_INSTR(); 4799} 4800 4801/**************************************************************************** 4802REMARKS: 4803Handles opcode 0x6f 4804****************************************************************************/ 4805static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 4806{ 4807 START_OF_INSTR(); 4808 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4809 DECODE_PRINTF("OUTSD\n"); 4810 outs(4); 4811 } else { 4812 DECODE_PRINTF("OUTSW\n"); 4813 outs(2); 4814 } 4815 TRACE_AND_STEP(); 4816 DECODE_CLEAR_SEGOVR(); 4817 END_OF_INSTR(); 4818} 4819 4820/**************************************************************************** 4821REMARKS: 4822Handles opcode 0x70 4823****************************************************************************/ 4824static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1)) 4825{ 4826 s8 offset; 4827 u16 target; 4828 4829 /* jump to byte offset if overflow flag is set */ 4830 START_OF_INSTR(); 4831 DECODE_PRINTF("JO\t"); 4832 offset = (s8)fetch_byte_imm(); 4833 target = (u16)(M.x86.R_IP + (s16)offset); 4834 DECODE_PRINTF2("%x\n", target); 4835 TRACE_AND_STEP(); 4836 if (ACCESS_FLAG(F_OF)) 4837 M.x86.R_IP = target; 4838 DECODE_CLEAR_SEGOVR(); 4839 END_OF_INSTR(); 4840} 4841 4842/**************************************************************************** 4843REMARKS: 4844Handles opcode 0x71 4845****************************************************************************/ 4846static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1)) 4847{ 4848 s8 offset; 4849 u16 target; 4850 4851 /* jump to byte offset if overflow is not set */ 4852 START_OF_INSTR(); 4853 DECODE_PRINTF("JNO\t"); 4854 offset = (s8)fetch_byte_imm(); 4855 target = (u16)(M.x86.R_IP + (s16)offset); 4856 DECODE_PRINTF2("%x\n", target); 4857 TRACE_AND_STEP(); 4858 if (!ACCESS_FLAG(F_OF)) 4859 M.x86.R_IP = target; 4860 DECODE_CLEAR_SEGOVR(); 4861 END_OF_INSTR(); 4862} 4863 4864/**************************************************************************** 4865REMARKS: 4866Handles opcode 0x72 4867****************************************************************************/ 4868static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1)) 4869{ 4870 s8 offset; 4871 u16 target; 4872 4873 /* jump to byte offset if carry flag is set. */ 4874 START_OF_INSTR(); 4875 DECODE_PRINTF("JB\t"); 4876 offset = (s8)fetch_byte_imm(); 4877 target = (u16)(M.x86.R_IP + (s16)offset); 4878 DECODE_PRINTF2("%x\n", target); 4879 TRACE_AND_STEP(); 4880 if (ACCESS_FLAG(F_CF)) 4881 M.x86.R_IP = target; 4882 DECODE_CLEAR_SEGOVR(); 4883 END_OF_INSTR(); 4884} 4885 4886/**************************************************************************** 4887REMARKS: 4888Handles opcode 0x73 4889****************************************************************************/ 4890static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1)) 4891{ 4892 s8 offset; 4893 u16 target; 4894 4895 /* jump to byte offset if carry flag is clear. */ 4896 START_OF_INSTR(); 4897 DECODE_PRINTF("JNB\t"); 4898 offset = (s8)fetch_byte_imm(); 4899 target = (u16)(M.x86.R_IP + (s16)offset); 4900 DECODE_PRINTF2("%x\n", target); 4901 TRACE_AND_STEP(); 4902 if (!ACCESS_FLAG(F_CF)) 4903 M.x86.R_IP = target; 4904 DECODE_CLEAR_SEGOVR(); 4905 END_OF_INSTR(); 4906} 4907 4908/**************************************************************************** 4909REMARKS: 4910Handles opcode 0x74 4911****************************************************************************/ 4912static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1)) 4913{ 4914 s8 offset; 4915 u16 target; 4916 4917 /* jump to byte offset if zero flag is set. */ 4918 START_OF_INSTR(); 4919 DECODE_PRINTF("JZ\t"); 4920 offset = (s8)fetch_byte_imm(); 4921 target = (u16)(M.x86.R_IP + (s16)offset); 4922 DECODE_PRINTF2("%x\n", target); 4923 TRACE_AND_STEP(); 4924 if (ACCESS_FLAG(F_ZF)) 4925 M.x86.R_IP = target; 4926 DECODE_CLEAR_SEGOVR(); 4927 END_OF_INSTR(); 4928} 4929 4930/**************************************************************************** 4931REMARKS: 4932Handles opcode 0x75 4933****************************************************************************/ 4934static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1)) 4935{ 4936 s8 offset; 4937 u16 target; 4938 4939 /* jump to byte offset if zero flag is clear. */ 4940 START_OF_INSTR(); 4941 DECODE_PRINTF("JNZ\t"); 4942 offset = (s8)fetch_byte_imm(); 4943 target = (u16)(M.x86.R_IP + (s16)offset); 4944 DECODE_PRINTF2("%x\n", target); 4945 TRACE_AND_STEP(); 4946 if (!ACCESS_FLAG(F_ZF)) 4947 M.x86.R_IP = target; 4948 DECODE_CLEAR_SEGOVR(); 4949 END_OF_INSTR(); 4950} 4951 4952/**************************************************************************** 4953REMARKS: 4954Handles opcode 0x76 4955****************************************************************************/ 4956static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1)) 4957{ 4958 s8 offset; 4959 u16 target; 4960 4961 /* jump to byte offset if carry flag is set or if the zero 4962 flag is set. */ 4963 START_OF_INSTR(); 4964 DECODE_PRINTF("JBE\t"); 4965 offset = (s8)fetch_byte_imm(); 4966 target = (u16)(M.x86.R_IP + (s16)offset); 4967 DECODE_PRINTF2("%x\n", target); 4968 TRACE_AND_STEP(); 4969 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) 4970 M.x86.R_IP = target; 4971 DECODE_CLEAR_SEGOVR(); 4972 END_OF_INSTR(); 4973} 4974 4975/**************************************************************************** 4976REMARKS: 4977Handles opcode 0x77 4978****************************************************************************/ 4979static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1)) 4980{ 4981 s8 offset; 4982 u16 target; 4983 4984 /* jump to byte offset if carry flag is clear and if the zero 4985 flag is clear */ 4986 START_OF_INSTR(); 4987 DECODE_PRINTF("JNBE\t"); 4988 offset = (s8)fetch_byte_imm(); 4989 target = (u16)(M.x86.R_IP + (s16)offset); 4990 DECODE_PRINTF2("%x\n", target); 4991 TRACE_AND_STEP(); 4992 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))) 4993 M.x86.R_IP = target; 4994 DECODE_CLEAR_SEGOVR(); 4995 END_OF_INSTR(); 4996} 4997 4998/**************************************************************************** 4999REMARKS: 5000Handles opcode 0x78 5001****************************************************************************/ 5002static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1)) 5003{ 5004 s8 offset; 5005 u16 target; 5006 5007 /* jump to byte offset if sign flag is set */ 5008 START_OF_INSTR(); 5009 DECODE_PRINTF("JS\t"); 5010 offset = (s8)fetch_byte_imm(); 5011 target = (u16)(M.x86.R_IP + (s16)offset); 5012 DECODE_PRINTF2("%x\n", target); 5013 TRACE_AND_STEP(); 5014 if (ACCESS_FLAG(F_SF)) 5015 M.x86.R_IP = target; 5016 DECODE_CLEAR_SEGOVR(); 5017 END_OF_INSTR(); 5018} 5019 5020/**************************************************************************** 5021REMARKS: 5022Handles opcode 0x79 5023****************************************************************************/ 5024static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1)) 5025{ 5026 s8 offset; 5027 u16 target; 5028 5029 /* jump to byte offset if sign flag is clear */ 5030 START_OF_INSTR(); 5031 DECODE_PRINTF("JNS\t"); 5032 offset = (s8)fetch_byte_imm(); 5033 target = (u16)(M.x86.R_IP + (s16)offset); 5034 DECODE_PRINTF2("%x\n", target); 5035 TRACE_AND_STEP(); 5036 if (!ACCESS_FLAG(F_SF)) 5037 M.x86.R_IP = target; 5038 DECODE_CLEAR_SEGOVR(); 5039 END_OF_INSTR(); 5040} 5041 5042/**************************************************************************** 5043REMARKS: 5044Handles opcode 0x7a 5045****************************************************************************/ 5046static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1)) 5047{ 5048 s8 offset; 5049 u16 target; 5050 5051 /* jump to byte offset if parity flag is set (even parity) */ 5052 START_OF_INSTR(); 5053 DECODE_PRINTF("JP\t"); 5054 offset = (s8)fetch_byte_imm(); 5055 target = (u16)(M.x86.R_IP + (s16)offset); 5056 DECODE_PRINTF2("%x\n", target); 5057 TRACE_AND_STEP(); 5058 if (ACCESS_FLAG(F_PF)) 5059 M.x86.R_IP = target; 5060 DECODE_CLEAR_SEGOVR(); 5061 END_OF_INSTR(); 5062} 5063 5064/**************************************************************************** 5065REMARKS: 5066Handles opcode 0x7b 5067****************************************************************************/ 5068static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1)) 5069{ 5070 s8 offset; 5071 u16 target; 5072 5073 /* jump to byte offset if parity flag is clear (odd parity) */ 5074 START_OF_INSTR(); 5075 DECODE_PRINTF("JNP\t"); 5076 offset = (s8)fetch_byte_imm(); 5077 target = (u16)(M.x86.R_IP + (s16)offset); 5078 DECODE_PRINTF2("%x\n", target); 5079 TRACE_AND_STEP(); 5080 if (!ACCESS_FLAG(F_PF)) 5081 M.x86.R_IP = target; 5082 DECODE_CLEAR_SEGOVR(); 5083 END_OF_INSTR(); 5084} 5085 5086/**************************************************************************** 5087REMARKS: 5088Handles opcode 0x7c 5089****************************************************************************/ 5090static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1)) 5091{ 5092 s8 offset; 5093 u16 target; 5094 int sf, of; 5095 5096 /* jump to byte offset if sign flag not equal to overflow flag. */ 5097 START_OF_INSTR(); 5098 DECODE_PRINTF("JL\t"); 5099 offset = (s8)fetch_byte_imm(); 5100 target = (u16)(M.x86.R_IP + (s16)offset); 5101 DECODE_PRINTF2("%x\n", target); 5102 TRACE_AND_STEP(); 5103 sf = ACCESS_FLAG(F_SF) != 0; 5104 of = ACCESS_FLAG(F_OF) != 0; 5105 if (sf ^ of) 5106 M.x86.R_IP = target; 5107 DECODE_CLEAR_SEGOVR(); 5108 END_OF_INSTR(); 5109} 5110 5111/**************************************************************************** 5112REMARKS: 5113Handles opcode 0x7d 5114****************************************************************************/ 5115static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1)) 5116{ 5117 s8 offset; 5118 u16 target; 5119 int sf, of; 5120 5121 /* jump to byte offset if sign flag not equal to overflow flag. */ 5122 START_OF_INSTR(); 5123 DECODE_PRINTF("JNL\t"); 5124 offset = (s8)fetch_byte_imm(); 5125 target = (u16)(M.x86.R_IP + (s16)offset); 5126 DECODE_PRINTF2("%x\n", target); 5127 TRACE_AND_STEP(); 5128 sf = ACCESS_FLAG(F_SF) != 0; 5129 of = ACCESS_FLAG(F_OF) != 0; 5130 /* note: inverse of above, but using == instead of xor. */ 5131 if (sf == of) 5132 M.x86.R_IP = target; 5133 DECODE_CLEAR_SEGOVR(); 5134 END_OF_INSTR(); 5135} 5136 5137/**************************************************************************** 5138REMARKS: 5139Handles opcode 0x7e 5140****************************************************************************/ 5141static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1)) 5142{ 5143 s8 offset; 5144 u16 target; 5145 int sf, of; 5146 5147 /* jump to byte offset if sign flag not equal to overflow flag 5148 or the zero flag is set */ 5149 START_OF_INSTR(); 5150 DECODE_PRINTF("JLE\t"); 5151 offset = (s8)fetch_byte_imm(); 5152 target = (u16)(M.x86.R_IP + (s16)offset); 5153 DECODE_PRINTF2("%x\n", target); 5154 TRACE_AND_STEP(); 5155 sf = ACCESS_FLAG(F_SF) != 0; 5156 of = ACCESS_FLAG(F_OF) != 0; 5157 if ((sf ^ of) || ACCESS_FLAG(F_ZF)) 5158 M.x86.R_IP = target; 5159 DECODE_CLEAR_SEGOVR(); 5160 END_OF_INSTR(); 5161} 5162 5163/**************************************************************************** 5164REMARKS: 5165Handles opcode 0x7f 5166****************************************************************************/ 5167static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1)) 5168{ 5169 s8 offset; 5170 u16 target; 5171 int sf, of; 5172 5173 /* jump to byte offset if sign flag equal to overflow flag. 5174 and the zero flag is clear */ 5175 START_OF_INSTR(); 5176 DECODE_PRINTF("JNLE\t"); 5177 offset = (s8)fetch_byte_imm(); 5178 target = (u16)(M.x86.R_IP + (s16)offset); 5179 DECODE_PRINTF2("%x\n", target); 5180 TRACE_AND_STEP(); 5181 sf = ACCESS_FLAG(F_SF) != 0; 5182 of = ACCESS_FLAG(F_OF) != 0; 5183 if ((sf == of) && !ACCESS_FLAG(F_ZF)) 5184 M.x86.R_IP = target; 5185 DECODE_CLEAR_SEGOVR(); 5186 END_OF_INSTR(); 5187} 5188 5189static u8 (*opc80_byte_operation[])(u8 d, u8 s) = 5190{ 5191 add_byte, /* 00 */ 5192 or_byte, /* 01 */ 5193 adc_byte, /* 02 */ 5194 sbb_byte, /* 03 */ 5195 and_byte, /* 04 */ 5196 sub_byte, /* 05 */ 5197 xor_byte, /* 06 */ 5198 cmp_byte, /* 07 */ 5199}; 5200 5201/**************************************************************************** 5202REMARKS: 5203Handles opcode 0x80 5204****************************************************************************/ 5205static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5206{ 5207 int mod, rl, rh; 5208 u8 *destreg; 5209 uint destoffset; 5210 u8 imm; 5211 u8 destval; 5212 5213 /* 5214 * Weirdo special case instruction format. Part of the opcode 5215 * held below in "RH". Doubly nested case would result, except 5216 * that the decoded instruction 5217 */ 5218 START_OF_INSTR(); 5219 FETCH_DECODE_MODRM(mod, rh, rl); 5220#ifdef DEBUG 5221 if (DEBUG_DECODE()) { 5222 /* XXX DECODE_PRINTF may be changed to something more 5223 general, so that it is important to leave the strings 5224 in the same format, even though the result is that the 5225 above test is done twice. */ 5226 5227 switch (rh) { 5228 case 0: 5229 DECODE_PRINTF("ADD\t"); 5230 break; 5231 case 1: 5232 DECODE_PRINTF("OR\t"); 5233 break; 5234 case 2: 5235 DECODE_PRINTF("ADC\t"); 5236 break; 5237 case 3: 5238 DECODE_PRINTF("SBB\t"); 5239 break; 5240 case 4: 5241 DECODE_PRINTF("AND\t"); 5242 break; 5243 case 5: 5244 DECODE_PRINTF("SUB\t"); 5245 break; 5246 case 6: 5247 DECODE_PRINTF("XOR\t"); 5248 break; 5249 case 7: 5250 DECODE_PRINTF("CMP\t"); 5251 break; 5252 } 5253 } 5254#endif 5255 /* know operation, decode the mod byte to find the addressing 5256 mode. */ 5257 switch (mod) { 5258 case 0: 5259 DECODE_PRINTF("BYTE PTR "); 5260 destoffset = decode_rm00_address(rl); 5261 DECODE_PRINTF(","); 5262 destval = fetch_data_byte(destoffset); 5263 imm = fetch_byte_imm(); 5264 DECODE_PRINTF2("%x\n", imm); 5265 TRACE_AND_STEP(); 5266 destval = (*opc80_byte_operation[rh]) (destval, imm); 5267 if (rh != 7) 5268 store_data_byte(destoffset, destval); 5269 break; 5270 case 1: 5271 DECODE_PRINTF("BYTE PTR "); 5272 destoffset = decode_rm01_address(rl); 5273 DECODE_PRINTF(","); 5274 destval = fetch_data_byte(destoffset); 5275 imm = fetch_byte_imm(); 5276 DECODE_PRINTF2("%x\n", imm); 5277 TRACE_AND_STEP(); 5278 destval = (*opc80_byte_operation[rh]) (destval, imm); 5279 if (rh != 7) 5280 store_data_byte(destoffset, destval); 5281 break; 5282 case 2: 5283 DECODE_PRINTF("BYTE PTR "); 5284 destoffset = decode_rm10_address(rl); 5285 DECODE_PRINTF(","); 5286 destval = fetch_data_byte(destoffset); 5287 imm = fetch_byte_imm(); 5288 DECODE_PRINTF2("%x\n", imm); 5289 TRACE_AND_STEP(); 5290 destval = (*opc80_byte_operation[rh]) (destval, imm); 5291 if (rh != 7) 5292 store_data_byte(destoffset, destval); 5293 break; 5294 case 3: /* register to register */ 5295 destreg = DECODE_RM_BYTE_REGISTER(rl); 5296 DECODE_PRINTF(","); 5297 imm = fetch_byte_imm(); 5298 DECODE_PRINTF2("%x\n", imm); 5299 TRACE_AND_STEP(); 5300 destval = (*opc80_byte_operation[rh]) (*destreg, imm); 5301 if (rh != 7) 5302 *destreg = destval; 5303 break; 5304 } 5305 DECODE_CLEAR_SEGOVR(); 5306 END_OF_INSTR(); 5307} 5308 5309static u16 (*opc81_word_operation[])(u16 d, u16 s) = 5310{ 5311 add_word, /*00 */ 5312 or_word, /*01 */ 5313 adc_word, /*02 */ 5314 sbb_word, /*03 */ 5315 and_word, /*04 */ 5316 sub_word, /*05 */ 5317 xor_word, /*06 */ 5318 cmp_word, /*07 */ 5319}; 5320 5321static u32 (*opc81_long_operation[])(u32 d, u32 s) = 5322{ 5323 add_long, /*00 */ 5324 or_long, /*01 */ 5325 adc_long, /*02 */ 5326 sbb_long, /*03 */ 5327 and_long, /*04 */ 5328 sub_long, /*05 */ 5329 xor_long, /*06 */ 5330 cmp_long, /*07 */ 5331}; 5332 5333/**************************************************************************** 5334REMARKS: 5335Handles opcode 0x81 5336****************************************************************************/ 5337static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5338{ 5339 int mod, rl, rh; 5340 uint destoffset; 5341 5342 /* 5343 * Weirdo special case instruction format. Part of the opcode 5344 * held below in "RH". Doubly nested case would result, except 5345 * that the decoded instruction 5346 */ 5347 START_OF_INSTR(); 5348 FETCH_DECODE_MODRM(mod, rh, rl); 5349#ifdef DEBUG 5350 if (DEBUG_DECODE()) { 5351 /* XXX DECODE_PRINTF may be changed to something more 5352 general, so that it is important to leave the strings 5353 in the same format, even though the result is that the 5354 above test is done twice. */ 5355 5356 switch (rh) { 5357 case 0: 5358 DECODE_PRINTF("ADD\t"); 5359 break; 5360 case 1: 5361 DECODE_PRINTF("OR\t"); 5362 break; 5363 case 2: 5364 DECODE_PRINTF("ADC\t"); 5365 break; 5366 case 3: 5367 DECODE_PRINTF("SBB\t"); 5368 break; 5369 case 4: 5370 DECODE_PRINTF("AND\t"); 5371 break; 5372 case 5: 5373 DECODE_PRINTF("SUB\t"); 5374 break; 5375 case 6: 5376 DECODE_PRINTF("XOR\t"); 5377 break; 5378 case 7: 5379 DECODE_PRINTF("CMP\t"); 5380 break; 5381 } 5382 } 5383#endif 5384 /* 5385 * Know operation, decode the mod byte to find the addressing 5386 * mode. 5387 */ 5388 switch (mod) { 5389 case 0: 5390 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5391 u32 destval,imm; 5392 5393 DECODE_PRINTF("DWORD PTR "); 5394 destoffset = decode_rm00_address(rl); 5395 DECODE_PRINTF(","); 5396 destval = fetch_data_long(destoffset); 5397 imm = fetch_long_imm(); 5398 DECODE_PRINTF2("%x\n", imm); 5399 TRACE_AND_STEP(); 5400 destval = (*opc81_long_operation[rh]) (destval, imm); 5401 if (rh != 7) 5402 store_data_long(destoffset, destval); 5403 } else { 5404 u16 destval,imm; 5405 5406 DECODE_PRINTF("WORD PTR "); 5407 destoffset = decode_rm00_address(rl); 5408 DECODE_PRINTF(","); 5409 destval = fetch_data_word(destoffset); 5410 imm = fetch_word_imm(); 5411 DECODE_PRINTF2("%x\n", imm); 5412 TRACE_AND_STEP(); 5413 destval = (*opc81_word_operation[rh]) (destval, imm); 5414 if (rh != 7) 5415 store_data_word(destoffset, destval); 5416 } 5417 break; 5418 case 1: 5419 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5420 u32 destval,imm; 5421 5422 DECODE_PRINTF("DWORD PTR "); 5423 destoffset = decode_rm01_address(rl); 5424 DECODE_PRINTF(","); 5425 destval = fetch_data_long(destoffset); 5426 imm = fetch_long_imm(); 5427 DECODE_PRINTF2("%x\n", imm); 5428 TRACE_AND_STEP(); 5429 destval = (*opc81_long_operation[rh]) (destval, imm); 5430 if (rh != 7) 5431 store_data_long(destoffset, destval); 5432 } else { 5433 u16 destval,imm; 5434 5435 DECODE_PRINTF("WORD PTR "); 5436 destoffset = decode_rm01_address(rl); 5437 DECODE_PRINTF(","); 5438 destval = fetch_data_word(destoffset); 5439 imm = fetch_word_imm(); 5440 DECODE_PRINTF2("%x\n", imm); 5441 TRACE_AND_STEP(); 5442 destval = (*opc81_word_operation[rh]) (destval, imm); 5443 if (rh != 7) 5444 store_data_word(destoffset, destval); 5445 } 5446 break; 5447 case 2: 5448 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5449 u32 destval,imm; 5450 5451 DECODE_PRINTF("DWORD PTR "); 5452 destoffset = decode_rm10_address(rl); 5453 DECODE_PRINTF(","); 5454 destval = fetch_data_long(destoffset); 5455 imm = fetch_long_imm(); 5456 DECODE_PRINTF2("%x\n", imm); 5457 TRACE_AND_STEP(); 5458 destval = (*opc81_long_operation[rh]) (destval, imm); 5459 if (rh != 7) 5460 store_data_long(destoffset, destval); 5461 } else { 5462 u16 destval,imm; 5463 5464 DECODE_PRINTF("WORD PTR "); 5465 destoffset = decode_rm10_address(rl); 5466 DECODE_PRINTF(","); 5467 destval = fetch_data_word(destoffset); 5468 imm = fetch_word_imm(); 5469 DECODE_PRINTF2("%x\n", imm); 5470 TRACE_AND_STEP(); 5471 destval = (*opc81_word_operation[rh]) (destval, imm); 5472 if (rh != 7) 5473 store_data_word(destoffset, destval); 5474 } 5475 break; 5476 case 3: /* register to register */ 5477 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5478 u32 *destreg; 5479 u32 destval,imm; 5480 5481 destreg = DECODE_RM_LONG_REGISTER(rl); 5482 DECODE_PRINTF(","); 5483 imm = fetch_long_imm(); 5484 DECODE_PRINTF2("%x\n", imm); 5485 TRACE_AND_STEP(); 5486 destval = (*opc81_long_operation[rh]) (*destreg, imm); 5487 if (rh != 7) 5488 *destreg = destval; 5489 } else { 5490 u16 *destreg; 5491 u16 destval,imm; 5492 5493 destreg = DECODE_RM_WORD_REGISTER(rl); 5494 DECODE_PRINTF(","); 5495 imm = fetch_word_imm(); 5496 DECODE_PRINTF2("%x\n", imm); 5497 TRACE_AND_STEP(); 5498 destval = (*opc81_word_operation[rh]) (*destreg, imm); 5499 if (rh != 7) 5500 *destreg = destval; 5501 } 5502 break; 5503 } 5504 DECODE_CLEAR_SEGOVR(); 5505 END_OF_INSTR(); 5506} 5507 5508static u8 (*opc82_byte_operation[])(u8 s, u8 d) = 5509{ 5510 add_byte, /*00 */ 5511 or_byte, /*01 *//*YYY UNUSED ???? */ 5512 adc_byte, /*02 */ 5513 sbb_byte, /*03 */ 5514 and_byte, /*04 *//*YYY UNUSED ???? */ 5515 sub_byte, /*05 */ 5516 xor_byte, /*06 *//*YYY UNUSED ???? */ 5517 cmp_byte, /*07 */ 5518}; 5519 5520/**************************************************************************** 5521REMARKS: 5522Handles opcode 0x82 5523****************************************************************************/ 5524static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5525{ 5526 int mod, rl, rh; 5527 u8 *destreg; 5528 uint destoffset; 5529 u8 imm; 5530 u8 destval; 5531 5532 /* 5533 * Weirdo special case instruction format. Part of the opcode 5534 * held below in "RH". Doubly nested case would result, except 5535 * that the decoded instruction Similar to opcode 81, except that 5536 * the immediate byte is sign extended to a word length. 5537 */ 5538 START_OF_INSTR(); 5539 FETCH_DECODE_MODRM(mod, rh, rl); 5540#ifdef DEBUG 5541 if (DEBUG_DECODE()) { 5542 /* XXX DECODE_PRINTF may be changed to something more 5543 general, so that it is important to leave the strings 5544 in the same format, even though the result is that the 5545 above test is done twice. */ 5546 switch (rh) { 5547 case 0: 5548 DECODE_PRINTF("ADD\t"); 5549 break; 5550 case 1: 5551 DECODE_PRINTF("OR\t"); 5552 break; 5553 case 2: 5554 DECODE_PRINTF("ADC\t"); 5555 break; 5556 case 3: 5557 DECODE_PRINTF("SBB\t"); 5558 break; 5559 case 4: 5560 DECODE_PRINTF("AND\t"); 5561 break; 5562 case 5: 5563 DECODE_PRINTF("SUB\t"); 5564 break; 5565 case 6: 5566 DECODE_PRINTF("XOR\t"); 5567 break; 5568 case 7: 5569 DECODE_PRINTF("CMP\t"); 5570 break; 5571 } 5572 } 5573#endif 5574 /* know operation, decode the mod byte to find the addressing 5575 mode. */ 5576 switch (mod) { 5577 case 0: 5578 DECODE_PRINTF("BYTE PTR "); 5579 destoffset = decode_rm00_address(rl); 5580 destval = fetch_data_byte(destoffset); 5581 imm = fetch_byte_imm(); 5582 DECODE_PRINTF2(",%x\n", imm); 5583 TRACE_AND_STEP(); 5584 destval = (*opc82_byte_operation[rh]) (destval, imm); 5585 if (rh != 7) 5586 store_data_byte(destoffset, destval); 5587 break; 5588 case 1: 5589 DECODE_PRINTF("BYTE PTR "); 5590 destoffset = decode_rm01_address(rl); 5591 destval = fetch_data_byte(destoffset); 5592 imm = fetch_byte_imm(); 5593 DECODE_PRINTF2(",%x\n", imm); 5594 TRACE_AND_STEP(); 5595 destval = (*opc82_byte_operation[rh]) (destval, imm); 5596 if (rh != 7) 5597 store_data_byte(destoffset, destval); 5598 break; 5599 case 2: 5600 DECODE_PRINTF("BYTE PTR "); 5601 destoffset = decode_rm10_address(rl); 5602 destval = fetch_data_byte(destoffset); 5603 imm = fetch_byte_imm(); 5604 DECODE_PRINTF2(",%x\n", imm); 5605 TRACE_AND_STEP(); 5606 destval = (*opc82_byte_operation[rh]) (destval, imm); 5607 if (rh != 7) 5608 store_data_byte(destoffset, destval); 5609 break; 5610 case 3: /* register to register */ 5611 destreg = DECODE_RM_BYTE_REGISTER(rl); 5612 imm = fetch_byte_imm(); 5613 DECODE_PRINTF2(",%x\n", imm); 5614 TRACE_AND_STEP(); 5615 destval = (*opc82_byte_operation[rh]) (*destreg, imm); 5616 if (rh != 7) 5617 *destreg = destval; 5618 break; 5619 } 5620 DECODE_CLEAR_SEGOVR(); 5621 END_OF_INSTR(); 5622} 5623 5624static u16 (*opc83_word_operation[])(u16 s, u16 d) = 5625{ 5626 add_word, /*00 */ 5627 or_word, /*01 *//*YYY UNUSED ???? */ 5628 adc_word, /*02 */ 5629 sbb_word, /*03 */ 5630 and_word, /*04 *//*YYY UNUSED ???? */ 5631 sub_word, /*05 */ 5632 xor_word, /*06 *//*YYY UNUSED ???? */ 5633 cmp_word, /*07 */ 5634}; 5635 5636static u32 (*opc83_long_operation[])(u32 s, u32 d) = 5637{ 5638 add_long, /*00 */ 5639 or_long, /*01 *//*YYY UNUSED ???? */ 5640 adc_long, /*02 */ 5641 sbb_long, /*03 */ 5642 and_long, /*04 *//*YYY UNUSED ???? */ 5643 sub_long, /*05 */ 5644 xor_long, /*06 *//*YYY UNUSED ???? */ 5645 cmp_long, /*07 */ 5646}; 5647 5648/**************************************************************************** 5649REMARKS: 5650Handles opcode 0x83 5651****************************************************************************/ 5652static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5653{ 5654 int mod, rl, rh; 5655 uint destoffset; 5656 5657 /* 5658 * Weirdo special case instruction format. Part of the opcode 5659 * held below in "RH". Doubly nested case would result, except 5660 * that the decoded instruction Similar to opcode 81, except that 5661 * the immediate byte is sign extended to a word length. 5662 */ 5663 START_OF_INSTR(); 5664 FETCH_DECODE_MODRM(mod, rh, rl); 5665#ifdef DEBUG 5666 if (DEBUG_DECODE()) { 5667 /* XXX DECODE_PRINTF may be changed to something more 5668 general, so that it is important to leave the strings 5669 in the same format, even though the result is that the 5670 above test is done twice. */ 5671 switch (rh) { 5672 case 0: 5673 DECODE_PRINTF("ADD\t"); 5674 break; 5675 case 1: 5676 DECODE_PRINTF("OR\t"); 5677 break; 5678 case 2: 5679 DECODE_PRINTF("ADC\t"); 5680 break; 5681 case 3: 5682 DECODE_PRINTF("SBB\t"); 5683 break; 5684 case 4: 5685 DECODE_PRINTF("AND\t"); 5686 break; 5687 case 5: 5688 DECODE_PRINTF("SUB\t"); 5689 break; 5690 case 6: 5691 DECODE_PRINTF("XOR\t"); 5692 break; 5693 case 7: 5694 DECODE_PRINTF("CMP\t"); 5695 break; 5696 } 5697 } 5698#endif 5699 /* know operation, decode the mod byte to find the addressing 5700 mode. */ 5701 switch (mod) { 5702 case 0: 5703 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5704 u32 destval,imm; 5705 5706 DECODE_PRINTF("DWORD PTR "); 5707 destoffset = decode_rm00_address(rl); 5708 destval = fetch_data_long(destoffset); 5709 imm = (s8) fetch_byte_imm(); 5710 DECODE_PRINTF2(",%x\n", imm); 5711 TRACE_AND_STEP(); 5712 destval = (*opc83_long_operation[rh]) (destval, imm); 5713 if (rh != 7) 5714 store_data_long(destoffset, destval); 5715 } else { 5716 u16 destval,imm; 5717 5718 DECODE_PRINTF("WORD PTR "); 5719 destoffset = decode_rm00_address(rl); 5720 destval = fetch_data_word(destoffset); 5721 imm = (s8) fetch_byte_imm(); 5722 DECODE_PRINTF2(",%x\n", imm); 5723 TRACE_AND_STEP(); 5724 destval = (*opc83_word_operation[rh]) (destval, imm); 5725 if (rh != 7) 5726 store_data_word(destoffset, destval); 5727 } 5728 break; 5729 case 1: 5730 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5731 u32 destval,imm; 5732 5733 DECODE_PRINTF("DWORD PTR "); 5734 destoffset = decode_rm01_address(rl); 5735 destval = fetch_data_long(destoffset); 5736 imm = (s8) fetch_byte_imm(); 5737 DECODE_PRINTF2(",%x\n", imm); 5738 TRACE_AND_STEP(); 5739 destval = (*opc83_long_operation[rh]) (destval, imm); 5740 if (rh != 7) 5741 store_data_long(destoffset, destval); 5742 } else { 5743 u16 destval,imm; 5744 5745 DECODE_PRINTF("WORD PTR "); 5746 destoffset = decode_rm01_address(rl); 5747 destval = fetch_data_word(destoffset); 5748 imm = (s8) fetch_byte_imm(); 5749 DECODE_PRINTF2(",%x\n", imm); 5750 TRACE_AND_STEP(); 5751 destval = (*opc83_word_operation[rh]) (destval, imm); 5752 if (rh != 7) 5753 store_data_word(destoffset, destval); 5754 } 5755 break; 5756 case 2: 5757 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5758 u32 destval,imm; 5759 5760 DECODE_PRINTF("DWORD PTR "); 5761 destoffset = decode_rm10_address(rl); 5762 destval = fetch_data_long(destoffset); 5763 imm = (s8) fetch_byte_imm(); 5764 DECODE_PRINTF2(",%x\n", imm); 5765 TRACE_AND_STEP(); 5766 destval = (*opc83_long_operation[rh]) (destval, imm); 5767 if (rh != 7) 5768 store_data_long(destoffset, destval); 5769 } else { 5770 u16 destval,imm; 5771 5772 DECODE_PRINTF("WORD PTR "); 5773 destoffset = decode_rm10_address(rl); 5774 destval = fetch_data_word(destoffset); 5775 imm = (s8) fetch_byte_imm(); 5776 DECODE_PRINTF2(",%x\n", imm); 5777 TRACE_AND_STEP(); 5778 destval = (*opc83_word_operation[rh]) (destval, imm); 5779 if (rh != 7) 5780 store_data_word(destoffset, destval); 5781 } 5782 break; 5783 case 3: /* register to register */ 5784 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5785 u32 *destreg; 5786 u32 destval,imm; 5787 5788 destreg = DECODE_RM_LONG_REGISTER(rl); 5789 imm = (s8) fetch_byte_imm(); 5790 DECODE_PRINTF2(",%x\n", imm); 5791 TRACE_AND_STEP(); 5792 destval = (*opc83_long_operation[rh]) (*destreg, imm); 5793 if (rh != 7) 5794 *destreg = destval; 5795 } else { 5796 u16 *destreg; 5797 u16 destval,imm; 5798 5799 destreg = DECODE_RM_WORD_REGISTER(rl); 5800 imm = (s8) fetch_byte_imm(); 5801 DECODE_PRINTF2(",%x\n", imm); 5802 TRACE_AND_STEP(); 5803 destval = (*opc83_word_operation[rh]) (*destreg, imm); 5804 if (rh != 7) 5805 *destreg = destval; 5806 } 5807 break; 5808 } 5809 DECODE_CLEAR_SEGOVR(); 5810 END_OF_INSTR(); 5811} 5812 5813/**************************************************************************** 5814REMARKS: 5815Handles opcode 0x84 5816****************************************************************************/ 5817static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5818{ 5819 int mod, rl, rh; 5820 u8 *destreg, *srcreg; 5821 uint destoffset; 5822 u8 destval; 5823 5824 START_OF_INSTR(); 5825 DECODE_PRINTF("TEST\t"); 5826 FETCH_DECODE_MODRM(mod, rh, rl); 5827 switch (mod) { 5828 case 0: 5829 destoffset = decode_rm00_address(rl); 5830 DECODE_PRINTF(","); 5831 destval = fetch_data_byte(destoffset); 5832 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5833 DECODE_PRINTF("\n"); 5834 TRACE_AND_STEP(); 5835 test_byte(destval, *srcreg); 5836 break; 5837 case 1: 5838 destoffset = decode_rm01_address(rl); 5839 DECODE_PRINTF(","); 5840 destval = fetch_data_byte(destoffset); 5841 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5842 DECODE_PRINTF("\n"); 5843 TRACE_AND_STEP(); 5844 test_byte(destval, *srcreg); 5845 break; 5846 case 2: 5847 destoffset = decode_rm10_address(rl); 5848 DECODE_PRINTF(","); 5849 destval = fetch_data_byte(destoffset); 5850 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5851 DECODE_PRINTF("\n"); 5852 TRACE_AND_STEP(); 5853 test_byte(destval, *srcreg); 5854 break; 5855 case 3: /* register to register */ 5856 destreg = DECODE_RM_BYTE_REGISTER(rl); 5857 DECODE_PRINTF(","); 5858 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5859 DECODE_PRINTF("\n"); 5860 TRACE_AND_STEP(); 5861 test_byte(*destreg, *srcreg); 5862 break; 5863 } 5864 DECODE_CLEAR_SEGOVR(); 5865 END_OF_INSTR(); 5866} 5867 5868/**************************************************************************** 5869REMARKS: 5870Handles opcode 0x85 5871****************************************************************************/ 5872static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 5873{ 5874 int mod, rl, rh; 5875 uint destoffset; 5876 5877 START_OF_INSTR(); 5878 DECODE_PRINTF("TEST\t"); 5879 FETCH_DECODE_MODRM(mod, rh, rl); 5880 switch (mod) { 5881 case 0: 5882 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5883 u32 destval; 5884 u32 *srcreg; 5885 5886 destoffset = decode_rm00_address(rl); 5887 DECODE_PRINTF(","); 5888 destval = fetch_data_long(destoffset); 5889 srcreg = DECODE_RM_LONG_REGISTER(rh); 5890 DECODE_PRINTF("\n"); 5891 TRACE_AND_STEP(); 5892 test_long(destval, *srcreg); 5893 } else { 5894 u16 destval; 5895 u16 *srcreg; 5896 5897 destoffset = decode_rm00_address(rl); 5898 DECODE_PRINTF(","); 5899 destval = fetch_data_word(destoffset); 5900 srcreg = DECODE_RM_WORD_REGISTER(rh); 5901 DECODE_PRINTF("\n"); 5902 TRACE_AND_STEP(); 5903 test_word(destval, *srcreg); 5904 } 5905 break; 5906 case 1: 5907 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5908 u32 destval; 5909 u32 *srcreg; 5910 5911 destoffset = decode_rm01_address(rl); 5912 DECODE_PRINTF(","); 5913 destval = fetch_data_long(destoffset); 5914 srcreg = DECODE_RM_LONG_REGISTER(rh); 5915 DECODE_PRINTF("\n"); 5916 TRACE_AND_STEP(); 5917 test_long(destval, *srcreg); 5918 } else { 5919 u16 destval; 5920 u16 *srcreg; 5921 5922 destoffset = decode_rm01_address(rl); 5923 DECODE_PRINTF(","); 5924 destval = fetch_data_word(destoffset); 5925 srcreg = DECODE_RM_WORD_REGISTER(rh); 5926 DECODE_PRINTF("\n"); 5927 TRACE_AND_STEP(); 5928 test_word(destval, *srcreg); 5929 } 5930 break; 5931 case 2: 5932 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5933 u32 destval; 5934 u32 *srcreg; 5935 5936 destoffset = decode_rm10_address(rl); 5937 DECODE_PRINTF(","); 5938 destval = fetch_data_long(destoffset); 5939 srcreg = DECODE_RM_LONG_REGISTER(rh); 5940 DECODE_PRINTF("\n"); 5941 TRACE_AND_STEP(); 5942 test_long(destval, *srcreg); 5943 } else { 5944 u16 destval; 5945 u16 *srcreg; 5946 5947 destoffset = decode_rm10_address(rl); 5948 DECODE_PRINTF(","); 5949 destval = fetch_data_word(destoffset); 5950 srcreg = DECODE_RM_WORD_REGISTER(rh); 5951 DECODE_PRINTF("\n"); 5952 TRACE_AND_STEP(); 5953 test_word(destval, *srcreg); 5954 } 5955 break; 5956 case 3: /* register to register */ 5957 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5958 u32 *destreg,*srcreg; 5959 5960 destreg = DECODE_RM_LONG_REGISTER(rl); 5961 DECODE_PRINTF(","); 5962 srcreg = DECODE_RM_LONG_REGISTER(rh); 5963 DECODE_PRINTF("\n"); 5964 TRACE_AND_STEP(); 5965 test_long(*destreg, *srcreg); 5966 } else { 5967 u16 *destreg,*srcreg; 5968 5969 destreg = DECODE_RM_WORD_REGISTER(rl); 5970 DECODE_PRINTF(","); 5971 srcreg = DECODE_RM_WORD_REGISTER(rh); 5972 DECODE_PRINTF("\n"); 5973 TRACE_AND_STEP(); 5974 test_word(*destreg, *srcreg); 5975 } 5976 break; 5977 } 5978 DECODE_CLEAR_SEGOVR(); 5979 END_OF_INSTR(); 5980} 5981 5982/**************************************************************************** 5983REMARKS: 5984Handles opcode 0x86 5985****************************************************************************/ 5986static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5987{ 5988 int mod, rl, rh; 5989 u8 *destreg, *srcreg; 5990 uint destoffset; 5991 u8 destval; 5992 u8 tmp; 5993 5994 START_OF_INSTR(); 5995 DECODE_PRINTF("XCHG\t"); 5996 FETCH_DECODE_MODRM(mod, rh, rl); 5997 switch (mod) { 5998 case 0: 5999 destoffset = decode_rm00_address(rl); 6000 DECODE_PRINTF(","); 6001 destval = fetch_data_byte(destoffset); 6002 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6003 DECODE_PRINTF("\n"); 6004 TRACE_AND_STEP(); 6005 tmp = *srcreg; 6006 *srcreg = destval; 6007 destval = tmp; 6008 store_data_byte(destoffset, destval); 6009 break; 6010 case 1: 6011 destoffset = decode_rm01_address(rl); 6012 DECODE_PRINTF(","); 6013 destval = fetch_data_byte(destoffset); 6014 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6015 DECODE_PRINTF("\n"); 6016 TRACE_AND_STEP(); 6017 tmp = *srcreg; 6018 *srcreg = destval; 6019 destval = tmp; 6020 store_data_byte(destoffset, destval); 6021 break; 6022 case 2: 6023 destoffset = decode_rm10_address(rl); 6024 DECODE_PRINTF(","); 6025 destval = fetch_data_byte(destoffset); 6026 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6027 DECODE_PRINTF("\n"); 6028 TRACE_AND_STEP(); 6029 tmp = *srcreg; 6030 *srcreg = destval; 6031 destval = tmp; 6032 store_data_byte(destoffset, destval); 6033 break; 6034 case 3: /* register to register */ 6035 destreg = DECODE_RM_BYTE_REGISTER(rl); 6036 DECODE_PRINTF(","); 6037 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6038 DECODE_PRINTF("\n"); 6039 TRACE_AND_STEP(); 6040 tmp = *srcreg; 6041 *srcreg = *destreg; 6042 *destreg = tmp; 6043 break; 6044 } 6045 DECODE_CLEAR_SEGOVR(); 6046 END_OF_INSTR(); 6047} 6048 6049/**************************************************************************** 6050REMARKS: 6051Handles opcode 0x87 6052****************************************************************************/ 6053static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 6054{ 6055 int mod, rl, rh; 6056 uint destoffset; 6057 6058 START_OF_INSTR(); 6059 DECODE_PRINTF("XCHG\t"); 6060 FETCH_DECODE_MODRM(mod, rh, rl); 6061 switch (mod) { 6062 case 0: 6063 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6064 u32 *srcreg; 6065 u32 destval,tmp; 6066 6067 destoffset = decode_rm00_address(rl); 6068 DECODE_PRINTF(","); 6069 destval = fetch_data_long(destoffset); 6070 srcreg = DECODE_RM_LONG_REGISTER(rh); 6071 DECODE_PRINTF("\n"); 6072 TRACE_AND_STEP(); 6073 tmp = *srcreg; 6074 *srcreg = destval; 6075 destval = tmp; 6076 store_data_long(destoffset, destval); 6077 } else { 6078 u16 *srcreg; 6079 u16 destval,tmp; 6080 6081 destoffset = decode_rm00_address(rl); 6082 DECODE_PRINTF(","); 6083 destval = fetch_data_word(destoffset); 6084 srcreg = DECODE_RM_WORD_REGISTER(rh); 6085 DECODE_PRINTF("\n"); 6086 TRACE_AND_STEP(); 6087 tmp = *srcreg; 6088 *srcreg = destval; 6089 destval = tmp; 6090 store_data_word(destoffset, destval); 6091 } 6092 break; 6093 case 1: 6094 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6095 u32 *srcreg; 6096 u32 destval,tmp; 6097 6098 destoffset = decode_rm01_address(rl); 6099 DECODE_PRINTF(","); 6100 destval = fetch_data_long(destoffset); 6101 srcreg = DECODE_RM_LONG_REGISTER(rh); 6102 DECODE_PRINTF("\n"); 6103 TRACE_AND_STEP(); 6104 tmp = *srcreg; 6105 *srcreg = destval; 6106 destval = tmp; 6107 store_data_long(destoffset, destval); 6108 } else { 6109 u16 *srcreg; 6110 u16 destval,tmp; 6111 6112 destoffset = decode_rm01_address(rl); 6113 DECODE_PRINTF(","); 6114 destval = fetch_data_word(destoffset); 6115 srcreg = DECODE_RM_WORD_REGISTER(rh); 6116 DECODE_PRINTF("\n"); 6117 TRACE_AND_STEP(); 6118 tmp = *srcreg; 6119 *srcreg = destval; 6120 destval = tmp; 6121 store_data_word(destoffset, destval); 6122 } 6123 break; 6124 case 2: 6125 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6126 u32 *srcreg; 6127 u32 destval,tmp; 6128 6129 destoffset = decode_rm10_address(rl); 6130 DECODE_PRINTF(","); 6131 destval = fetch_data_long(destoffset); 6132 srcreg = DECODE_RM_LONG_REGISTER(rh); 6133 DECODE_PRINTF("\n"); 6134 TRACE_AND_STEP(); 6135 tmp = *srcreg; 6136 *srcreg = destval; 6137 destval = tmp; 6138 store_data_long(destoffset, destval); 6139 } else { 6140 u16 *srcreg; 6141 u16 destval,tmp; 6142 6143 destoffset = decode_rm10_address(rl); 6144 DECODE_PRINTF(","); 6145 destval = fetch_data_word(destoffset); 6146 srcreg = DECODE_RM_WORD_REGISTER(rh); 6147 DECODE_PRINTF("\n"); 6148 TRACE_AND_STEP(); 6149 tmp = *srcreg; 6150 *srcreg = destval; 6151 destval = tmp; 6152 store_data_word(destoffset, destval); 6153 } 6154 break; 6155 case 3: /* register to register */ 6156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6157 u32 *destreg,*srcreg; 6158 u32 tmp; 6159 6160 destreg = DECODE_RM_LONG_REGISTER(rl); 6161 DECODE_PRINTF(","); 6162 srcreg = DECODE_RM_LONG_REGISTER(rh); 6163 DECODE_PRINTF("\n"); 6164 TRACE_AND_STEP(); 6165 tmp = *srcreg; 6166 *srcreg = *destreg; 6167 *destreg = tmp; 6168 } else { 6169 u16 *destreg,*srcreg; 6170 u16 tmp; 6171 6172 destreg = DECODE_RM_WORD_REGISTER(rl); 6173 DECODE_PRINTF(","); 6174 srcreg = DECODE_RM_WORD_REGISTER(rh); 6175 DECODE_PRINTF("\n"); 6176 TRACE_AND_STEP(); 6177 tmp = *srcreg; 6178 *srcreg = *destreg; 6179 *destreg = tmp; 6180 } 6181 break; 6182 } 6183 DECODE_CLEAR_SEGOVR(); 6184 END_OF_INSTR(); 6185} 6186 6187/**************************************************************************** 6188REMARKS: 6189Handles opcode 0x88 6190****************************************************************************/ 6191static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6192{ 6193 int mod, rl, rh; 6194 u8 *destreg, *srcreg; 6195 uint destoffset; 6196 6197 START_OF_INSTR(); 6198 DECODE_PRINTF("MOV\t"); 6199 FETCH_DECODE_MODRM(mod, rh, rl); 6200 switch (mod) { 6201 case 0: 6202 destoffset = decode_rm00_address(rl); 6203 DECODE_PRINTF(","); 6204 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6205 DECODE_PRINTF("\n"); 6206 TRACE_AND_STEP(); 6207 store_data_byte(destoffset, *srcreg); 6208 break; 6209 case 1: 6210 destoffset = decode_rm01_address(rl); 6211 DECODE_PRINTF(","); 6212 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6213 DECODE_PRINTF("\n"); 6214 TRACE_AND_STEP(); 6215 store_data_byte(destoffset, *srcreg); 6216 break; 6217 case 2: 6218 destoffset = decode_rm10_address(rl); 6219 DECODE_PRINTF(","); 6220 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6221 DECODE_PRINTF("\n"); 6222 TRACE_AND_STEP(); 6223 store_data_byte(destoffset, *srcreg); 6224 break; 6225 case 3: /* register to register */ 6226 destreg = DECODE_RM_BYTE_REGISTER(rl); 6227 DECODE_PRINTF(","); 6228 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6229 DECODE_PRINTF("\n"); 6230 TRACE_AND_STEP(); 6231 *destreg = *srcreg; 6232 break; 6233 } 6234 DECODE_CLEAR_SEGOVR(); 6235 END_OF_INSTR(); 6236} 6237 6238/**************************************************************************** 6239REMARKS: 6240Handles opcode 0x89 6241****************************************************************************/ 6242static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 6243{ 6244 int mod, rl, rh; 6245 u32 destoffset; 6246 6247 START_OF_INSTR(); 6248 DECODE_PRINTF("MOV\t"); 6249 FETCH_DECODE_MODRM(mod, rh, rl); 6250 switch (mod) { 6251 case 0: 6252 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6253 u32 *srcreg; 6254 6255 destoffset = decode_rm00_address(rl); 6256 DECODE_PRINTF(","); 6257 srcreg = DECODE_RM_LONG_REGISTER(rh); 6258 DECODE_PRINTF("\n"); 6259 TRACE_AND_STEP(); 6260 store_data_long(destoffset, *srcreg); 6261 } else { 6262 u16 *srcreg; 6263 6264 destoffset = decode_rm00_address(rl); 6265 DECODE_PRINTF(","); 6266 srcreg = DECODE_RM_WORD_REGISTER(rh); 6267 DECODE_PRINTF("\n"); 6268 TRACE_AND_STEP(); 6269 store_data_word(destoffset, *srcreg); 6270 } 6271 break; 6272 case 1: 6273 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6274 u32 *srcreg; 6275 6276 destoffset = decode_rm01_address(rl); 6277 DECODE_PRINTF(","); 6278 srcreg = DECODE_RM_LONG_REGISTER(rh); 6279 DECODE_PRINTF("\n"); 6280 TRACE_AND_STEP(); 6281 store_data_long(destoffset, *srcreg); 6282 } else { 6283 u16 *srcreg; 6284 6285 destoffset = decode_rm01_address(rl); 6286 DECODE_PRINTF(","); 6287 srcreg = DECODE_RM_WORD_REGISTER(rh); 6288 DECODE_PRINTF("\n"); 6289 TRACE_AND_STEP(); 6290 store_data_word(destoffset, *srcreg); 6291 } 6292 break; 6293 case 2: 6294 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6295 u32 *srcreg; 6296 6297 destoffset = decode_rm10_address(rl); 6298 DECODE_PRINTF(","); 6299 srcreg = DECODE_RM_LONG_REGISTER(rh); 6300 DECODE_PRINTF("\n"); 6301 TRACE_AND_STEP(); 6302 store_data_long(destoffset, *srcreg); 6303 } else { 6304 u16 *srcreg; 6305 6306 destoffset = decode_rm10_address(rl); 6307 DECODE_PRINTF(","); 6308 srcreg = DECODE_RM_WORD_REGISTER(rh); 6309 DECODE_PRINTF("\n"); 6310 TRACE_AND_STEP(); 6311 store_data_word(destoffset, *srcreg); 6312 } 6313 break; 6314 case 3: /* register to register */ 6315 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6316 u32 *destreg,*srcreg; 6317 6318 destreg = DECODE_RM_LONG_REGISTER(rl); 6319 DECODE_PRINTF(","); 6320 srcreg = DECODE_RM_LONG_REGISTER(rh); 6321 DECODE_PRINTF("\n"); 6322 TRACE_AND_STEP(); 6323 *destreg = *srcreg; 6324 } else { 6325 u16 *destreg,*srcreg; 6326 6327 destreg = DECODE_RM_WORD_REGISTER(rl); 6328 DECODE_PRINTF(","); 6329 srcreg = DECODE_RM_WORD_REGISTER(rh); 6330 DECODE_PRINTF("\n"); 6331 TRACE_AND_STEP(); 6332 *destreg = *srcreg; 6333 } 6334 break; 6335 } 6336 DECODE_CLEAR_SEGOVR(); 6337 END_OF_INSTR(); 6338} 6339 6340/**************************************************************************** 6341REMARKS: 6342Handles opcode 0x8a 6343****************************************************************************/ 6344static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 6345{ 6346 int mod, rl, rh; 6347 u8 *destreg, *srcreg; 6348 uint srcoffset; 6349 u8 srcval; 6350 6351 START_OF_INSTR(); 6352 DECODE_PRINTF("MOV\t"); 6353 FETCH_DECODE_MODRM(mod, rh, rl); 6354 switch (mod) { 6355 case 0: 6356 destreg = DECODE_RM_BYTE_REGISTER(rh); 6357 DECODE_PRINTF(","); 6358 srcoffset = decode_rm00_address(rl); 6359 srcval = fetch_data_byte(srcoffset); 6360 DECODE_PRINTF("\n"); 6361 TRACE_AND_STEP(); 6362 *destreg = srcval; 6363 break; 6364 case 1: 6365 destreg = DECODE_RM_BYTE_REGISTER(rh); 6366 DECODE_PRINTF(","); 6367 srcoffset = decode_rm01_address(rl); 6368 srcval = fetch_data_byte(srcoffset); 6369 DECODE_PRINTF("\n"); 6370 TRACE_AND_STEP(); 6371 *destreg = srcval; 6372 break; 6373 case 2: 6374 destreg = DECODE_RM_BYTE_REGISTER(rh); 6375 DECODE_PRINTF(","); 6376 srcoffset = decode_rm10_address(rl); 6377 srcval = fetch_data_byte(srcoffset); 6378 DECODE_PRINTF("\n"); 6379 TRACE_AND_STEP(); 6380 *destreg = srcval; 6381 break; 6382 case 3: /* register to register */ 6383 destreg = DECODE_RM_BYTE_REGISTER(rh); 6384 DECODE_PRINTF(","); 6385 srcreg = DECODE_RM_BYTE_REGISTER(rl); 6386 DECODE_PRINTF("\n"); 6387 TRACE_AND_STEP(); 6388 *destreg = *srcreg; 6389 break; 6390 } 6391 DECODE_CLEAR_SEGOVR(); 6392 END_OF_INSTR(); 6393} 6394 6395/**************************************************************************** 6396REMARKS: 6397Handles opcode 0x8b 6398****************************************************************************/ 6399static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 6400{ 6401 int mod, rl, rh; 6402 uint srcoffset; 6403 6404 START_OF_INSTR(); 6405 DECODE_PRINTF("MOV\t"); 6406 FETCH_DECODE_MODRM(mod, rh, rl); 6407 switch (mod) { 6408 case 0: 6409 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6410 u32 *destreg; 6411 u32 srcval; 6412 6413 destreg = DECODE_RM_LONG_REGISTER(rh); 6414 DECODE_PRINTF(","); 6415 srcoffset = decode_rm00_address(rl); 6416 srcval = fetch_data_long(srcoffset); 6417 DECODE_PRINTF("\n"); 6418 TRACE_AND_STEP(); 6419 *destreg = srcval; 6420 } else { 6421 u16 *destreg; 6422 u16 srcval; 6423 6424 destreg = DECODE_RM_WORD_REGISTER(rh); 6425 DECODE_PRINTF(","); 6426 srcoffset = decode_rm00_address(rl); 6427 srcval = fetch_data_word(srcoffset); 6428 DECODE_PRINTF("\n"); 6429 TRACE_AND_STEP(); 6430 *destreg = srcval; 6431 } 6432 break; 6433 case 1: 6434 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6435 u32 *destreg; 6436 u32 srcval; 6437 6438 destreg = DECODE_RM_LONG_REGISTER(rh); 6439 DECODE_PRINTF(","); 6440 srcoffset = decode_rm01_address(rl); 6441 srcval = fetch_data_long(srcoffset); 6442 DECODE_PRINTF("\n"); 6443 TRACE_AND_STEP(); 6444 *destreg = srcval; 6445 } else { 6446 u16 *destreg; 6447 u16 srcval; 6448 6449 destreg = DECODE_RM_WORD_REGISTER(rh); 6450 DECODE_PRINTF(","); 6451 srcoffset = decode_rm01_address(rl); 6452 srcval = fetch_data_word(srcoffset); 6453 DECODE_PRINTF("\n"); 6454 TRACE_AND_STEP(); 6455 *destreg = srcval; 6456 } 6457 break; 6458 case 2: 6459 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6460 u32 *destreg; 6461 u32 srcval; 6462 6463 destreg = DECODE_RM_LONG_REGISTER(rh); 6464 DECODE_PRINTF(","); 6465 srcoffset = decode_rm10_address(rl); 6466 srcval = fetch_data_long(srcoffset); 6467 DECODE_PRINTF("\n"); 6468 TRACE_AND_STEP(); 6469 *destreg = srcval; 6470 } else { 6471 u16 *destreg; 6472 u16 srcval; 6473 6474 destreg = DECODE_RM_WORD_REGISTER(rh); 6475 DECODE_PRINTF(","); 6476 srcoffset = decode_rm10_address(rl); 6477 srcval = fetch_data_word(srcoffset); 6478 DECODE_PRINTF("\n"); 6479 TRACE_AND_STEP(); 6480 *destreg = srcval; 6481 } 6482 break; 6483 case 3: /* register to register */ 6484 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6485 u32 *destreg, *srcreg; 6486 6487 destreg = DECODE_RM_LONG_REGISTER(rh); 6488 DECODE_PRINTF(","); 6489 srcreg = DECODE_RM_LONG_REGISTER(rl); 6490 DECODE_PRINTF("\n"); 6491 TRACE_AND_STEP(); 6492 *destreg = *srcreg; 6493 } else { 6494 u16 *destreg, *srcreg; 6495 6496 destreg = DECODE_RM_WORD_REGISTER(rh); 6497 DECODE_PRINTF(","); 6498 srcreg = DECODE_RM_WORD_REGISTER(rl); 6499 DECODE_PRINTF("\n"); 6500 TRACE_AND_STEP(); 6501 *destreg = *srcreg; 6502 } 6503 break; 6504 } 6505 DECODE_CLEAR_SEGOVR(); 6506 END_OF_INSTR(); 6507} 6508 6509/**************************************************************************** 6510REMARKS: 6511Handles opcode 0x8c 6512****************************************************************************/ 6513static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 6514{ 6515 int mod, rl, rh; 6516 u16 *destreg, *srcreg; 6517 uint destoffset; 6518 u16 destval; 6519 6520 START_OF_INSTR(); 6521 DECODE_PRINTF("MOV\t"); 6522 FETCH_DECODE_MODRM(mod, rh, rl); 6523 switch (mod) { 6524 case 0: 6525 destoffset = decode_rm00_address(rl); 6526 DECODE_PRINTF(","); 6527 srcreg = decode_rm_seg_register(rh); 6528 DECODE_PRINTF("\n"); 6529 TRACE_AND_STEP(); 6530 destval = *srcreg; 6531 store_data_word(destoffset, destval); 6532 break; 6533 case 1: 6534 destoffset = decode_rm01_address(rl); 6535 DECODE_PRINTF(","); 6536 srcreg = decode_rm_seg_register(rh); 6537 DECODE_PRINTF("\n"); 6538 TRACE_AND_STEP(); 6539 destval = *srcreg; 6540 store_data_word(destoffset, destval); 6541 break; 6542 case 2: 6543 destoffset = decode_rm10_address(rl); 6544 DECODE_PRINTF(","); 6545 srcreg = decode_rm_seg_register(rh); 6546 DECODE_PRINTF("\n"); 6547 TRACE_AND_STEP(); 6548 destval = *srcreg; 6549 store_data_word(destoffset, destval); 6550 break; 6551 case 3: /* register to register */ 6552 destreg = DECODE_RM_WORD_REGISTER(rl); 6553 DECODE_PRINTF(","); 6554 srcreg = decode_rm_seg_register(rh); 6555 DECODE_PRINTF("\n"); 6556 TRACE_AND_STEP(); 6557 *destreg = *srcreg; 6558 break; 6559 } 6560 DECODE_CLEAR_SEGOVR(); 6561 END_OF_INSTR(); 6562} 6563 6564/**************************************************************************** 6565REMARKS: 6566Handles opcode 0x8d 6567****************************************************************************/ 6568static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 6569{ 6570 int mod, rl, rh; 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_DATA) { 6578 u32 *srcreg; 6579 u32 destoffset; 6580 6581 srcreg = DECODE_RM_LONG_REGISTER(rh); 6582 DECODE_PRINTF(","); 6583 destoffset = decode_rm00_address(rl); 6584 DECODE_PRINTF("\n"); 6585 TRACE_AND_STEP(); 6586 *srcreg = destoffset; 6587 } else { 6588 u16 *srcreg; 6589 u16 destoffset; 6590 6591 srcreg = DECODE_RM_WORD_REGISTER(rh); 6592 DECODE_PRINTF(","); 6593 destoffset = decode_rm00_address(rl); 6594 DECODE_PRINTF("\n"); 6595 TRACE_AND_STEP(); 6596 *srcreg = destoffset; 6597 } 6598 break; 6599 case 1: 6600 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6601 u32 *srcreg; 6602 u32 destoffset; 6603 6604 srcreg = DECODE_RM_LONG_REGISTER(rh); 6605 DECODE_PRINTF(","); 6606 destoffset = decode_rm01_address(rl); 6607 DECODE_PRINTF("\n"); 6608 TRACE_AND_STEP(); 6609 *srcreg = destoffset; 6610 } else { 6611 u16 *srcreg; 6612 u16 destoffset; 6613 6614 srcreg = DECODE_RM_WORD_REGISTER(rh); 6615 DECODE_PRINTF(","); 6616 destoffset = decode_rm01_address(rl); 6617 DECODE_PRINTF("\n"); 6618 TRACE_AND_STEP(); 6619 *srcreg = destoffset; 6620 } 6621 break; 6622 case 2: 6623 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6624 u32 *srcreg; 6625 u32 destoffset; 6626 6627 srcreg = DECODE_RM_LONG_REGISTER(rh); 6628 DECODE_PRINTF(","); 6629 destoffset = decode_rm10_address(rl); 6630 DECODE_PRINTF("\n"); 6631 TRACE_AND_STEP(); 6632 *srcreg = destoffset; 6633 } else { 6634 u16 *srcreg; 6635 u16 destoffset; 6636 6637 srcreg = DECODE_RM_WORD_REGISTER(rh); 6638 DECODE_PRINTF(","); 6639 destoffset = decode_rm10_address(rl); 6640 DECODE_PRINTF("\n"); 6641 TRACE_AND_STEP(); 6642 *srcreg = destoffset; 6643 } 6644 break; 6645 case 3: /* register to register */ 6646 /* undefined. Do nothing. */ 6647 break; 6648 } 6649 DECODE_CLEAR_SEGOVR(); 6650 END_OF_INSTR(); 6651} 6652 6653/**************************************************************************** 6654REMARKS: 6655Handles opcode 0x8e 6656****************************************************************************/ 6657static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 6658{ 6659 int mod, rl, rh; 6660 u16 *destreg, *srcreg; 6661 uint srcoffset; 6662 u16 srcval; 6663 6664 START_OF_INSTR(); 6665 DECODE_PRINTF("MOV\t"); 6666 FETCH_DECODE_MODRM(mod, rh, rl); 6667 switch (mod) { 6668 case 0: 6669 destreg = decode_rm_seg_register(rh); 6670 DECODE_PRINTF(","); 6671 srcoffset = decode_rm00_address(rl); 6672 srcval = fetch_data_word(srcoffset); 6673 DECODE_PRINTF("\n"); 6674 TRACE_AND_STEP(); 6675 *destreg = srcval; 6676 break; 6677 case 1: 6678 destreg = decode_rm_seg_register(rh); 6679 DECODE_PRINTF(","); 6680 srcoffset = decode_rm01_address(rl); 6681 srcval = fetch_data_word(srcoffset); 6682 DECODE_PRINTF("\n"); 6683 TRACE_AND_STEP(); 6684 *destreg = srcval; 6685 break; 6686 case 2: 6687 destreg = decode_rm_seg_register(rh); 6688 DECODE_PRINTF(","); 6689 srcoffset = decode_rm10_address(rl); 6690 srcval = fetch_data_word(srcoffset); 6691 DECODE_PRINTF("\n"); 6692 TRACE_AND_STEP(); 6693 *destreg = srcval; 6694 break; 6695 case 3: /* register to register */ 6696 destreg = decode_rm_seg_register(rh); 6697 DECODE_PRINTF(","); 6698 srcreg = DECODE_RM_WORD_REGISTER(rl); 6699 DECODE_PRINTF("\n"); 6700 TRACE_AND_STEP(); 6701 *destreg = *srcreg; 6702 break; 6703 } 6704 /* 6705 * Clean up, and reset all the R_xSP pointers to the correct 6706 * locations. This is about 3x too much overhead (doing all the 6707 * segreg ptrs when only one is needed, but this instruction 6708 * *cannot* be that common, and this isn't too much work anyway. 6709 */ 6710 DECODE_CLEAR_SEGOVR(); 6711 END_OF_INSTR(); 6712} 6713 6714/**************************************************************************** 6715REMARKS: 6716Handles opcode 0x8f 6717****************************************************************************/ 6718static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 6719{ 6720 int mod, rl, rh; 6721 uint destoffset; 6722 6723 START_OF_INSTR(); 6724 DECODE_PRINTF("POP\t"); 6725 FETCH_DECODE_MODRM(mod, rh, rl); 6726 if (rh != 0) { 6727 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 6728 HALT_SYS(); 6729 } 6730 switch (mod) { 6731 case 0: 6732 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6733 u32 destval; 6734 6735 destoffset = decode_rm00_address(rl); 6736 DECODE_PRINTF("\n"); 6737 TRACE_AND_STEP(); 6738 destval = pop_long(); 6739 store_data_long(destoffset, destval); 6740 } else { 6741 u16 destval; 6742 6743 destoffset = decode_rm00_address(rl); 6744 DECODE_PRINTF("\n"); 6745 TRACE_AND_STEP(); 6746 destval = pop_word(); 6747 store_data_word(destoffset, destval); 6748 } 6749 break; 6750 case 1: 6751 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6752 u32 destval; 6753 6754 destoffset = decode_rm01_address(rl); 6755 DECODE_PRINTF("\n"); 6756 TRACE_AND_STEP(); 6757 destval = pop_long(); 6758 store_data_long(destoffset, destval); 6759 } else { 6760 u16 destval; 6761 6762 destoffset = decode_rm01_address(rl); 6763 DECODE_PRINTF("\n"); 6764 TRACE_AND_STEP(); 6765 destval = pop_word(); 6766 store_data_word(destoffset, destval); 6767 } 6768 break; 6769 case 2: 6770 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6771 u32 destval; 6772 6773 destoffset = decode_rm10_address(rl); 6774 DECODE_PRINTF("\n"); 6775 TRACE_AND_STEP(); 6776 destval = pop_long(); 6777 store_data_long(destoffset, destval); 6778 } else { 6779 u16 destval; 6780 6781 destoffset = decode_rm10_address(rl); 6782 DECODE_PRINTF("\n"); 6783 TRACE_AND_STEP(); 6784 destval = pop_word(); 6785 store_data_word(destoffset, destval); 6786 } 6787 break; 6788 case 3: /* register to register */ 6789 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6790 u32 *destreg; 6791 6792 destreg = DECODE_RM_LONG_REGISTER(rl); 6793 DECODE_PRINTF("\n"); 6794 TRACE_AND_STEP(); 6795 *destreg = pop_long(); 6796 } else { 6797 u16 *destreg; 6798 6799 destreg = DECODE_RM_WORD_REGISTER(rl); 6800 DECODE_PRINTF("\n"); 6801 TRACE_AND_STEP(); 6802 *destreg = pop_word(); 6803 } 6804 break; 6805 } 6806 DECODE_CLEAR_SEGOVR(); 6807 END_OF_INSTR(); 6808} 6809 6810/**************************************************************************** 6811REMARKS: 6812Handles opcode 0x90 6813****************************************************************************/ 6814static void x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 6815{ 6816 START_OF_INSTR(); 6817 DECODE_PRINTF("NOP\n"); 6818 TRACE_AND_STEP(); 6819 DECODE_CLEAR_SEGOVR(); 6820 END_OF_INSTR(); 6821} 6822 6823/**************************************************************************** 6824REMARKS: 6825Handles opcode 0x91 6826****************************************************************************/ 6827static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1)) 6828{ 6829 u32 tmp; 6830 6831 START_OF_INSTR(); 6832 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6833 DECODE_PRINTF("XCHG\tEAX,ECX\n"); 6834 } else { 6835 DECODE_PRINTF("XCHG\tAX,CX\n"); 6836 } 6837 TRACE_AND_STEP(); 6838 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6839 tmp = M.x86.R_EAX; 6840 M.x86.R_EAX = M.x86.R_ECX; 6841 M.x86.R_ECX = tmp; 6842 } else { 6843 tmp = M.x86.R_AX; 6844 M.x86.R_AX = M.x86.R_CX; 6845 M.x86.R_CX = (u16)tmp; 6846 } 6847 DECODE_CLEAR_SEGOVR(); 6848 END_OF_INSTR(); 6849} 6850 6851/**************************************************************************** 6852REMARKS: 6853Handles opcode 0x92 6854****************************************************************************/ 6855static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1)) 6856{ 6857 u32 tmp; 6858 6859 START_OF_INSTR(); 6860 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6861 DECODE_PRINTF("XCHG\tEAX,EDX\n"); 6862 } else { 6863 DECODE_PRINTF("XCHG\tAX,DX\n"); 6864 } 6865 TRACE_AND_STEP(); 6866 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6867 tmp = M.x86.R_EAX; 6868 M.x86.R_EAX = M.x86.R_EDX; 6869 M.x86.R_EDX = tmp; 6870 } else { 6871 tmp = M.x86.R_AX; 6872 M.x86.R_AX = M.x86.R_DX; 6873 M.x86.R_DX = (u16)tmp; 6874 } 6875 DECODE_CLEAR_SEGOVR(); 6876 END_OF_INSTR(); 6877} 6878 6879/**************************************************************************** 6880REMARKS: 6881Handles opcode 0x93 6882****************************************************************************/ 6883static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1)) 6884{ 6885 u32 tmp; 6886 6887 START_OF_INSTR(); 6888 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6889 DECODE_PRINTF("XCHG\tEAX,EBX\n"); 6890 } else { 6891 DECODE_PRINTF("XCHG\tAX,BX\n"); 6892 } 6893 TRACE_AND_STEP(); 6894 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6895 tmp = M.x86.R_EAX; 6896 M.x86.R_EAX = M.x86.R_EBX; 6897 M.x86.R_EBX = tmp; 6898 } else { 6899 tmp = M.x86.R_AX; 6900 M.x86.R_AX = M.x86.R_BX; 6901 M.x86.R_BX = (u16)tmp; 6902 } 6903 DECODE_CLEAR_SEGOVR(); 6904 END_OF_INSTR(); 6905} 6906 6907/**************************************************************************** 6908REMARKS: 6909Handles opcode 0x94 6910****************************************************************************/ 6911static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1)) 6912{ 6913 u32 tmp; 6914 6915 START_OF_INSTR(); 6916 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6917 DECODE_PRINTF("XCHG\tEAX,ESP\n"); 6918 } else { 6919 DECODE_PRINTF("XCHG\tAX,SP\n"); 6920 } 6921 TRACE_AND_STEP(); 6922 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6923 tmp = M.x86.R_EAX; 6924 M.x86.R_EAX = M.x86.R_ESP; 6925 M.x86.R_ESP = tmp; 6926 } else { 6927 tmp = M.x86.R_AX; 6928 M.x86.R_AX = M.x86.R_SP; 6929 M.x86.R_SP = (u16)tmp; 6930 } 6931 DECODE_CLEAR_SEGOVR(); 6932 END_OF_INSTR(); 6933} 6934 6935/**************************************************************************** 6936REMARKS: 6937Handles opcode 0x95 6938****************************************************************************/ 6939static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1)) 6940{ 6941 u32 tmp; 6942 6943 START_OF_INSTR(); 6944 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6945 DECODE_PRINTF("XCHG\tEAX,EBP\n"); 6946 } else { 6947 DECODE_PRINTF("XCHG\tAX,BP\n"); 6948 } 6949 TRACE_AND_STEP(); 6950 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6951 tmp = M.x86.R_EAX; 6952 M.x86.R_EAX = M.x86.R_EBP; 6953 M.x86.R_EBP = tmp; 6954 } else { 6955 tmp = M.x86.R_AX; 6956 M.x86.R_AX = M.x86.R_BP; 6957 M.x86.R_BP = (u16)tmp; 6958 } 6959 DECODE_CLEAR_SEGOVR(); 6960 END_OF_INSTR(); 6961} 6962 6963/**************************************************************************** 6964REMARKS: 6965Handles opcode 0x96 6966****************************************************************************/ 6967static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1)) 6968{ 6969 u32 tmp; 6970 6971 START_OF_INSTR(); 6972 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6973 DECODE_PRINTF("XCHG\tEAX,ESI\n"); 6974 } else { 6975 DECODE_PRINTF("XCHG\tAX,SI\n"); 6976 } 6977 TRACE_AND_STEP(); 6978 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6979 tmp = M.x86.R_EAX; 6980 M.x86.R_EAX = M.x86.R_ESI; 6981 M.x86.R_ESI = tmp; 6982 } else { 6983 tmp = M.x86.R_AX; 6984 M.x86.R_AX = M.x86.R_SI; 6985 M.x86.R_SI = (u16)tmp; 6986 } 6987 DECODE_CLEAR_SEGOVR(); 6988 END_OF_INSTR(); 6989} 6990 6991/**************************************************************************** 6992REMARKS: 6993Handles opcode 0x97 6994****************************************************************************/ 6995static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1)) 6996{ 6997 u32 tmp; 6998 6999 START_OF_INSTR(); 7000 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7001 DECODE_PRINTF("XCHG\tEAX,EDI\n"); 7002 } else { 7003 DECODE_PRINTF("XCHG\tAX,DI\n"); 7004 } 7005 TRACE_AND_STEP(); 7006 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7007 tmp = M.x86.R_EAX; 7008 M.x86.R_EAX = M.x86.R_EDI; 7009 M.x86.R_EDI = tmp; 7010 } else { 7011 tmp = M.x86.R_AX; 7012 M.x86.R_AX = M.x86.R_DI; 7013 M.x86.R_DI = (u16)tmp; 7014 } 7015 DECODE_CLEAR_SEGOVR(); 7016 END_OF_INSTR(); 7017} 7018 7019/**************************************************************************** 7020REMARKS: 7021Handles opcode 0x98 7022****************************************************************************/ 7023static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 7024{ 7025 START_OF_INSTR(); 7026 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7027 DECODE_PRINTF("CWDE\n"); 7028 } else { 7029 DECODE_PRINTF("CBW\n"); 7030 } 7031 TRACE_AND_STEP(); 7032 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7033 if (M.x86.R_AX & 0x8000) { 7034 M.x86.R_EAX |= 0xffff0000; 7035 } else { 7036 M.x86.R_EAX &= 0x0000ffff; 7037 } 7038 } else { 7039 if (M.x86.R_AL & 0x80) { 7040 M.x86.R_AH = 0xff; 7041 } else { 7042 M.x86.R_AH = 0x0; 7043 } 7044 } 7045 DECODE_CLEAR_SEGOVR(); 7046 END_OF_INSTR(); 7047} 7048 7049/**************************************************************************** 7050REMARKS: 7051Handles opcode 0x99 7052****************************************************************************/ 7053static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 7054{ 7055 START_OF_INSTR(); 7056 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7057 DECODE_PRINTF("CDQ\n"); 7058 } else { 7059 DECODE_PRINTF("CWD\n"); 7060 } 7061 DECODE_PRINTF("CWD\n"); 7062 TRACE_AND_STEP(); 7063 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7064 if (M.x86.R_EAX & 0x80000000) { 7065 M.x86.R_EDX = 0xffffffff; 7066 } else { 7067 M.x86.R_EDX = 0x0; 7068 } 7069 } else { 7070 if (M.x86.R_AX & 0x8000) { 7071 M.x86.R_DX = 0xffff; 7072 } else { 7073 M.x86.R_DX = 0x0; 7074 } 7075 } 7076 DECODE_CLEAR_SEGOVR(); 7077 END_OF_INSTR(); 7078} 7079 7080/**************************************************************************** 7081REMARKS: 7082Handles opcode 0x9a 7083****************************************************************************/ 7084static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 7085{ 7086 u16 farseg, faroff; 7087 7088 START_OF_INSTR(); 7089 DECODE_PRINTF("CALL\t"); 7090 faroff = fetch_word_imm(); 7091 farseg = fetch_word_imm(); 7092 DECODE_PRINTF2("%04x:", farseg); 7093 DECODE_PRINTF2("%04x\n", faroff); 7094 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 7095 7096 /* XXX 7097 * 7098 * Hooked interrupt vectors calling into our "BIOS" will cause 7099 * problems unless all intersegment stuff is checked for BIOS 7100 * access. Check needed here. For moment, let it alone. 7101 */ 7102 TRACE_AND_STEP(); 7103 push_word(M.x86.R_CS); 7104 M.x86.R_CS = farseg; 7105 push_word(M.x86.R_IP); 7106 M.x86.R_IP = faroff; 7107 DECODE_CLEAR_SEGOVR(); 7108 END_OF_INSTR(); 7109} 7110 7111/**************************************************************************** 7112REMARKS: 7113Handles opcode 0x9b 7114****************************************************************************/ 7115static void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 7116{ 7117 START_OF_INSTR(); 7118 DECODE_PRINTF("WAIT"); 7119 TRACE_AND_STEP(); 7120 /* NADA. */ 7121 DECODE_CLEAR_SEGOVR(); 7122 END_OF_INSTR(); 7123} 7124 7125/**************************************************************************** 7126REMARKS: 7127Handles opcode 0x9c 7128****************************************************************************/ 7129static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 7130{ 7131 u32 flags; 7132 7133 START_OF_INSTR(); 7134 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7135 DECODE_PRINTF("PUSHFD\n"); 7136 } else { 7137 DECODE_PRINTF("PUSHF\n"); 7138 } 7139 TRACE_AND_STEP(); 7140 7141 /* clear out *all* bits not representing flags, and turn on real bits */ 7142 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 7143 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7144 push_long(flags); 7145 } else { 7146 push_word((u16)flags); 7147 } 7148 DECODE_CLEAR_SEGOVR(); 7149 END_OF_INSTR(); 7150} 7151 7152/**************************************************************************** 7153REMARKS: 7154Handles opcode 0x9d 7155****************************************************************************/ 7156static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 7157{ 7158 START_OF_INSTR(); 7159 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7160 DECODE_PRINTF("POPFD\n"); 7161 } else { 7162 DECODE_PRINTF("POPF\n"); 7163 } 7164 TRACE_AND_STEP(); 7165 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7166 M.x86.R_EFLG = pop_long(); 7167 } else { 7168 M.x86.R_FLG = pop_word(); 7169 } 7170 DECODE_CLEAR_SEGOVR(); 7171 END_OF_INSTR(); 7172} 7173 7174/**************************************************************************** 7175REMARKS: 7176Handles opcode 0x9e 7177****************************************************************************/ 7178static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 7179{ 7180 START_OF_INSTR(); 7181 DECODE_PRINTF("SAHF\n"); 7182 TRACE_AND_STEP(); 7183 /* clear the lower bits of the flag register */ 7184 M.x86.R_FLG &= 0xffffff00; 7185 /* or in the AH register into the flags register */ 7186 M.x86.R_FLG |= M.x86.R_AH; 7187 DECODE_CLEAR_SEGOVR(); 7188 END_OF_INSTR(); 7189} 7190 7191/**************************************************************************** 7192REMARKS: 7193Handles opcode 0x9f 7194****************************************************************************/ 7195static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 7196{ 7197 START_OF_INSTR(); 7198 DECODE_PRINTF("LAHF\n"); 7199 TRACE_AND_STEP(); 7200 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 7201 /*undocumented TC++ behavior??? Nope. It's documented, but 7202 you have too look real hard to notice it. */ 7203 M.x86.R_AH |= 0x2; 7204 DECODE_CLEAR_SEGOVR(); 7205 END_OF_INSTR(); 7206} 7207 7208/**************************************************************************** 7209REMARKS: 7210Handles opcode 0xa0 7211****************************************************************************/ 7212static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 7213{ 7214 u16 offset; 7215 7216 START_OF_INSTR(); 7217 DECODE_PRINTF("MOV\tAL,"); 7218 offset = fetch_word_imm(); 7219 DECODE_PRINTF2("[%04x]\n", offset); 7220 TRACE_AND_STEP(); 7221 M.x86.R_AL = fetch_data_byte(offset); 7222 DECODE_CLEAR_SEGOVR(); 7223 END_OF_INSTR(); 7224} 7225 7226/**************************************************************************** 7227REMARKS: 7228Handles opcode 0xa1 7229****************************************************************************/ 7230static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 7231{ 7232 u16 offset; 7233 7234 START_OF_INSTR(); 7235 offset = fetch_word_imm(); 7236 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7237 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 7238 } else { 7239 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 7240 } 7241 TRACE_AND_STEP(); 7242 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7243 M.x86.R_EAX = fetch_data_long(offset); 7244 } else { 7245 M.x86.R_AX = fetch_data_word(offset); 7246 } 7247 DECODE_CLEAR_SEGOVR(); 7248 END_OF_INSTR(); 7249} 7250 7251/**************************************************************************** 7252REMARKS: 7253Handles opcode 0xa2 7254****************************************************************************/ 7255static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 7256{ 7257 u16 offset; 7258 7259 START_OF_INSTR(); 7260 DECODE_PRINTF("MOV\t"); 7261 offset = fetch_word_imm(); 7262 DECODE_PRINTF2("[%04x],AL\n", offset); 7263 TRACE_AND_STEP(); 7264 store_data_byte(offset, M.x86.R_AL); 7265 DECODE_CLEAR_SEGOVR(); 7266 END_OF_INSTR(); 7267} 7268 7269/**************************************************************************** 7270REMARKS: 7271Handles opcode 0xa3 7272****************************************************************************/ 7273static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 7274{ 7275 u16 offset; 7276 7277 START_OF_INSTR(); 7278 offset = fetch_word_imm(); 7279 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7280 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 7281 } else { 7282 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 7283 } 7284 TRACE_AND_STEP(); 7285 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7286 store_data_long(offset, M.x86.R_EAX); 7287 } else { 7288 store_data_word(offset, M.x86.R_AX); 7289 } 7290 DECODE_CLEAR_SEGOVR(); 7291 END_OF_INSTR(); 7292} 7293 7294/**************************************************************************** 7295REMARKS: 7296Handles opcode 0xa4 7297****************************************************************************/ 7298static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 7299{ 7300 u8 val; 7301 u32 count; 7302 int inc; 7303 7304 START_OF_INSTR(); 7305 DECODE_PRINTF("MOVS\tBYTE\n"); 7306 if (ACCESS_FLAG(F_DF)) /* down */ 7307 inc = -1; 7308 else 7309 inc = 1; 7310 TRACE_AND_STEP(); 7311 count = 1; 7312 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7313 /* dont care whether REPE or REPNE */ 7314 /* move them until CX is ZERO. */ 7315 count = M.x86.R_CX; 7316 M.x86.R_CX = 0; 7317 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7318 } 7319 while (count--) { 7320 val = fetch_data_byte(M.x86.R_SI); 7321 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 7322 M.x86.R_SI += inc; 7323 M.x86.R_DI += inc; 7324 } 7325 DECODE_CLEAR_SEGOVR(); 7326 END_OF_INSTR(); 7327} 7328 7329/**************************************************************************** 7330REMARKS: 7331Handles opcode 0xa5 7332****************************************************************************/ 7333static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 7334{ 7335 u32 val; 7336 int inc; 7337 u32 count; 7338 7339 START_OF_INSTR(); 7340 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7341 DECODE_PRINTF("MOVS\tDWORD\n"); 7342 if (ACCESS_FLAG(F_DF)) /* down */ 7343 inc = -4; 7344 else 7345 inc = 4; 7346 } else { 7347 DECODE_PRINTF("MOVS\tWORD\n"); 7348 if (ACCESS_FLAG(F_DF)) /* down */ 7349 inc = -2; 7350 else 7351 inc = 2; 7352 } 7353 TRACE_AND_STEP(); 7354 count = 1; 7355 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7356 /* dont care whether REPE or REPNE */ 7357 /* move them until CX is ZERO. */ 7358 count = M.x86.R_CX; 7359 M.x86.R_CX = 0; 7360 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7361 } 7362 while (count--) { 7363 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7364 val = fetch_data_long(M.x86.R_SI); 7365 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 7366 } else { 7367 val = fetch_data_word(M.x86.R_SI); 7368 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 7369 } 7370 M.x86.R_SI += inc; 7371 M.x86.R_DI += inc; 7372 } 7373 DECODE_CLEAR_SEGOVR(); 7374 END_OF_INSTR(); 7375} 7376 7377/**************************************************************************** 7378REMARKS: 7379Handles opcode 0xa6 7380****************************************************************************/ 7381static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 7382{ 7383 s8 val1, val2; 7384 int inc; 7385 7386 START_OF_INSTR(); 7387 DECODE_PRINTF("CMPS\tBYTE\n"); 7388 TRACE_AND_STEP(); 7389 if (ACCESS_FLAG(F_DF)) /* down */ 7390 inc = -1; 7391 else 7392 inc = 1; 7393 7394 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7395 /* REPE */ 7396 /* move them until CX is ZERO. */ 7397 while (M.x86.R_CX != 0) { 7398 val1 = fetch_data_byte(M.x86.R_SI); 7399 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7400 cmp_byte(val1, val2); 7401 M.x86.R_CX -= 1; 7402 M.x86.R_SI += inc; 7403 M.x86.R_DI += inc; 7404 if (ACCESS_FLAG(F_ZF) == 0) 7405 break; 7406 } 7407 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7408 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7409 /* REPNE */ 7410 /* move them until CX is ZERO. */ 7411 while (M.x86.R_CX != 0) { 7412 val1 = fetch_data_byte(M.x86.R_SI); 7413 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7414 cmp_byte(val1, val2); 7415 M.x86.R_CX -= 1; 7416 M.x86.R_SI += inc; 7417 M.x86.R_DI += inc; 7418 if (ACCESS_FLAG(F_ZF)) 7419 break; /* zero flag set means equal */ 7420 } 7421 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7422 } else { 7423 val1 = fetch_data_byte(M.x86.R_SI); 7424 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7425 cmp_byte(val1, val2); 7426 M.x86.R_SI += inc; 7427 M.x86.R_DI += inc; 7428 } 7429 DECODE_CLEAR_SEGOVR(); 7430 END_OF_INSTR(); 7431} 7432 7433/**************************************************************************** 7434REMARKS: 7435Handles opcode 0xa7 7436****************************************************************************/ 7437static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 7438{ 7439 u32 val1,val2; 7440 int inc; 7441 7442 START_OF_INSTR(); 7443 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7444 DECODE_PRINTF("CMPS\tDWORD\n"); 7445 if (ACCESS_FLAG(F_DF)) /* down */ 7446 inc = -4; 7447 else 7448 inc = 4; 7449 } else { 7450 DECODE_PRINTF("CMPS\tWORD\n"); 7451 if (ACCESS_FLAG(F_DF)) /* down */ 7452 inc = -2; 7453 else 7454 inc = 2; 7455 } 7456 TRACE_AND_STEP(); 7457 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7458 /* REPE */ 7459 /* move them until CX is ZERO. */ 7460 while (M.x86.R_CX != 0) { 7461 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7462 val1 = fetch_data_long(M.x86.R_SI); 7463 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7464 cmp_long(val1, val2); 7465 } else { 7466 val1 = fetch_data_word(M.x86.R_SI); 7467 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7468 cmp_word((u16)val1, (u16)val2); 7469 } 7470 M.x86.R_CX -= 1; 7471 M.x86.R_SI += inc; 7472 M.x86.R_DI += inc; 7473 if (ACCESS_FLAG(F_ZF) == 0) 7474 break; 7475 } 7476 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7477 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7478 /* REPNE */ 7479 /* move them until CX is ZERO. */ 7480 while (M.x86.R_CX != 0) { 7481 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7482 val1 = fetch_data_long(M.x86.R_SI); 7483 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7484 cmp_long(val1, val2); 7485 } else { 7486 val1 = fetch_data_word(M.x86.R_SI); 7487 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7488 cmp_word((u16)val1, (u16)val2); 7489 } 7490 M.x86.R_CX -= 1; 7491 M.x86.R_SI += inc; 7492 M.x86.R_DI += inc; 7493 if (ACCESS_FLAG(F_ZF)) 7494 break; /* zero flag set means equal */ 7495 } 7496 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7497 } else { 7498 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7499 val1 = fetch_data_long(M.x86.R_SI); 7500 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7501 cmp_long(val1, val2); 7502 } else { 7503 val1 = fetch_data_word(M.x86.R_SI); 7504 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7505 cmp_word((u16)val1, (u16)val2); 7506 } 7507 M.x86.R_SI += inc; 7508 M.x86.R_DI += inc; 7509 } 7510 DECODE_CLEAR_SEGOVR(); 7511 END_OF_INSTR(); 7512} 7513 7514/**************************************************************************** 7515REMARKS: 7516Handles opcode 0xa8 7517****************************************************************************/ 7518static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 7519{ 7520 int imm; 7521 7522 START_OF_INSTR(); 7523 DECODE_PRINTF("TEST\tAL,"); 7524 imm = fetch_byte_imm(); 7525 DECODE_PRINTF2("%04x\n", imm); 7526 TRACE_AND_STEP(); 7527 test_byte(M.x86.R_AL, (u8)imm); 7528 DECODE_CLEAR_SEGOVR(); 7529 END_OF_INSTR(); 7530} 7531 7532/**************************************************************************** 7533REMARKS: 7534Handles opcode 0xa9 7535****************************************************************************/ 7536static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 7537{ 7538 u32 srcval; 7539 7540 START_OF_INSTR(); 7541 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7542 DECODE_PRINTF("TEST\tEAX,"); 7543 srcval = fetch_long_imm(); 7544 } else { 7545 DECODE_PRINTF("TEST\tAX,"); 7546 srcval = fetch_word_imm(); 7547 } 7548 DECODE_PRINTF2("%x\n", srcval); 7549 TRACE_AND_STEP(); 7550 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7551 test_long(M.x86.R_EAX, srcval); 7552 } else { 7553 test_word(M.x86.R_AX, (u16)srcval); 7554 } 7555 DECODE_CLEAR_SEGOVR(); 7556 END_OF_INSTR(); 7557} 7558 7559/**************************************************************************** 7560REMARKS: 7561Handles opcode 0xaa 7562****************************************************************************/ 7563static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 7564{ 7565 int inc; 7566 7567 START_OF_INSTR(); 7568 DECODE_PRINTF("STOS\tBYTE\n"); 7569 if (ACCESS_FLAG(F_DF)) /* down */ 7570 inc = -1; 7571 else 7572 inc = 1; 7573 TRACE_AND_STEP(); 7574 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7575 /* dont care whether REPE or REPNE */ 7576 /* move them until CX is ZERO. */ 7577 while (M.x86.R_CX != 0) { 7578 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7579 M.x86.R_CX -= 1; 7580 M.x86.R_DI += inc; 7581 } 7582 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7583 } else { 7584 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7585 M.x86.R_DI += inc; 7586 } 7587 DECODE_CLEAR_SEGOVR(); 7588 END_OF_INSTR(); 7589} 7590 7591/**************************************************************************** 7592REMARKS: 7593Handles opcode 0xab 7594****************************************************************************/ 7595static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 7596{ 7597 int inc; 7598 u32 count; 7599 7600 START_OF_INSTR(); 7601 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7602 DECODE_PRINTF("STOS\tDWORD\n"); 7603 if (ACCESS_FLAG(F_DF)) /* down */ 7604 inc = -4; 7605 else 7606 inc = 4; 7607 } else { 7608 DECODE_PRINTF("STOS\tWORD\n"); 7609 if (ACCESS_FLAG(F_DF)) /* down */ 7610 inc = -2; 7611 else 7612 inc = 2; 7613 } 7614 TRACE_AND_STEP(); 7615 count = 1; 7616 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7617 /* dont care whether REPE or REPNE */ 7618 /* move them until CX is ZERO. */ 7619 count = M.x86.R_CX; 7620 M.x86.R_CX = 0; 7621 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7622 } 7623 while (count--) { 7624 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7625 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 7626 } else { 7627 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 7628 } 7629 M.x86.R_DI += inc; 7630 } 7631 DECODE_CLEAR_SEGOVR(); 7632 END_OF_INSTR(); 7633} 7634 7635/**************************************************************************** 7636REMARKS: 7637Handles opcode 0xac 7638****************************************************************************/ 7639static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 7640{ 7641 int inc; 7642 7643 START_OF_INSTR(); 7644 DECODE_PRINTF("LODS\tBYTE\n"); 7645 TRACE_AND_STEP(); 7646 if (ACCESS_FLAG(F_DF)) /* down */ 7647 inc = -1; 7648 else 7649 inc = 1; 7650 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7651 /* dont care whether REPE or REPNE */ 7652 /* move them until CX is ZERO. */ 7653 while (M.x86.R_CX != 0) { 7654 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7655 M.x86.R_CX -= 1; 7656 M.x86.R_SI += inc; 7657 } 7658 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7659 } else { 7660 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7661 M.x86.R_SI += inc; 7662 } 7663 DECODE_CLEAR_SEGOVR(); 7664 END_OF_INSTR(); 7665} 7666 7667/**************************************************************************** 7668REMARKS: 7669Handles opcode 0xad 7670****************************************************************************/ 7671static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 7672{ 7673 int inc; 7674 u32 count; 7675 7676 START_OF_INSTR(); 7677 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7678 DECODE_PRINTF("LODS\tDWORD\n"); 7679 if (ACCESS_FLAG(F_DF)) /* down */ 7680 inc = -4; 7681 else 7682 inc = 4; 7683 } else { 7684 DECODE_PRINTF("LODS\tWORD\n"); 7685 if (ACCESS_FLAG(F_DF)) /* down */ 7686 inc = -2; 7687 else 7688 inc = 2; 7689 } 7690 TRACE_AND_STEP(); 7691 count = 1; 7692 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7693 /* dont care whether REPE or REPNE */ 7694 /* move them until CX is ZERO. */ 7695 count = M.x86.R_CX; 7696 M.x86.R_CX = 0; 7697 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7698 } 7699 while (count--) { 7700 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7701 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 7702 } else { 7703 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 7704 } 7705 M.x86.R_SI += inc; 7706 } 7707 DECODE_CLEAR_SEGOVR(); 7708 END_OF_INSTR(); 7709} 7710 7711/**************************************************************************** 7712REMARKS: 7713Handles opcode 0xae 7714****************************************************************************/ 7715static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 7716{ 7717 s8 val2; 7718 int inc; 7719 7720 START_OF_INSTR(); 7721 DECODE_PRINTF("SCAS\tBYTE\n"); 7722 TRACE_AND_STEP(); 7723 if (ACCESS_FLAG(F_DF)) /* down */ 7724 inc = -1; 7725 else 7726 inc = 1; 7727 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7728 /* REPE */ 7729 /* move them until CX is ZERO. */ 7730 while (M.x86.R_CX != 0) { 7731 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7732 cmp_byte(M.x86.R_AL, val2); 7733 M.x86.R_CX -= 1; 7734 M.x86.R_DI += inc; 7735 if (ACCESS_FLAG(F_ZF) == 0) 7736 break; 7737 } 7738 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7739 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7740 /* REPNE */ 7741 /* move them until CX is ZERO. */ 7742 while (M.x86.R_CX != 0) { 7743 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7744 cmp_byte(M.x86.R_AL, val2); 7745 M.x86.R_CX -= 1; 7746 M.x86.R_DI += inc; 7747 if (ACCESS_FLAG(F_ZF)) 7748 break; /* zero flag set means equal */ 7749 } 7750 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7751 } else { 7752 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7753 cmp_byte(M.x86.R_AL, val2); 7754 M.x86.R_DI += inc; 7755 } 7756 DECODE_CLEAR_SEGOVR(); 7757 END_OF_INSTR(); 7758} 7759 7760/**************************************************************************** 7761REMARKS: 7762Handles opcode 0xaf 7763****************************************************************************/ 7764static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 7765{ 7766 int inc; 7767 u32 val; 7768 7769 START_OF_INSTR(); 7770 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7771 DECODE_PRINTF("SCAS\tDWORD\n"); 7772 if (ACCESS_FLAG(F_DF)) /* down */ 7773 inc = -4; 7774 else 7775 inc = 4; 7776 } else { 7777 DECODE_PRINTF("SCAS\tWORD\n"); 7778 if (ACCESS_FLAG(F_DF)) /* down */ 7779 inc = -2; 7780 else 7781 inc = 2; 7782 } 7783 TRACE_AND_STEP(); 7784 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7785 /* REPE */ 7786 /* move them until CX is ZERO. */ 7787 while (M.x86.R_CX != 0) { 7788 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7789 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7790 cmp_long(M.x86.R_EAX, val); 7791 } else { 7792 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7793 cmp_word(M.x86.R_AX, (u16)val); 7794 } 7795 M.x86.R_CX -= 1; 7796 M.x86.R_DI += inc; 7797 if (ACCESS_FLAG(F_ZF) == 0) 7798 break; 7799 } 7800 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7801 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7802 /* REPNE */ 7803 /* move them until CX is ZERO. */ 7804 while (M.x86.R_CX != 0) { 7805 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7806 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7807 cmp_long(M.x86.R_EAX, val); 7808 } else { 7809 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7810 cmp_word(M.x86.R_AX, (u16)val); 7811 } 7812 M.x86.R_CX -= 1; 7813 M.x86.R_DI += inc; 7814 if (ACCESS_FLAG(F_ZF)) 7815 break; /* zero flag set means equal */ 7816 } 7817 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7818 } else { 7819 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7820 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7821 cmp_long(M.x86.R_EAX, val); 7822 } else { 7823 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7824 cmp_word(M.x86.R_AX, (u16)val); 7825 } 7826 M.x86.R_DI += inc; 7827 } 7828 DECODE_CLEAR_SEGOVR(); 7829 END_OF_INSTR(); 7830} 7831 7832/**************************************************************************** 7833REMARKS: 7834Handles opcode 0xb0 7835****************************************************************************/ 7836static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 7837{ 7838 u8 imm; 7839 7840 START_OF_INSTR(); 7841 DECODE_PRINTF("MOV\tAL,"); 7842 imm = fetch_byte_imm(); 7843 DECODE_PRINTF2("%x\n", imm); 7844 TRACE_AND_STEP(); 7845 M.x86.R_AL = imm; 7846 DECODE_CLEAR_SEGOVR(); 7847 END_OF_INSTR(); 7848} 7849 7850/**************************************************************************** 7851REMARKS: 7852Handles opcode 0xb1 7853****************************************************************************/ 7854static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) 7855{ 7856 u8 imm; 7857 7858 START_OF_INSTR(); 7859 DECODE_PRINTF("MOV\tCL,"); 7860 imm = fetch_byte_imm(); 7861 DECODE_PRINTF2("%x\n", imm); 7862 TRACE_AND_STEP(); 7863 M.x86.R_CL = imm; 7864 DECODE_CLEAR_SEGOVR(); 7865 END_OF_INSTR(); 7866} 7867 7868/**************************************************************************** 7869REMARKS: 7870Handles opcode 0xb2 7871****************************************************************************/ 7872static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) 7873{ 7874 u8 imm; 7875 7876 START_OF_INSTR(); 7877 DECODE_PRINTF("MOV\tDL,"); 7878 imm = fetch_byte_imm(); 7879 DECODE_PRINTF2("%x\n", imm); 7880 TRACE_AND_STEP(); 7881 M.x86.R_DL = imm; 7882 DECODE_CLEAR_SEGOVR(); 7883 END_OF_INSTR(); 7884} 7885 7886/**************************************************************************** 7887REMARKS: 7888Handles opcode 0xb3 7889****************************************************************************/ 7890static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) 7891{ 7892 u8 imm; 7893 7894 START_OF_INSTR(); 7895 DECODE_PRINTF("MOV\tBL,"); 7896 imm = fetch_byte_imm(); 7897 DECODE_PRINTF2("%x\n", imm); 7898 TRACE_AND_STEP(); 7899 M.x86.R_BL = imm; 7900 DECODE_CLEAR_SEGOVR(); 7901 END_OF_INSTR(); 7902} 7903 7904/**************************************************************************** 7905REMARKS: 7906Handles opcode 0xb4 7907****************************************************************************/ 7908static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) 7909{ 7910 u8 imm; 7911 7912 START_OF_INSTR(); 7913 DECODE_PRINTF("MOV\tAH,"); 7914 imm = fetch_byte_imm(); 7915 DECODE_PRINTF2("%x\n", imm); 7916 TRACE_AND_STEP(); 7917 M.x86.R_AH = imm; 7918 DECODE_CLEAR_SEGOVR(); 7919 END_OF_INSTR(); 7920} 7921 7922/**************************************************************************** 7923REMARKS: 7924Handles opcode 0xb5 7925****************************************************************************/ 7926static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) 7927{ 7928 u8 imm; 7929 7930 START_OF_INSTR(); 7931 DECODE_PRINTF("MOV\tCH,"); 7932 imm = fetch_byte_imm(); 7933 DECODE_PRINTF2("%x\n", imm); 7934 TRACE_AND_STEP(); 7935 M.x86.R_CH = imm; 7936 DECODE_CLEAR_SEGOVR(); 7937 END_OF_INSTR(); 7938} 7939 7940/**************************************************************************** 7941REMARKS: 7942Handles opcode 0xb6 7943****************************************************************************/ 7944static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) 7945{ 7946 u8 imm; 7947 7948 START_OF_INSTR(); 7949 DECODE_PRINTF("MOV\tDH,"); 7950 imm = fetch_byte_imm(); 7951 DECODE_PRINTF2("%x\n", imm); 7952 TRACE_AND_STEP(); 7953 M.x86.R_DH = imm; 7954 DECODE_CLEAR_SEGOVR(); 7955 END_OF_INSTR(); 7956} 7957 7958/**************************************************************************** 7959REMARKS: 7960Handles opcode 0xb7 7961****************************************************************************/ 7962static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) 7963{ 7964 u8 imm; 7965 7966 START_OF_INSTR(); 7967 DECODE_PRINTF("MOV\tBH,"); 7968 imm = fetch_byte_imm(); 7969 DECODE_PRINTF2("%x\n", imm); 7970 TRACE_AND_STEP(); 7971 M.x86.R_BH = imm; 7972 DECODE_CLEAR_SEGOVR(); 7973 END_OF_INSTR(); 7974} 7975 7976/**************************************************************************** 7977REMARKS: 7978Handles opcode 0xb8 7979****************************************************************************/ 7980static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 7981{ 7982 u32 srcval; 7983 7984 START_OF_INSTR(); 7985 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7986 DECODE_PRINTF("MOV\tEAX,"); 7987 srcval = fetch_long_imm(); 7988 } else { 7989 DECODE_PRINTF("MOV\tAX,"); 7990 srcval = fetch_word_imm(); 7991 } 7992 DECODE_PRINTF2("%x\n", srcval); 7993 TRACE_AND_STEP(); 7994 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7995 M.x86.R_EAX = srcval; 7996 } else { 7997 M.x86.R_AX = (u16)srcval; 7998 } 7999 DECODE_CLEAR_SEGOVR(); 8000 END_OF_INSTR(); 8001} 8002 8003/**************************************************************************** 8004REMARKS: 8005Handles opcode 0xb9 8006****************************************************************************/ 8007static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) 8008{ 8009 u32 srcval; 8010 8011 START_OF_INSTR(); 8012 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8013 DECODE_PRINTF("MOV\tECX,"); 8014 srcval = fetch_long_imm(); 8015 } else { 8016 DECODE_PRINTF("MOV\tCX,"); 8017 srcval = fetch_word_imm(); 8018 } 8019 DECODE_PRINTF2("%x\n", srcval); 8020 TRACE_AND_STEP(); 8021 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8022 M.x86.R_ECX = srcval; 8023 } else { 8024 M.x86.R_CX = (u16)srcval; 8025 } 8026 DECODE_CLEAR_SEGOVR(); 8027 END_OF_INSTR(); 8028} 8029 8030/**************************************************************************** 8031REMARKS: 8032Handles opcode 0xba 8033****************************************************************************/ 8034static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) 8035{ 8036 u32 srcval; 8037 8038 START_OF_INSTR(); 8039 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8040 DECODE_PRINTF("MOV\tEDX,"); 8041 srcval = fetch_long_imm(); 8042 } else { 8043 DECODE_PRINTF("MOV\tDX,"); 8044 srcval = fetch_word_imm(); 8045 } 8046 DECODE_PRINTF2("%x\n", srcval); 8047 TRACE_AND_STEP(); 8048 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8049 M.x86.R_EDX = srcval; 8050 } else { 8051 M.x86.R_DX = (u16)srcval; 8052 } 8053 DECODE_CLEAR_SEGOVR(); 8054 END_OF_INSTR(); 8055} 8056 8057/**************************************************************************** 8058REMARKS: 8059Handles opcode 0xbb 8060****************************************************************************/ 8061static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) 8062{ 8063 u32 srcval; 8064 8065 START_OF_INSTR(); 8066 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8067 DECODE_PRINTF("MOV\tEBX,"); 8068 srcval = fetch_long_imm(); 8069 } else { 8070 DECODE_PRINTF("MOV\tBX,"); 8071 srcval = fetch_word_imm(); 8072 } 8073 DECODE_PRINTF2("%x\n", srcval); 8074 TRACE_AND_STEP(); 8075 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8076 M.x86.R_EBX = srcval; 8077 } else { 8078 M.x86.R_BX = (u16)srcval; 8079 } 8080 DECODE_CLEAR_SEGOVR(); 8081 END_OF_INSTR(); 8082} 8083 8084/**************************************************************************** 8085REMARKS: 8086Handles opcode 0xbc 8087****************************************************************************/ 8088static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) 8089{ 8090 u32 srcval; 8091 8092 START_OF_INSTR(); 8093 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8094 DECODE_PRINTF("MOV\tESP,"); 8095 srcval = fetch_long_imm(); 8096 } else { 8097 DECODE_PRINTF("MOV\tSP,"); 8098 srcval = fetch_word_imm(); 8099 } 8100 DECODE_PRINTF2("%x\n", srcval); 8101 TRACE_AND_STEP(); 8102 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8103 M.x86.R_ESP = srcval; 8104 } else { 8105 M.x86.R_SP = (u16)srcval; 8106 } 8107 DECODE_CLEAR_SEGOVR(); 8108 END_OF_INSTR(); 8109} 8110 8111/**************************************************************************** 8112REMARKS: 8113Handles opcode 0xbd 8114****************************************************************************/ 8115static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) 8116{ 8117 u32 srcval; 8118 8119 START_OF_INSTR(); 8120 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8121 DECODE_PRINTF("MOV\tEBP,"); 8122 srcval = fetch_long_imm(); 8123 } else { 8124 DECODE_PRINTF("MOV\tBP,"); 8125 srcval = fetch_word_imm(); 8126 } 8127 DECODE_PRINTF2("%x\n", srcval); 8128 TRACE_AND_STEP(); 8129 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8130 M.x86.R_EBP = srcval; 8131 } else { 8132 M.x86.R_BP = (u16)srcval; 8133 } 8134 DECODE_CLEAR_SEGOVR(); 8135 END_OF_INSTR(); 8136} 8137 8138/**************************************************************************** 8139REMARKS: 8140Handles opcode 0xbe 8141****************************************************************************/ 8142static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) 8143{ 8144 u32 srcval; 8145 8146 START_OF_INSTR(); 8147 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8148 DECODE_PRINTF("MOV\tESI,"); 8149 srcval = fetch_long_imm(); 8150 } else { 8151 DECODE_PRINTF("MOV\tSI,"); 8152 srcval = fetch_word_imm(); 8153 } 8154 DECODE_PRINTF2("%x\n", srcval); 8155 TRACE_AND_STEP(); 8156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8157 M.x86.R_ESI = srcval; 8158 } else { 8159 M.x86.R_SI = (u16)srcval; 8160 } 8161 DECODE_CLEAR_SEGOVR(); 8162 END_OF_INSTR(); 8163} 8164 8165/**************************************************************************** 8166REMARKS: 8167Handles opcode 0xbf 8168****************************************************************************/ 8169static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) 8170{ 8171 u32 srcval; 8172 8173 START_OF_INSTR(); 8174 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8175 DECODE_PRINTF("MOV\tEDI,"); 8176 srcval = fetch_long_imm(); 8177 } else { 8178 DECODE_PRINTF("MOV\tDI,"); 8179 srcval = fetch_word_imm(); 8180 } 8181 DECODE_PRINTF2("%x\n", srcval); 8182 TRACE_AND_STEP(); 8183 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8184 M.x86.R_EDI = srcval; 8185 } else { 8186 M.x86.R_DI = (u16)srcval; 8187 } 8188 DECODE_CLEAR_SEGOVR(); 8189 END_OF_INSTR(); 8190} 8191 8192/* used by opcodes c0, d0, and d2. */ 8193static u8(*opcD0_byte_operation[])(u8 d, u8 s) = 8194{ 8195 rol_byte, 8196 ror_byte, 8197 rcl_byte, 8198 rcr_byte, 8199 shl_byte, 8200 shr_byte, 8201 shl_byte, /* sal_byte === shl_byte by definition */ 8202 sar_byte, 8203}; 8204 8205/**************************************************************************** 8206REMARKS: 8207Handles opcode 0xc0 8208****************************************************************************/ 8209static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 8210{ 8211 int mod, rl, rh; 8212 u8 *destreg; 8213 uint destoffset; 8214 u8 destval; 8215 u8 amt; 8216 8217 /* 8218 * Yet another weirdo special case instruction format. Part of 8219 * the opcode held below in "RH". Doubly nested case would 8220 * result, except that the decoded instruction 8221 */ 8222 START_OF_INSTR(); 8223 FETCH_DECODE_MODRM(mod, rh, rl); 8224#ifdef DEBUG 8225 if (DEBUG_DECODE()) { 8226 /* XXX DECODE_PRINTF may be changed to something more 8227 general, so that it is important to leave the strings 8228 in the same format, even though the result is that the 8229 above test is done twice. */ 8230 8231 switch (rh) { 8232 case 0: 8233 DECODE_PRINTF("ROL\t"); 8234 break; 8235 case 1: 8236 DECODE_PRINTF("ROR\t"); 8237 break; 8238 case 2: 8239 DECODE_PRINTF("RCL\t"); 8240 break; 8241 case 3: 8242 DECODE_PRINTF("RCR\t"); 8243 break; 8244 case 4: 8245 DECODE_PRINTF("SHL\t"); 8246 break; 8247 case 5: 8248 DECODE_PRINTF("SHR\t"); 8249 break; 8250 case 6: 8251 DECODE_PRINTF("SAL\t"); 8252 break; 8253 case 7: 8254 DECODE_PRINTF("SAR\t"); 8255 break; 8256 } 8257 } 8258#endif 8259 /* know operation, decode the mod byte to find the addressing 8260 mode. */ 8261 switch (mod) { 8262 case 0: 8263 DECODE_PRINTF("BYTE PTR "); 8264 destoffset = decode_rm00_address(rl); 8265 amt = fetch_byte_imm(); 8266 DECODE_PRINTF2(",%x\n", amt); 8267 destval = fetch_data_byte(destoffset); 8268 TRACE_AND_STEP(); 8269 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8270 store_data_byte(destoffset, destval); 8271 break; 8272 case 1: 8273 DECODE_PRINTF("BYTE PTR "); 8274 destoffset = decode_rm01_address(rl); 8275 amt = fetch_byte_imm(); 8276 DECODE_PRINTF2(",%x\n", amt); 8277 destval = fetch_data_byte(destoffset); 8278 TRACE_AND_STEP(); 8279 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8280 store_data_byte(destoffset, destval); 8281 break; 8282 case 2: 8283 DECODE_PRINTF("BYTE PTR "); 8284 destoffset = decode_rm10_address(rl); 8285 amt = fetch_byte_imm(); 8286 DECODE_PRINTF2(",%x\n", amt); 8287 destval = fetch_data_byte(destoffset); 8288 TRACE_AND_STEP(); 8289 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8290 store_data_byte(destoffset, destval); 8291 break; 8292 case 3: /* register to register */ 8293 destreg = DECODE_RM_BYTE_REGISTER(rl); 8294 amt = fetch_byte_imm(); 8295 DECODE_PRINTF2(",%x\n", amt); 8296 TRACE_AND_STEP(); 8297 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 8298 *destreg = destval; 8299 break; 8300 } 8301 DECODE_CLEAR_SEGOVR(); 8302 END_OF_INSTR(); 8303} 8304 8305/* used by opcodes c1, d1, and d3. */ 8306static u16(*opcD1_word_operation[])(u16 s, u8 d) = 8307{ 8308 rol_word, 8309 ror_word, 8310 rcl_word, 8311 rcr_word, 8312 shl_word, 8313 shr_word, 8314 shl_word, /* sal_byte === shl_byte by definition */ 8315 sar_word, 8316}; 8317 8318/* used by opcodes c1, d1, and d3. */ 8319static u32 (*opcD1_long_operation[])(u32 s, u8 d) = 8320{ 8321 rol_long, 8322 ror_long, 8323 rcl_long, 8324 rcr_long, 8325 shl_long, 8326 shr_long, 8327 shl_long, /* sal_byte === shl_byte by definition */ 8328 sar_long, 8329}; 8330 8331/**************************************************************************** 8332REMARKS: 8333Handles opcode 0xc1 8334****************************************************************************/ 8335static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 8336{ 8337 int mod, rl, rh; 8338 uint destoffset; 8339 u8 amt; 8340 8341 /* 8342 * Yet another weirdo special case instruction format. Part of 8343 * the opcode held below in "RH". Doubly nested case would 8344 * result, except that the decoded instruction 8345 */ 8346 START_OF_INSTR(); 8347 FETCH_DECODE_MODRM(mod, rh, rl); 8348#ifdef DEBUG 8349 if (DEBUG_DECODE()) { 8350 /* XXX DECODE_PRINTF may be changed to something more 8351 general, so that it is important to leave the strings 8352 in the same format, even though the result is that the 8353 above test is done twice. */ 8354 8355 switch (rh) { 8356 case 0: 8357 DECODE_PRINTF("ROL\t"); 8358 break; 8359 case 1: 8360 DECODE_PRINTF("ROR\t"); 8361 break; 8362 case 2: 8363 DECODE_PRINTF("RCL\t"); 8364 break; 8365 case 3: 8366 DECODE_PRINTF("RCR\t"); 8367 break; 8368 case 4: 8369 DECODE_PRINTF("SHL\t"); 8370 break; 8371 case 5: 8372 DECODE_PRINTF("SHR\t"); 8373 break; 8374 case 6: 8375 DECODE_PRINTF("SAL\t"); 8376 break; 8377 case 7: 8378 DECODE_PRINTF("SAR\t"); 8379 break; 8380 } 8381 } 8382#endif 8383 /* know operation, decode the mod byte to find the addressing 8384 mode. */ 8385 switch (mod) { 8386 case 0: 8387 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8388 u32 destval; 8389 8390 DECODE_PRINTF("DWORD PTR "); 8391 destoffset = decode_rm00_address(rl); 8392 amt = fetch_byte_imm(); 8393 DECODE_PRINTF2(",%x\n", amt); 8394 destval = fetch_data_long(destoffset); 8395 TRACE_AND_STEP(); 8396 destval = (*opcD1_long_operation[rh]) (destval, amt); 8397 store_data_long(destoffset, destval); 8398 } else { 8399 u16 destval; 8400 8401 DECODE_PRINTF("WORD PTR "); 8402 destoffset = decode_rm00_address(rl); 8403 amt = fetch_byte_imm(); 8404 DECODE_PRINTF2(",%x\n", amt); 8405 destval = fetch_data_word(destoffset); 8406 TRACE_AND_STEP(); 8407 destval = (*opcD1_word_operation[rh]) (destval, amt); 8408 store_data_word(destoffset, destval); 8409 } 8410 break; 8411 case 1: 8412 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8413 u32 destval; 8414 8415 DECODE_PRINTF("DWORD PTR "); 8416 destoffset = decode_rm01_address(rl); 8417 amt = fetch_byte_imm(); 8418 DECODE_PRINTF2(",%x\n", amt); 8419 destval = fetch_data_long(destoffset); 8420 TRACE_AND_STEP(); 8421 destval = (*opcD1_long_operation[rh]) (destval, amt); 8422 store_data_long(destoffset, destval); 8423 } else { 8424 u16 destval; 8425 8426 DECODE_PRINTF("WORD PTR "); 8427 destoffset = decode_rm01_address(rl); 8428 amt = fetch_byte_imm(); 8429 DECODE_PRINTF2(",%x\n", amt); 8430 destval = fetch_data_word(destoffset); 8431 TRACE_AND_STEP(); 8432 destval = (*opcD1_word_operation[rh]) (destval, amt); 8433 store_data_word(destoffset, destval); 8434 } 8435 break; 8436 case 2: 8437 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8438 u32 destval; 8439 8440 DECODE_PRINTF("DWORD PTR "); 8441 destoffset = decode_rm10_address(rl); 8442 amt = fetch_byte_imm(); 8443 DECODE_PRINTF2(",%x\n", amt); 8444 destval = fetch_data_long(destoffset); 8445 TRACE_AND_STEP(); 8446 destval = (*opcD1_long_operation[rh]) (destval, amt); 8447 store_data_long(destoffset, destval); 8448 } else { 8449 u16 destval; 8450 8451 DECODE_PRINTF("WORD PTR "); 8452 destoffset = decode_rm10_address(rl); 8453 amt = fetch_byte_imm(); 8454 DECODE_PRINTF2(",%x\n", amt); 8455 destval = fetch_data_word(destoffset); 8456 TRACE_AND_STEP(); 8457 destval = (*opcD1_word_operation[rh]) (destval, amt); 8458 store_data_word(destoffset, destval); 8459 } 8460 break; 8461 case 3: /* register to register */ 8462 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8463 u32 *destreg; 8464 8465 destreg = DECODE_RM_LONG_REGISTER(rl); 8466 amt = fetch_byte_imm(); 8467 DECODE_PRINTF2(",%x\n", amt); 8468 TRACE_AND_STEP(); 8469 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 8470 } else { 8471 u16 *destreg; 8472 8473 destreg = DECODE_RM_WORD_REGISTER(rl); 8474 amt = fetch_byte_imm(); 8475 DECODE_PRINTF2(",%x\n", amt); 8476 TRACE_AND_STEP(); 8477 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 8478 } 8479 break; 8480 } 8481 DECODE_CLEAR_SEGOVR(); 8482 END_OF_INSTR(); 8483} 8484 8485/**************************************************************************** 8486REMARKS: 8487Handles opcode 0xc2 8488****************************************************************************/ 8489static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 8490{ 8491 u16 imm; 8492 8493 START_OF_INSTR(); 8494 DECODE_PRINTF("RET\t"); 8495 imm = fetch_word_imm(); 8496 DECODE_PRINTF2("%x\n", imm); 8497 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8498 TRACE_AND_STEP(); 8499 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8500 M.x86.R_IP = pop_long(); 8501 } else { 8502 M.x86.R_IP = pop_word(); 8503 } 8504 M.x86.R_SP += imm; 8505 DECODE_CLEAR_SEGOVR(); 8506 END_OF_INSTR(); 8507} 8508 8509/**************************************************************************** 8510REMARKS: 8511Handles opcode 0xc3 8512****************************************************************************/ 8513static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 8514{ 8515 START_OF_INSTR(); 8516 DECODE_PRINTF("RET\n"); 8517 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8518 TRACE_AND_STEP(); 8519 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8520 M.x86.R_IP = pop_long(); 8521 } else { 8522 M.x86.R_IP = pop_word(); 8523 } 8524 DECODE_CLEAR_SEGOVR(); 8525 END_OF_INSTR(); 8526} 8527 8528/**************************************************************************** 8529REMARKS: 8530Handles opcode 0xc4 8531****************************************************************************/ 8532static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 8533{ 8534 int mod, rh, rl; 8535 u16 *dstreg; 8536 uint srcoffset; 8537 8538 START_OF_INSTR(); 8539 DECODE_PRINTF("LES\t"); 8540 FETCH_DECODE_MODRM(mod, rh, rl); 8541 switch (mod) { 8542 case 0: 8543 dstreg = DECODE_RM_WORD_REGISTER(rh); 8544 DECODE_PRINTF(","); 8545 srcoffset = decode_rm00_address(rl); 8546 DECODE_PRINTF("\n"); 8547 TRACE_AND_STEP(); 8548 *dstreg = fetch_data_word(srcoffset); 8549 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8550 break; 8551 case 1: 8552 dstreg = DECODE_RM_WORD_REGISTER(rh); 8553 DECODE_PRINTF(","); 8554 srcoffset = decode_rm01_address(rl); 8555 DECODE_PRINTF("\n"); 8556 TRACE_AND_STEP(); 8557 *dstreg = fetch_data_word(srcoffset); 8558 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8559 break; 8560 case 2: 8561 dstreg = DECODE_RM_WORD_REGISTER(rh); 8562 DECODE_PRINTF(","); 8563 srcoffset = decode_rm10_address(rl); 8564 DECODE_PRINTF("\n"); 8565 TRACE_AND_STEP(); 8566 *dstreg = fetch_data_word(srcoffset); 8567 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8568 break; 8569 case 3: /* register to register */ 8570 /* UNDEFINED! */ 8571 TRACE_AND_STEP(); 8572 } 8573 DECODE_CLEAR_SEGOVR(); 8574 END_OF_INSTR(); 8575} 8576 8577/**************************************************************************** 8578REMARKS: 8579Handles opcode 0xc5 8580****************************************************************************/ 8581static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 8582{ 8583 int mod, rh, rl; 8584 u16 *dstreg; 8585 uint srcoffset; 8586 8587 START_OF_INSTR(); 8588 DECODE_PRINTF("LDS\t"); 8589 FETCH_DECODE_MODRM(mod, rh, rl); 8590 switch (mod) { 8591 case 0: 8592 dstreg = DECODE_RM_WORD_REGISTER(rh); 8593 DECODE_PRINTF(","); 8594 srcoffset = decode_rm00_address(rl); 8595 DECODE_PRINTF("\n"); 8596 TRACE_AND_STEP(); 8597 *dstreg = fetch_data_word(srcoffset); 8598 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8599 break; 8600 case 1: 8601 dstreg = DECODE_RM_WORD_REGISTER(rh); 8602 DECODE_PRINTF(","); 8603 srcoffset = decode_rm01_address(rl); 8604 DECODE_PRINTF("\n"); 8605 TRACE_AND_STEP(); 8606 *dstreg = fetch_data_word(srcoffset); 8607 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8608 break; 8609 case 2: 8610 dstreg = DECODE_RM_WORD_REGISTER(rh); 8611 DECODE_PRINTF(","); 8612 srcoffset = decode_rm10_address(rl); 8613 DECODE_PRINTF("\n"); 8614 TRACE_AND_STEP(); 8615 *dstreg = fetch_data_word(srcoffset); 8616 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8617 break; 8618 case 3: /* register to register */ 8619 /* UNDEFINED! */ 8620 TRACE_AND_STEP(); 8621 } 8622 DECODE_CLEAR_SEGOVR(); 8623 END_OF_INSTR(); 8624} 8625 8626/**************************************************************************** 8627REMARKS: 8628Handles opcode 0xc6 8629****************************************************************************/ 8630static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 8631{ 8632 int mod, rl, rh; 8633 u8 *destreg; 8634 uint destoffset; 8635 u8 imm; 8636 8637 START_OF_INSTR(); 8638 DECODE_PRINTF("MOV\t"); 8639 FETCH_DECODE_MODRM(mod, rh, rl); 8640 if (rh != 0) { 8641 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 8642 HALT_SYS(); 8643 } 8644 switch (mod) { 8645 case 0: 8646 DECODE_PRINTF("BYTE PTR "); 8647 destoffset = decode_rm00_address(rl); 8648 imm = fetch_byte_imm(); 8649 DECODE_PRINTF2(",%2x\n", imm); 8650 TRACE_AND_STEP(); 8651 store_data_byte(destoffset, imm); 8652 break; 8653 case 1: 8654 DECODE_PRINTF("BYTE PTR "); 8655 destoffset = decode_rm01_address(rl); 8656 imm = fetch_byte_imm(); 8657 DECODE_PRINTF2(",%2x\n", imm); 8658 TRACE_AND_STEP(); 8659 store_data_byte(destoffset, imm); 8660 break; 8661 case 2: 8662 DECODE_PRINTF("BYTE PTR "); 8663 destoffset = decode_rm10_address(rl); 8664 imm = fetch_byte_imm(); 8665 DECODE_PRINTF2(",%2x\n", imm); 8666 TRACE_AND_STEP(); 8667 store_data_byte(destoffset, imm); 8668 break; 8669 case 3: /* register to register */ 8670 destreg = DECODE_RM_BYTE_REGISTER(rl); 8671 imm = fetch_byte_imm(); 8672 DECODE_PRINTF2(",%2x\n", imm); 8673 TRACE_AND_STEP(); 8674 *destreg = imm; 8675 break; 8676 } 8677 DECODE_CLEAR_SEGOVR(); 8678 END_OF_INSTR(); 8679} 8680 8681/**************************************************************************** 8682REMARKS: 8683Handles opcode 0xc7 8684****************************************************************************/ 8685static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 8686{ 8687 int mod, rl, rh; 8688 uint destoffset; 8689 8690 START_OF_INSTR(); 8691 DECODE_PRINTF("MOV\t"); 8692 FETCH_DECODE_MODRM(mod, rh, rl); 8693 if (rh != 0) { 8694 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 8695 HALT_SYS(); 8696 } 8697 switch (mod) { 8698 case 0: 8699 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8700 u32 imm; 8701 8702 DECODE_PRINTF("DWORD PTR "); 8703 destoffset = decode_rm00_address(rl); 8704 imm = fetch_long_imm(); 8705 DECODE_PRINTF2(",%x\n", imm); 8706 TRACE_AND_STEP(); 8707 store_data_long(destoffset, imm); 8708 } else { 8709 u16 imm; 8710 8711 DECODE_PRINTF("WORD PTR "); 8712 destoffset = decode_rm00_address(rl); 8713 imm = fetch_word_imm(); 8714 DECODE_PRINTF2(",%x\n", imm); 8715 TRACE_AND_STEP(); 8716 store_data_word(destoffset, imm); 8717 } 8718 break; 8719 case 1: 8720 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8721 u32 imm; 8722 8723 DECODE_PRINTF("DWORD PTR "); 8724 destoffset = decode_rm01_address(rl); 8725 imm = fetch_long_imm(); 8726 DECODE_PRINTF2(",%x\n", imm); 8727 TRACE_AND_STEP(); 8728 store_data_long(destoffset, imm); 8729 } else { 8730 u16 imm; 8731 8732 DECODE_PRINTF("WORD PTR "); 8733 destoffset = decode_rm01_address(rl); 8734 imm = fetch_word_imm(); 8735 DECODE_PRINTF2(",%x\n", imm); 8736 TRACE_AND_STEP(); 8737 store_data_word(destoffset, imm); 8738 } 8739 break; 8740 case 2: 8741 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8742 u32 imm; 8743 8744 DECODE_PRINTF("DWORD PTR "); 8745 destoffset = decode_rm10_address(rl); 8746 imm = fetch_long_imm(); 8747 DECODE_PRINTF2(",%x\n", imm); 8748 TRACE_AND_STEP(); 8749 store_data_long(destoffset, imm); 8750 } else { 8751 u16 imm; 8752 8753 DECODE_PRINTF("WORD PTR "); 8754 destoffset = decode_rm10_address(rl); 8755 imm = fetch_word_imm(); 8756 DECODE_PRINTF2(",%x\n", imm); 8757 TRACE_AND_STEP(); 8758 store_data_word(destoffset, imm); 8759 } 8760 break; 8761 case 3: /* register to register */ 8762 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8763 u32 *destreg; 8764 u32 imm; 8765 8766 destreg = DECODE_RM_LONG_REGISTER(rl); 8767 imm = fetch_long_imm(); 8768 DECODE_PRINTF2(",%x\n", imm); 8769 TRACE_AND_STEP(); 8770 *destreg = imm; 8771 } else { 8772 u16 *destreg; 8773 u16 imm; 8774 8775 destreg = DECODE_RM_WORD_REGISTER(rl); 8776 imm = fetch_word_imm(); 8777 DECODE_PRINTF2(",%x\n", imm); 8778 TRACE_AND_STEP(); 8779 *destreg = imm; 8780 } 8781 break; 8782 } 8783 DECODE_CLEAR_SEGOVR(); 8784 END_OF_INSTR(); 8785} 8786 8787/**************************************************************************** 8788REMARKS: 8789Handles opcode 0xc8 8790****************************************************************************/ 8791static void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 8792{ 8793 u16 local,frame_pointer; 8794 u8 nesting; 8795 int i; 8796 8797 START_OF_INSTR(); 8798 local = fetch_word_imm(); 8799 nesting = fetch_byte_imm(); 8800 DECODE_PRINTF2("ENTER %x\n", local); 8801 DECODE_PRINTF2(",%x\n", nesting); 8802 TRACE_AND_STEP(); 8803 push_word(M.x86.R_BP); 8804 frame_pointer = M.x86.R_SP; 8805 if (nesting > 0) { 8806 for (i = 1; i < nesting; i++) { 8807 M.x86.R_BP -= 2; 8808 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 8809 } 8810 push_word(frame_pointer); 8811 } 8812 M.x86.R_BP = frame_pointer; 8813 M.x86.R_SP = (u16)(M.x86.R_SP - local); 8814 DECODE_CLEAR_SEGOVR(); 8815 END_OF_INSTR(); 8816} 8817 8818/**************************************************************************** 8819REMARKS: 8820Handles opcode 0xc9 8821****************************************************************************/ 8822static void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 8823{ 8824 START_OF_INSTR(); 8825 DECODE_PRINTF("LEAVE\n"); 8826 TRACE_AND_STEP(); 8827 M.x86.R_SP = M.x86.R_BP; 8828 M.x86.R_BP = pop_word(); 8829 DECODE_CLEAR_SEGOVR(); 8830 END_OF_INSTR(); 8831} 8832 8833/**************************************************************************** 8834REMARKS: 8835Handles opcode 0xca 8836****************************************************************************/ 8837static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 8838{ 8839 u16 imm; 8840 8841 START_OF_INSTR(); 8842 DECODE_PRINTF("RETF\t"); 8843 imm = fetch_word_imm(); 8844 DECODE_PRINTF2("%x\n", imm); 8845 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8846 TRACE_AND_STEP(); 8847 M.x86.R_IP = pop_word(); 8848 M.x86.R_CS = pop_word(); 8849 M.x86.R_SP += imm; 8850 DECODE_CLEAR_SEGOVR(); 8851 END_OF_INSTR(); 8852} 8853 8854/**************************************************************************** 8855REMARKS: 8856Handles opcode 0xcb 8857****************************************************************************/ 8858static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 8859{ 8860 START_OF_INSTR(); 8861 DECODE_PRINTF("RETF\n"); 8862 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8863 TRACE_AND_STEP(); 8864 M.x86.R_IP = pop_word(); 8865 M.x86.R_CS = pop_word(); 8866 DECODE_CLEAR_SEGOVR(); 8867 END_OF_INSTR(); 8868} 8869 8870/**************************************************************************** 8871REMARKS: 8872Handles opcode 0xcc 8873****************************************************************************/ 8874static void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 8875{ 8876 START_OF_INSTR(); 8877 DECODE_PRINTF("INT 3\n"); 8878 TRACE_AND_STEP(); 8879 if (_X86EMU_intrTab[3]) { 8880 (*_X86EMU_intrTab[3])(3); 8881 } else { 8882 push_word((u16)M.x86.R_FLG); 8883 CLEAR_FLAG(F_IF); 8884 CLEAR_FLAG(F_TF); 8885 push_word(M.x86.R_CS); 8886 M.x86.R_CS = mem_access_word(3 * 4 + 2); 8887 push_word(M.x86.R_IP); 8888 M.x86.R_IP = mem_access_word(3 * 4); 8889 } 8890 DECODE_CLEAR_SEGOVR(); 8891 END_OF_INSTR(); 8892} 8893 8894/**************************************************************************** 8895REMARKS: 8896Handles opcode 0xcd 8897****************************************************************************/ 8898static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 8899{ 8900 u8 intnum; 8901 8902 START_OF_INSTR(); 8903 DECODE_PRINTF("INT\t"); 8904 intnum = fetch_byte_imm(); 8905 DECODE_PRINTF2("%x\n", intnum); 8906 TRACE_AND_STEP(); 8907 if (_X86EMU_intrTab[intnum]) { 8908 (*_X86EMU_intrTab[intnum])(intnum); 8909 } else { 8910 push_word((u16)M.x86.R_FLG); 8911 CLEAR_FLAG(F_IF); 8912 CLEAR_FLAG(F_TF); 8913 push_word(M.x86.R_CS); 8914 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 8915 push_word(M.x86.R_IP); 8916 M.x86.R_IP = mem_access_word(intnum * 4); 8917 } 8918 DECODE_CLEAR_SEGOVR(); 8919 END_OF_INSTR(); 8920} 8921 8922/**************************************************************************** 8923REMARKS: 8924Handles opcode 0xce 8925****************************************************************************/ 8926static void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 8927{ 8928 START_OF_INSTR(); 8929 DECODE_PRINTF("INTO\n"); 8930 TRACE_AND_STEP(); 8931 if (ACCESS_FLAG(F_OF)) { 8932 if (_X86EMU_intrTab[4]) { 8933 (*_X86EMU_intrTab[4])(4); 8934 } else { 8935 push_word((u16)M.x86.R_FLG); 8936 CLEAR_FLAG(F_IF); 8937 CLEAR_FLAG(F_TF); 8938 push_word(M.x86.R_CS); 8939 M.x86.R_CS = mem_access_word(4 * 4 + 2); 8940 push_word(M.x86.R_IP); 8941 M.x86.R_IP = mem_access_word(4 * 4); 8942 } 8943 } 8944 DECODE_CLEAR_SEGOVR(); 8945 END_OF_INSTR(); 8946} 8947 8948/**************************************************************************** 8949REMARKS: 8950Handles opcode 0xcf 8951****************************************************************************/ 8952static void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 8953{ 8954 START_OF_INSTR(); 8955 DECODE_PRINTF("IRET\n"); 8956 8957 TRACE_AND_STEP(); 8958 8959 M.x86.R_IP = pop_word(); 8960 M.x86.R_CS = pop_word(); 8961 M.x86.R_FLG = pop_word(); 8962 DECODE_CLEAR_SEGOVR(); 8963 END_OF_INSTR(); 8964} 8965 8966/**************************************************************************** 8967REMARKS: 8968Handles opcode 0xd0 8969****************************************************************************/ 8970static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 8971{ 8972 int mod, rl, rh; 8973 u8 *destreg; 8974 uint destoffset; 8975 u8 destval; 8976 8977 /* 8978 * Yet another weirdo special case instruction format. Part of 8979 * the opcode held below in "RH". Doubly nested case would 8980 * result, except that the decoded instruction 8981 */ 8982 START_OF_INSTR(); 8983 FETCH_DECODE_MODRM(mod, rh, rl); 8984#ifdef DEBUG 8985 if (DEBUG_DECODE()) { 8986 /* XXX DECODE_PRINTF may be changed to something more 8987 general, so that it is important to leave the strings 8988 in the same format, even though the result is that the 8989 above test is done twice. */ 8990 switch (rh) { 8991 case 0: 8992 DECODE_PRINTF("ROL\t"); 8993 break; 8994 case 1: 8995 DECODE_PRINTF("ROR\t"); 8996 break; 8997 case 2: 8998 DECODE_PRINTF("RCL\t"); 8999 break; 9000 case 3: 9001 DECODE_PRINTF("RCR\t"); 9002 break; 9003 case 4: 9004 DECODE_PRINTF("SHL\t"); 9005 break; 9006 case 5: 9007 DECODE_PRINTF("SHR\t"); 9008 break; 9009 case 6: 9010 DECODE_PRINTF("SAL\t"); 9011 break; 9012 case 7: 9013 DECODE_PRINTF("SAR\t"); 9014 break; 9015 } 9016 } 9017#endif 9018 /* know operation, decode the mod byte to find the addressing 9019 mode. */ 9020 switch (mod) { 9021 case 0: 9022 DECODE_PRINTF("BYTE PTR "); 9023 destoffset = decode_rm00_address(rl); 9024 DECODE_PRINTF(",1\n"); 9025 destval = fetch_data_byte(destoffset); 9026 TRACE_AND_STEP(); 9027 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9028 store_data_byte(destoffset, destval); 9029 break; 9030 case 1: 9031 DECODE_PRINTF("BYTE PTR "); 9032 destoffset = decode_rm01_address(rl); 9033 DECODE_PRINTF(",1\n"); 9034 destval = fetch_data_byte(destoffset); 9035 TRACE_AND_STEP(); 9036 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9037 store_data_byte(destoffset, destval); 9038 break; 9039 case 2: 9040 DECODE_PRINTF("BYTE PTR "); 9041 destoffset = decode_rm10_address(rl); 9042 DECODE_PRINTF(",1\n"); 9043 destval = fetch_data_byte(destoffset); 9044 TRACE_AND_STEP(); 9045 destval = (*opcD0_byte_operation[rh]) (destval, 1); 9046 store_data_byte(destoffset, destval); 9047 break; 9048 case 3: /* register to register */ 9049 destreg = DECODE_RM_BYTE_REGISTER(rl); 9050 DECODE_PRINTF(",1\n"); 9051 TRACE_AND_STEP(); 9052 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 9053 *destreg = destval; 9054 break; 9055 } 9056 DECODE_CLEAR_SEGOVR(); 9057 END_OF_INSTR(); 9058} 9059 9060/**************************************************************************** 9061REMARKS: 9062Handles opcode 0xd1 9063****************************************************************************/ 9064static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 9065{ 9066 int mod, rl, rh; 9067 uint destoffset; 9068 9069 /* 9070 * Yet another weirdo special case instruction format. Part of 9071 * the opcode held below in "RH". Doubly nested case would 9072 * result, except that the decoded instruction 9073 */ 9074 START_OF_INSTR(); 9075 FETCH_DECODE_MODRM(mod, rh, rl); 9076#ifdef DEBUG 9077 if (DEBUG_DECODE()) { 9078 /* XXX DECODE_PRINTF may be changed to something more 9079 general, so that it is important to leave the strings 9080 in the same format, even though the result is that the 9081 above test is done twice. */ 9082 switch (rh) { 9083 case 0: 9084 DECODE_PRINTF("ROL\t"); 9085 break; 9086 case 1: 9087 DECODE_PRINTF("ROR\t"); 9088 break; 9089 case 2: 9090 DECODE_PRINTF("RCL\t"); 9091 break; 9092 case 3: 9093 DECODE_PRINTF("RCR\t"); 9094 break; 9095 case 4: 9096 DECODE_PRINTF("SHL\t"); 9097 break; 9098 case 5: 9099 DECODE_PRINTF("SHR\t"); 9100 break; 9101 case 6: 9102 DECODE_PRINTF("SAL\t"); 9103 break; 9104 case 7: 9105 DECODE_PRINTF("SAR\t"); 9106 break; 9107 } 9108 } 9109#endif 9110 /* know operation, decode the mod byte to find the addressing 9111 mode. */ 9112 switch (mod) { 9113 case 0: 9114 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9115 u32 destval; 9116 9117 DECODE_PRINTF("DWORD PTR "); 9118 destoffset = decode_rm00_address(rl); 9119 DECODE_PRINTF(",1\n"); 9120 destval = fetch_data_long(destoffset); 9121 TRACE_AND_STEP(); 9122 destval = (*opcD1_long_operation[rh]) (destval, 1); 9123 store_data_long(destoffset, destval); 9124 } else { 9125 u16 destval; 9126 9127 DECODE_PRINTF("WORD PTR "); 9128 destoffset = decode_rm00_address(rl); 9129 DECODE_PRINTF(",1\n"); 9130 destval = fetch_data_word(destoffset); 9131 TRACE_AND_STEP(); 9132 destval = (*opcD1_word_operation[rh]) (destval, 1); 9133 store_data_word(destoffset, destval); 9134 } 9135 break; 9136 case 1: 9137 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9138 u32 destval; 9139 9140 DECODE_PRINTF("DWORD PTR "); 9141 destoffset = decode_rm01_address(rl); 9142 DECODE_PRINTF(",1\n"); 9143 destval = fetch_data_long(destoffset); 9144 TRACE_AND_STEP(); 9145 destval = (*opcD1_long_operation[rh]) (destval, 1); 9146 store_data_long(destoffset, destval); 9147 } else { 9148 u16 destval; 9149 9150 DECODE_PRINTF("WORD PTR "); 9151 destoffset = decode_rm01_address(rl); 9152 DECODE_PRINTF(",1\n"); 9153 destval = fetch_data_word(destoffset); 9154 TRACE_AND_STEP(); 9155 destval = (*opcD1_word_operation[rh]) (destval, 1); 9156 store_data_word(destoffset, destval); 9157 } 9158 break; 9159 case 2: 9160 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9161 u32 destval; 9162 9163 DECODE_PRINTF("DWORD PTR "); 9164 destoffset = decode_rm10_address(rl); 9165 DECODE_PRINTF(",1\n"); 9166 destval = fetch_data_long(destoffset); 9167 TRACE_AND_STEP(); 9168 destval = (*opcD1_long_operation[rh]) (destval, 1); 9169 store_data_long(destoffset, destval); 9170 } else { 9171 u16 destval; 9172 9173 DECODE_PRINTF("BYTE PTR "); 9174 destoffset = decode_rm10_address(rl); 9175 DECODE_PRINTF(",1\n"); 9176 destval = fetch_data_word(destoffset); 9177 TRACE_AND_STEP(); 9178 destval = (*opcD1_word_operation[rh]) (destval, 1); 9179 store_data_word(destoffset, destval); 9180 } 9181 break; 9182 case 3: /* register to register */ 9183 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9184 u32 destval; 9185 u32 *destreg; 9186 9187 destreg = DECODE_RM_LONG_REGISTER(rl); 9188 DECODE_PRINTF(",1\n"); 9189 TRACE_AND_STEP(); 9190 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 9191 *destreg = destval; 9192 } else { 9193 u16 destval; 9194 u16 *destreg; 9195 9196 destreg = DECODE_RM_WORD_REGISTER(rl); 9197 DECODE_PRINTF(",1\n"); 9198 TRACE_AND_STEP(); 9199 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 9200 *destreg = destval; 9201 } 9202 break; 9203 } 9204 DECODE_CLEAR_SEGOVR(); 9205 END_OF_INSTR(); 9206} 9207 9208/**************************************************************************** 9209REMARKS: 9210Handles opcode 0xd2 9211****************************************************************************/ 9212static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 9213{ 9214 int mod, rl, rh; 9215 u8 *destreg; 9216 uint destoffset; 9217 u8 destval; 9218 u8 amt; 9219 9220 /* 9221 * Yet another weirdo special case instruction format. Part of 9222 * the opcode held below in "RH". Doubly nested case would 9223 * result, except that the decoded instruction 9224 */ 9225 START_OF_INSTR(); 9226 FETCH_DECODE_MODRM(mod, rh, rl); 9227#ifdef DEBUG 9228 if (DEBUG_DECODE()) { 9229 /* XXX DECODE_PRINTF may be changed to something more 9230 general, so that it is important to leave the strings 9231 in the same format, even though the result is that the 9232 above test is done twice. */ 9233 switch (rh) { 9234 case 0: 9235 DECODE_PRINTF("ROL\t"); 9236 break; 9237 case 1: 9238 DECODE_PRINTF("ROR\t"); 9239 break; 9240 case 2: 9241 DECODE_PRINTF("RCL\t"); 9242 break; 9243 case 3: 9244 DECODE_PRINTF("RCR\t"); 9245 break; 9246 case 4: 9247 DECODE_PRINTF("SHL\t"); 9248 break; 9249 case 5: 9250 DECODE_PRINTF("SHR\t"); 9251 break; 9252 case 6: 9253 DECODE_PRINTF("SAL\t"); 9254 break; 9255 case 7: 9256 DECODE_PRINTF("SAR\t"); 9257 break; 9258 } 9259 } 9260#endif 9261 /* know operation, decode the mod byte to find the addressing 9262 mode. */ 9263 amt = M.x86.R_CL; 9264 switch (mod) { 9265 case 0: 9266 DECODE_PRINTF("BYTE PTR "); 9267 destoffset = decode_rm00_address(rl); 9268 DECODE_PRINTF(",CL\n"); 9269 destval = fetch_data_byte(destoffset); 9270 TRACE_AND_STEP(); 9271 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9272 store_data_byte(destoffset, destval); 9273 break; 9274 case 1: 9275 DECODE_PRINTF("BYTE PTR "); 9276 destoffset = decode_rm01_address(rl); 9277 DECODE_PRINTF(",CL\n"); 9278 destval = fetch_data_byte(destoffset); 9279 TRACE_AND_STEP(); 9280 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9281 store_data_byte(destoffset, destval); 9282 break; 9283 case 2: 9284 DECODE_PRINTF("BYTE PTR "); 9285 destoffset = decode_rm10_address(rl); 9286 DECODE_PRINTF(",CL\n"); 9287 destval = fetch_data_byte(destoffset); 9288 TRACE_AND_STEP(); 9289 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9290 store_data_byte(destoffset, destval); 9291 break; 9292 case 3: /* register to register */ 9293 destreg = DECODE_RM_BYTE_REGISTER(rl); 9294 DECODE_PRINTF(",CL\n"); 9295 TRACE_AND_STEP(); 9296 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 9297 *destreg = destval; 9298 break; 9299 } 9300 DECODE_CLEAR_SEGOVR(); 9301 END_OF_INSTR(); 9302} 9303 9304/**************************************************************************** 9305REMARKS: 9306Handles opcode 0xd3 9307****************************************************************************/ 9308static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 9309{ 9310 int mod, rl, rh; 9311 uint destoffset; 9312 u8 amt; 9313 9314 /* 9315 * Yet another weirdo special case instruction format. Part of 9316 * the opcode held below in "RH". Doubly nested case would 9317 * result, except that the decoded instruction 9318 */ 9319 START_OF_INSTR(); 9320 FETCH_DECODE_MODRM(mod, rh, rl); 9321#ifdef DEBUG 9322 if (DEBUG_DECODE()) { 9323 /* XXX DECODE_PRINTF may be changed to something more 9324 general, so that it is important to leave the strings 9325 in the same format, even though the result is that the 9326 above test is done twice. */ 9327 switch (rh) { 9328 case 0: 9329 DECODE_PRINTF("ROL\t"); 9330 break; 9331 case 1: 9332 DECODE_PRINTF("ROR\t"); 9333 break; 9334 case 2: 9335 DECODE_PRINTF("RCL\t"); 9336 break; 9337 case 3: 9338 DECODE_PRINTF("RCR\t"); 9339 break; 9340 case 4: 9341 DECODE_PRINTF("SHL\t"); 9342 break; 9343 case 5: 9344 DECODE_PRINTF("SHR\t"); 9345 break; 9346 case 6: 9347 DECODE_PRINTF("SAL\t"); 9348 break; 9349 case 7: 9350 DECODE_PRINTF("SAR\t"); 9351 break; 9352 } 9353 } 9354#endif 9355 /* know operation, decode the mod byte to find the addressing 9356 mode. */ 9357 amt = M.x86.R_CL; 9358 switch (mod) { 9359 case 0: 9360 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9361 u32 destval; 9362 9363 DECODE_PRINTF("DWORD PTR "); 9364 destoffset = decode_rm00_address(rl); 9365 DECODE_PRINTF(",CL\n"); 9366 destval = fetch_data_long(destoffset); 9367 TRACE_AND_STEP(); 9368 destval = (*opcD1_long_operation[rh]) (destval, amt); 9369 store_data_long(destoffset, destval); 9370 } else { 9371 u16 destval; 9372 9373 DECODE_PRINTF("WORD PTR "); 9374 destoffset = decode_rm00_address(rl); 9375 DECODE_PRINTF(",CL\n"); 9376 destval = fetch_data_word(destoffset); 9377 TRACE_AND_STEP(); 9378 destval = (*opcD1_word_operation[rh]) (destval, amt); 9379 store_data_word(destoffset, destval); 9380 } 9381 break; 9382 case 1: 9383 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9384 u32 destval; 9385 9386 DECODE_PRINTF("DWORD PTR "); 9387 destoffset = decode_rm01_address(rl); 9388 DECODE_PRINTF(",CL\n"); 9389 destval = fetch_data_long(destoffset); 9390 TRACE_AND_STEP(); 9391 destval = (*opcD1_long_operation[rh]) (destval, amt); 9392 store_data_long(destoffset, destval); 9393 } else { 9394 u16 destval; 9395 9396 DECODE_PRINTF("WORD PTR "); 9397 destoffset = decode_rm01_address(rl); 9398 DECODE_PRINTF(",CL\n"); 9399 destval = fetch_data_word(destoffset); 9400 TRACE_AND_STEP(); 9401 destval = (*opcD1_word_operation[rh]) (destval, amt); 9402 store_data_word(destoffset, destval); 9403 } 9404 break; 9405 case 2: 9406 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9407 u32 destval; 9408 9409 DECODE_PRINTF("DWORD PTR "); 9410 destoffset = decode_rm10_address(rl); 9411 DECODE_PRINTF(",CL\n"); 9412 destval = fetch_data_long(destoffset); 9413 TRACE_AND_STEP(); 9414 destval = (*opcD1_long_operation[rh]) (destval, amt); 9415 store_data_long(destoffset, destval); 9416 } else { 9417 u16 destval; 9418 9419 DECODE_PRINTF("WORD PTR "); 9420 destoffset = decode_rm10_address(rl); 9421 DECODE_PRINTF(",CL\n"); 9422 destval = fetch_data_word(destoffset); 9423 TRACE_AND_STEP(); 9424 destval = (*opcD1_word_operation[rh]) (destval, amt); 9425 store_data_word(destoffset, destval); 9426 } 9427 break; 9428 case 3: /* register to register */ 9429 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9430 u32 *destreg; 9431 9432 destreg = DECODE_RM_LONG_REGISTER(rl); 9433 DECODE_PRINTF(",CL\n"); 9434 TRACE_AND_STEP(); 9435 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 9436 } else { 9437 u16 *destreg; 9438 9439 destreg = DECODE_RM_WORD_REGISTER(rl); 9440 DECODE_PRINTF(",CL\n"); 9441 TRACE_AND_STEP(); 9442 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 9443 } 9444 break; 9445 } 9446 DECODE_CLEAR_SEGOVR(); 9447 END_OF_INSTR(); 9448} 9449 9450/**************************************************************************** 9451REMARKS: 9452Handles opcode 0xd4 9453****************************************************************************/ 9454static void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 9455{ 9456 u8 a; 9457 9458 START_OF_INSTR(); 9459 DECODE_PRINTF("AAM\n"); 9460 a = fetch_byte_imm(); /* this is a stupid encoding. */ 9461 if (a != 10) { 9462 /* fix: add base decoding 9463 aam_word(u8 val, int base a) */ 9464 DECODE_PRINTF("ERROR DECODING AAM\n"); 9465 TRACE_REGS(); 9466 HALT_SYS(); 9467 } 9468 TRACE_AND_STEP(); 9469 /* note the type change here --- returning AL and AH in AX. */ 9470 M.x86.R_AX = aam_word(M.x86.R_AL); 9471 DECODE_CLEAR_SEGOVR(); 9472 END_OF_INSTR(); 9473} 9474 9475/**************************************************************************** 9476REMARKS: 9477Handles opcode 0xd5 9478****************************************************************************/ 9479static void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 9480{ 9481 u8 a; 9482 9483 START_OF_INSTR(); 9484 DECODE_PRINTF("AAD\n"); 9485 a = fetch_byte_imm(); 9486 if (a != 10) { 9487 /* fix: add base decoding 9488 aad_word(u16 val, int base a) */ 9489 DECODE_PRINTF("ERROR DECODING AAM\n"); 9490 TRACE_REGS(); 9491 HALT_SYS(); 9492 } 9493 TRACE_AND_STEP(); 9494 M.x86.R_AX = aad_word(M.x86.R_AX); 9495 DECODE_CLEAR_SEGOVR(); 9496 END_OF_INSTR(); 9497} 9498 9499/* opcode 0xd6 ILLEGAL OPCODE */ 9500 9501/**************************************************************************** 9502REMARKS: 9503Handles opcode 0xd7 9504****************************************************************************/ 9505static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 9506{ 9507 u16 addr; 9508 9509 START_OF_INSTR(); 9510 DECODE_PRINTF("XLAT\n"); 9511 TRACE_AND_STEP(); 9512 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 9513 M.x86.R_AL = fetch_data_byte(addr); 9514 DECODE_CLEAR_SEGOVR(); 9515 END_OF_INSTR(); 9516} 9517 9518/* instuctions D8 .. DF are in i87_ops.c */ 9519 9520/**************************************************************************** 9521REMARKS: 9522Handles opcode 0xe0 9523****************************************************************************/ 9524static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 9525{ 9526 s16 ip; 9527 9528 START_OF_INSTR(); 9529 DECODE_PRINTF("LOOPNE\t"); 9530 ip = (s8) fetch_byte_imm(); 9531 ip += (s16) M.x86.R_IP; 9532 DECODE_PRINTF2("%04x\n", ip); 9533 TRACE_AND_STEP(); 9534 M.x86.R_CX -= 1; 9535 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 9536 M.x86.R_IP = ip; 9537 DECODE_CLEAR_SEGOVR(); 9538 END_OF_INSTR(); 9539} 9540 9541/**************************************************************************** 9542REMARKS: 9543Handles opcode 0xe1 9544****************************************************************************/ 9545static void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 9546{ 9547 s16 ip; 9548 9549 START_OF_INSTR(); 9550 DECODE_PRINTF("LOOPE\t"); 9551 ip = (s8) fetch_byte_imm(); 9552 ip += (s16) M.x86.R_IP; 9553 DECODE_PRINTF2("%04x\n", ip); 9554 TRACE_AND_STEP(); 9555 M.x86.R_CX -= 1; 9556 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 9557 M.x86.R_IP = ip; 9558 DECODE_CLEAR_SEGOVR(); 9559 END_OF_INSTR(); 9560} 9561 9562/**************************************************************************** 9563REMARKS: 9564Handles opcode 0xe2 9565****************************************************************************/ 9566static void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 9567{ 9568 s16 ip; 9569 9570 START_OF_INSTR(); 9571 DECODE_PRINTF("LOOP\t"); 9572 ip = (s8) fetch_byte_imm(); 9573 ip += (s16) M.x86.R_IP; 9574 DECODE_PRINTF2("%04x\n", ip); 9575 TRACE_AND_STEP(); 9576 M.x86.R_CX -= 1; 9577 if (M.x86.R_CX != 0) 9578 M.x86.R_IP = ip; 9579 DECODE_CLEAR_SEGOVR(); 9580 END_OF_INSTR(); 9581} 9582 9583/**************************************************************************** 9584REMARKS: 9585Handles opcode 0xe3 9586****************************************************************************/ 9587static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 9588{ 9589 u16 target; 9590 s8 offset; 9591 9592 /* jump to byte offset if overflow flag is set */ 9593 START_OF_INSTR(); 9594 DECODE_PRINTF("JCXZ\t"); 9595 offset = (s8)fetch_byte_imm(); 9596 target = (u16)(M.x86.R_IP + offset); 9597 DECODE_PRINTF2("%x\n", target); 9598 TRACE_AND_STEP(); 9599 if (M.x86.R_CX == 0) 9600 M.x86.R_IP = target; 9601 DECODE_CLEAR_SEGOVR(); 9602 END_OF_INSTR(); 9603} 9604 9605/**************************************************************************** 9606REMARKS: 9607Handles opcode 0xe4 9608****************************************************************************/ 9609static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 9610{ 9611 u8 port; 9612 9613 START_OF_INSTR(); 9614 DECODE_PRINTF("IN\t"); 9615 port = (u8) fetch_byte_imm(); 9616 DECODE_PRINTF2("%x,AL\n", port); 9617 TRACE_AND_STEP(); 9618 M.x86.R_AL = (*sys_inb)(port); 9619 DECODE_CLEAR_SEGOVR(); 9620 END_OF_INSTR(); 9621} 9622 9623/**************************************************************************** 9624REMARKS: 9625Handles opcode 0xe5 9626****************************************************************************/ 9627static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 9628{ 9629 u8 port; 9630 9631 START_OF_INSTR(); 9632 DECODE_PRINTF("IN\t"); 9633 port = (u8) fetch_byte_imm(); 9634 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9635 DECODE_PRINTF2("EAX,%x\n", port); 9636 } else { 9637 DECODE_PRINTF2("AX,%x\n", port); 9638 } 9639 TRACE_AND_STEP(); 9640 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9641 M.x86.R_EAX = (*sys_inl)(port); 9642 } else { 9643 M.x86.R_AX = (*sys_inw)(port); 9644 } 9645 DECODE_CLEAR_SEGOVR(); 9646 END_OF_INSTR(); 9647} 9648 9649/**************************************************************************** 9650REMARKS: 9651Handles opcode 0xe6 9652****************************************************************************/ 9653static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 9654{ 9655 u8 port; 9656 9657 START_OF_INSTR(); 9658 DECODE_PRINTF("OUT\t"); 9659 port = (u8) fetch_byte_imm(); 9660 DECODE_PRINTF2("%x,AL\n", port); 9661 TRACE_AND_STEP(); 9662 (*sys_outb)(port, M.x86.R_AL); 9663 DECODE_CLEAR_SEGOVR(); 9664 END_OF_INSTR(); 9665} 9666 9667/**************************************************************************** 9668REMARKS: 9669Handles opcode 0xe7 9670****************************************************************************/ 9671static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 9672{ 9673 u8 port; 9674 9675 START_OF_INSTR(); 9676 DECODE_PRINTF("OUT\t"); 9677 port = (u8) fetch_byte_imm(); 9678 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9679 DECODE_PRINTF2("%x,EAX\n", port); 9680 } else { 9681 DECODE_PRINTF2("%x,AX\n", port); 9682 } 9683 TRACE_AND_STEP(); 9684 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9685 (*sys_outl)(port, M.x86.R_EAX); 9686 } else { 9687 (*sys_outw)(port, M.x86.R_AX); 9688 } 9689 DECODE_CLEAR_SEGOVR(); 9690 END_OF_INSTR(); 9691} 9692 9693/**************************************************************************** 9694REMARKS: 9695Handles opcode 0xe8 9696****************************************************************************/ 9697static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 9698{ 9699 s32 ip 9700 9701 START_OF_INSTR(); 9702 DECODE_PRINTF("CALL\t"); 9703 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9704 ip = (s32) fetch_long_imm(); 9705 ip += (s32) M.x86.R_IP; /* CHECK SIGN */ 9706 } else { 9707 ip = (s16) fetch_word_imm(); 9708 ip += (s16) M.x86.R_IP; /* CHECK SIGN */ 9709 } 9710 DECODE_PRINTF2("%04x\n", (u32)ip); 9711 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, ""); 9712 TRACE_AND_STEP(); 9713 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9714 push_long(M.x86.R_IP); 9715 } else { 9716 push_word(M.x86.R_IP); 9717 } 9718 M.x86.R_IP = ip; 9719 DECODE_CLEAR_SEGOVR(); 9720 END_OF_INSTR(); 9721} 9722 9723/**************************************************************************** 9724REMARKS: 9725Handles opcode 0xe9 9726****************************************************************************/ 9727static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 9728{ 9729 int ip; 9730 9731 START_OF_INSTR(); 9732 DECODE_PRINTF("JMP\t"); 9733 ip = (s16)fetch_word_imm(); 9734 ip += (s16)M.x86.R_IP; 9735 DECODE_PRINTF2("%04x\n", (u16)ip); 9736 TRACE_AND_STEP(); 9737 M.x86.R_IP = (u16)ip; 9738 DECODE_CLEAR_SEGOVR(); 9739 END_OF_INSTR(); 9740} 9741 9742/**************************************************************************** 9743REMARKS: 9744Handles opcode 0xea 9745****************************************************************************/ 9746static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 9747{ 9748 u16 cs, ip; 9749 9750 START_OF_INSTR(); 9751 DECODE_PRINTF("JMP\tFAR "); 9752 ip = fetch_word_imm(); 9753 cs = fetch_word_imm(); 9754 DECODE_PRINTF2("%04x:", cs); 9755 DECODE_PRINTF2("%04x\n", ip); 9756 TRACE_AND_STEP(); 9757 M.x86.R_IP = ip; 9758 M.x86.R_CS = cs; 9759 DECODE_CLEAR_SEGOVR(); 9760 END_OF_INSTR(); 9761} 9762 9763/**************************************************************************** 9764REMARKS: 9765Handles opcode 0xeb 9766****************************************************************************/ 9767static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 9768{ 9769 u16 target; 9770 s8 offset; 9771 9772 START_OF_INSTR(); 9773 DECODE_PRINTF("JMP\t"); 9774 offset = (s8)fetch_byte_imm(); 9775 target = (u16)(M.x86.R_IP + offset); 9776 DECODE_PRINTF2("%x\n", target); 9777 TRACE_AND_STEP(); 9778 M.x86.R_IP = target; 9779 DECODE_CLEAR_SEGOVR(); 9780 END_OF_INSTR(); 9781} 9782 9783/**************************************************************************** 9784REMARKS: 9785Handles opcode 0xec 9786****************************************************************************/ 9787static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 9788{ 9789 START_OF_INSTR(); 9790 DECODE_PRINTF("IN\tAL,DX\n"); 9791 TRACE_AND_STEP(); 9792 M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 9793 DECODE_CLEAR_SEGOVR(); 9794 END_OF_INSTR(); 9795} 9796 9797/**************************************************************************** 9798REMARKS: 9799Handles opcode 0xed 9800****************************************************************************/ 9801static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 9802{ 9803 START_OF_INSTR(); 9804 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9805 DECODE_PRINTF("IN\tEAX,DX\n"); 9806 } else { 9807 DECODE_PRINTF("IN\tAX,DX\n"); 9808 } 9809 TRACE_AND_STEP(); 9810 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9811 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 9812 } else { 9813 M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 9814 } 9815 DECODE_CLEAR_SEGOVR(); 9816 END_OF_INSTR(); 9817} 9818 9819/**************************************************************************** 9820REMARKS: 9821Handles opcode 0xee 9822****************************************************************************/ 9823static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 9824{ 9825 START_OF_INSTR(); 9826 DECODE_PRINTF("OUT\tDX,AL\n"); 9827 TRACE_AND_STEP(); 9828 (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 9829 DECODE_CLEAR_SEGOVR(); 9830 END_OF_INSTR(); 9831} 9832 9833/**************************************************************************** 9834REMARKS: 9835Handles opcode 0xef 9836****************************************************************************/ 9837static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 9838{ 9839 START_OF_INSTR(); 9840 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9841 DECODE_PRINTF("OUT\tDX,EAX\n"); 9842 } else { 9843 DECODE_PRINTF("OUT\tDX,AX\n"); 9844 } 9845 TRACE_AND_STEP(); 9846 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9847 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 9848 } else { 9849 (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 9850 } 9851 DECODE_CLEAR_SEGOVR(); 9852 END_OF_INSTR(); 9853} 9854 9855/**************************************************************************** 9856REMARKS: 9857Handles opcode 0xf0 9858****************************************************************************/ 9859static void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 9860{ 9861 START_OF_INSTR(); 9862 DECODE_PRINTF("LOCK:\n"); 9863 TRACE_AND_STEP(); 9864 DECODE_CLEAR_SEGOVR(); 9865 END_OF_INSTR(); 9866} 9867 9868/*opcode 0xf1 ILLEGAL OPERATION */ 9869 9870/**************************************************************************** 9871REMARKS: 9872Handles opcode 0xf2 9873****************************************************************************/ 9874static void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 9875{ 9876 START_OF_INSTR(); 9877 DECODE_PRINTF("REPNE\n"); 9878 TRACE_AND_STEP(); 9879 M.x86.mode |= SYSMODE_PREFIX_REPNE; 9880 DECODE_CLEAR_SEGOVR(); 9881 END_OF_INSTR(); 9882} 9883 9884/**************************************************************************** 9885REMARKS: 9886Handles opcode 0xf3 9887****************************************************************************/ 9888static void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 9889{ 9890 START_OF_INSTR(); 9891 DECODE_PRINTF("REPE\n"); 9892 TRACE_AND_STEP(); 9893 M.x86.mode |= SYSMODE_PREFIX_REPE; 9894 DECODE_CLEAR_SEGOVR(); 9895 END_OF_INSTR(); 9896} 9897 9898/**************************************************************************** 9899REMARKS: 9900Handles opcode 0xf4 9901****************************************************************************/ 9902static void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 9903{ 9904 START_OF_INSTR(); 9905 DECODE_PRINTF("HALT\n"); 9906 TRACE_AND_STEP(); 9907 HALT_SYS(); 9908 DECODE_CLEAR_SEGOVR(); 9909 END_OF_INSTR(); 9910} 9911 9912/**************************************************************************** 9913REMARKS: 9914Handles opcode 0xf5 9915****************************************************************************/ 9916static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 9917{ 9918 /* complement the carry flag. */ 9919 START_OF_INSTR(); 9920 DECODE_PRINTF("CMC\n"); 9921 TRACE_AND_STEP(); 9922 TOGGLE_FLAG(F_CF); 9923 DECODE_CLEAR_SEGOVR(); 9924 END_OF_INSTR(); 9925} 9926 9927/**************************************************************************** 9928REMARKS: 9929Handles opcode 0xf6 9930****************************************************************************/ 9931static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 9932{ 9933 int mod, rl, rh; 9934 u8 *destreg; 9935 uint destoffset; 9936 u8 destval, srcval; 9937 9938 /* long, drawn out code follows. Double switch for a total 9939 of 32 cases. */ 9940 START_OF_INSTR(); 9941 FETCH_DECODE_MODRM(mod, rh, rl); 9942 switch (mod) { 9943 case 0: /* mod=00 */ 9944 switch (rh) { 9945 case 0: /* test byte imm */ 9946 DECODE_PRINTF("TEST\tBYTE PTR "); 9947 destoffset = decode_rm00_address(rl); 9948 DECODE_PRINTF(","); 9949 srcval = fetch_byte_imm(); 9950 DECODE_PRINTF2("%02x\n", srcval); 9951 destval = fetch_data_byte(destoffset); 9952 TRACE_AND_STEP(); 9953 test_byte(destval, srcval); 9954 break; 9955 case 1: 9956 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 9957 HALT_SYS(); 9958 break; 9959 case 2: 9960 DECODE_PRINTF("NOT\tBYTE PTR "); 9961 destoffset = decode_rm00_address(rl); 9962 DECODE_PRINTF("\n"); 9963 destval = fetch_data_byte(destoffset); 9964 TRACE_AND_STEP(); 9965 destval = not_byte(destval); 9966 store_data_byte(destoffset, destval); 9967 break; 9968 case 3: 9969 DECODE_PRINTF("NEG\tBYTE PTR "); 9970 destoffset = decode_rm00_address(rl); 9971 DECODE_PRINTF("\n"); 9972 destval = fetch_data_byte(destoffset); 9973 TRACE_AND_STEP(); 9974 destval = neg_byte(destval); 9975 store_data_byte(destoffset, destval); 9976 break; 9977 case 4: 9978 DECODE_PRINTF("MUL\tBYTE PTR "); 9979 destoffset = decode_rm00_address(rl); 9980 DECODE_PRINTF("\n"); 9981 destval = fetch_data_byte(destoffset); 9982 TRACE_AND_STEP(); 9983 mul_byte(destval); 9984 break; 9985 case 5: 9986 DECODE_PRINTF("IMUL\tBYTE PTR "); 9987 destoffset = decode_rm00_address(rl); 9988 DECODE_PRINTF("\n"); 9989 destval = fetch_data_byte(destoffset); 9990 TRACE_AND_STEP(); 9991 imul_byte(destval); 9992 break; 9993 case 6: 9994 DECODE_PRINTF("DIV\tBYTE PTR "); 9995 destoffset = decode_rm00_address(rl); 9996 DECODE_PRINTF("\n"); 9997 destval = fetch_data_byte(destoffset); 9998 TRACE_AND_STEP(); 9999 div_byte(destval); 10000 break; 10001 case 7: 10002 DECODE_PRINTF("IDIV\tBYTE PTR "); 10003 destoffset = decode_rm00_address(rl); 10004 DECODE_PRINTF("\n"); 10005 destval = fetch_data_byte(destoffset); 10006 TRACE_AND_STEP(); 10007 idiv_byte(destval); 10008 break; 10009 } 10010 break; /* end mod==00 */ 10011 case 1: /* mod=01 */ 10012 switch (rh) { 10013 case 0: /* test byte imm */ 10014 DECODE_PRINTF("TEST\tBYTE PTR "); 10015 destoffset = decode_rm01_address(rl); 10016 DECODE_PRINTF(","); 10017 srcval = fetch_byte_imm(); 10018 DECODE_PRINTF2("%02x\n", srcval); 10019 destval = fetch_data_byte(destoffset); 10020 TRACE_AND_STEP(); 10021 test_byte(destval, srcval); 10022 break; 10023 case 1: 10024 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10025 HALT_SYS(); 10026 break; 10027 case 2: 10028 DECODE_PRINTF("NOT\tBYTE PTR "); 10029 destoffset = decode_rm01_address(rl); 10030 DECODE_PRINTF("\n"); 10031 destval = fetch_data_byte(destoffset); 10032 TRACE_AND_STEP(); 10033 destval = not_byte(destval); 10034 store_data_byte(destoffset, destval); 10035 break; 10036 case 3: 10037 DECODE_PRINTF("NEG\tBYTE PTR "); 10038 destoffset = decode_rm01_address(rl); 10039 DECODE_PRINTF("\n"); 10040 destval = fetch_data_byte(destoffset); 10041 TRACE_AND_STEP(); 10042 destval = neg_byte(destval); 10043 store_data_byte(destoffset, destval); 10044 break; 10045 case 4: 10046 DECODE_PRINTF("MUL\tBYTE PTR "); 10047 destoffset = decode_rm01_address(rl); 10048 DECODE_PRINTF("\n"); 10049 destval = fetch_data_byte(destoffset); 10050 TRACE_AND_STEP(); 10051 mul_byte(destval); 10052 break; 10053 case 5: 10054 DECODE_PRINTF("IMUL\tBYTE PTR "); 10055 destoffset = decode_rm01_address(rl); 10056 DECODE_PRINTF("\n"); 10057 destval = fetch_data_byte(destoffset); 10058 TRACE_AND_STEP(); 10059 imul_byte(destval); 10060 break; 10061 case 6: 10062 DECODE_PRINTF("DIV\tBYTE PTR "); 10063 destoffset = decode_rm01_address(rl); 10064 DECODE_PRINTF("\n"); 10065 destval = fetch_data_byte(destoffset); 10066 TRACE_AND_STEP(); 10067 div_byte(destval); 10068 break; 10069 case 7: 10070 DECODE_PRINTF("IDIV\tBYTE PTR "); 10071 destoffset = decode_rm01_address(rl); 10072 DECODE_PRINTF("\n"); 10073 destval = fetch_data_byte(destoffset); 10074 TRACE_AND_STEP(); 10075 idiv_byte(destval); 10076 break; 10077 } 10078 break; /* end mod==01 */ 10079 case 2: /* mod=10 */ 10080 switch (rh) { 10081 case 0: /* test byte imm */ 10082 DECODE_PRINTF("TEST\tBYTE PTR "); 10083 destoffset = decode_rm10_address(rl); 10084 DECODE_PRINTF(","); 10085 srcval = fetch_byte_imm(); 10086 DECODE_PRINTF2("%02x\n", srcval); 10087 destval = fetch_data_byte(destoffset); 10088 TRACE_AND_STEP(); 10089 test_byte(destval, srcval); 10090 break; 10091 case 1: 10092 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10093 HALT_SYS(); 10094 break; 10095 case 2: 10096 DECODE_PRINTF("NOT\tBYTE PTR "); 10097 destoffset = decode_rm10_address(rl); 10098 DECODE_PRINTF("\n"); 10099 destval = fetch_data_byte(destoffset); 10100 TRACE_AND_STEP(); 10101 destval = not_byte(destval); 10102 store_data_byte(destoffset, destval); 10103 break; 10104 case 3: 10105 DECODE_PRINTF("NEG\tBYTE PTR "); 10106 destoffset = decode_rm10_address(rl); 10107 DECODE_PRINTF("\n"); 10108 destval = fetch_data_byte(destoffset); 10109 TRACE_AND_STEP(); 10110 destval = neg_byte(destval); 10111 store_data_byte(destoffset, destval); 10112 break; 10113 case 4: 10114 DECODE_PRINTF("MUL\tBYTE PTR "); 10115 destoffset = decode_rm10_address(rl); 10116 DECODE_PRINTF("\n"); 10117 destval = fetch_data_byte(destoffset); 10118 TRACE_AND_STEP(); 10119 mul_byte(destval); 10120 break; 10121 case 5: 10122 DECODE_PRINTF("IMUL\tBYTE PTR "); 10123 destoffset = decode_rm10_address(rl); 10124 DECODE_PRINTF("\n"); 10125 destval = fetch_data_byte(destoffset); 10126 TRACE_AND_STEP(); 10127 imul_byte(destval); 10128 break; 10129 case 6: 10130 DECODE_PRINTF("DIV\tBYTE PTR "); 10131 destoffset = decode_rm10_address(rl); 10132 DECODE_PRINTF("\n"); 10133 destval = fetch_data_byte(destoffset); 10134 TRACE_AND_STEP(); 10135 div_byte(destval); 10136 break; 10137 case 7: 10138 DECODE_PRINTF("IDIV\tBYTE PTR "); 10139 destoffset = decode_rm10_address(rl); 10140 DECODE_PRINTF("\n"); 10141 destval = fetch_data_byte(destoffset); 10142 TRACE_AND_STEP(); 10143 idiv_byte(destval); 10144 break; 10145 } 10146 break; /* end mod==10 */ 10147 case 3: /* mod=11 */ 10148 switch (rh) { 10149 case 0: /* test byte imm */ 10150 DECODE_PRINTF("TEST\t"); 10151 destreg = DECODE_RM_BYTE_REGISTER(rl); 10152 DECODE_PRINTF(","); 10153 srcval = fetch_byte_imm(); 10154 DECODE_PRINTF2("%02x\n", srcval); 10155 TRACE_AND_STEP(); 10156 test_byte(*destreg, srcval); 10157 break; 10158 case 1: 10159 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10160 HALT_SYS(); 10161 break; 10162 case 2: 10163 DECODE_PRINTF("NOT\t"); 10164 destreg = DECODE_RM_BYTE_REGISTER(rl); 10165 DECODE_PRINTF("\n"); 10166 TRACE_AND_STEP(); 10167 *destreg = not_byte(*destreg); 10168 break; 10169 case 3: 10170 DECODE_PRINTF("NEG\t"); 10171 destreg = DECODE_RM_BYTE_REGISTER(rl); 10172 DECODE_PRINTF("\n"); 10173 TRACE_AND_STEP(); 10174 *destreg = neg_byte(*destreg); 10175 break; 10176 case 4: 10177 DECODE_PRINTF("MUL\t"); 10178 destreg = DECODE_RM_BYTE_REGISTER(rl); 10179 DECODE_PRINTF("\n"); 10180 TRACE_AND_STEP(); 10181 mul_byte(*destreg); /*!!! */ 10182 break; 10183 case 5: 10184 DECODE_PRINTF("IMUL\t"); 10185 destreg = DECODE_RM_BYTE_REGISTER(rl); 10186 DECODE_PRINTF("\n"); 10187 TRACE_AND_STEP(); 10188 imul_byte(*destreg); 10189 break; 10190 case 6: 10191 DECODE_PRINTF("DIV\t"); 10192 destreg = DECODE_RM_BYTE_REGISTER(rl); 10193 DECODE_PRINTF("\n"); 10194 TRACE_AND_STEP(); 10195 div_byte(*destreg); 10196 break; 10197 case 7: 10198 DECODE_PRINTF("IDIV\t"); 10199 destreg = DECODE_RM_BYTE_REGISTER(rl); 10200 DECODE_PRINTF("\n"); 10201 TRACE_AND_STEP(); 10202 idiv_byte(*destreg); 10203 break; 10204 } 10205 break; /* end mod==11 */ 10206 } 10207 DECODE_CLEAR_SEGOVR(); 10208 END_OF_INSTR(); 10209} 10210 10211/**************************************************************************** 10212REMARKS: 10213Handles opcode 0xf7 10214****************************************************************************/ 10215static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 10216{ 10217 int mod, rl, rh; 10218 uint destoffset; 10219 10220 /* long, drawn out code follows. Double switch for a total 10221 of 32 cases. */ 10222 START_OF_INSTR(); 10223 FETCH_DECODE_MODRM(mod, rh, rl); 10224 switch (mod) { 10225 case 0: /* mod=00 */ 10226 switch (rh) { 10227 case 0: /* test word imm */ 10228 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10229 u32 destval,srcval; 10230 10231 DECODE_PRINTF("TEST\tDWORD PTR "); 10232 destoffset = decode_rm00_address(rl); 10233 DECODE_PRINTF(","); 10234 srcval = fetch_long_imm(); 10235 DECODE_PRINTF2("%x\n", srcval); 10236 destval = fetch_data_long(destoffset); 10237 TRACE_AND_STEP(); 10238 test_long(destval, srcval); 10239 } else { 10240 u16 destval,srcval; 10241 10242 DECODE_PRINTF("TEST\tWORD PTR "); 10243 destoffset = decode_rm00_address(rl); 10244 DECODE_PRINTF(","); 10245 srcval = fetch_word_imm(); 10246 DECODE_PRINTF2("%x\n", srcval); 10247 destval = fetch_data_word(destoffset); 10248 TRACE_AND_STEP(); 10249 test_word(destval, srcval); 10250 } 10251 break; 10252 case 1: 10253 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 10254 HALT_SYS(); 10255 break; 10256 case 2: 10257 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10258 u32 destval; 10259 10260 DECODE_PRINTF("NOT\tDWORD PTR "); 10261 destoffset = decode_rm00_address(rl); 10262 DECODE_PRINTF("\n"); 10263 destval = fetch_data_long(destoffset); 10264 TRACE_AND_STEP(); 10265 destval = not_long(destval); 10266 store_data_long(destoffset, destval); 10267 } else { 10268 u16 destval; 10269 10270 DECODE_PRINTF("NOT\tWORD PTR "); 10271 destoffset = decode_rm00_address(rl); 10272 DECODE_PRINTF("\n"); 10273 destval = fetch_data_word(destoffset); 10274 TRACE_AND_STEP(); 10275 destval = not_word(destval); 10276 store_data_word(destoffset, destval); 10277 } 10278 break; 10279 case 3: 10280 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10281 u32 destval; 10282 10283 DECODE_PRINTF("NEG\tDWORD PTR "); 10284 destoffset = decode_rm00_address(rl); 10285 DECODE_PRINTF("\n"); 10286 destval = fetch_data_long(destoffset); 10287 TRACE_AND_STEP(); 10288 destval = neg_long(destval); 10289 store_data_long(destoffset, destval); 10290 } else { 10291 u16 destval; 10292 10293 DECODE_PRINTF("NEG\tWORD PTR "); 10294 destoffset = decode_rm00_address(rl); 10295 DECODE_PRINTF("\n"); 10296 destval = fetch_data_word(destoffset); 10297 TRACE_AND_STEP(); 10298 destval = neg_word(destval); 10299 store_data_word(destoffset, destval); 10300 } 10301 break; 10302 case 4: 10303 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10304 u32 destval; 10305 10306 DECODE_PRINTF("MUL\tDWORD PTR "); 10307 destoffset = decode_rm00_address(rl); 10308 DECODE_PRINTF("\n"); 10309 destval = fetch_data_long(destoffset); 10310 TRACE_AND_STEP(); 10311 mul_long(destval); 10312 } else { 10313 u16 destval; 10314 10315 DECODE_PRINTF("MUL\tWORD PTR "); 10316 destoffset = decode_rm00_address(rl); 10317 DECODE_PRINTF("\n"); 10318 destval = fetch_data_word(destoffset); 10319 TRACE_AND_STEP(); 10320 mul_word(destval); 10321 } 10322 break; 10323 case 5: 10324 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10325 u32 destval; 10326 10327 DECODE_PRINTF("IMUL\tDWORD PTR "); 10328 destoffset = decode_rm00_address(rl); 10329 DECODE_PRINTF("\n"); 10330 destval = fetch_data_long(destoffset); 10331 TRACE_AND_STEP(); 10332 imul_long(destval); 10333 } else { 10334 u16 destval; 10335 10336 DECODE_PRINTF("IMUL\tWORD PTR "); 10337 destoffset = decode_rm00_address(rl); 10338 DECODE_PRINTF("\n"); 10339 destval = fetch_data_word(destoffset); 10340 TRACE_AND_STEP(); 10341 imul_word(destval); 10342 } 10343 break; 10344 case 6: 10345 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10346 u32 destval; 10347 10348 DECODE_PRINTF("DIV\tDWORD PTR "); 10349 destoffset = decode_rm00_address(rl); 10350 DECODE_PRINTF("\n"); 10351 destval = fetch_data_long(destoffset); 10352 TRACE_AND_STEP(); 10353 div_long(destval); 10354 } else { 10355 u16 destval; 10356 10357 DECODE_PRINTF("DIV\tWORD PTR "); 10358 destoffset = decode_rm00_address(rl); 10359 DECODE_PRINTF("\n"); 10360 destval = fetch_data_word(destoffset); 10361 TRACE_AND_STEP(); 10362 div_word(destval); 10363 } 10364 break; 10365 case 7: 10366 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10367 u32 destval; 10368 10369 DECODE_PRINTF("IDIV\tDWORD PTR "); 10370 destoffset = decode_rm00_address(rl); 10371 DECODE_PRINTF("\n"); 10372 destval = fetch_data_long(destoffset); 10373 TRACE_AND_STEP(); 10374 idiv_long(destval); 10375 } else { 10376 u16 destval; 10377 10378 DECODE_PRINTF("IDIV\tWORD PTR "); 10379 destoffset = decode_rm00_address(rl); 10380 DECODE_PRINTF("\n"); 10381 destval = fetch_data_word(destoffset); 10382 TRACE_AND_STEP(); 10383 idiv_word(destval); 10384 } 10385 break; 10386 } 10387 break; /* end mod==00 */ 10388 case 1: /* mod=01 */ 10389 switch (rh) { 10390 case 0: /* test word imm */ 10391 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10392 u32 destval,srcval; 10393 10394 DECODE_PRINTF("TEST\tDWORD PTR "); 10395 destoffset = decode_rm01_address(rl); 10396 DECODE_PRINTF(","); 10397 srcval = fetch_long_imm(); 10398 DECODE_PRINTF2("%x\n", srcval); 10399 destval = fetch_data_long(destoffset); 10400 TRACE_AND_STEP(); 10401 test_long(destval, srcval); 10402 } else { 10403 u16 destval,srcval; 10404 10405 DECODE_PRINTF("TEST\tWORD PTR "); 10406 destoffset = decode_rm01_address(rl); 10407 DECODE_PRINTF(","); 10408 srcval = fetch_word_imm(); 10409 DECODE_PRINTF2("%x\n", srcval); 10410 destval = fetch_data_word(destoffset); 10411 TRACE_AND_STEP(); 10412 test_word(destval, srcval); 10413 } 10414 break; 10415 case 1: 10416 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10417 HALT_SYS(); 10418 break; 10419 case 2: 10420 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10421 u32 destval; 10422 10423 DECODE_PRINTF("NOT\tDWORD PTR "); 10424 destoffset = decode_rm01_address(rl); 10425 DECODE_PRINTF("\n"); 10426 destval = fetch_data_long(destoffset); 10427 TRACE_AND_STEP(); 10428 destval = not_long(destval); 10429 store_data_long(destoffset, destval); 10430 } else { 10431 u16 destval; 10432 10433 DECODE_PRINTF("NOT\tWORD PTR "); 10434 destoffset = decode_rm01_address(rl); 10435 DECODE_PRINTF("\n"); 10436 destval = fetch_data_word(destoffset); 10437 TRACE_AND_STEP(); 10438 destval = not_word(destval); 10439 store_data_word(destoffset, destval); 10440 } 10441 break; 10442 case 3: 10443 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10444 u32 destval; 10445 10446 DECODE_PRINTF("NEG\tDWORD PTR "); 10447 destoffset = decode_rm01_address(rl); 10448 DECODE_PRINTF("\n"); 10449 destval = fetch_data_long(destoffset); 10450 TRACE_AND_STEP(); 10451 destval = neg_long(destval); 10452 store_data_long(destoffset, destval); 10453 } else { 10454 u16 destval; 10455 10456 DECODE_PRINTF("NEG\tWORD PTR "); 10457 destoffset = decode_rm01_address(rl); 10458 DECODE_PRINTF("\n"); 10459 destval = fetch_data_word(destoffset); 10460 TRACE_AND_STEP(); 10461 destval = neg_word(destval); 10462 store_data_word(destoffset, destval); 10463 } 10464 break; 10465 case 4: 10466 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10467 u32 destval; 10468 10469 DECODE_PRINTF("MUL\tDWORD PTR "); 10470 destoffset = decode_rm01_address(rl); 10471 DECODE_PRINTF("\n"); 10472 destval = fetch_data_long(destoffset); 10473 TRACE_AND_STEP(); 10474 mul_long(destval); 10475 } else { 10476 u16 destval; 10477 10478 DECODE_PRINTF("MUL\tWORD PTR "); 10479 destoffset = decode_rm01_address(rl); 10480 DECODE_PRINTF("\n"); 10481 destval = fetch_data_word(destoffset); 10482 TRACE_AND_STEP(); 10483 mul_word(destval); 10484 } 10485 break; 10486 case 5: 10487 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10488 u32 destval; 10489 10490 DECODE_PRINTF("IMUL\tDWORD PTR "); 10491 destoffset = decode_rm01_address(rl); 10492 DECODE_PRINTF("\n"); 10493 destval = fetch_data_long(destoffset); 10494 TRACE_AND_STEP(); 10495 imul_long(destval); 10496 } else { 10497 u16 destval; 10498 10499 DECODE_PRINTF("IMUL\tWORD PTR "); 10500 destoffset = decode_rm01_address(rl); 10501 DECODE_PRINTF("\n"); 10502 destval = fetch_data_word(destoffset); 10503 TRACE_AND_STEP(); 10504 imul_word(destval); 10505 } 10506 break; 10507 case 6: 10508 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10509 u32 destval; 10510 10511 DECODE_PRINTF("DIV\tDWORD PTR "); 10512 destoffset = decode_rm01_address(rl); 10513 DECODE_PRINTF("\n"); 10514 destval = fetch_data_long(destoffset); 10515 TRACE_AND_STEP(); 10516 div_long(destval); 10517 } else { 10518 u16 destval; 10519 10520 DECODE_PRINTF("DIV\tWORD PTR "); 10521 destoffset = decode_rm01_address(rl); 10522 DECODE_PRINTF("\n"); 10523 destval = fetch_data_word(destoffset); 10524 TRACE_AND_STEP(); 10525 div_word(destval); 10526 } 10527 break; 10528 case 7: 10529 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10530 u32 destval; 10531 10532 DECODE_PRINTF("IDIV\tDWORD PTR "); 10533 destoffset = decode_rm01_address(rl); 10534 DECODE_PRINTF("\n"); 10535 destval = fetch_data_long(destoffset); 10536 TRACE_AND_STEP(); 10537 idiv_long(destval); 10538 } else { 10539 u16 destval; 10540 10541 DECODE_PRINTF("IDIV\tWORD PTR "); 10542 destoffset = decode_rm01_address(rl); 10543 DECODE_PRINTF("\n"); 10544 destval = fetch_data_word(destoffset); 10545 TRACE_AND_STEP(); 10546 idiv_word(destval); 10547 } 10548 break; 10549 } 10550 break; /* end mod==01 */ 10551 case 2: /* mod=10 */ 10552 switch (rh) { 10553 case 0: /* test word imm */ 10554 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10555 u32 destval,srcval; 10556 10557 DECODE_PRINTF("TEST\tDWORD PTR "); 10558 destoffset = decode_rm10_address(rl); 10559 DECODE_PRINTF(","); 10560 srcval = fetch_long_imm(); 10561 DECODE_PRINTF2("%x\n", srcval); 10562 destval = fetch_data_long(destoffset); 10563 TRACE_AND_STEP(); 10564 test_long(destval, srcval); 10565 } else { 10566 u16 destval,srcval; 10567 10568 DECODE_PRINTF("TEST\tWORD PTR "); 10569 destoffset = decode_rm10_address(rl); 10570 DECODE_PRINTF(","); 10571 srcval = fetch_word_imm(); 10572 DECODE_PRINTF2("%x\n", srcval); 10573 destval = fetch_data_word(destoffset); 10574 TRACE_AND_STEP(); 10575 test_word(destval, srcval); 10576 } 10577 break; 10578 case 1: 10579 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10580 HALT_SYS(); 10581 break; 10582 case 2: 10583 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10584 u32 destval; 10585 10586 DECODE_PRINTF("NOT\tDWORD PTR "); 10587 destoffset = decode_rm10_address(rl); 10588 DECODE_PRINTF("\n"); 10589 destval = fetch_data_long(destoffset); 10590 TRACE_AND_STEP(); 10591 destval = not_long(destval); 10592 store_data_long(destoffset, destval); 10593 } else { 10594 u16 destval; 10595 10596 DECODE_PRINTF("NOT\tWORD PTR "); 10597 destoffset = decode_rm10_address(rl); 10598 DECODE_PRINTF("\n"); 10599 destval = fetch_data_word(destoffset); 10600 TRACE_AND_STEP(); 10601 destval = not_word(destval); 10602 store_data_word(destoffset, destval); 10603 } 10604 break; 10605 case 3: 10606 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10607 u32 destval; 10608 10609 DECODE_PRINTF("NEG\tDWORD PTR "); 10610 destoffset = decode_rm10_address(rl); 10611 DECODE_PRINTF("\n"); 10612 destval = fetch_data_long(destoffset); 10613 TRACE_AND_STEP(); 10614 destval = neg_long(destval); 10615 store_data_long(destoffset, destval); 10616 } else { 10617 u16 destval; 10618 10619 DECODE_PRINTF("NEG\tWORD PTR "); 10620 destoffset = decode_rm10_address(rl); 10621 DECODE_PRINTF("\n"); 10622 destval = fetch_data_word(destoffset); 10623 TRACE_AND_STEP(); 10624 destval = neg_word(destval); 10625 store_data_word(destoffset, destval); 10626 } 10627 break; 10628 case 4: 10629 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10630 u32 destval; 10631 10632 DECODE_PRINTF("MUL\tDWORD PTR "); 10633 destoffset = decode_rm10_address(rl); 10634 DECODE_PRINTF("\n"); 10635 destval = fetch_data_long(destoffset); 10636 TRACE_AND_STEP(); 10637 mul_long(destval); 10638 } else { 10639 u16 destval; 10640 10641 DECODE_PRINTF("MUL\tWORD PTR "); 10642 destoffset = decode_rm10_address(rl); 10643 DECODE_PRINTF("\n"); 10644 destval = fetch_data_word(destoffset); 10645 TRACE_AND_STEP(); 10646 mul_word(destval); 10647 } 10648 break; 10649 case 5: 10650 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10651 u32 destval; 10652 10653 DECODE_PRINTF("IMUL\tDWORD PTR "); 10654 destoffset = decode_rm10_address(rl); 10655 DECODE_PRINTF("\n"); 10656 destval = fetch_data_long(destoffset); 10657 TRACE_AND_STEP(); 10658 imul_long(destval); 10659 } else { 10660 u16 destval; 10661 10662 DECODE_PRINTF("IMUL\tWORD PTR "); 10663 destoffset = decode_rm10_address(rl); 10664 DECODE_PRINTF("\n"); 10665 destval = fetch_data_word(destoffset); 10666 TRACE_AND_STEP(); 10667 imul_word(destval); 10668 } 10669 break; 10670 case 6: 10671 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10672 u32 destval; 10673 10674 DECODE_PRINTF("DIV\tDWORD PTR "); 10675 destoffset = decode_rm10_address(rl); 10676 DECODE_PRINTF("\n"); 10677 destval = fetch_data_long(destoffset); 10678 TRACE_AND_STEP(); 10679 div_long(destval); 10680 } else { 10681 u16 destval; 10682 10683 DECODE_PRINTF("DIV\tWORD PTR "); 10684 destoffset = decode_rm10_address(rl); 10685 DECODE_PRINTF("\n"); 10686 destval = fetch_data_word(destoffset); 10687 TRACE_AND_STEP(); 10688 div_word(destval); 10689 } 10690 break; 10691 case 7: 10692 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10693 u32 destval; 10694 10695 DECODE_PRINTF("IDIV\tDWORD PTR "); 10696 destoffset = decode_rm10_address(rl); 10697 DECODE_PRINTF("\n"); 10698 destval = fetch_data_long(destoffset); 10699 TRACE_AND_STEP(); 10700 idiv_long(destval); 10701 } else { 10702 u16 destval; 10703 10704 DECODE_PRINTF("IDIV\tWORD PTR "); 10705 destoffset = decode_rm10_address(rl); 10706 DECODE_PRINTF("\n"); 10707 destval = fetch_data_word(destoffset); 10708 TRACE_AND_STEP(); 10709 idiv_word(destval); 10710 } 10711 break; 10712 } 10713 break; /* end mod==10 */ 10714 case 3: /* mod=11 */ 10715 switch (rh) { 10716 case 0: /* test word imm */ 10717 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10718 u32 *destreg; 10719 u32 srcval; 10720 10721 DECODE_PRINTF("TEST\t"); 10722 destreg = DECODE_RM_LONG_REGISTER(rl); 10723 DECODE_PRINTF(","); 10724 srcval = fetch_long_imm(); 10725 DECODE_PRINTF2("%x\n", srcval); 10726 TRACE_AND_STEP(); 10727 test_long(*destreg, srcval); 10728 } else { 10729 u16 *destreg; 10730 u16 srcval; 10731 10732 DECODE_PRINTF("TEST\t"); 10733 destreg = DECODE_RM_WORD_REGISTER(rl); 10734 DECODE_PRINTF(","); 10735 srcval = fetch_word_imm(); 10736 DECODE_PRINTF2("%x\n", srcval); 10737 TRACE_AND_STEP(); 10738 test_word(*destreg, srcval); 10739 } 10740 break; 10741 case 1: 10742 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10743 HALT_SYS(); 10744 break; 10745 case 2: 10746 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10747 u32 *destreg; 10748 10749 DECODE_PRINTF("NOT\t"); 10750 destreg = DECODE_RM_LONG_REGISTER(rl); 10751 DECODE_PRINTF("\n"); 10752 TRACE_AND_STEP(); 10753 *destreg = not_long(*destreg); 10754 } else { 10755 u16 *destreg; 10756 10757 DECODE_PRINTF("NOT\t"); 10758 destreg = DECODE_RM_WORD_REGISTER(rl); 10759 DECODE_PRINTF("\n"); 10760 TRACE_AND_STEP(); 10761 *destreg = not_word(*destreg); 10762 } 10763 break; 10764 case 3: 10765 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10766 u32 *destreg; 10767 10768 DECODE_PRINTF("NEG\t"); 10769 destreg = DECODE_RM_LONG_REGISTER(rl); 10770 DECODE_PRINTF("\n"); 10771 TRACE_AND_STEP(); 10772 *destreg = neg_long(*destreg); 10773 } else { 10774 u16 *destreg; 10775 10776 DECODE_PRINTF("NEG\t"); 10777 destreg = DECODE_RM_WORD_REGISTER(rl); 10778 DECODE_PRINTF("\n"); 10779 TRACE_AND_STEP(); 10780 *destreg = neg_word(*destreg); 10781 } 10782 break; 10783 case 4: 10784 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10785 u32 *destreg; 10786 10787 DECODE_PRINTF("MUL\t"); 10788 destreg = DECODE_RM_LONG_REGISTER(rl); 10789 DECODE_PRINTF("\n"); 10790 TRACE_AND_STEP(); 10791 mul_long(*destreg); /*!!! */ 10792 } else { 10793 u16 *destreg; 10794 10795 DECODE_PRINTF("MUL\t"); 10796 destreg = DECODE_RM_WORD_REGISTER(rl); 10797 DECODE_PRINTF("\n"); 10798 TRACE_AND_STEP(); 10799 mul_word(*destreg); /*!!! */ 10800 } 10801 break; 10802 case 5: 10803 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10804 u32 *destreg; 10805 10806 DECODE_PRINTF("IMUL\t"); 10807 destreg = DECODE_RM_LONG_REGISTER(rl); 10808 DECODE_PRINTF("\n"); 10809 TRACE_AND_STEP(); 10810 imul_long(*destreg); 10811 } else { 10812 u16 *destreg; 10813 10814 DECODE_PRINTF("IMUL\t"); 10815 destreg = DECODE_RM_WORD_REGISTER(rl); 10816 DECODE_PRINTF("\n"); 10817 TRACE_AND_STEP(); 10818 imul_word(*destreg); 10819 } 10820 break; 10821 case 6: 10822 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10823 u32 *destreg; 10824 10825 DECODE_PRINTF("DIV\t"); 10826 destreg = DECODE_RM_LONG_REGISTER(rl); 10827 DECODE_PRINTF("\n"); 10828 TRACE_AND_STEP(); 10829 div_long(*destreg); 10830 } else { 10831 u16 *destreg; 10832 10833 DECODE_PRINTF("DIV\t"); 10834 destreg = DECODE_RM_WORD_REGISTER(rl); 10835 DECODE_PRINTF("\n"); 10836 TRACE_AND_STEP(); 10837 div_word(*destreg); 10838 } 10839 break; 10840 case 7: 10841 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10842 u32 *destreg; 10843 10844 DECODE_PRINTF("IDIV\t"); 10845 destreg = DECODE_RM_LONG_REGISTER(rl); 10846 DECODE_PRINTF("\n"); 10847 TRACE_AND_STEP(); 10848 idiv_long(*destreg); 10849 } else { 10850 u16 *destreg; 10851 10852 DECODE_PRINTF("IDIV\t"); 10853 destreg = DECODE_RM_WORD_REGISTER(rl); 10854 DECODE_PRINTF("\n"); 10855 TRACE_AND_STEP(); 10856 idiv_word(*destreg); 10857 } 10858 break; 10859 } 10860 break; /* end mod==11 */ 10861 } 10862 DECODE_CLEAR_SEGOVR(); 10863 END_OF_INSTR(); 10864} 10865 10866/**************************************************************************** 10867REMARKS: 10868Handles opcode 0xf8 10869****************************************************************************/ 10870static void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 10871{ 10872 /* clear the carry flag. */ 10873 START_OF_INSTR(); 10874 DECODE_PRINTF("CLC\n"); 10875 TRACE_AND_STEP(); 10876 CLEAR_FLAG(F_CF); 10877 DECODE_CLEAR_SEGOVR(); 10878 END_OF_INSTR(); 10879} 10880 10881/**************************************************************************** 10882REMARKS: 10883Handles opcode 0xf9 10884****************************************************************************/ 10885static void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 10886{ 10887 /* set the carry flag. */ 10888 START_OF_INSTR(); 10889 DECODE_PRINTF("STC\n"); 10890 TRACE_AND_STEP(); 10891 SET_FLAG(F_CF); 10892 DECODE_CLEAR_SEGOVR(); 10893 END_OF_INSTR(); 10894} 10895 10896/**************************************************************************** 10897REMARKS: 10898Handles opcode 0xfa 10899****************************************************************************/ 10900static void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 10901{ 10902 /* clear interrupts. */ 10903 START_OF_INSTR(); 10904 DECODE_PRINTF("CLI\n"); 10905 TRACE_AND_STEP(); 10906 CLEAR_FLAG(F_IF); 10907 DECODE_CLEAR_SEGOVR(); 10908 END_OF_INSTR(); 10909} 10910 10911/**************************************************************************** 10912REMARKS: 10913Handles opcode 0xfb 10914****************************************************************************/ 10915static void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 10916{ 10917 /* enable interrupts. */ 10918 START_OF_INSTR(); 10919 DECODE_PRINTF("STI\n"); 10920 TRACE_AND_STEP(); 10921 SET_FLAG(F_IF); 10922 DECODE_CLEAR_SEGOVR(); 10923 END_OF_INSTR(); 10924} 10925 10926/**************************************************************************** 10927REMARKS: 10928Handles opcode 0xfc 10929****************************************************************************/ 10930static void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 10931{ 10932 /* clear interrupts. */ 10933 START_OF_INSTR(); 10934 DECODE_PRINTF("CLD\n"); 10935 TRACE_AND_STEP(); 10936 CLEAR_FLAG(F_DF); 10937 DECODE_CLEAR_SEGOVR(); 10938 END_OF_INSTR(); 10939} 10940 10941/**************************************************************************** 10942REMARKS: 10943Handles opcode 0xfd 10944****************************************************************************/ 10945static void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 10946{ 10947 /* clear interrupts. */ 10948 START_OF_INSTR(); 10949 DECODE_PRINTF("STD\n"); 10950 TRACE_AND_STEP(); 10951 SET_FLAG(F_DF); 10952 DECODE_CLEAR_SEGOVR(); 10953 END_OF_INSTR(); 10954} 10955 10956/**************************************************************************** 10957REMARKS: 10958Handles opcode 0xfe 10959****************************************************************************/ 10960static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 10961{ 10962 int mod, rh, rl; 10963 u8 destval; 10964 uint destoffset; 10965 u8 *destreg; 10966 10967 /* Yet another special case instruction. */ 10968 START_OF_INSTR(); 10969 FETCH_DECODE_MODRM(mod, rh, rl); 10970#ifdef DEBUG 10971 if (DEBUG_DECODE()) { 10972 /* XXX DECODE_PRINTF may be changed to something more 10973 general, so that it is important to leave the strings 10974 in the same format, even though the result is that the 10975 above test is done twice. */ 10976 10977 switch (rh) { 10978 case 0: 10979 DECODE_PRINTF("INC\t"); 10980 break; 10981 case 1: 10982 DECODE_PRINTF("DEC\t"); 10983 break; 10984 case 2: 10985 case 3: 10986 case 4: 10987 case 5: 10988 case 6: 10989 case 7: 10990 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 10991 HALT_SYS(); 10992 break; 10993 } 10994 } 10995#endif 10996 switch (mod) { 10997 case 0: 10998 DECODE_PRINTF("BYTE PTR "); 10999 destoffset = decode_rm00_address(rl); 11000 DECODE_PRINTF("\n"); 11001 switch (rh) { 11002 case 0: /* inc word ptr ... */ 11003 destval = fetch_data_byte(destoffset); 11004 TRACE_AND_STEP(); 11005 destval = inc_byte(destval); 11006 store_data_byte(destoffset, destval); 11007 break; 11008 case 1: /* dec word ptr ... */ 11009 destval = fetch_data_byte(destoffset); 11010 TRACE_AND_STEP(); 11011 destval = dec_byte(destval); 11012 store_data_byte(destoffset, destval); 11013 break; 11014 } 11015 break; 11016 case 1: 11017 DECODE_PRINTF("BYTE PTR "); 11018 destoffset = decode_rm01_address(rl); 11019 DECODE_PRINTF("\n"); 11020 switch (rh) { 11021 case 0: 11022 destval = fetch_data_byte(destoffset); 11023 TRACE_AND_STEP(); 11024 destval = inc_byte(destval); 11025 store_data_byte(destoffset, destval); 11026 break; 11027 case 1: 11028 destval = fetch_data_byte(destoffset); 11029 TRACE_AND_STEP(); 11030 destval = dec_byte(destval); 11031 store_data_byte(destoffset, destval); 11032 break; 11033 } 11034 break; 11035 case 2: 11036 DECODE_PRINTF("BYTE PTR "); 11037 destoffset = decode_rm10_address(rl); 11038 DECODE_PRINTF("\n"); 11039 switch (rh) { 11040 case 0: 11041 destval = fetch_data_byte(destoffset); 11042 TRACE_AND_STEP(); 11043 destval = inc_byte(destval); 11044 store_data_byte(destoffset, destval); 11045 break; 11046 case 1: 11047 destval = fetch_data_byte(destoffset); 11048 TRACE_AND_STEP(); 11049 destval = dec_byte(destval); 11050 store_data_byte(destoffset, destval); 11051 break; 11052 } 11053 break; 11054 case 3: 11055 destreg = DECODE_RM_BYTE_REGISTER(rl); 11056 DECODE_PRINTF("\n"); 11057 switch (rh) { 11058 case 0: 11059 TRACE_AND_STEP(); 11060 *destreg = inc_byte(*destreg); 11061 break; 11062 case 1: 11063 TRACE_AND_STEP(); 11064 *destreg = dec_byte(*destreg); 11065 break; 11066 } 11067 break; 11068 } 11069 DECODE_CLEAR_SEGOVR(); 11070 END_OF_INSTR(); 11071} 11072 11073/**************************************************************************** 11074REMARKS: 11075Handles opcode 0xff 11076****************************************************************************/ 11077static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 11078{ 11079 int mod, rh, rl; 11080 uint destoffset = 0; 11081 u16 *destreg; 11082 u16 destval,destval2; 11083 11084 /* Yet another special case instruction. */ 11085 START_OF_INSTR(); 11086 FETCH_DECODE_MODRM(mod, rh, rl); 11087#ifdef DEBUG 11088 if (DEBUG_DECODE()) { 11089 /* XXX DECODE_PRINTF may be changed to something more 11090 general, so that it is important to leave the strings 11091 in the same format, even though the result is that the 11092 above test is done twice. */ 11093 11094 switch (rh) { 11095 case 0: 11096 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11097 DECODE_PRINTF("INC\tDWORD PTR "); 11098 } else { 11099 DECODE_PRINTF("INC\tWORD PTR "); 11100 } 11101 break; 11102 case 1: 11103 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11104 DECODE_PRINTF("DEC\tDWORD PTR "); 11105 } else { 11106 DECODE_PRINTF("DEC\tWORD PTR "); 11107 } 11108 break; 11109 case 2: 11110 DECODE_PRINTF("CALL\t"); 11111 break; 11112 case 3: 11113 DECODE_PRINTF("CALL\tFAR "); 11114 break; 11115 case 4: 11116 DECODE_PRINTF("JMP\t"); 11117 break; 11118 case 5: 11119 DECODE_PRINTF("JMP\tFAR "); 11120 break; 11121 case 6: 11122 DECODE_PRINTF("PUSH\t"); 11123 break; 11124 case 7: 11125 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 11126 HALT_SYS(); 11127 break; 11128 } 11129 } 11130#endif 11131 switch (mod) { 11132 case 0: 11133 destoffset = decode_rm00_address(rl); 11134 DECODE_PRINTF("\n"); 11135 switch (rh) { 11136 case 0: /* inc word ptr ... */ 11137 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11138 u32 destval; 11139 11140 destval = fetch_data_long(destoffset); 11141 TRACE_AND_STEP(); 11142 destval = inc_long(destval); 11143 store_data_long(destoffset, destval); 11144 } else { 11145 u16 destval; 11146 11147 destval = fetch_data_word(destoffset); 11148 TRACE_AND_STEP(); 11149 destval = inc_word(destval); 11150 store_data_word(destoffset, destval); 11151 } 11152 break; 11153 case 1: /* dec word ptr ... */ 11154 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11155 u32 destval; 11156 11157 destval = fetch_data_long(destoffset); 11158 TRACE_AND_STEP(); 11159 destval = dec_long(destval); 11160 store_data_long(destoffset, destval); 11161 } else { 11162 u16 destval; 11163 11164 destval = fetch_data_word(destoffset); 11165 TRACE_AND_STEP(); 11166 destval = dec_word(destval); 11167 store_data_word(destoffset, destval); 11168 } 11169 break; 11170 case 2: /* call word ptr ... */ 11171 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11172 u32 destval; 11173 11174 destval = fetch_data_long(destoffset); 11175 TRACE_AND_STEP(); 11176 push_long(M.x86.R_EIP); 11177 M.x86.R_EIP = destval; 11178 } else { 11179 destval = fetch_data_word(destoffset); 11180 TRACE_AND_STEP(); 11181 push_word(M.x86.R_IP); 11182 M.x86.R_IP = destval; 11183 } 11184 break; 11185 case 3: /* call far ptr ... */ 11186 destval = fetch_data_word(destoffset); 11187 destval2 = fetch_data_word(destoffset + 2); 11188 TRACE_AND_STEP(); 11189 push_word(M.x86.R_CS); 11190 M.x86.R_CS = destval2; 11191 push_word(M.x86.R_IP); 11192 M.x86.R_IP = destval; 11193 break; 11194 case 4: /* jmp word ptr ... */ 11195 destval = fetch_data_word(destoffset); 11196 TRACE_AND_STEP(); 11197 M.x86.R_IP = destval; 11198 break; 11199 case 5: /* jmp far ptr ... */ 11200 destval = fetch_data_word(destoffset); 11201 destval2 = fetch_data_word(destoffset + 2); 11202 TRACE_AND_STEP(); 11203 M.x86.R_IP = destval; 11204 M.x86.R_CS = destval2; 11205 break; 11206 case 6: /* push word ptr ... */ 11207 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11208 u32 destval; 11209 11210 destval = fetch_data_long(destoffset); 11211 TRACE_AND_STEP(); 11212 push_long(destval); 11213 } else { 11214 u16 destval; 11215 11216 destval = fetch_data_word(destoffset); 11217 TRACE_AND_STEP(); 11218 push_word(destval); 11219 } 11220 break; 11221 } 11222 break; 11223 case 1: 11224 destoffset = decode_rm01_address(rl); 11225 DECODE_PRINTF("\n"); 11226 switch (rh) { 11227 case 0: 11228 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11229 u32 destval; 11230 11231 destval = fetch_data_long(destoffset); 11232 TRACE_AND_STEP(); 11233 destval = inc_long(destval); 11234 store_data_long(destoffset, destval); 11235 } else { 11236 u16 destval; 11237 11238 destval = fetch_data_word(destoffset); 11239 TRACE_AND_STEP(); 11240 destval = inc_word(destval); 11241 store_data_word(destoffset, destval); 11242 } 11243 break; 11244 case 1: 11245 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11246 u32 destval; 11247 11248 destval = fetch_data_long(destoffset); 11249 TRACE_AND_STEP(); 11250 destval = dec_long(destval); 11251 store_data_long(destoffset, destval); 11252 } else { 11253 u16 destval; 11254 11255 destval = fetch_data_word(destoffset); 11256 TRACE_AND_STEP(); 11257 destval = dec_word(destval); 11258 store_data_word(destoffset, destval); 11259 } 11260 break; 11261 case 2: /* call word ptr ... */ 11262 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11263 u32 destval; 11264 11265 destval = fetch_data_long(destoffset); 11266 TRACE_AND_STEP(); 11267 push_long(M.x86.R_EIP); 11268 M.x86.R_EIP = destval; 11269 } else { 11270 destval = fetch_data_word(destoffset); 11271 TRACE_AND_STEP(); 11272 push_word(M.x86.R_IP); 11273 M.x86.R_IP = destval; 11274 } 11275 break; 11276 case 3: /* call far ptr ... */ 11277 destval = fetch_data_word(destoffset); 11278 destval2 = fetch_data_word(destoffset + 2); 11279 TRACE_AND_STEP(); 11280 push_word(M.x86.R_CS); 11281 M.x86.R_CS = destval2; 11282 push_word(M.x86.R_IP); 11283 M.x86.R_IP = destval; 11284 break; 11285 case 4: /* jmp word ptr ... */ 11286 destval = fetch_data_word(destoffset); 11287 TRACE_AND_STEP(); 11288 M.x86.R_IP = destval; 11289 break; 11290 case 5: /* jmp far ptr ... */ 11291 destval = fetch_data_word(destoffset); 11292 destval2 = fetch_data_word(destoffset + 2); 11293 TRACE_AND_STEP(); 11294 M.x86.R_IP = destval; 11295 M.x86.R_CS = destval2; 11296 break; 11297 case 6: /* push word ptr ... */ 11298 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11299 u32 destval; 11300 11301 destval = fetch_data_long(destoffset); 11302 TRACE_AND_STEP(); 11303 push_long(destval); 11304 } else { 11305 u16 destval; 11306 11307 destval = fetch_data_word(destoffset); 11308 TRACE_AND_STEP(); 11309 push_word(destval); 11310 } 11311 break; 11312 } 11313 break; 11314 case 2: 11315 destoffset = decode_rm10_address(rl); 11316 DECODE_PRINTF("\n"); 11317 switch (rh) { 11318 case 0: 11319 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11320 u32 destval; 11321 11322 destval = fetch_data_long(destoffset); 11323 TRACE_AND_STEP(); 11324 destval = inc_long(destval); 11325 store_data_long(destoffset, destval); 11326 } else { 11327 u16 destval; 11328 11329 destval = fetch_data_word(destoffset); 11330 TRACE_AND_STEP(); 11331 destval = inc_word(destval); 11332 store_data_word(destoffset, destval); 11333 } 11334 break; 11335 case 1: 11336 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11337 u32 destval; 11338 11339 destval = fetch_data_long(destoffset); 11340 TRACE_AND_STEP(); 11341 destval = dec_long(destval); 11342 store_data_long(destoffset, destval); 11343 } else { 11344 u16 destval; 11345 11346 destval = fetch_data_word(destoffset); 11347 TRACE_AND_STEP(); 11348 destval = dec_word(destval); 11349 store_data_word(destoffset, destval); 11350 } 11351 break; 11352 case 2: /* call word ptr ... */ 11353 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11354 u32 destval; 11355 11356 destval = fetch_data_long(destoffset); 11357 TRACE_AND_STEP(); 11358 push_long(M.x86.R_EIP); 11359 M.x86.R_EIP = destval; 11360 } else { 11361 destval = fetch_data_word(destoffset); 11362 TRACE_AND_STEP(); 11363 push_word(M.x86.R_IP); 11364 M.x86.R_IP = destval; 11365 } 11366 break; 11367 case 3: /* call far ptr ... */ 11368 destval = fetch_data_word(destoffset); 11369 destval2 = fetch_data_word(destoffset + 2); 11370 TRACE_AND_STEP(); 11371 push_word(M.x86.R_CS); 11372 M.x86.R_CS = destval2; 11373 push_word(M.x86.R_IP); 11374 M.x86.R_IP = destval; 11375 break; 11376 case 4: /* jmp word ptr ... */ 11377 destval = fetch_data_word(destoffset); 11378 TRACE_AND_STEP(); 11379 M.x86.R_IP = destval; 11380 break; 11381 case 5: /* jmp far ptr ... */ 11382 destval = fetch_data_word(destoffset); 11383 destval2 = fetch_data_word(destoffset + 2); 11384 TRACE_AND_STEP(); 11385 M.x86.R_IP = destval; 11386 M.x86.R_CS = destval2; 11387 break; 11388 case 6: /* push word ptr ... */ 11389 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11390 u32 destval; 11391 11392 destval = fetch_data_long(destoffset); 11393 TRACE_AND_STEP(); 11394 push_long(destval); 11395 } else { 11396 u16 destval; 11397 11398 destval = fetch_data_word(destoffset); 11399 TRACE_AND_STEP(); 11400 push_word(destval); 11401 } 11402 break; 11403 } 11404 break; 11405 case 3: 11406 switch (rh) { 11407 case 0: 11408 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11409 u32 *destreg; 11410 11411 destreg = DECODE_RM_LONG_REGISTER(rl); 11412 DECODE_PRINTF("\n"); 11413 TRACE_AND_STEP(); 11414 *destreg = inc_long(*destreg); 11415 } else { 11416 u16 *destreg; 11417 11418 destreg = DECODE_RM_WORD_REGISTER(rl); 11419 DECODE_PRINTF("\n"); 11420 TRACE_AND_STEP(); 11421 *destreg = inc_word(*destreg); 11422 } 11423 break; 11424 case 1: 11425 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11426 u32 *destreg; 11427 11428 destreg = DECODE_RM_LONG_REGISTER(rl); 11429 DECODE_PRINTF("\n"); 11430 TRACE_AND_STEP(); 11431 *destreg = dec_long(*destreg); 11432 } else { 11433 u16 *destreg; 11434 11435 destreg = DECODE_RM_WORD_REGISTER(rl); 11436 DECODE_PRINTF("\n"); 11437 TRACE_AND_STEP(); 11438 *destreg = dec_word(*destreg); 11439 } 11440 break; 11441 case 2: /* call word ptr ... */ 11442 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11443 u32 *destreg; 11444 11445 destreg = DECODE_RM_LONG_REGISTER(rl); 11446 DECODE_PRINTF("\n"); 11447 TRACE_AND_STEP(); 11448 push_long(M.x86.R_EIP); 11449 M.x86.R_EIP = *destreg; 11450 } else { 11451 destreg = DECODE_RM_WORD_REGISTER(rl); 11452 DECODE_PRINTF("\n"); 11453 TRACE_AND_STEP(); 11454 push_word(M.x86.R_IP); 11455 M.x86.R_IP = *destreg; 11456 } 11457 break; 11458 case 3: /* jmp far ptr ... */ 11459 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11460 TRACE_AND_STEP(); 11461 HALT_SYS(); 11462 break; 11463 11464 case 4: /* jmp ... */ 11465 destreg = DECODE_RM_WORD_REGISTER(rl); 11466 DECODE_PRINTF("\n"); 11467 TRACE_AND_STEP(); 11468 M.x86.R_IP = (u16) (*destreg); 11469 break; 11470 case 5: /* jmp far ptr ... */ 11471 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11472 TRACE_AND_STEP(); 11473 HALT_SYS(); 11474 break; 11475 case 6: 11476 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11477 u32 *destreg; 11478 11479 destreg = DECODE_RM_LONG_REGISTER(rl); 11480 DECODE_PRINTF("\n"); 11481 TRACE_AND_STEP(); 11482 push_long(*destreg); 11483 } else { 11484 u16 *destreg; 11485 11486 destreg = DECODE_RM_WORD_REGISTER(rl); 11487 DECODE_PRINTF("\n"); 11488 TRACE_AND_STEP(); 11489 push_word(*destreg); 11490 } 11491 break; 11492 } 11493 break; 11494 } 11495 DECODE_CLEAR_SEGOVR(); 11496 END_OF_INSTR(); 11497} 11498 11499/*************************************************************************** 11500 * Single byte operation code table: 11501 **************************************************************************/ 11502void (*x86emu_optab[256])(u8) = 11503{ 11504/* 0x00 */ x86emuOp_add_byte_RM_R, 11505/* 0x01 */ x86emuOp_add_word_RM_R, 11506/* 0x02 */ x86emuOp_add_byte_R_RM, 11507/* 0x03 */ x86emuOp_add_word_R_RM, 11508/* 0x04 */ x86emuOp_add_byte_AL_IMM, 11509/* 0x05 */ x86emuOp_add_word_AX_IMM, 11510/* 0x06 */ x86emuOp_push_ES, 11511/* 0x07 */ x86emuOp_pop_ES, 11512 11513/* 0x08 */ x86emuOp_or_byte_RM_R, 11514/* 0x09 */ x86emuOp_or_word_RM_R, 11515/* 0x0a */ x86emuOp_or_byte_R_RM, 11516/* 0x0b */ x86emuOp_or_word_R_RM, 11517/* 0x0c */ x86emuOp_or_byte_AL_IMM, 11518/* 0x0d */ x86emuOp_or_word_AX_IMM, 11519/* 0x0e */ x86emuOp_push_CS, 11520/* 0x0f */ x86emuOp_two_byte, 11521 11522/* 0x10 */ x86emuOp_adc_byte_RM_R, 11523/* 0x11 */ x86emuOp_adc_word_RM_R, 11524/* 0x12 */ x86emuOp_adc_byte_R_RM, 11525/* 0x13 */ x86emuOp_adc_word_R_RM, 11526/* 0x14 */ x86emuOp_adc_byte_AL_IMM, 11527/* 0x15 */ x86emuOp_adc_word_AX_IMM, 11528/* 0x16 */ x86emuOp_push_SS, 11529/* 0x17 */ x86emuOp_pop_SS, 11530 11531/* 0x18 */ x86emuOp_sbb_byte_RM_R, 11532/* 0x19 */ x86emuOp_sbb_word_RM_R, 11533/* 0x1a */ x86emuOp_sbb_byte_R_RM, 11534/* 0x1b */ x86emuOp_sbb_word_R_RM, 11535/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, 11536/* 0x1d */ x86emuOp_sbb_word_AX_IMM, 11537/* 0x1e */ x86emuOp_push_DS, 11538/* 0x1f */ x86emuOp_pop_DS, 11539 11540/* 0x20 */ x86emuOp_and_byte_RM_R, 11541/* 0x21 */ x86emuOp_and_word_RM_R, 11542/* 0x22 */ x86emuOp_and_byte_R_RM, 11543/* 0x23 */ x86emuOp_and_word_R_RM, 11544/* 0x24 */ x86emuOp_and_byte_AL_IMM, 11545/* 0x25 */ x86emuOp_and_word_AX_IMM, 11546/* 0x26 */ x86emuOp_segovr_ES, 11547/* 0x27 */ x86emuOp_daa, 11548 11549/* 0x28 */ x86emuOp_sub_byte_RM_R, 11550/* 0x29 */ x86emuOp_sub_word_RM_R, 11551/* 0x2a */ x86emuOp_sub_byte_R_RM, 11552/* 0x2b */ x86emuOp_sub_word_R_RM, 11553/* 0x2c */ x86emuOp_sub_byte_AL_IMM, 11554/* 0x2d */ x86emuOp_sub_word_AX_IMM, 11555/* 0x2e */ x86emuOp_segovr_CS, 11556/* 0x2f */ x86emuOp_das, 11557 11558/* 0x30 */ x86emuOp_xor_byte_RM_R, 11559/* 0x31 */ x86emuOp_xor_word_RM_R, 11560/* 0x32 */ x86emuOp_xor_byte_R_RM, 11561/* 0x33 */ x86emuOp_xor_word_R_RM, 11562/* 0x34 */ x86emuOp_xor_byte_AL_IMM, 11563/* 0x35 */ x86emuOp_xor_word_AX_IMM, 11564/* 0x36 */ x86emuOp_segovr_SS, 11565/* 0x37 */ x86emuOp_aaa, 11566 11567/* 0x38 */ x86emuOp_cmp_byte_RM_R, 11568/* 0x39 */ x86emuOp_cmp_word_RM_R, 11569/* 0x3a */ x86emuOp_cmp_byte_R_RM, 11570/* 0x3b */ x86emuOp_cmp_word_R_RM, 11571/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, 11572/* 0x3d */ x86emuOp_cmp_word_AX_IMM, 11573/* 0x3e */ x86emuOp_segovr_DS, 11574/* 0x3f */ x86emuOp_aas, 11575 11576/* 0x40 */ x86emuOp_inc_AX, 11577/* 0x41 */ x86emuOp_inc_CX, 11578/* 0x42 */ x86emuOp_inc_DX, 11579/* 0x43 */ x86emuOp_inc_BX, 11580/* 0x44 */ x86emuOp_inc_SP, 11581/* 0x45 */ x86emuOp_inc_BP, 11582/* 0x46 */ x86emuOp_inc_SI, 11583/* 0x47 */ x86emuOp_inc_DI, 11584 11585/* 0x48 */ x86emuOp_dec_AX, 11586/* 0x49 */ x86emuOp_dec_CX, 11587/* 0x4a */ x86emuOp_dec_DX, 11588/* 0x4b */ x86emuOp_dec_BX, 11589/* 0x4c */ x86emuOp_dec_SP, 11590/* 0x4d */ x86emuOp_dec_BP, 11591/* 0x4e */ x86emuOp_dec_SI, 11592/* 0x4f */ x86emuOp_dec_DI, 11593 11594/* 0x50 */ x86emuOp_push_AX, 11595/* 0x51 */ x86emuOp_push_CX, 11596/* 0x52 */ x86emuOp_push_DX, 11597/* 0x53 */ x86emuOp_push_BX, 11598/* 0x54 */ x86emuOp_push_SP, 11599/* 0x55 */ x86emuOp_push_BP, 11600/* 0x56 */ x86emuOp_push_SI, 11601/* 0x57 */ x86emuOp_push_DI, 11602 11603/* 0x58 */ x86emuOp_pop_AX, 11604/* 0x59 */ x86emuOp_pop_CX, 11605/* 0x5a */ x86emuOp_pop_DX, 11606/* 0x5b */ x86emuOp_pop_BX, 11607/* 0x5c */ x86emuOp_pop_SP, 11608/* 0x5d */ x86emuOp_pop_BP, 11609/* 0x5e */ x86emuOp_pop_SI, 11610/* 0x5f */ x86emuOp_pop_DI, 11611 11612/* 0x60 */ x86emuOp_push_all, 11613/* 0x61 */ x86emuOp_pop_all, 11614/* 0x62 */ x86emuOp_illegal_op, /* bound */ 11615/* 0x63 */ x86emuOp_illegal_op, /* arpl */ 11616/* 0x64 */ x86emuOp_segovr_FS, 11617/* 0x65 */ x86emuOp_segovr_GS, 11618/* 0x66 */ x86emuOp_prefix_data, 11619/* 0x67 */ x86emuOp_prefix_addr, 11620 11621/* 0x68 */ x86emuOp_push_word_IMM, 11622/* 0x69 */ x86emuOp_imul_word_IMM, 11623/* 0x6a */ x86emuOp_push_byte_IMM, 11624/* 0x6b */ x86emuOp_imul_byte_IMM, 11625/* 0x6c */ x86emuOp_ins_byte, 11626/* 0x6d */ x86emuOp_ins_word, 11627/* 0x6e */ x86emuOp_outs_byte, 11628/* 0x6f */ x86emuOp_outs_word, 11629 11630/* 0x70 */ x86emuOp_jump_near_O, 11631/* 0x71 */ x86emuOp_jump_near_NO, 11632/* 0x72 */ x86emuOp_jump_near_B, 11633/* 0x73 */ x86emuOp_jump_near_NB, 11634/* 0x74 */ x86emuOp_jump_near_Z, 11635/* 0x75 */ x86emuOp_jump_near_NZ, 11636/* 0x76 */ x86emuOp_jump_near_BE, 11637/* 0x77 */ x86emuOp_jump_near_NBE, 11638 11639/* 0x78 */ x86emuOp_jump_near_S, 11640/* 0x79 */ x86emuOp_jump_near_NS, 11641/* 0x7a */ x86emuOp_jump_near_P, 11642/* 0x7b */ x86emuOp_jump_near_NP, 11643/* 0x7c */ x86emuOp_jump_near_L, 11644/* 0x7d */ x86emuOp_jump_near_NL, 11645/* 0x7e */ x86emuOp_jump_near_LE, 11646/* 0x7f */ x86emuOp_jump_near_NLE, 11647 11648/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 11649/* 0x81 */ x86emuOp_opc81_word_RM_IMM, 11650/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 11651/* 0x83 */ x86emuOp_opc83_word_RM_IMM, 11652/* 0x84 */ x86emuOp_test_byte_RM_R, 11653/* 0x85 */ x86emuOp_test_word_RM_R, 11654/* 0x86 */ x86emuOp_xchg_byte_RM_R, 11655/* 0x87 */ x86emuOp_xchg_word_RM_R, 11656 11657/* 0x88 */ x86emuOp_mov_byte_RM_R, 11658/* 0x89 */ x86emuOp_mov_word_RM_R, 11659/* 0x8a */ x86emuOp_mov_byte_R_RM, 11660/* 0x8b */ x86emuOp_mov_word_R_RM, 11661/* 0x8c */ x86emuOp_mov_word_RM_SR, 11662/* 0x8d */ x86emuOp_lea_word_R_M, 11663/* 0x8e */ x86emuOp_mov_word_SR_RM, 11664/* 0x8f */ x86emuOp_pop_RM, 11665 11666/* 0x90 */ x86emuOp_nop, 11667/* 0x91 */ x86emuOp_xchg_word_AX_CX, 11668/* 0x92 */ x86emuOp_xchg_word_AX_DX, 11669/* 0x93 */ x86emuOp_xchg_word_AX_BX, 11670/* 0x94 */ x86emuOp_xchg_word_AX_SP, 11671/* 0x95 */ x86emuOp_xchg_word_AX_BP, 11672/* 0x96 */ x86emuOp_xchg_word_AX_SI, 11673/* 0x97 */ x86emuOp_xchg_word_AX_DI, 11674 11675/* 0x98 */ x86emuOp_cbw, 11676/* 0x99 */ x86emuOp_cwd, 11677/* 0x9a */ x86emuOp_call_far_IMM, 11678/* 0x9b */ x86emuOp_wait, 11679/* 0x9c */ x86emuOp_pushf_word, 11680/* 0x9d */ x86emuOp_popf_word, 11681/* 0x9e */ x86emuOp_sahf, 11682/* 0x9f */ x86emuOp_lahf, 11683 11684/* 0xa0 */ x86emuOp_mov_AL_M_IMM, 11685/* 0xa1 */ x86emuOp_mov_AX_M_IMM, 11686/* 0xa2 */ x86emuOp_mov_M_AL_IMM, 11687/* 0xa3 */ x86emuOp_mov_M_AX_IMM, 11688/* 0xa4 */ x86emuOp_movs_byte, 11689/* 0xa5 */ x86emuOp_movs_word, 11690/* 0xa6 */ x86emuOp_cmps_byte, 11691/* 0xa7 */ x86emuOp_cmps_word, 11692/* 0xa8 */ x86emuOp_test_AL_IMM, 11693/* 0xa9 */ x86emuOp_test_AX_IMM, 11694/* 0xaa */ x86emuOp_stos_byte, 11695/* 0xab */ x86emuOp_stos_word, 11696/* 0xac */ x86emuOp_lods_byte, 11697/* 0xad */ x86emuOp_lods_word, 11698/* 0xac */ x86emuOp_scas_byte, 11699/* 0xad */ x86emuOp_scas_word, 11700 11701 11702/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, 11703/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, 11704/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, 11705/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, 11706/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, 11707/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, 11708/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, 11709/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, 11710 11711/* 0xb8 */ x86emuOp_mov_word_AX_IMM, 11712/* 0xb9 */ x86emuOp_mov_word_CX_IMM, 11713/* 0xba */ x86emuOp_mov_word_DX_IMM, 11714/* 0xbb */ x86emuOp_mov_word_BX_IMM, 11715/* 0xbc */ x86emuOp_mov_word_SP_IMM, 11716/* 0xbd */ x86emuOp_mov_word_BP_IMM, 11717/* 0xbe */ x86emuOp_mov_word_SI_IMM, 11718/* 0xbf */ x86emuOp_mov_word_DI_IMM, 11719 11720/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 11721/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 11722/* 0xc2 */ x86emuOp_ret_near_IMM, 11723/* 0xc3 */ x86emuOp_ret_near, 11724/* 0xc4 */ x86emuOp_les_R_IMM, 11725/* 0xc5 */ x86emuOp_lds_R_IMM, 11726/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 11727/* 0xc7 */ x86emuOp_mov_word_RM_IMM, 11728/* 0xc8 */ x86emuOp_enter, 11729/* 0xc9 */ x86emuOp_leave, 11730/* 0xca */ x86emuOp_ret_far_IMM, 11731/* 0xcb */ x86emuOp_ret_far, 11732/* 0xcc */ x86emuOp_int3, 11733/* 0xcd */ x86emuOp_int_IMM, 11734/* 0xce */ x86emuOp_into, 11735/* 0xcf */ x86emuOp_iret, 11736 11737/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 11738/* 0xd1 */ x86emuOp_opcD1_word_RM_1, 11739/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 11740/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 11741/* 0xd4 */ x86emuOp_aam, 11742/* 0xd5 */ x86emuOp_aad, 11743/* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 11744/* 0xd7 */ x86emuOp_xlat, 11745/* 0xd8 */ x86emuOp_esc_coprocess_d8, 11746/* 0xd9 */ x86emuOp_esc_coprocess_d9, 11747/* 0xda */ x86emuOp_esc_coprocess_da, 11748/* 0xdb */ x86emuOp_esc_coprocess_db, 11749/* 0xdc */ x86emuOp_esc_coprocess_dc, 11750/* 0xdd */ x86emuOp_esc_coprocess_dd, 11751/* 0xde */ x86emuOp_esc_coprocess_de, 11752/* 0xdf */ x86emuOp_esc_coprocess_df, 11753 11754/* 0xe0 */ x86emuOp_loopne, 11755/* 0xe1 */ x86emuOp_loope, 11756/* 0xe2 */ x86emuOp_loop, 11757/* 0xe3 */ x86emuOp_jcxz, 11758/* 0xe4 */ x86emuOp_in_byte_AL_IMM, 11759/* 0xe5 */ x86emuOp_in_word_AX_IMM, 11760/* 0xe6 */ x86emuOp_out_byte_IMM_AL, 11761/* 0xe7 */ x86emuOp_out_word_IMM_AX, 11762 11763/* 0xe8 */ x86emuOp_call_near_IMM, 11764/* 0xe9 */ x86emuOp_jump_near_IMM, 11765/* 0xea */ x86emuOp_jump_far_IMM, 11766/* 0xeb */ x86emuOp_jump_byte_IMM, 11767/* 0xec */ x86emuOp_in_byte_AL_DX, 11768/* 0xed */ x86emuOp_in_word_AX_DX, 11769/* 0xee */ x86emuOp_out_byte_DX_AL, 11770/* 0xef */ x86emuOp_out_word_DX_AX, 11771 11772/* 0xf0 */ x86emuOp_lock, 11773/* 0xf1 */ x86emuOp_illegal_op, 11774/* 0xf2 */ x86emuOp_repne, 11775/* 0xf3 */ x86emuOp_repe, 11776/* 0xf4 */ x86emuOp_halt, 11777/* 0xf5 */ x86emuOp_cmc, 11778/* 0xf6 */ x86emuOp_opcF6_byte_RM, 11779/* 0xf7 */ x86emuOp_opcF7_word_RM, 11780 11781/* 0xf8 */ x86emuOp_clc, 11782/* 0xf9 */ x86emuOp_stc, 11783/* 0xfa */ x86emuOp_cli, 11784/* 0xfb */ x86emuOp_sti, 11785/* 0xfc */ x86emuOp_cld, 11786/* 0xfd */ x86emuOp_std, 11787/* 0xfe */ x86emuOp_opcFE_byte_RM, 11788/* 0xff */ x86emuOp_opcFF_word_RM, 11789}; 11790