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/* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */ 74 75#include "x86emu/x86emui.h" 76#include "x86emu/ops_protos.h" 77#include "lib_printf.h" 78 79/*----------------------------- Implementation ----------------------------*/ 80 81/**************************************************************************** 82PARAMETERS: 83op1 - Instruction op code 84 85REMARKS: 86Handles illegal opcodes. 87****************************************************************************/ 88void x86emuOp_illegal_op( 89 u8 op1) 90{ 91 START_OF_INSTR(); 92 DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); 93 TRACE_REGS(); 94 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", 95 M.x86.R_CS, M.x86.R_IP-1,op1); 96 HALT_SYS(); 97 END_OF_INSTR(); 98} 99 100/**************************************************************************** 101REMARKS: 102Handles opcode 0x00 103****************************************************************************/ 104void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1)) 105{ 106 int mod, rl, rh; 107 uint destoffset; 108 u8 *destreg, *srcreg; 109 u8 destval; 110 111 START_OF_INSTR(); 112 DECODE_PRINTF("ADD\t"); 113 FETCH_DECODE_MODRM(mod, rh, rl); 114 switch (mod) { 115 case 0: 116 destoffset = decode_rm00_address(rl); 117 DECODE_PRINTF(","); 118 destval = fetch_data_byte(destoffset); 119 srcreg = DECODE_RM_BYTE_REGISTER(rh); 120 DECODE_PRINTF("\n"); 121 TRACE_AND_STEP(); 122 destval = add_byte(destval, *srcreg); 123 store_data_byte(destoffset, destval); 124 break; 125 case 1: 126 destoffset = decode_rm01_address(rl); 127 DECODE_PRINTF(","); 128 destval = fetch_data_byte(destoffset); 129 srcreg = DECODE_RM_BYTE_REGISTER(rh); 130 DECODE_PRINTF("\n"); 131 TRACE_AND_STEP(); 132 destval = add_byte(destval, *srcreg); 133 store_data_byte(destoffset, destval); 134 break; 135 case 2: 136 destoffset = decode_rm10_address(rl); 137 DECODE_PRINTF(","); 138 destval = fetch_data_byte(destoffset); 139 srcreg = DECODE_RM_BYTE_REGISTER(rh); 140 DECODE_PRINTF("\n"); 141 TRACE_AND_STEP(); 142 destval = add_byte(destval, *srcreg); 143 store_data_byte(destoffset, destval); 144 break; 145 case 3: /* register to register */ 146 destreg = DECODE_RM_BYTE_REGISTER(rl); 147 DECODE_PRINTF(","); 148 srcreg = DECODE_RM_BYTE_REGISTER(rh); 149 DECODE_PRINTF("\n"); 150 TRACE_AND_STEP(); 151 *destreg = add_byte(*destreg, *srcreg); 152 break; 153 } 154 DECODE_CLEAR_SEGOVR(); 155 END_OF_INSTR(); 156} 157 158/**************************************************************************** 159REMARKS: 160Handles opcode 0x01 161****************************************************************************/ 162void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1)) 163{ 164 int mod, rl, rh; 165 uint destoffset; 166 167 START_OF_INSTR(); 168 DECODE_PRINTF("ADD\t"); 169 FETCH_DECODE_MODRM(mod, rh, rl); 170 switch (mod) { 171 case 0: 172 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 173 u32 destval; 174 u32 *srcreg; 175 176 destoffset = decode_rm00_address(rl); 177 DECODE_PRINTF(","); 178 destval = fetch_data_long(destoffset); 179 srcreg = DECODE_RM_LONG_REGISTER(rh); 180 DECODE_PRINTF("\n"); 181 TRACE_AND_STEP(); 182 destval = add_long(destval, *srcreg); 183 store_data_long(destoffset, destval); 184 } else { 185 u16 destval; 186 u16 *srcreg; 187 188 destoffset = decode_rm00_address(rl); 189 DECODE_PRINTF(","); 190 destval = fetch_data_word(destoffset); 191 srcreg = DECODE_RM_WORD_REGISTER(rh); 192 DECODE_PRINTF("\n"); 193 TRACE_AND_STEP(); 194 destval = add_word(destval, *srcreg); 195 store_data_word(destoffset, destval); 196 } 197 break; 198 case 1: 199 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 200 u32 destval; 201 u32 *srcreg; 202 203 destoffset = decode_rm01_address(rl); 204 DECODE_PRINTF(","); 205 destval = fetch_data_long(destoffset); 206 srcreg = DECODE_RM_LONG_REGISTER(rh); 207 DECODE_PRINTF("\n"); 208 TRACE_AND_STEP(); 209 destval = add_long(destval, *srcreg); 210 store_data_long(destoffset, destval); 211 } else { 212 u16 destval; 213 u16 *srcreg; 214 215 destoffset = decode_rm01_address(rl); 216 DECODE_PRINTF(","); 217 destval = fetch_data_word(destoffset); 218 srcreg = DECODE_RM_WORD_REGISTER(rh); 219 DECODE_PRINTF("\n"); 220 TRACE_AND_STEP(); 221 destval = add_word(destval, *srcreg); 222 store_data_word(destoffset, destval); 223 } 224 break; 225 case 2: 226 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 227 u32 destval; 228 u32 *srcreg; 229 230 destoffset = decode_rm10_address(rl); 231 DECODE_PRINTF(","); 232 destval = fetch_data_long(destoffset); 233 srcreg = DECODE_RM_LONG_REGISTER(rh); 234 DECODE_PRINTF("\n"); 235 TRACE_AND_STEP(); 236 destval = add_long(destval, *srcreg); 237 store_data_long(destoffset, destval); 238 } else { 239 u16 destval; 240 u16 *srcreg; 241 242 destoffset = decode_rm10_address(rl); 243 DECODE_PRINTF(","); 244 destval = fetch_data_word(destoffset); 245 srcreg = DECODE_RM_WORD_REGISTER(rh); 246 DECODE_PRINTF("\n"); 247 TRACE_AND_STEP(); 248 destval = add_word(destval, *srcreg); 249 store_data_word(destoffset, destval); 250 } 251 break; 252 case 3: /* register to register */ 253 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 254 u32 *destreg,*srcreg; 255 256 destreg = DECODE_RM_LONG_REGISTER(rl); 257 DECODE_PRINTF(","); 258 srcreg = DECODE_RM_LONG_REGISTER(rh); 259 DECODE_PRINTF("\n"); 260 TRACE_AND_STEP(); 261 *destreg = add_long(*destreg, *srcreg); 262 } else { 263 u16 *destreg,*srcreg; 264 265 destreg = DECODE_RM_WORD_REGISTER(rl); 266 DECODE_PRINTF(","); 267 srcreg = DECODE_RM_WORD_REGISTER(rh); 268 DECODE_PRINTF("\n"); 269 TRACE_AND_STEP(); 270 *destreg = add_word(*destreg, *srcreg); 271 } 272 break; 273 } 274 DECODE_CLEAR_SEGOVR(); 275 END_OF_INSTR(); 276} 277 278/**************************************************************************** 279REMARKS: 280Handles opcode 0x02 281****************************************************************************/ 282void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1)) 283{ 284 int mod, rl, rh; 285 u8 *destreg, *srcreg; 286 uint srcoffset; 287 u8 srcval; 288 289 START_OF_INSTR(); 290 DECODE_PRINTF("ADD\t"); 291 FETCH_DECODE_MODRM(mod, rh, rl); 292 switch (mod) { 293 case 0: 294 destreg = DECODE_RM_BYTE_REGISTER(rh); 295 DECODE_PRINTF(","); 296 srcoffset = decode_rm00_address(rl); 297 srcval = fetch_data_byte(srcoffset); 298 DECODE_PRINTF("\n"); 299 TRACE_AND_STEP(); 300 *destreg = add_byte(*destreg, srcval); 301 break; 302 case 1: 303 destreg = DECODE_RM_BYTE_REGISTER(rh); 304 DECODE_PRINTF(","); 305 srcoffset = decode_rm01_address(rl); 306 srcval = fetch_data_byte(srcoffset); 307 DECODE_PRINTF("\n"); 308 TRACE_AND_STEP(); 309 *destreg = add_byte(*destreg, srcval); 310 break; 311 case 2: 312 destreg = DECODE_RM_BYTE_REGISTER(rh); 313 DECODE_PRINTF(","); 314 srcoffset = decode_rm10_address(rl); 315 srcval = fetch_data_byte(srcoffset); 316 DECODE_PRINTF("\n"); 317 TRACE_AND_STEP(); 318 *destreg = add_byte(*destreg, srcval); 319 break; 320 case 3: /* register to register */ 321 destreg = DECODE_RM_BYTE_REGISTER(rh); 322 DECODE_PRINTF(","); 323 srcreg = DECODE_RM_BYTE_REGISTER(rl); 324 DECODE_PRINTF("\n"); 325 TRACE_AND_STEP(); 326 *destreg = add_byte(*destreg, *srcreg); 327 break; 328 } 329 DECODE_CLEAR_SEGOVR(); 330 END_OF_INSTR(); 331} 332 333/**************************************************************************** 334REMARKS: 335Handles opcode 0x03 336****************************************************************************/ 337void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1)) 338{ 339 int mod, rl, rh; 340 uint srcoffset; 341 342 START_OF_INSTR(); 343 DECODE_PRINTF("ADD\t"); 344 FETCH_DECODE_MODRM(mod, rh, rl); 345 switch (mod) { 346 case 0: 347 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 348 u32 *destreg; 349 u32 srcval; 350 351 destreg = DECODE_RM_LONG_REGISTER(rh); 352 DECODE_PRINTF(","); 353 srcoffset = decode_rm00_address(rl); 354 srcval = fetch_data_long(srcoffset); 355 DECODE_PRINTF("\n"); 356 TRACE_AND_STEP(); 357 *destreg = add_long(*destreg, srcval); 358 } else { 359 u16 *destreg; 360 u16 srcval; 361 362 destreg = DECODE_RM_WORD_REGISTER(rh); 363 DECODE_PRINTF(","); 364 srcoffset = decode_rm00_address(rl); 365 srcval = fetch_data_word(srcoffset); 366 DECODE_PRINTF("\n"); 367 TRACE_AND_STEP(); 368 *destreg = add_word(*destreg, srcval); 369 } 370 break; 371 case 1: 372 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 373 u32 *destreg; 374 u32 srcval; 375 376 destreg = DECODE_RM_LONG_REGISTER(rh); 377 DECODE_PRINTF(","); 378 srcoffset = decode_rm01_address(rl); 379 srcval = fetch_data_long(srcoffset); 380 DECODE_PRINTF("\n"); 381 TRACE_AND_STEP(); 382 *destreg = add_long(*destreg, srcval); 383 } else { 384 u16 *destreg; 385 u16 srcval; 386 387 destreg = DECODE_RM_WORD_REGISTER(rh); 388 DECODE_PRINTF(","); 389 srcoffset = decode_rm01_address(rl); 390 srcval = fetch_data_word(srcoffset); 391 DECODE_PRINTF("\n"); 392 TRACE_AND_STEP(); 393 *destreg = add_word(*destreg, srcval); 394 } 395 break; 396 case 2: 397 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 398 u32 *destreg; 399 u32 srcval; 400 401 destreg = DECODE_RM_LONG_REGISTER(rh); 402 DECODE_PRINTF(","); 403 srcoffset = decode_rm10_address(rl); 404 srcval = fetch_data_long(srcoffset); 405 DECODE_PRINTF("\n"); 406 TRACE_AND_STEP(); 407 *destreg = add_long(*destreg, srcval); 408 } else { 409 u16 *destreg; 410 u16 srcval; 411 412 destreg = DECODE_RM_WORD_REGISTER(rh); 413 DECODE_PRINTF(","); 414 srcoffset = decode_rm10_address(rl); 415 srcval = fetch_data_word(srcoffset); 416 DECODE_PRINTF("\n"); 417 TRACE_AND_STEP(); 418 *destreg = add_word(*destreg, srcval); 419 } 420 break; 421 case 3: /* register to register */ 422 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 423 u32 *destreg,*srcreg; 424 425 destreg = DECODE_RM_LONG_REGISTER(rh); 426 DECODE_PRINTF(","); 427 srcreg = DECODE_RM_LONG_REGISTER(rl); 428 DECODE_PRINTF("\n"); 429 TRACE_AND_STEP(); 430 *destreg = add_long(*destreg, *srcreg); 431 } else { 432 u16 *destreg,*srcreg; 433 434 destreg = DECODE_RM_WORD_REGISTER(rh); 435 DECODE_PRINTF(","); 436 srcreg = DECODE_RM_WORD_REGISTER(rl); 437 DECODE_PRINTF("\n"); 438 TRACE_AND_STEP(); 439 *destreg = add_word(*destreg, *srcreg); 440 } 441 break; 442 } 443 DECODE_CLEAR_SEGOVR(); 444 END_OF_INSTR(); 445} 446 447/**************************************************************************** 448REMARKS: 449Handles opcode 0x04 450****************************************************************************/ 451void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 452{ 453 u8 srcval; 454 455 START_OF_INSTR(); 456 DECODE_PRINTF("ADD\tAL,"); 457 srcval = fetch_byte_imm(); 458 DECODE_PRINTF2("%x\n", srcval); 459 TRACE_AND_STEP(); 460 M.x86.R_AL = add_byte(M.x86.R_AL, srcval); 461 DECODE_CLEAR_SEGOVR(); 462 END_OF_INSTR(); 463} 464 465/**************************************************************************** 466REMARKS: 467Handles opcode 0x05 468****************************************************************************/ 469void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 470{ 471 u32 srcval; 472 473 START_OF_INSTR(); 474 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 475 DECODE_PRINTF("ADD\tEAX,"); 476 srcval = fetch_long_imm(); 477 } else { 478 DECODE_PRINTF("ADD\tAX,"); 479 srcval = fetch_word_imm(); 480 } 481 DECODE_PRINTF2("%x\n", srcval); 482 TRACE_AND_STEP(); 483 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 484 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval); 485 } else { 486 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval); 487 } 488 DECODE_CLEAR_SEGOVR(); 489 END_OF_INSTR(); 490} 491 492/**************************************************************************** 493REMARKS: 494Handles opcode 0x06 495****************************************************************************/ 496void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 497{ 498 START_OF_INSTR(); 499 DECODE_PRINTF("PUSH\tES\n"); 500 TRACE_AND_STEP(); 501 push_word(M.x86.R_ES); 502 DECODE_CLEAR_SEGOVR(); 503 END_OF_INSTR(); 504} 505 506/**************************************************************************** 507REMARKS: 508Handles opcode 0x07 509****************************************************************************/ 510void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 511{ 512 START_OF_INSTR(); 513 DECODE_PRINTF("POP\tES\n"); 514 TRACE_AND_STEP(); 515 M.x86.R_ES = pop_word(); 516 DECODE_CLEAR_SEGOVR(); 517 END_OF_INSTR(); 518} 519 520/**************************************************************************** 521REMARKS: 522Handles opcode 0x08 523****************************************************************************/ 524void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1)) 525{ 526 int mod, rl, rh; 527 u8 *destreg, *srcreg; 528 uint destoffset; 529 u8 destval; 530 531 START_OF_INSTR(); 532 DECODE_PRINTF("OR\t"); 533 FETCH_DECODE_MODRM(mod, rh, rl); 534 switch (mod) { 535 case 0: 536 destoffset = decode_rm00_address(rl); 537 DECODE_PRINTF(","); 538 destval = fetch_data_byte(destoffset); 539 srcreg = DECODE_RM_BYTE_REGISTER(rh); 540 DECODE_PRINTF("\n"); 541 TRACE_AND_STEP(); 542 destval = or_byte(destval, *srcreg); 543 store_data_byte(destoffset, destval); 544 break; 545 case 1: 546 destoffset = decode_rm01_address(rl); 547 DECODE_PRINTF(","); 548 destval = fetch_data_byte(destoffset); 549 srcreg = DECODE_RM_BYTE_REGISTER(rh); 550 DECODE_PRINTF("\n"); 551 TRACE_AND_STEP(); 552 destval = or_byte(destval, *srcreg); 553 store_data_byte(destoffset, destval); 554 break; 555 case 2: 556 destoffset = decode_rm10_address(rl); 557 DECODE_PRINTF(","); 558 destval = fetch_data_byte(destoffset); 559 srcreg = DECODE_RM_BYTE_REGISTER(rh); 560 DECODE_PRINTF("\n"); 561 TRACE_AND_STEP(); 562 destval = or_byte(destval, *srcreg); 563 store_data_byte(destoffset, destval); 564 break; 565 case 3: /* register to register */ 566 destreg = DECODE_RM_BYTE_REGISTER(rl); 567 DECODE_PRINTF(","); 568 srcreg = DECODE_RM_BYTE_REGISTER(rh); 569 DECODE_PRINTF("\n"); 570 TRACE_AND_STEP(); 571 *destreg = or_byte(*destreg, *srcreg); 572 break; 573 } 574 DECODE_CLEAR_SEGOVR(); 575 END_OF_INSTR(); 576} 577 578/**************************************************************************** 579REMARKS: 580Handles opcode 0x09 581****************************************************************************/ 582void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1)) 583{ 584 int mod, rl, rh; 585 uint destoffset; 586 587 START_OF_INSTR(); 588 DECODE_PRINTF("OR\t"); 589 FETCH_DECODE_MODRM(mod, rh, rl); 590 switch (mod) { 591 case 0: 592 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 593 u32 destval; 594 u32 *srcreg; 595 596 destoffset = decode_rm00_address(rl); 597 DECODE_PRINTF(","); 598 destval = fetch_data_long(destoffset); 599 srcreg = DECODE_RM_LONG_REGISTER(rh); 600 DECODE_PRINTF("\n"); 601 TRACE_AND_STEP(); 602 destval = or_long(destval, *srcreg); 603 store_data_long(destoffset, destval); 604 } else { 605 u16 destval; 606 u16 *srcreg; 607 608 destoffset = decode_rm00_address(rl); 609 DECODE_PRINTF(","); 610 destval = fetch_data_word(destoffset); 611 srcreg = DECODE_RM_WORD_REGISTER(rh); 612 DECODE_PRINTF("\n"); 613 TRACE_AND_STEP(); 614 destval = or_word(destval, *srcreg); 615 store_data_word(destoffset, destval); 616 } 617 break; 618 case 1: 619 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 620 u32 destval; 621 u32 *srcreg; 622 623 destoffset = decode_rm01_address(rl); 624 DECODE_PRINTF(","); 625 destval = fetch_data_long(destoffset); 626 srcreg = DECODE_RM_LONG_REGISTER(rh); 627 DECODE_PRINTF("\n"); 628 TRACE_AND_STEP(); 629 destval = or_long(destval, *srcreg); 630 store_data_long(destoffset, destval); 631 } else { 632 u16 destval; 633 u16 *srcreg; 634 635 destoffset = decode_rm01_address(rl); 636 DECODE_PRINTF(","); 637 destval = fetch_data_word(destoffset); 638 srcreg = DECODE_RM_WORD_REGISTER(rh); 639 DECODE_PRINTF("\n"); 640 TRACE_AND_STEP(); 641 destval = or_word(destval, *srcreg); 642 store_data_word(destoffset, destval); 643 } 644 break; 645 case 2: 646 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 647 u32 destval; 648 u32 *srcreg; 649 650 destoffset = decode_rm10_address(rl); 651 DECODE_PRINTF(","); 652 destval = fetch_data_long(destoffset); 653 srcreg = DECODE_RM_LONG_REGISTER(rh); 654 DECODE_PRINTF("\n"); 655 TRACE_AND_STEP(); 656 destval = or_long(destval, *srcreg); 657 store_data_long(destoffset, destval); 658 } else { 659 u16 destval; 660 u16 *srcreg; 661 662 destoffset = decode_rm10_address(rl); 663 DECODE_PRINTF(","); 664 destval = fetch_data_word(destoffset); 665 srcreg = DECODE_RM_WORD_REGISTER(rh); 666 DECODE_PRINTF("\n"); 667 TRACE_AND_STEP(); 668 destval = or_word(destval, *srcreg); 669 store_data_word(destoffset, destval); 670 } 671 break; 672 case 3: /* register to register */ 673 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 674 u32 *destreg,*srcreg; 675 676 destreg = DECODE_RM_LONG_REGISTER(rl); 677 DECODE_PRINTF(","); 678 srcreg = DECODE_RM_LONG_REGISTER(rh); 679 DECODE_PRINTF("\n"); 680 TRACE_AND_STEP(); 681 *destreg = or_long(*destreg, *srcreg); 682 } else { 683 u16 *destreg,*srcreg; 684 685 destreg = DECODE_RM_WORD_REGISTER(rl); 686 DECODE_PRINTF(","); 687 srcreg = DECODE_RM_WORD_REGISTER(rh); 688 DECODE_PRINTF("\n"); 689 TRACE_AND_STEP(); 690 *destreg = or_word(*destreg, *srcreg); 691 } 692 break; 693 } 694 DECODE_CLEAR_SEGOVR(); 695 END_OF_INSTR(); 696} 697 698/**************************************************************************** 699REMARKS: 700Handles opcode 0x0a 701****************************************************************************/ 702void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1)) 703{ 704 int mod, rl, rh; 705 u8 *destreg, *srcreg; 706 uint srcoffset; 707 u8 srcval; 708 709 START_OF_INSTR(); 710 DECODE_PRINTF("OR\t"); 711 FETCH_DECODE_MODRM(mod, rh, rl); 712 switch (mod) { 713 case 0: 714 destreg = DECODE_RM_BYTE_REGISTER(rh); 715 DECODE_PRINTF(","); 716 srcoffset = decode_rm00_address(rl); 717 srcval = fetch_data_byte(srcoffset); 718 DECODE_PRINTF("\n"); 719 TRACE_AND_STEP(); 720 *destreg = or_byte(*destreg, srcval); 721 break; 722 case 1: 723 destreg = DECODE_RM_BYTE_REGISTER(rh); 724 DECODE_PRINTF(","); 725 srcoffset = decode_rm01_address(rl); 726 srcval = fetch_data_byte(srcoffset); 727 DECODE_PRINTF("\n"); 728 TRACE_AND_STEP(); 729 *destreg = or_byte(*destreg, srcval); 730 break; 731 case 2: 732 destreg = DECODE_RM_BYTE_REGISTER(rh); 733 DECODE_PRINTF(","); 734 srcoffset = decode_rm10_address(rl); 735 srcval = fetch_data_byte(srcoffset); 736 DECODE_PRINTF("\n"); 737 TRACE_AND_STEP(); 738 *destreg = or_byte(*destreg, srcval); 739 break; 740 case 3: /* register to register */ 741 destreg = DECODE_RM_BYTE_REGISTER(rh); 742 DECODE_PRINTF(","); 743 srcreg = DECODE_RM_BYTE_REGISTER(rl); 744 DECODE_PRINTF("\n"); 745 TRACE_AND_STEP(); 746 *destreg = or_byte(*destreg, *srcreg); 747 break; 748 } 749 DECODE_CLEAR_SEGOVR(); 750 END_OF_INSTR(); 751} 752 753/**************************************************************************** 754REMARKS: 755Handles opcode 0x0b 756****************************************************************************/ 757void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1)) 758{ 759 int mod, rl, rh; 760 uint srcoffset; 761 762 START_OF_INSTR(); 763 DECODE_PRINTF("OR\t"); 764 FETCH_DECODE_MODRM(mod, rh, rl); 765 switch (mod) { 766 case 0: 767 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 768 u32 *destreg; 769 u32 srcval; 770 771 destreg = DECODE_RM_LONG_REGISTER(rh); 772 DECODE_PRINTF(","); 773 srcoffset = decode_rm00_address(rl); 774 srcval = fetch_data_long(srcoffset); 775 DECODE_PRINTF("\n"); 776 TRACE_AND_STEP(); 777 *destreg = or_long(*destreg, srcval); 778 } else { 779 u16 *destreg; 780 u16 srcval; 781 782 destreg = DECODE_RM_WORD_REGISTER(rh); 783 DECODE_PRINTF(","); 784 srcoffset = decode_rm00_address(rl); 785 srcval = fetch_data_word(srcoffset); 786 DECODE_PRINTF("\n"); 787 TRACE_AND_STEP(); 788 *destreg = or_word(*destreg, srcval); 789 } 790 break; 791 case 1: 792 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 793 u32 *destreg; 794 u32 srcval; 795 796 destreg = DECODE_RM_LONG_REGISTER(rh); 797 DECODE_PRINTF(","); 798 srcoffset = decode_rm01_address(rl); 799 srcval = fetch_data_long(srcoffset); 800 DECODE_PRINTF("\n"); 801 TRACE_AND_STEP(); 802 *destreg = or_long(*destreg, srcval); 803 } else { 804 u16 *destreg; 805 u16 srcval; 806 807 destreg = DECODE_RM_WORD_REGISTER(rh); 808 DECODE_PRINTF(","); 809 srcoffset = decode_rm01_address(rl); 810 srcval = fetch_data_word(srcoffset); 811 DECODE_PRINTF("\n"); 812 TRACE_AND_STEP(); 813 *destreg = or_word(*destreg, srcval); 814 } 815 break; 816 case 2: 817 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 818 u32 *destreg; 819 u32 srcval; 820 821 destreg = DECODE_RM_LONG_REGISTER(rh); 822 DECODE_PRINTF(","); 823 srcoffset = decode_rm10_address(rl); 824 srcval = fetch_data_long(srcoffset); 825 DECODE_PRINTF("\n"); 826 TRACE_AND_STEP(); 827 *destreg = or_long(*destreg, srcval); 828 } else { 829 u16 *destreg; 830 u16 srcval; 831 832 destreg = DECODE_RM_WORD_REGISTER(rh); 833 DECODE_PRINTF(","); 834 srcoffset = decode_rm10_address(rl); 835 srcval = fetch_data_word(srcoffset); 836 DECODE_PRINTF("\n"); 837 TRACE_AND_STEP(); 838 *destreg = or_word(*destreg, srcval); 839 } 840 break; 841 case 3: /* register to register */ 842 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 843 u32 *destreg,*srcreg; 844 845 destreg = DECODE_RM_LONG_REGISTER(rh); 846 DECODE_PRINTF(","); 847 srcreg = DECODE_RM_LONG_REGISTER(rl); 848 DECODE_PRINTF("\n"); 849 TRACE_AND_STEP(); 850 *destreg = or_long(*destreg, *srcreg); 851 } else { 852 u16 *destreg,*srcreg; 853 854 destreg = DECODE_RM_WORD_REGISTER(rh); 855 DECODE_PRINTF(","); 856 srcreg = DECODE_RM_WORD_REGISTER(rl); 857 DECODE_PRINTF("\n"); 858 TRACE_AND_STEP(); 859 *destreg = or_word(*destreg, *srcreg); 860 } 861 break; 862 } 863 DECODE_CLEAR_SEGOVR(); 864 END_OF_INSTR(); 865} 866 867/**************************************************************************** 868REMARKS: 869Handles opcode 0x0c 870****************************************************************************/ 871void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 872{ 873 u8 srcval; 874 875 START_OF_INSTR(); 876 DECODE_PRINTF("OR\tAL,"); 877 srcval = fetch_byte_imm(); 878 DECODE_PRINTF2("%x\n", srcval); 879 TRACE_AND_STEP(); 880 M.x86.R_AL = or_byte(M.x86.R_AL, srcval); 881 DECODE_CLEAR_SEGOVR(); 882 END_OF_INSTR(); 883} 884 885/**************************************************************************** 886REMARKS: 887Handles opcode 0x0d 888****************************************************************************/ 889void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 890{ 891 u32 srcval; 892 893 START_OF_INSTR(); 894 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 895 DECODE_PRINTF("OR\tEAX,"); 896 srcval = fetch_long_imm(); 897 } else { 898 DECODE_PRINTF("OR\tAX,"); 899 srcval = fetch_word_imm(); 900 } 901 DECODE_PRINTF2("%x\n", srcval); 902 TRACE_AND_STEP(); 903 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 904 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval); 905 } else { 906 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval); 907 } 908 DECODE_CLEAR_SEGOVR(); 909 END_OF_INSTR(); 910} 911 912/**************************************************************************** 913REMARKS: 914Handles opcode 0x0e 915****************************************************************************/ 916void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 917{ 918 START_OF_INSTR(); 919 DECODE_PRINTF("PUSH\tCS\n"); 920 TRACE_AND_STEP(); 921 push_word(M.x86.R_CS); 922 DECODE_CLEAR_SEGOVR(); 923 END_OF_INSTR(); 924} 925 926/**************************************************************************** 927REMARKS: 928Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 929****************************************************************************/ 930void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 931{ 932 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 933 INC_DECODED_INST_LEN(1); 934 (*x86emu_optab2[op2])(op2); 935} 936 937/**************************************************************************** 938REMARKS: 939Handles opcode 0x10 940****************************************************************************/ 941void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1)) 942{ 943 int mod, rl, rh; 944 u8 *destreg, *srcreg; 945 uint destoffset; 946 u8 destval; 947 948 START_OF_INSTR(); 949 DECODE_PRINTF("ADC\t"); 950 FETCH_DECODE_MODRM(mod, rh, rl); 951 switch (mod) { 952 case 0: 953 destoffset = decode_rm00_address(rl); 954 DECODE_PRINTF(","); 955 destval = fetch_data_byte(destoffset); 956 srcreg = DECODE_RM_BYTE_REGISTER(rh); 957 DECODE_PRINTF("\n"); 958 TRACE_AND_STEP(); 959 destval = adc_byte(destval, *srcreg); 960 store_data_byte(destoffset, destval); 961 break; 962 case 1: 963 destoffset = decode_rm01_address(rl); 964 DECODE_PRINTF(","); 965 destval = fetch_data_byte(destoffset); 966 srcreg = DECODE_RM_BYTE_REGISTER(rh); 967 DECODE_PRINTF("\n"); 968 TRACE_AND_STEP(); 969 destval = adc_byte(destval, *srcreg); 970 store_data_byte(destoffset, destval); 971 break; 972 case 2: 973 destoffset = decode_rm10_address(rl); 974 DECODE_PRINTF(","); 975 destval = fetch_data_byte(destoffset); 976 srcreg = DECODE_RM_BYTE_REGISTER(rh); 977 DECODE_PRINTF("\n"); 978 TRACE_AND_STEP(); 979 destval = adc_byte(destval, *srcreg); 980 store_data_byte(destoffset, destval); 981 break; 982 case 3: /* register to register */ 983 destreg = DECODE_RM_BYTE_REGISTER(rl); 984 DECODE_PRINTF(","); 985 srcreg = DECODE_RM_BYTE_REGISTER(rh); 986 DECODE_PRINTF("\n"); 987 TRACE_AND_STEP(); 988 *destreg = adc_byte(*destreg, *srcreg); 989 break; 990 } 991 DECODE_CLEAR_SEGOVR(); 992 END_OF_INSTR(); 993} 994 995/**************************************************************************** 996REMARKS: 997Handles opcode 0x11 998****************************************************************************/ 999void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1)) 1000{ 1001 int mod, rl, rh; 1002 uint destoffset; 1003 1004 START_OF_INSTR(); 1005 DECODE_PRINTF("ADC\t"); 1006 FETCH_DECODE_MODRM(mod, rh, rl); 1007 switch (mod) { 1008 case 0: 1009 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1010 u32 destval; 1011 u32 *srcreg; 1012 1013 destoffset = decode_rm00_address(rl); 1014 DECODE_PRINTF(","); 1015 destval = fetch_data_long(destoffset); 1016 srcreg = DECODE_RM_LONG_REGISTER(rh); 1017 DECODE_PRINTF("\n"); 1018 TRACE_AND_STEP(); 1019 destval = adc_long(destval, *srcreg); 1020 store_data_long(destoffset, destval); 1021 } else { 1022 u16 destval; 1023 u16 *srcreg; 1024 1025 destoffset = decode_rm00_address(rl); 1026 DECODE_PRINTF(","); 1027 destval = fetch_data_word(destoffset); 1028 srcreg = DECODE_RM_WORD_REGISTER(rh); 1029 DECODE_PRINTF("\n"); 1030 TRACE_AND_STEP(); 1031 destval = adc_word(destval, *srcreg); 1032 store_data_word(destoffset, destval); 1033 } 1034 break; 1035 case 1: 1036 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1037 u32 destval; 1038 u32 *srcreg; 1039 1040 destoffset = decode_rm01_address(rl); 1041 DECODE_PRINTF(","); 1042 destval = fetch_data_long(destoffset); 1043 srcreg = DECODE_RM_LONG_REGISTER(rh); 1044 DECODE_PRINTF("\n"); 1045 TRACE_AND_STEP(); 1046 destval = adc_long(destval, *srcreg); 1047 store_data_long(destoffset, destval); 1048 } else { 1049 u16 destval; 1050 u16 *srcreg; 1051 1052 destoffset = decode_rm01_address(rl); 1053 DECODE_PRINTF(","); 1054 destval = fetch_data_word(destoffset); 1055 srcreg = DECODE_RM_WORD_REGISTER(rh); 1056 DECODE_PRINTF("\n"); 1057 TRACE_AND_STEP(); 1058 destval = adc_word(destval, *srcreg); 1059 store_data_word(destoffset, destval); 1060 } 1061 break; 1062 case 2: 1063 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1064 u32 destval; 1065 u32 *srcreg; 1066 1067 destoffset = decode_rm10_address(rl); 1068 DECODE_PRINTF(","); 1069 destval = fetch_data_long(destoffset); 1070 srcreg = DECODE_RM_LONG_REGISTER(rh); 1071 DECODE_PRINTF("\n"); 1072 TRACE_AND_STEP(); 1073 destval = adc_long(destval, *srcreg); 1074 store_data_long(destoffset, destval); 1075 } else { 1076 u16 destval; 1077 u16 *srcreg; 1078 1079 destoffset = decode_rm10_address(rl); 1080 DECODE_PRINTF(","); 1081 destval = fetch_data_word(destoffset); 1082 srcreg = DECODE_RM_WORD_REGISTER(rh); 1083 DECODE_PRINTF("\n"); 1084 TRACE_AND_STEP(); 1085 destval = adc_word(destval, *srcreg); 1086 store_data_word(destoffset, destval); 1087 } 1088 break; 1089 case 3: /* register to register */ 1090 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1091 u32 *destreg,*srcreg; 1092 1093 destreg = DECODE_RM_LONG_REGISTER(rl); 1094 DECODE_PRINTF(","); 1095 srcreg = DECODE_RM_LONG_REGISTER(rh); 1096 DECODE_PRINTF("\n"); 1097 TRACE_AND_STEP(); 1098 *destreg = adc_long(*destreg, *srcreg); 1099 } else { 1100 u16 *destreg,*srcreg; 1101 1102 destreg = DECODE_RM_WORD_REGISTER(rl); 1103 DECODE_PRINTF(","); 1104 srcreg = DECODE_RM_WORD_REGISTER(rh); 1105 DECODE_PRINTF("\n"); 1106 TRACE_AND_STEP(); 1107 *destreg = adc_word(*destreg, *srcreg); 1108 } 1109 break; 1110 } 1111 DECODE_CLEAR_SEGOVR(); 1112 END_OF_INSTR(); 1113} 1114 1115/**************************************************************************** 1116REMARKS: 1117Handles opcode 0x12 1118****************************************************************************/ 1119void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1120{ 1121 int mod, rl, rh; 1122 u8 *destreg, *srcreg; 1123 uint srcoffset; 1124 u8 srcval; 1125 1126 START_OF_INSTR(); 1127 DECODE_PRINTF("ADC\t"); 1128 FETCH_DECODE_MODRM(mod, rh, rl); 1129 switch (mod) { 1130 case 0: 1131 destreg = DECODE_RM_BYTE_REGISTER(rh); 1132 DECODE_PRINTF(","); 1133 srcoffset = decode_rm00_address(rl); 1134 srcval = fetch_data_byte(srcoffset); 1135 DECODE_PRINTF("\n"); 1136 TRACE_AND_STEP(); 1137 *destreg = adc_byte(*destreg, srcval); 1138 break; 1139 case 1: 1140 destreg = DECODE_RM_BYTE_REGISTER(rh); 1141 DECODE_PRINTF(","); 1142 srcoffset = decode_rm01_address(rl); 1143 srcval = fetch_data_byte(srcoffset); 1144 DECODE_PRINTF("\n"); 1145 TRACE_AND_STEP(); 1146 *destreg = adc_byte(*destreg, srcval); 1147 break; 1148 case 2: 1149 destreg = DECODE_RM_BYTE_REGISTER(rh); 1150 DECODE_PRINTF(","); 1151 srcoffset = decode_rm10_address(rl); 1152 srcval = fetch_data_byte(srcoffset); 1153 DECODE_PRINTF("\n"); 1154 TRACE_AND_STEP(); 1155 *destreg = adc_byte(*destreg, srcval); 1156 break; 1157 case 3: /* register to register */ 1158 destreg = DECODE_RM_BYTE_REGISTER(rh); 1159 DECODE_PRINTF(","); 1160 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1161 DECODE_PRINTF("\n"); 1162 TRACE_AND_STEP(); 1163 *destreg = adc_byte(*destreg, *srcreg); 1164 break; 1165 } 1166 DECODE_CLEAR_SEGOVR(); 1167 END_OF_INSTR(); 1168} 1169 1170/**************************************************************************** 1171REMARKS: 1172Handles opcode 0x13 1173****************************************************************************/ 1174void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1)) 1175{ 1176 int mod, rl, rh; 1177 uint srcoffset; 1178 1179 START_OF_INSTR(); 1180 DECODE_PRINTF("ADC\t"); 1181 FETCH_DECODE_MODRM(mod, rh, rl); 1182 switch (mod) { 1183 case 0: 1184 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1185 u32 *destreg; 1186 u32 srcval; 1187 1188 destreg = DECODE_RM_LONG_REGISTER(rh); 1189 DECODE_PRINTF(","); 1190 srcoffset = decode_rm00_address(rl); 1191 srcval = fetch_data_long(srcoffset); 1192 DECODE_PRINTF("\n"); 1193 TRACE_AND_STEP(); 1194 *destreg = adc_long(*destreg, srcval); 1195 } else { 1196 u16 *destreg; 1197 u16 srcval; 1198 1199 destreg = DECODE_RM_WORD_REGISTER(rh); 1200 DECODE_PRINTF(","); 1201 srcoffset = decode_rm00_address(rl); 1202 srcval = fetch_data_word(srcoffset); 1203 DECODE_PRINTF("\n"); 1204 TRACE_AND_STEP(); 1205 *destreg = adc_word(*destreg, srcval); 1206 } 1207 break; 1208 case 1: 1209 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1210 u32 *destreg; 1211 u32 srcval; 1212 1213 destreg = DECODE_RM_LONG_REGISTER(rh); 1214 DECODE_PRINTF(","); 1215 srcoffset = decode_rm01_address(rl); 1216 srcval = fetch_data_long(srcoffset); 1217 DECODE_PRINTF("\n"); 1218 TRACE_AND_STEP(); 1219 *destreg = adc_long(*destreg, srcval); 1220 } else { 1221 u16 *destreg; 1222 u16 srcval; 1223 1224 destreg = DECODE_RM_WORD_REGISTER(rh); 1225 DECODE_PRINTF(","); 1226 srcoffset = decode_rm01_address(rl); 1227 srcval = fetch_data_word(srcoffset); 1228 DECODE_PRINTF("\n"); 1229 TRACE_AND_STEP(); 1230 *destreg = adc_word(*destreg, srcval); 1231 } 1232 break; 1233 case 2: 1234 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1235 u32 *destreg; 1236 u32 srcval; 1237 1238 destreg = DECODE_RM_LONG_REGISTER(rh); 1239 DECODE_PRINTF(","); 1240 srcoffset = decode_rm10_address(rl); 1241 srcval = fetch_data_long(srcoffset); 1242 DECODE_PRINTF("\n"); 1243 TRACE_AND_STEP(); 1244 *destreg = adc_long(*destreg, srcval); 1245 } else { 1246 u16 *destreg; 1247 u16 srcval; 1248 1249 destreg = DECODE_RM_WORD_REGISTER(rh); 1250 DECODE_PRINTF(","); 1251 srcoffset = decode_rm10_address(rl); 1252 srcval = fetch_data_word(srcoffset); 1253 DECODE_PRINTF("\n"); 1254 TRACE_AND_STEP(); 1255 *destreg = adc_word(*destreg, srcval); 1256 } 1257 break; 1258 case 3: /* register to register */ 1259 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1260 u32 *destreg,*srcreg; 1261 1262 destreg = DECODE_RM_LONG_REGISTER(rh); 1263 DECODE_PRINTF(","); 1264 srcreg = DECODE_RM_LONG_REGISTER(rl); 1265 DECODE_PRINTF("\n"); 1266 TRACE_AND_STEP(); 1267 *destreg = adc_long(*destreg, *srcreg); 1268 } else { 1269 u16 *destreg,*srcreg; 1270 1271 destreg = DECODE_RM_WORD_REGISTER(rh); 1272 DECODE_PRINTF(","); 1273 srcreg = DECODE_RM_WORD_REGISTER(rl); 1274 DECODE_PRINTF("\n"); 1275 TRACE_AND_STEP(); 1276 *destreg = adc_word(*destreg, *srcreg); 1277 } 1278 break; 1279 } 1280 DECODE_CLEAR_SEGOVR(); 1281 END_OF_INSTR(); 1282} 1283 1284/**************************************************************************** 1285REMARKS: 1286Handles opcode 0x14 1287****************************************************************************/ 1288void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1289{ 1290 u8 srcval; 1291 1292 START_OF_INSTR(); 1293 DECODE_PRINTF("ADC\tAL,"); 1294 srcval = fetch_byte_imm(); 1295 DECODE_PRINTF2("%x\n", srcval); 1296 TRACE_AND_STEP(); 1297 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval); 1298 DECODE_CLEAR_SEGOVR(); 1299 END_OF_INSTR(); 1300} 1301 1302/**************************************************************************** 1303REMARKS: 1304Handles opcode 0x15 1305****************************************************************************/ 1306void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1307{ 1308 u32 srcval; 1309 1310 START_OF_INSTR(); 1311 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1312 DECODE_PRINTF("ADC\tEAX,"); 1313 srcval = fetch_long_imm(); 1314 } else { 1315 DECODE_PRINTF("ADC\tAX,"); 1316 srcval = fetch_word_imm(); 1317 } 1318 DECODE_PRINTF2("%x\n", srcval); 1319 TRACE_AND_STEP(); 1320 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1321 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval); 1322 } else { 1323 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval); 1324 } 1325 DECODE_CLEAR_SEGOVR(); 1326 END_OF_INSTR(); 1327} 1328 1329/**************************************************************************** 1330REMARKS: 1331Handles opcode 0x16 1332****************************************************************************/ 1333void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 1334{ 1335 START_OF_INSTR(); 1336 DECODE_PRINTF("PUSH\tSS\n"); 1337 TRACE_AND_STEP(); 1338 push_word(M.x86.R_SS); 1339 DECODE_CLEAR_SEGOVR(); 1340 END_OF_INSTR(); 1341} 1342 1343/**************************************************************************** 1344REMARKS: 1345Handles opcode 0x17 1346****************************************************************************/ 1347void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 1348{ 1349 START_OF_INSTR(); 1350 DECODE_PRINTF("POP\tSS\n"); 1351 TRACE_AND_STEP(); 1352 M.x86.R_SS = pop_word(); 1353 DECODE_CLEAR_SEGOVR(); 1354 END_OF_INSTR(); 1355} 1356 1357/**************************************************************************** 1358REMARKS: 1359Handles opcode 0x18 1360****************************************************************************/ 1361void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1362{ 1363 int mod, rl, rh; 1364 u8 *destreg, *srcreg; 1365 uint destoffset; 1366 u8 destval; 1367 1368 START_OF_INSTR(); 1369 DECODE_PRINTF("SBB\t"); 1370 FETCH_DECODE_MODRM(mod, rh, rl); 1371 switch (mod) { 1372 case 0: 1373 destoffset = decode_rm00_address(rl); 1374 DECODE_PRINTF(","); 1375 destval = fetch_data_byte(destoffset); 1376 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1377 DECODE_PRINTF("\n"); 1378 TRACE_AND_STEP(); 1379 destval = sbb_byte(destval, *srcreg); 1380 store_data_byte(destoffset, destval); 1381 break; 1382 case 1: 1383 destoffset = decode_rm01_address(rl); 1384 DECODE_PRINTF(","); 1385 destval = fetch_data_byte(destoffset); 1386 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1387 DECODE_PRINTF("\n"); 1388 TRACE_AND_STEP(); 1389 destval = sbb_byte(destval, *srcreg); 1390 store_data_byte(destoffset, destval); 1391 break; 1392 case 2: 1393 destoffset = decode_rm10_address(rl); 1394 DECODE_PRINTF(","); 1395 destval = fetch_data_byte(destoffset); 1396 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1397 DECODE_PRINTF("\n"); 1398 TRACE_AND_STEP(); 1399 destval = sbb_byte(destval, *srcreg); 1400 store_data_byte(destoffset, destval); 1401 break; 1402 case 3: /* register to register */ 1403 destreg = DECODE_RM_BYTE_REGISTER(rl); 1404 DECODE_PRINTF(","); 1405 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1406 DECODE_PRINTF("\n"); 1407 TRACE_AND_STEP(); 1408 *destreg = sbb_byte(*destreg, *srcreg); 1409 break; 1410 } 1411 DECODE_CLEAR_SEGOVR(); 1412 END_OF_INSTR(); 1413} 1414 1415/**************************************************************************** 1416REMARKS: 1417Handles opcode 0x19 1418****************************************************************************/ 1419void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1)) 1420{ 1421 int mod, rl, rh; 1422 uint destoffset; 1423 1424 START_OF_INSTR(); 1425 DECODE_PRINTF("SBB\t"); 1426 FETCH_DECODE_MODRM(mod, rh, rl); 1427 switch (mod) { 1428 case 0: 1429 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1430 u32 destval; 1431 u32 *srcreg; 1432 1433 destoffset = decode_rm00_address(rl); 1434 DECODE_PRINTF(","); 1435 destval = fetch_data_long(destoffset); 1436 srcreg = DECODE_RM_LONG_REGISTER(rh); 1437 DECODE_PRINTF("\n"); 1438 TRACE_AND_STEP(); 1439 destval = sbb_long(destval, *srcreg); 1440 store_data_long(destoffset, destval); 1441 } else { 1442 u16 destval; 1443 u16 *srcreg; 1444 1445 destoffset = decode_rm00_address(rl); 1446 DECODE_PRINTF(","); 1447 destval = fetch_data_word(destoffset); 1448 srcreg = DECODE_RM_WORD_REGISTER(rh); 1449 DECODE_PRINTF("\n"); 1450 TRACE_AND_STEP(); 1451 destval = sbb_word(destval, *srcreg); 1452 store_data_word(destoffset, destval); 1453 } 1454 break; 1455 case 1: 1456 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1457 u32 destval; 1458 u32 *srcreg; 1459 1460 destoffset = decode_rm01_address(rl); 1461 DECODE_PRINTF(","); 1462 destval = fetch_data_long(destoffset); 1463 srcreg = DECODE_RM_LONG_REGISTER(rh); 1464 DECODE_PRINTF("\n"); 1465 TRACE_AND_STEP(); 1466 destval = sbb_long(destval, *srcreg); 1467 store_data_long(destoffset, destval); 1468 } else { 1469 u16 destval; 1470 u16 *srcreg; 1471 1472 destoffset = decode_rm01_address(rl); 1473 DECODE_PRINTF(","); 1474 destval = fetch_data_word(destoffset); 1475 srcreg = DECODE_RM_WORD_REGISTER(rh); 1476 DECODE_PRINTF("\n"); 1477 TRACE_AND_STEP(); 1478 destval = sbb_word(destval, *srcreg); 1479 store_data_word(destoffset, destval); 1480 } 1481 break; 1482 case 2: 1483 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1484 u32 destval; 1485 u32 *srcreg; 1486 1487 destoffset = decode_rm10_address(rl); 1488 DECODE_PRINTF(","); 1489 destval = fetch_data_long(destoffset); 1490 srcreg = DECODE_RM_LONG_REGISTER(rh); 1491 DECODE_PRINTF("\n"); 1492 TRACE_AND_STEP(); 1493 destval = sbb_long(destval, *srcreg); 1494 store_data_long(destoffset, destval); 1495 } else { 1496 u16 destval; 1497 u16 *srcreg; 1498 1499 destoffset = decode_rm10_address(rl); 1500 DECODE_PRINTF(","); 1501 destval = fetch_data_word(destoffset); 1502 srcreg = DECODE_RM_WORD_REGISTER(rh); 1503 DECODE_PRINTF("\n"); 1504 TRACE_AND_STEP(); 1505 destval = sbb_word(destval, *srcreg); 1506 store_data_word(destoffset, destval); 1507 } 1508 break; 1509 case 3: /* register to register */ 1510 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1511 u32 *destreg,*srcreg; 1512 1513 destreg = DECODE_RM_LONG_REGISTER(rl); 1514 DECODE_PRINTF(","); 1515 srcreg = DECODE_RM_LONG_REGISTER(rh); 1516 DECODE_PRINTF("\n"); 1517 TRACE_AND_STEP(); 1518 *destreg = sbb_long(*destreg, *srcreg); 1519 } else { 1520 u16 *destreg,*srcreg; 1521 1522 destreg = DECODE_RM_WORD_REGISTER(rl); 1523 DECODE_PRINTF(","); 1524 srcreg = DECODE_RM_WORD_REGISTER(rh); 1525 DECODE_PRINTF("\n"); 1526 TRACE_AND_STEP(); 1527 *destreg = sbb_word(*destreg, *srcreg); 1528 } 1529 break; 1530 } 1531 DECODE_CLEAR_SEGOVR(); 1532 END_OF_INSTR(); 1533} 1534 1535/**************************************************************************** 1536REMARKS: 1537Handles opcode 0x1a 1538****************************************************************************/ 1539void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1540{ 1541 int mod, rl, rh; 1542 u8 *destreg, *srcreg; 1543 uint srcoffset; 1544 u8 srcval; 1545 1546 START_OF_INSTR(); 1547 DECODE_PRINTF("SBB\t"); 1548 FETCH_DECODE_MODRM(mod, rh, rl); 1549 switch (mod) { 1550 case 0: 1551 destreg = DECODE_RM_BYTE_REGISTER(rh); 1552 DECODE_PRINTF(","); 1553 srcoffset = decode_rm00_address(rl); 1554 srcval = fetch_data_byte(srcoffset); 1555 DECODE_PRINTF("\n"); 1556 TRACE_AND_STEP(); 1557 *destreg = sbb_byte(*destreg, srcval); 1558 break; 1559 case 1: 1560 destreg = DECODE_RM_BYTE_REGISTER(rh); 1561 DECODE_PRINTF(","); 1562 srcoffset = decode_rm01_address(rl); 1563 srcval = fetch_data_byte(srcoffset); 1564 DECODE_PRINTF("\n"); 1565 TRACE_AND_STEP(); 1566 *destreg = sbb_byte(*destreg, srcval); 1567 break; 1568 case 2: 1569 destreg = DECODE_RM_BYTE_REGISTER(rh); 1570 DECODE_PRINTF(","); 1571 srcoffset = decode_rm10_address(rl); 1572 srcval = fetch_data_byte(srcoffset); 1573 DECODE_PRINTF("\n"); 1574 TRACE_AND_STEP(); 1575 *destreg = sbb_byte(*destreg, srcval); 1576 break; 1577 case 3: /* register to register */ 1578 destreg = DECODE_RM_BYTE_REGISTER(rh); 1579 DECODE_PRINTF(","); 1580 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1581 DECODE_PRINTF("\n"); 1582 TRACE_AND_STEP(); 1583 *destreg = sbb_byte(*destreg, *srcreg); 1584 break; 1585 } 1586 DECODE_CLEAR_SEGOVR(); 1587 END_OF_INSTR(); 1588} 1589 1590/**************************************************************************** 1591REMARKS: 1592Handles opcode 0x1b 1593****************************************************************************/ 1594void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1)) 1595{ 1596 int mod, rl, rh; 1597 uint srcoffset; 1598 1599 START_OF_INSTR(); 1600 DECODE_PRINTF("SBB\t"); 1601 FETCH_DECODE_MODRM(mod, rh, rl); 1602 switch (mod) { 1603 case 0: 1604 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1605 u32 *destreg; 1606 u32 srcval; 1607 1608 destreg = DECODE_RM_LONG_REGISTER(rh); 1609 DECODE_PRINTF(","); 1610 srcoffset = decode_rm00_address(rl); 1611 srcval = fetch_data_long(srcoffset); 1612 DECODE_PRINTF("\n"); 1613 TRACE_AND_STEP(); 1614 *destreg = sbb_long(*destreg, srcval); 1615 } else { 1616 u16 *destreg; 1617 u16 srcval; 1618 1619 destreg = DECODE_RM_WORD_REGISTER(rh); 1620 DECODE_PRINTF(","); 1621 srcoffset = decode_rm00_address(rl); 1622 srcval = fetch_data_word(srcoffset); 1623 DECODE_PRINTF("\n"); 1624 TRACE_AND_STEP(); 1625 *destreg = sbb_word(*destreg, srcval); 1626 } 1627 break; 1628 case 1: 1629 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1630 u32 *destreg; 1631 u32 srcval; 1632 1633 destreg = DECODE_RM_LONG_REGISTER(rh); 1634 DECODE_PRINTF(","); 1635 srcoffset = decode_rm01_address(rl); 1636 srcval = fetch_data_long(srcoffset); 1637 DECODE_PRINTF("\n"); 1638 TRACE_AND_STEP(); 1639 *destreg = sbb_long(*destreg, srcval); 1640 } else { 1641 u16 *destreg; 1642 u16 srcval; 1643 1644 destreg = DECODE_RM_WORD_REGISTER(rh); 1645 DECODE_PRINTF(","); 1646 srcoffset = decode_rm01_address(rl); 1647 srcval = fetch_data_word(srcoffset); 1648 DECODE_PRINTF("\n"); 1649 TRACE_AND_STEP(); 1650 *destreg = sbb_word(*destreg, srcval); 1651 } 1652 break; 1653 case 2: 1654 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1655 u32 *destreg; 1656 u32 srcval; 1657 1658 destreg = DECODE_RM_LONG_REGISTER(rh); 1659 DECODE_PRINTF(","); 1660 srcoffset = decode_rm10_address(rl); 1661 srcval = fetch_data_long(srcoffset); 1662 DECODE_PRINTF("\n"); 1663 TRACE_AND_STEP(); 1664 *destreg = sbb_long(*destreg, srcval); 1665 } else { 1666 u16 *destreg; 1667 u16 srcval; 1668 1669 destreg = DECODE_RM_WORD_REGISTER(rh); 1670 DECODE_PRINTF(","); 1671 srcoffset = decode_rm10_address(rl); 1672 srcval = fetch_data_word(srcoffset); 1673 DECODE_PRINTF("\n"); 1674 TRACE_AND_STEP(); 1675 *destreg = sbb_word(*destreg, srcval); 1676 } 1677 break; 1678 case 3: /* register to register */ 1679 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1680 u32 *destreg,*srcreg; 1681 1682 destreg = DECODE_RM_LONG_REGISTER(rh); 1683 DECODE_PRINTF(","); 1684 srcreg = DECODE_RM_LONG_REGISTER(rl); 1685 DECODE_PRINTF("\n"); 1686 TRACE_AND_STEP(); 1687 *destreg = sbb_long(*destreg, *srcreg); 1688 } else { 1689 u16 *destreg,*srcreg; 1690 1691 destreg = DECODE_RM_WORD_REGISTER(rh); 1692 DECODE_PRINTF(","); 1693 srcreg = DECODE_RM_WORD_REGISTER(rl); 1694 DECODE_PRINTF("\n"); 1695 TRACE_AND_STEP(); 1696 *destreg = sbb_word(*destreg, *srcreg); 1697 } 1698 break; 1699 } 1700 DECODE_CLEAR_SEGOVR(); 1701 END_OF_INSTR(); 1702} 1703 1704/**************************************************************************** 1705REMARKS: 1706Handles opcode 0x1c 1707****************************************************************************/ 1708void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 1709{ 1710 u8 srcval; 1711 1712 START_OF_INSTR(); 1713 DECODE_PRINTF("SBB\tAL,"); 1714 srcval = fetch_byte_imm(); 1715 DECODE_PRINTF2("%x\n", srcval); 1716 TRACE_AND_STEP(); 1717 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval); 1718 DECODE_CLEAR_SEGOVR(); 1719 END_OF_INSTR(); 1720} 1721 1722/**************************************************************************** 1723REMARKS: 1724Handles opcode 0x1d 1725****************************************************************************/ 1726void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 1727{ 1728 u32 srcval; 1729 1730 START_OF_INSTR(); 1731 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1732 DECODE_PRINTF("SBB\tEAX,"); 1733 srcval = fetch_long_imm(); 1734 } else { 1735 DECODE_PRINTF("SBB\tAX,"); 1736 srcval = fetch_word_imm(); 1737 } 1738 DECODE_PRINTF2("%x\n", srcval); 1739 TRACE_AND_STEP(); 1740 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1741 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval); 1742 } else { 1743 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval); 1744 } 1745 DECODE_CLEAR_SEGOVR(); 1746 END_OF_INSTR(); 1747} 1748 1749/**************************************************************************** 1750REMARKS: 1751Handles opcode 0x1e 1752****************************************************************************/ 1753void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 1754{ 1755 START_OF_INSTR(); 1756 DECODE_PRINTF("PUSH\tDS\n"); 1757 TRACE_AND_STEP(); 1758 push_word(M.x86.R_DS); 1759 DECODE_CLEAR_SEGOVR(); 1760 END_OF_INSTR(); 1761} 1762 1763/**************************************************************************** 1764REMARKS: 1765Handles opcode 0x1f 1766****************************************************************************/ 1767void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 1768{ 1769 START_OF_INSTR(); 1770 DECODE_PRINTF("POP\tDS\n"); 1771 TRACE_AND_STEP(); 1772 M.x86.R_DS = pop_word(); 1773 DECODE_CLEAR_SEGOVR(); 1774 END_OF_INSTR(); 1775} 1776 1777/**************************************************************************** 1778REMARKS: 1779Handles opcode 0x20 1780****************************************************************************/ 1781void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1782{ 1783 int mod, rl, rh; 1784 u8 *destreg, *srcreg; 1785 uint destoffset; 1786 u8 destval; 1787 1788 START_OF_INSTR(); 1789 DECODE_PRINTF("AND\t"); 1790 FETCH_DECODE_MODRM(mod, rh, rl); 1791 1792 switch (mod) { 1793 case 0: 1794 destoffset = decode_rm00_address(rl); 1795 DECODE_PRINTF(","); 1796 destval = fetch_data_byte(destoffset); 1797 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1798 DECODE_PRINTF("\n"); 1799 TRACE_AND_STEP(); 1800 destval = and_byte(destval, *srcreg); 1801 store_data_byte(destoffset, destval); 1802 break; 1803 1804 case 1: 1805 destoffset = decode_rm01_address(rl); 1806 DECODE_PRINTF(","); 1807 destval = fetch_data_byte(destoffset); 1808 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1809 DECODE_PRINTF("\n"); 1810 TRACE_AND_STEP(); 1811 destval = and_byte(destval, *srcreg); 1812 store_data_byte(destoffset, destval); 1813 break; 1814 1815 case 2: 1816 destoffset = decode_rm10_address(rl); 1817 DECODE_PRINTF(","); 1818 destval = fetch_data_byte(destoffset); 1819 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1820 DECODE_PRINTF("\n"); 1821 TRACE_AND_STEP(); 1822 destval = and_byte(destval, *srcreg); 1823 store_data_byte(destoffset, destval); 1824 break; 1825 1826 case 3: /* register to register */ 1827 destreg = DECODE_RM_BYTE_REGISTER(rl); 1828 DECODE_PRINTF(","); 1829 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1830 DECODE_PRINTF("\n"); 1831 TRACE_AND_STEP(); 1832 *destreg = and_byte(*destreg, *srcreg); 1833 break; 1834 } 1835 DECODE_CLEAR_SEGOVR(); 1836 END_OF_INSTR(); 1837} 1838 1839/**************************************************************************** 1840REMARKS: 1841Handles opcode 0x21 1842****************************************************************************/ 1843void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1)) 1844{ 1845 int mod, rl, rh; 1846 uint destoffset; 1847 1848 START_OF_INSTR(); 1849 DECODE_PRINTF("AND\t"); 1850 FETCH_DECODE_MODRM(mod, rh, rl); 1851 switch (mod) { 1852 case 0: 1853 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1854 u32 destval; 1855 u32 *srcreg; 1856 1857 destoffset = decode_rm00_address(rl); 1858 DECODE_PRINTF(","); 1859 destval = fetch_data_long(destoffset); 1860 srcreg = DECODE_RM_LONG_REGISTER(rh); 1861 DECODE_PRINTF("\n"); 1862 TRACE_AND_STEP(); 1863 destval = and_long(destval, *srcreg); 1864 store_data_long(destoffset, destval); 1865 } else { 1866 u16 destval; 1867 u16 *srcreg; 1868 1869 destoffset = decode_rm00_address(rl); 1870 DECODE_PRINTF(","); 1871 destval = fetch_data_word(destoffset); 1872 srcreg = DECODE_RM_WORD_REGISTER(rh); 1873 DECODE_PRINTF("\n"); 1874 TRACE_AND_STEP(); 1875 destval = and_word(destval, *srcreg); 1876 store_data_word(destoffset, destval); 1877 } 1878 break; 1879 case 1: 1880 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1881 u32 destval; 1882 u32 *srcreg; 1883 1884 destoffset = decode_rm01_address(rl); 1885 DECODE_PRINTF(","); 1886 destval = fetch_data_long(destoffset); 1887 srcreg = DECODE_RM_LONG_REGISTER(rh); 1888 DECODE_PRINTF("\n"); 1889 TRACE_AND_STEP(); 1890 destval = and_long(destval, *srcreg); 1891 store_data_long(destoffset, destval); 1892 } else { 1893 u16 destval; 1894 u16 *srcreg; 1895 1896 destoffset = decode_rm01_address(rl); 1897 DECODE_PRINTF(","); 1898 destval = fetch_data_word(destoffset); 1899 srcreg = DECODE_RM_WORD_REGISTER(rh); 1900 DECODE_PRINTF("\n"); 1901 TRACE_AND_STEP(); 1902 destval = and_word(destval, *srcreg); 1903 store_data_word(destoffset, destval); 1904 } 1905 break; 1906 case 2: 1907 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1908 u32 destval; 1909 u32 *srcreg; 1910 1911 destoffset = decode_rm10_address(rl); 1912 DECODE_PRINTF(","); 1913 destval = fetch_data_long(destoffset); 1914 srcreg = DECODE_RM_LONG_REGISTER(rh); 1915 DECODE_PRINTF("\n"); 1916 TRACE_AND_STEP(); 1917 destval = and_long(destval, *srcreg); 1918 store_data_long(destoffset, destval); 1919 } else { 1920 u16 destval; 1921 u16 *srcreg; 1922 1923 destoffset = decode_rm10_address(rl); 1924 DECODE_PRINTF(","); 1925 destval = fetch_data_word(destoffset); 1926 srcreg = DECODE_RM_WORD_REGISTER(rh); 1927 DECODE_PRINTF("\n"); 1928 TRACE_AND_STEP(); 1929 destval = and_word(destval, *srcreg); 1930 store_data_word(destoffset, destval); 1931 } 1932 break; 1933 case 3: /* register to register */ 1934 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1935 u32 *destreg,*srcreg; 1936 1937 destreg = DECODE_RM_LONG_REGISTER(rl); 1938 DECODE_PRINTF(","); 1939 srcreg = DECODE_RM_LONG_REGISTER(rh); 1940 DECODE_PRINTF("\n"); 1941 TRACE_AND_STEP(); 1942 *destreg = and_long(*destreg, *srcreg); 1943 } else { 1944 u16 *destreg,*srcreg; 1945 1946 destreg = DECODE_RM_WORD_REGISTER(rl); 1947 DECODE_PRINTF(","); 1948 srcreg = DECODE_RM_WORD_REGISTER(rh); 1949 DECODE_PRINTF("\n"); 1950 TRACE_AND_STEP(); 1951 *destreg = and_word(*destreg, *srcreg); 1952 } 1953 break; 1954 } 1955 DECODE_CLEAR_SEGOVR(); 1956 END_OF_INSTR(); 1957} 1958 1959/**************************************************************************** 1960REMARKS: 1961Handles opcode 0x22 1962****************************************************************************/ 1963void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1964{ 1965 int mod, rl, rh; 1966 u8 *destreg, *srcreg; 1967 uint srcoffset; 1968 u8 srcval; 1969 1970 START_OF_INSTR(); 1971 DECODE_PRINTF("AND\t"); 1972 FETCH_DECODE_MODRM(mod, rh, rl); 1973 switch (mod) { 1974 case 0: 1975 destreg = DECODE_RM_BYTE_REGISTER(rh); 1976 DECODE_PRINTF(","); 1977 srcoffset = decode_rm00_address(rl); 1978 srcval = fetch_data_byte(srcoffset); 1979 DECODE_PRINTF("\n"); 1980 TRACE_AND_STEP(); 1981 *destreg = and_byte(*destreg, srcval); 1982 break; 1983 case 1: 1984 destreg = DECODE_RM_BYTE_REGISTER(rh); 1985 DECODE_PRINTF(","); 1986 srcoffset = decode_rm01_address(rl); 1987 srcval = fetch_data_byte(srcoffset); 1988 DECODE_PRINTF("\n"); 1989 TRACE_AND_STEP(); 1990 *destreg = and_byte(*destreg, srcval); 1991 break; 1992 case 2: 1993 destreg = DECODE_RM_BYTE_REGISTER(rh); 1994 DECODE_PRINTF(","); 1995 srcoffset = decode_rm10_address(rl); 1996 srcval = fetch_data_byte(srcoffset); 1997 DECODE_PRINTF("\n"); 1998 TRACE_AND_STEP(); 1999 *destreg = and_byte(*destreg, srcval); 2000 break; 2001 case 3: /* register to register */ 2002 destreg = DECODE_RM_BYTE_REGISTER(rh); 2003 DECODE_PRINTF(","); 2004 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2005 DECODE_PRINTF("\n"); 2006 TRACE_AND_STEP(); 2007 *destreg = and_byte(*destreg, *srcreg); 2008 break; 2009 } 2010 DECODE_CLEAR_SEGOVR(); 2011 END_OF_INSTR(); 2012} 2013 2014/**************************************************************************** 2015REMARKS: 2016Handles opcode 0x23 2017****************************************************************************/ 2018void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1)) 2019{ 2020 int mod, rl, rh; 2021 uint srcoffset; 2022 2023 START_OF_INSTR(); 2024 DECODE_PRINTF("AND\t"); 2025 FETCH_DECODE_MODRM(mod, rh, rl); 2026 switch (mod) { 2027 case 0: 2028 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2029 u32 *destreg; 2030 u32 srcval; 2031 2032 destreg = DECODE_RM_LONG_REGISTER(rh); 2033 DECODE_PRINTF(","); 2034 srcoffset = decode_rm00_address(rl); 2035 srcval = fetch_data_long(srcoffset); 2036 DECODE_PRINTF("\n"); 2037 TRACE_AND_STEP(); 2038 *destreg = and_long(*destreg, srcval); 2039 } else { 2040 u16 *destreg; 2041 u16 srcval; 2042 2043 destreg = DECODE_RM_WORD_REGISTER(rh); 2044 DECODE_PRINTF(","); 2045 srcoffset = decode_rm00_address(rl); 2046 srcval = fetch_data_word(srcoffset); 2047 DECODE_PRINTF("\n"); 2048 TRACE_AND_STEP(); 2049 *destreg = and_word(*destreg, srcval); 2050 } 2051 break; 2052 case 1: 2053 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2054 u32 *destreg; 2055 u32 srcval; 2056 2057 destreg = DECODE_RM_LONG_REGISTER(rh); 2058 DECODE_PRINTF(","); 2059 srcoffset = decode_rm01_address(rl); 2060 srcval = fetch_data_long(srcoffset); 2061 DECODE_PRINTF("\n"); 2062 TRACE_AND_STEP(); 2063 *destreg = and_long(*destreg, srcval); 2064 break; 2065 } else { 2066 u16 *destreg; 2067 u16 srcval; 2068 2069 destreg = DECODE_RM_WORD_REGISTER(rh); 2070 DECODE_PRINTF(","); 2071 srcoffset = decode_rm01_address(rl); 2072 srcval = fetch_data_word(srcoffset); 2073 DECODE_PRINTF("\n"); 2074 TRACE_AND_STEP(); 2075 *destreg = and_word(*destreg, srcval); 2076 break; 2077 } 2078 case 2: 2079 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2080 u32 *destreg; 2081 u32 srcval; 2082 2083 destreg = DECODE_RM_LONG_REGISTER(rh); 2084 DECODE_PRINTF(","); 2085 srcoffset = decode_rm10_address(rl); 2086 srcval = fetch_data_long(srcoffset); 2087 DECODE_PRINTF("\n"); 2088 TRACE_AND_STEP(); 2089 *destreg = and_long(*destreg, srcval); 2090 } else { 2091 u16 *destreg; 2092 u16 srcval; 2093 2094 destreg = DECODE_RM_WORD_REGISTER(rh); 2095 DECODE_PRINTF(","); 2096 srcoffset = decode_rm10_address(rl); 2097 srcval = fetch_data_word(srcoffset); 2098 DECODE_PRINTF("\n"); 2099 TRACE_AND_STEP(); 2100 *destreg = and_word(*destreg, srcval); 2101 } 2102 break; 2103 case 3: /* register to register */ 2104 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2105 u32 *destreg,*srcreg; 2106 2107 destreg = DECODE_RM_LONG_REGISTER(rh); 2108 DECODE_PRINTF(","); 2109 srcreg = DECODE_RM_LONG_REGISTER(rl); 2110 DECODE_PRINTF("\n"); 2111 TRACE_AND_STEP(); 2112 *destreg = and_long(*destreg, *srcreg); 2113 } else { 2114 u16 *destreg,*srcreg; 2115 2116 destreg = DECODE_RM_WORD_REGISTER(rh); 2117 DECODE_PRINTF(","); 2118 srcreg = DECODE_RM_WORD_REGISTER(rl); 2119 DECODE_PRINTF("\n"); 2120 TRACE_AND_STEP(); 2121 *destreg = and_word(*destreg, *srcreg); 2122 } 2123 break; 2124 } 2125 DECODE_CLEAR_SEGOVR(); 2126 END_OF_INSTR(); 2127} 2128 2129/**************************************************************************** 2130REMARKS: 2131Handles opcode 0x24 2132****************************************************************************/ 2133void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2134{ 2135 u8 srcval; 2136 2137 START_OF_INSTR(); 2138 DECODE_PRINTF("AND\tAL,"); 2139 srcval = fetch_byte_imm(); 2140 DECODE_PRINTF2("%x\n", srcval); 2141 TRACE_AND_STEP(); 2142 M.x86.R_AL = and_byte(M.x86.R_AL, srcval); 2143 DECODE_CLEAR_SEGOVR(); 2144 END_OF_INSTR(); 2145} 2146 2147/**************************************************************************** 2148REMARKS: 2149Handles opcode 0x25 2150****************************************************************************/ 2151void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2152{ 2153 u32 srcval; 2154 2155 START_OF_INSTR(); 2156 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2157 DECODE_PRINTF("AND\tEAX,"); 2158 srcval = fetch_long_imm(); 2159 } else { 2160 DECODE_PRINTF("AND\tAX,"); 2161 srcval = fetch_word_imm(); 2162 } 2163 DECODE_PRINTF2("%x\n", srcval); 2164 TRACE_AND_STEP(); 2165 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2166 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval); 2167 } else { 2168 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval); 2169 } 2170 DECODE_CLEAR_SEGOVR(); 2171 END_OF_INSTR(); 2172} 2173 2174/**************************************************************************** 2175REMARKS: 2176Handles opcode 0x26 2177****************************************************************************/ 2178void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 2179{ 2180 START_OF_INSTR(); 2181 DECODE_PRINTF("ES:\n"); 2182 TRACE_AND_STEP(); 2183 M.x86.mode |= SYSMODE_SEGOVR_ES; 2184 /* 2185 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 2186 * opcode subroutines we do not want to do this. 2187 */ 2188 END_OF_INSTR(); 2189} 2190 2191/**************************************************************************** 2192REMARKS: 2193Handles opcode 0x27 2194****************************************************************************/ 2195void x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 2196{ 2197 START_OF_INSTR(); 2198 DECODE_PRINTF("DAA\n"); 2199 TRACE_AND_STEP(); 2200 M.x86.R_AL = daa_byte(M.x86.R_AL); 2201 DECODE_CLEAR_SEGOVR(); 2202 END_OF_INSTR(); 2203} 2204 2205/**************************************************************************** 2206REMARKS: 2207Handles opcode 0x28 2208****************************************************************************/ 2209void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2210{ 2211 int mod, rl, rh; 2212 u8 *destreg, *srcreg; 2213 uint destoffset; 2214 u8 destval; 2215 2216 START_OF_INSTR(); 2217 DECODE_PRINTF("SUB\t"); 2218 FETCH_DECODE_MODRM(mod, rh, rl); 2219 switch (mod) { 2220 case 0: 2221 destoffset = decode_rm00_address(rl); 2222 DECODE_PRINTF(","); 2223 destval = fetch_data_byte(destoffset); 2224 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2225 DECODE_PRINTF("\n"); 2226 TRACE_AND_STEP(); 2227 destval = sub_byte(destval, *srcreg); 2228 store_data_byte(destoffset, destval); 2229 break; 2230 case 1: 2231 destoffset = decode_rm01_address(rl); 2232 DECODE_PRINTF(","); 2233 destval = fetch_data_byte(destoffset); 2234 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2235 DECODE_PRINTF("\n"); 2236 TRACE_AND_STEP(); 2237 destval = sub_byte(destval, *srcreg); 2238 store_data_byte(destoffset, destval); 2239 break; 2240 case 2: 2241 destoffset = decode_rm10_address(rl); 2242 DECODE_PRINTF(","); 2243 destval = fetch_data_byte(destoffset); 2244 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2245 DECODE_PRINTF("\n"); 2246 TRACE_AND_STEP(); 2247 destval = sub_byte(destval, *srcreg); 2248 store_data_byte(destoffset, destval); 2249 break; 2250 case 3: /* register to register */ 2251 destreg = DECODE_RM_BYTE_REGISTER(rl); 2252 DECODE_PRINTF(","); 2253 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2254 DECODE_PRINTF("\n"); 2255 TRACE_AND_STEP(); 2256 *destreg = sub_byte(*destreg, *srcreg); 2257 break; 2258 } 2259 DECODE_CLEAR_SEGOVR(); 2260 END_OF_INSTR(); 2261} 2262 2263/**************************************************************************** 2264REMARKS: 2265Handles opcode 0x29 2266****************************************************************************/ 2267void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1)) 2268{ 2269 int mod, rl, rh; 2270 uint destoffset; 2271 2272 START_OF_INSTR(); 2273 DECODE_PRINTF("SUB\t"); 2274 FETCH_DECODE_MODRM(mod, rh, rl); 2275 switch (mod) { 2276 case 0: 2277 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2278 u32 destval; 2279 u32 *srcreg; 2280 2281 destoffset = decode_rm00_address(rl); 2282 DECODE_PRINTF(","); 2283 destval = fetch_data_long(destoffset); 2284 srcreg = DECODE_RM_LONG_REGISTER(rh); 2285 DECODE_PRINTF("\n"); 2286 TRACE_AND_STEP(); 2287 destval = sub_long(destval, *srcreg); 2288 store_data_long(destoffset, destval); 2289 } else { 2290 u16 destval; 2291 u16 *srcreg; 2292 2293 destoffset = decode_rm00_address(rl); 2294 DECODE_PRINTF(","); 2295 destval = fetch_data_word(destoffset); 2296 srcreg = DECODE_RM_WORD_REGISTER(rh); 2297 DECODE_PRINTF("\n"); 2298 TRACE_AND_STEP(); 2299 destval = sub_word(destval, *srcreg); 2300 store_data_word(destoffset, destval); 2301 } 2302 break; 2303 case 1: 2304 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2305 u32 destval; 2306 u32 *srcreg; 2307 2308 destoffset = decode_rm01_address(rl); 2309 DECODE_PRINTF(","); 2310 destval = fetch_data_long(destoffset); 2311 srcreg = DECODE_RM_LONG_REGISTER(rh); 2312 DECODE_PRINTF("\n"); 2313 TRACE_AND_STEP(); 2314 destval = sub_long(destval, *srcreg); 2315 store_data_long(destoffset, destval); 2316 } else { 2317 u16 destval; 2318 u16 *srcreg; 2319 2320 destoffset = decode_rm01_address(rl); 2321 DECODE_PRINTF(","); 2322 destval = fetch_data_word(destoffset); 2323 srcreg = DECODE_RM_WORD_REGISTER(rh); 2324 DECODE_PRINTF("\n"); 2325 TRACE_AND_STEP(); 2326 destval = sub_word(destval, *srcreg); 2327 store_data_word(destoffset, destval); 2328 } 2329 break; 2330 case 2: 2331 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2332 u32 destval; 2333 u32 *srcreg; 2334 2335 destoffset = decode_rm10_address(rl); 2336 DECODE_PRINTF(","); 2337 destval = fetch_data_long(destoffset); 2338 srcreg = DECODE_RM_LONG_REGISTER(rh); 2339 DECODE_PRINTF("\n"); 2340 TRACE_AND_STEP(); 2341 destval = sub_long(destval, *srcreg); 2342 store_data_long(destoffset, destval); 2343 } else { 2344 u16 destval; 2345 u16 *srcreg; 2346 2347 destoffset = decode_rm10_address(rl); 2348 DECODE_PRINTF(","); 2349 destval = fetch_data_word(destoffset); 2350 srcreg = DECODE_RM_WORD_REGISTER(rh); 2351 DECODE_PRINTF("\n"); 2352 TRACE_AND_STEP(); 2353 destval = sub_word(destval, *srcreg); 2354 store_data_word(destoffset, destval); 2355 } 2356 break; 2357 case 3: /* register to register */ 2358 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2359 u32 *destreg,*srcreg; 2360 2361 destreg = DECODE_RM_LONG_REGISTER(rl); 2362 DECODE_PRINTF(","); 2363 srcreg = DECODE_RM_LONG_REGISTER(rh); 2364 DECODE_PRINTF("\n"); 2365 TRACE_AND_STEP(); 2366 *destreg = sub_long(*destreg, *srcreg); 2367 } else { 2368 u16 *destreg,*srcreg; 2369 2370 destreg = DECODE_RM_WORD_REGISTER(rl); 2371 DECODE_PRINTF(","); 2372 srcreg = DECODE_RM_WORD_REGISTER(rh); 2373 DECODE_PRINTF("\n"); 2374 TRACE_AND_STEP(); 2375 *destreg = sub_word(*destreg, *srcreg); 2376 } 2377 break; 2378 } 2379 DECODE_CLEAR_SEGOVR(); 2380 END_OF_INSTR(); 2381} 2382 2383/**************************************************************************** 2384REMARKS: 2385Handles opcode 0x2a 2386****************************************************************************/ 2387void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2388{ 2389 int mod, rl, rh; 2390 u8 *destreg, *srcreg; 2391 uint srcoffset; 2392 u8 srcval; 2393 2394 START_OF_INSTR(); 2395 DECODE_PRINTF("SUB\t"); 2396 FETCH_DECODE_MODRM(mod, rh, rl); 2397 switch (mod) { 2398 case 0: 2399 destreg = DECODE_RM_BYTE_REGISTER(rh); 2400 DECODE_PRINTF(","); 2401 srcoffset = decode_rm00_address(rl); 2402 srcval = fetch_data_byte(srcoffset); 2403 DECODE_PRINTF("\n"); 2404 TRACE_AND_STEP(); 2405 *destreg = sub_byte(*destreg, srcval); 2406 break; 2407 case 1: 2408 destreg = DECODE_RM_BYTE_REGISTER(rh); 2409 DECODE_PRINTF(","); 2410 srcoffset = decode_rm01_address(rl); 2411 srcval = fetch_data_byte(srcoffset); 2412 DECODE_PRINTF("\n"); 2413 TRACE_AND_STEP(); 2414 *destreg = sub_byte(*destreg, srcval); 2415 break; 2416 case 2: 2417 destreg = DECODE_RM_BYTE_REGISTER(rh); 2418 DECODE_PRINTF(","); 2419 srcoffset = decode_rm10_address(rl); 2420 srcval = fetch_data_byte(srcoffset); 2421 DECODE_PRINTF("\n"); 2422 TRACE_AND_STEP(); 2423 *destreg = sub_byte(*destreg, srcval); 2424 break; 2425 case 3: /* register to register */ 2426 destreg = DECODE_RM_BYTE_REGISTER(rh); 2427 DECODE_PRINTF(","); 2428 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2429 DECODE_PRINTF("\n"); 2430 TRACE_AND_STEP(); 2431 *destreg = sub_byte(*destreg, *srcreg); 2432 break; 2433 } 2434 DECODE_CLEAR_SEGOVR(); 2435 END_OF_INSTR(); 2436} 2437 2438/**************************************************************************** 2439REMARKS: 2440Handles opcode 0x2b 2441****************************************************************************/ 2442void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1)) 2443{ 2444 int mod, rl, rh; 2445 uint srcoffset; 2446 2447 START_OF_INSTR(); 2448 DECODE_PRINTF("SUB\t"); 2449 FETCH_DECODE_MODRM(mod, rh, rl); 2450 switch (mod) { 2451 case 0: 2452 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2453 u32 *destreg; 2454 u32 srcval; 2455 2456 destreg = DECODE_RM_LONG_REGISTER(rh); 2457 DECODE_PRINTF(","); 2458 srcoffset = decode_rm00_address(rl); 2459 srcval = fetch_data_long(srcoffset); 2460 DECODE_PRINTF("\n"); 2461 TRACE_AND_STEP(); 2462 *destreg = sub_long(*destreg, srcval); 2463 } else { 2464 u16 *destreg; 2465 u16 srcval; 2466 2467 destreg = DECODE_RM_WORD_REGISTER(rh); 2468 DECODE_PRINTF(","); 2469 srcoffset = decode_rm00_address(rl); 2470 srcval = fetch_data_word(srcoffset); 2471 DECODE_PRINTF("\n"); 2472 TRACE_AND_STEP(); 2473 *destreg = sub_word(*destreg, srcval); 2474 } 2475 break; 2476 case 1: 2477 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2478 u32 *destreg; 2479 u32 srcval; 2480 2481 destreg = DECODE_RM_LONG_REGISTER(rh); 2482 DECODE_PRINTF(","); 2483 srcoffset = decode_rm01_address(rl); 2484 srcval = fetch_data_long(srcoffset); 2485 DECODE_PRINTF("\n"); 2486 TRACE_AND_STEP(); 2487 *destreg = sub_long(*destreg, srcval); 2488 } else { 2489 u16 *destreg; 2490 u16 srcval; 2491 2492 destreg = DECODE_RM_WORD_REGISTER(rh); 2493 DECODE_PRINTF(","); 2494 srcoffset = decode_rm01_address(rl); 2495 srcval = fetch_data_word(srcoffset); 2496 DECODE_PRINTF("\n"); 2497 TRACE_AND_STEP(); 2498 *destreg = sub_word(*destreg, srcval); 2499 } 2500 break; 2501 case 2: 2502 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2503 u32 *destreg; 2504 u32 srcval; 2505 2506 destreg = DECODE_RM_LONG_REGISTER(rh); 2507 DECODE_PRINTF(","); 2508 srcoffset = decode_rm10_address(rl); 2509 srcval = fetch_data_long(srcoffset); 2510 DECODE_PRINTF("\n"); 2511 TRACE_AND_STEP(); 2512 *destreg = sub_long(*destreg, srcval); 2513 } else { 2514 u16 *destreg; 2515 u16 srcval; 2516 2517 destreg = DECODE_RM_WORD_REGISTER(rh); 2518 DECODE_PRINTF(","); 2519 srcoffset = decode_rm10_address(rl); 2520 srcval = fetch_data_word(srcoffset); 2521 DECODE_PRINTF("\n"); 2522 TRACE_AND_STEP(); 2523 *destreg = sub_word(*destreg, srcval); 2524 } 2525 break; 2526 case 3: /* register to register */ 2527 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2528 u32 *destreg,*srcreg; 2529 2530 destreg = DECODE_RM_LONG_REGISTER(rh); 2531 DECODE_PRINTF(","); 2532 srcreg = DECODE_RM_LONG_REGISTER(rl); 2533 DECODE_PRINTF("\n"); 2534 TRACE_AND_STEP(); 2535 *destreg = sub_long(*destreg, *srcreg); 2536 } else { 2537 u16 *destreg,*srcreg; 2538 2539 destreg = DECODE_RM_WORD_REGISTER(rh); 2540 DECODE_PRINTF(","); 2541 srcreg = DECODE_RM_WORD_REGISTER(rl); 2542 DECODE_PRINTF("\n"); 2543 TRACE_AND_STEP(); 2544 *destreg = sub_word(*destreg, *srcreg); 2545 } 2546 break; 2547 } 2548 DECODE_CLEAR_SEGOVR(); 2549 END_OF_INSTR(); 2550} 2551 2552/**************************************************************************** 2553REMARKS: 2554Handles opcode 0x2c 2555****************************************************************************/ 2556void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2557{ 2558 u8 srcval; 2559 2560 START_OF_INSTR(); 2561 DECODE_PRINTF("SUB\tAL,"); 2562 srcval = fetch_byte_imm(); 2563 DECODE_PRINTF2("%x\n", srcval); 2564 TRACE_AND_STEP(); 2565 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval); 2566 DECODE_CLEAR_SEGOVR(); 2567 END_OF_INSTR(); 2568} 2569 2570/**************************************************************************** 2571REMARKS: 2572Handles opcode 0x2d 2573****************************************************************************/ 2574void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2575{ 2576 u32 srcval; 2577 2578 START_OF_INSTR(); 2579 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2580 DECODE_PRINTF("SUB\tEAX,"); 2581 srcval = fetch_long_imm(); 2582 } else { 2583 DECODE_PRINTF("SUB\tAX,"); 2584 srcval = fetch_word_imm(); 2585 } 2586 DECODE_PRINTF2("%x\n", srcval); 2587 TRACE_AND_STEP(); 2588 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2589 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval); 2590 } else { 2591 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval); 2592 } 2593 DECODE_CLEAR_SEGOVR(); 2594 END_OF_INSTR(); 2595} 2596 2597/**************************************************************************** 2598REMARKS: 2599Handles opcode 0x2e 2600****************************************************************************/ 2601void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 2602{ 2603 START_OF_INSTR(); 2604 DECODE_PRINTF("CS:\n"); 2605 TRACE_AND_STEP(); 2606 M.x86.mode |= SYSMODE_SEGOVR_CS; 2607 /* note no DECODE_CLEAR_SEGOVR here. */ 2608 END_OF_INSTR(); 2609} 2610 2611/**************************************************************************** 2612REMARKS: 2613Handles opcode 0x2f 2614****************************************************************************/ 2615void x86emuOp_das(u8 X86EMU_UNUSED(op1)) 2616{ 2617 START_OF_INSTR(); 2618 DECODE_PRINTF("DAS\n"); 2619 TRACE_AND_STEP(); 2620 M.x86.R_AL = das_byte(M.x86.R_AL); 2621 DECODE_CLEAR_SEGOVR(); 2622 END_OF_INSTR(); 2623} 2624 2625/**************************************************************************** 2626REMARKS: 2627Handles opcode 0x30 2628****************************************************************************/ 2629void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1)) 2630{ 2631 int mod, rl, rh; 2632 u8 *destreg, *srcreg; 2633 uint destoffset; 2634 u8 destval; 2635 2636 START_OF_INSTR(); 2637 DECODE_PRINTF("XOR\t"); 2638 FETCH_DECODE_MODRM(mod, rh, rl); 2639 switch (mod) { 2640 case 0: 2641 destoffset = decode_rm00_address(rl); 2642 DECODE_PRINTF(","); 2643 destval = fetch_data_byte(destoffset); 2644 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2645 DECODE_PRINTF("\n"); 2646 TRACE_AND_STEP(); 2647 destval = xor_byte(destval, *srcreg); 2648 store_data_byte(destoffset, destval); 2649 break; 2650 case 1: 2651 destoffset = decode_rm01_address(rl); 2652 DECODE_PRINTF(","); 2653 destval = fetch_data_byte(destoffset); 2654 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2655 DECODE_PRINTF("\n"); 2656 TRACE_AND_STEP(); 2657 destval = xor_byte(destval, *srcreg); 2658 store_data_byte(destoffset, destval); 2659 break; 2660 case 2: 2661 destoffset = decode_rm10_address(rl); 2662 DECODE_PRINTF(","); 2663 destval = fetch_data_byte(destoffset); 2664 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2665 DECODE_PRINTF("\n"); 2666 TRACE_AND_STEP(); 2667 destval = xor_byte(destval, *srcreg); 2668 store_data_byte(destoffset, destval); 2669 break; 2670 case 3: /* register to register */ 2671 destreg = DECODE_RM_BYTE_REGISTER(rl); 2672 DECODE_PRINTF(","); 2673 srcreg = DECODE_RM_BYTE_REGISTER(rh); 2674 DECODE_PRINTF("\n"); 2675 TRACE_AND_STEP(); 2676 *destreg = xor_byte(*destreg, *srcreg); 2677 break; 2678 } 2679 DECODE_CLEAR_SEGOVR(); 2680 END_OF_INSTR(); 2681} 2682 2683/**************************************************************************** 2684REMARKS: 2685Handles opcode 0x31 2686****************************************************************************/ 2687void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1)) 2688{ 2689 int mod, rl, rh; 2690 uint destoffset; 2691 2692 START_OF_INSTR(); 2693 DECODE_PRINTF("XOR\t"); 2694 FETCH_DECODE_MODRM(mod, rh, rl); 2695 switch (mod) { 2696 case 0: 2697 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2698 u32 destval; 2699 u32 *srcreg; 2700 2701 destoffset = decode_rm00_address(rl); 2702 DECODE_PRINTF(","); 2703 destval = fetch_data_long(destoffset); 2704 srcreg = DECODE_RM_LONG_REGISTER(rh); 2705 DECODE_PRINTF("\n"); 2706 TRACE_AND_STEP(); 2707 destval = xor_long(destval, *srcreg); 2708 store_data_long(destoffset, destval); 2709 } else { 2710 u16 destval; 2711 u16 *srcreg; 2712 2713 destoffset = decode_rm00_address(rl); 2714 DECODE_PRINTF(","); 2715 destval = fetch_data_word(destoffset); 2716 srcreg = DECODE_RM_WORD_REGISTER(rh); 2717 DECODE_PRINTF("\n"); 2718 TRACE_AND_STEP(); 2719 destval = xor_word(destval, *srcreg); 2720 store_data_word(destoffset, destval); 2721 } 2722 break; 2723 case 1: 2724 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2725 u32 destval; 2726 u32 *srcreg; 2727 2728 destoffset = decode_rm01_address(rl); 2729 DECODE_PRINTF(","); 2730 destval = fetch_data_long(destoffset); 2731 srcreg = DECODE_RM_LONG_REGISTER(rh); 2732 DECODE_PRINTF("\n"); 2733 TRACE_AND_STEP(); 2734 destval = xor_long(destval, *srcreg); 2735 store_data_long(destoffset, destval); 2736 } else { 2737 u16 destval; 2738 u16 *srcreg; 2739 2740 destoffset = decode_rm01_address(rl); 2741 DECODE_PRINTF(","); 2742 destval = fetch_data_word(destoffset); 2743 srcreg = DECODE_RM_WORD_REGISTER(rh); 2744 DECODE_PRINTF("\n"); 2745 TRACE_AND_STEP(); 2746 destval = xor_word(destval, *srcreg); 2747 store_data_word(destoffset, destval); 2748 } 2749 break; 2750 case 2: 2751 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2752 u32 destval; 2753 u32 *srcreg; 2754 2755 destoffset = decode_rm10_address(rl); 2756 DECODE_PRINTF(","); 2757 destval = fetch_data_long(destoffset); 2758 srcreg = DECODE_RM_LONG_REGISTER(rh); 2759 DECODE_PRINTF("\n"); 2760 TRACE_AND_STEP(); 2761 destval = xor_long(destval, *srcreg); 2762 store_data_long(destoffset, destval); 2763 } else { 2764 u16 destval; 2765 u16 *srcreg; 2766 2767 destoffset = decode_rm10_address(rl); 2768 DECODE_PRINTF(","); 2769 destval = fetch_data_word(destoffset); 2770 srcreg = DECODE_RM_WORD_REGISTER(rh); 2771 DECODE_PRINTF("\n"); 2772 TRACE_AND_STEP(); 2773 destval = xor_word(destval, *srcreg); 2774 store_data_word(destoffset, destval); 2775 } 2776 break; 2777 case 3: /* register to register */ 2778 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2779 u32 *destreg,*srcreg; 2780 2781 destreg = DECODE_RM_LONG_REGISTER(rl); 2782 DECODE_PRINTF(","); 2783 srcreg = DECODE_RM_LONG_REGISTER(rh); 2784 DECODE_PRINTF("\n"); 2785 TRACE_AND_STEP(); 2786 *destreg = xor_long(*destreg, *srcreg); 2787 } else { 2788 u16 *destreg,*srcreg; 2789 2790 destreg = DECODE_RM_WORD_REGISTER(rl); 2791 DECODE_PRINTF(","); 2792 srcreg = DECODE_RM_WORD_REGISTER(rh); 2793 DECODE_PRINTF("\n"); 2794 TRACE_AND_STEP(); 2795 *destreg = xor_word(*destreg, *srcreg); 2796 } 2797 break; 2798 } 2799 DECODE_CLEAR_SEGOVR(); 2800 END_OF_INSTR(); 2801} 2802 2803/**************************************************************************** 2804REMARKS: 2805Handles opcode 0x32 2806****************************************************************************/ 2807void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1)) 2808{ 2809 int mod, rl, rh; 2810 u8 *destreg, *srcreg; 2811 uint srcoffset; 2812 u8 srcval; 2813 2814 START_OF_INSTR(); 2815 DECODE_PRINTF("XOR\t"); 2816 FETCH_DECODE_MODRM(mod, rh, rl); 2817 switch (mod) { 2818 case 0: 2819 destreg = DECODE_RM_BYTE_REGISTER(rh); 2820 DECODE_PRINTF(","); 2821 srcoffset = decode_rm00_address(rl); 2822 srcval = fetch_data_byte(srcoffset); 2823 DECODE_PRINTF("\n"); 2824 TRACE_AND_STEP(); 2825 *destreg = xor_byte(*destreg, srcval); 2826 break; 2827 case 1: 2828 destreg = DECODE_RM_BYTE_REGISTER(rh); 2829 DECODE_PRINTF(","); 2830 srcoffset = decode_rm01_address(rl); 2831 srcval = fetch_data_byte(srcoffset); 2832 DECODE_PRINTF("\n"); 2833 TRACE_AND_STEP(); 2834 *destreg = xor_byte(*destreg, srcval); 2835 break; 2836 case 2: 2837 destreg = DECODE_RM_BYTE_REGISTER(rh); 2838 DECODE_PRINTF(","); 2839 srcoffset = decode_rm10_address(rl); 2840 srcval = fetch_data_byte(srcoffset); 2841 DECODE_PRINTF("\n"); 2842 TRACE_AND_STEP(); 2843 *destreg = xor_byte(*destreg, srcval); 2844 break; 2845 case 3: /* register to register */ 2846 destreg = DECODE_RM_BYTE_REGISTER(rh); 2847 DECODE_PRINTF(","); 2848 srcreg = DECODE_RM_BYTE_REGISTER(rl); 2849 DECODE_PRINTF("\n"); 2850 TRACE_AND_STEP(); 2851 *destreg = xor_byte(*destreg, *srcreg); 2852 break; 2853 } 2854 DECODE_CLEAR_SEGOVR(); 2855 END_OF_INSTR(); 2856} 2857 2858/**************************************************************************** 2859REMARKS: 2860Handles opcode 0x33 2861****************************************************************************/ 2862void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1)) 2863{ 2864 int mod, rl, rh; 2865 uint srcoffset; 2866 2867 START_OF_INSTR(); 2868 DECODE_PRINTF("XOR\t"); 2869 FETCH_DECODE_MODRM(mod, rh, rl); 2870 switch (mod) { 2871 case 0: 2872 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2873 u32 *destreg; 2874 u32 srcval; 2875 2876 destreg = DECODE_RM_LONG_REGISTER(rh); 2877 DECODE_PRINTF(","); 2878 srcoffset = decode_rm00_address(rl); 2879 srcval = fetch_data_long(srcoffset); 2880 DECODE_PRINTF("\n"); 2881 TRACE_AND_STEP(); 2882 *destreg = xor_long(*destreg, srcval); 2883 } else { 2884 u16 *destreg; 2885 u16 srcval; 2886 2887 destreg = DECODE_RM_WORD_REGISTER(rh); 2888 DECODE_PRINTF(","); 2889 srcoffset = decode_rm00_address(rl); 2890 srcval = fetch_data_word(srcoffset); 2891 DECODE_PRINTF("\n"); 2892 TRACE_AND_STEP(); 2893 *destreg = xor_word(*destreg, srcval); 2894 } 2895 break; 2896 case 1: 2897 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2898 u32 *destreg; 2899 u32 srcval; 2900 2901 destreg = DECODE_RM_LONG_REGISTER(rh); 2902 DECODE_PRINTF(","); 2903 srcoffset = decode_rm01_address(rl); 2904 srcval = fetch_data_long(srcoffset); 2905 DECODE_PRINTF("\n"); 2906 TRACE_AND_STEP(); 2907 *destreg = xor_long(*destreg, srcval); 2908 } else { 2909 u16 *destreg; 2910 u16 srcval; 2911 2912 destreg = DECODE_RM_WORD_REGISTER(rh); 2913 DECODE_PRINTF(","); 2914 srcoffset = decode_rm01_address(rl); 2915 srcval = fetch_data_word(srcoffset); 2916 DECODE_PRINTF("\n"); 2917 TRACE_AND_STEP(); 2918 *destreg = xor_word(*destreg, srcval); 2919 } 2920 break; 2921 case 2: 2922 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2923 u32 *destreg; 2924 u32 srcval; 2925 2926 destreg = DECODE_RM_LONG_REGISTER(rh); 2927 DECODE_PRINTF(","); 2928 srcoffset = decode_rm10_address(rl); 2929 srcval = fetch_data_long(srcoffset); 2930 DECODE_PRINTF("\n"); 2931 TRACE_AND_STEP(); 2932 *destreg = xor_long(*destreg, srcval); 2933 } else { 2934 u16 *destreg; 2935 u16 srcval; 2936 2937 destreg = DECODE_RM_WORD_REGISTER(rh); 2938 DECODE_PRINTF(","); 2939 srcoffset = decode_rm10_address(rl); 2940 srcval = fetch_data_word(srcoffset); 2941 DECODE_PRINTF("\n"); 2942 TRACE_AND_STEP(); 2943 *destreg = xor_word(*destreg, srcval); 2944 } 2945 break; 2946 case 3: /* register to register */ 2947 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2948 u32 *destreg,*srcreg; 2949 2950 destreg = DECODE_RM_LONG_REGISTER(rh); 2951 DECODE_PRINTF(","); 2952 srcreg = DECODE_RM_LONG_REGISTER(rl); 2953 DECODE_PRINTF("\n"); 2954 TRACE_AND_STEP(); 2955 *destreg = xor_long(*destreg, *srcreg); 2956 } else { 2957 u16 *destreg,*srcreg; 2958 2959 destreg = DECODE_RM_WORD_REGISTER(rh); 2960 DECODE_PRINTF(","); 2961 srcreg = DECODE_RM_WORD_REGISTER(rl); 2962 DECODE_PRINTF("\n"); 2963 TRACE_AND_STEP(); 2964 *destreg = xor_word(*destreg, *srcreg); 2965 } 2966 break; 2967 } 2968 DECODE_CLEAR_SEGOVR(); 2969 END_OF_INSTR(); 2970} 2971 2972/**************************************************************************** 2973REMARKS: 2974Handles opcode 0x34 2975****************************************************************************/ 2976void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 2977{ 2978 u8 srcval; 2979 2980 START_OF_INSTR(); 2981 DECODE_PRINTF("XOR\tAL,"); 2982 srcval = fetch_byte_imm(); 2983 DECODE_PRINTF2("%x\n", srcval); 2984 TRACE_AND_STEP(); 2985 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval); 2986 DECODE_CLEAR_SEGOVR(); 2987 END_OF_INSTR(); 2988} 2989 2990/**************************************************************************** 2991REMARKS: 2992Handles opcode 0x35 2993****************************************************************************/ 2994void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 2995{ 2996 u32 srcval; 2997 2998 START_OF_INSTR(); 2999 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3000 DECODE_PRINTF("XOR\tEAX,"); 3001 srcval = fetch_long_imm(); 3002 } else { 3003 DECODE_PRINTF("XOR\tAX,"); 3004 srcval = fetch_word_imm(); 3005 } 3006 DECODE_PRINTF2("%x\n", srcval); 3007 TRACE_AND_STEP(); 3008 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3009 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval); 3010 } else { 3011 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval); 3012 } 3013 DECODE_CLEAR_SEGOVR(); 3014 END_OF_INSTR(); 3015} 3016 3017/**************************************************************************** 3018REMARKS: 3019Handles opcode 0x36 3020****************************************************************************/ 3021void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 3022{ 3023 START_OF_INSTR(); 3024 DECODE_PRINTF("SS:\n"); 3025 TRACE_AND_STEP(); 3026 M.x86.mode |= SYSMODE_SEGOVR_SS; 3027 /* no DECODE_CLEAR_SEGOVR ! */ 3028 END_OF_INSTR(); 3029} 3030 3031/**************************************************************************** 3032REMARKS: 3033Handles opcode 0x37 3034****************************************************************************/ 3035void x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 3036{ 3037 START_OF_INSTR(); 3038 DECODE_PRINTF("AAA\n"); 3039 TRACE_AND_STEP(); 3040 M.x86.R_AX = aaa_word(M.x86.R_AX); 3041 DECODE_CLEAR_SEGOVR(); 3042 END_OF_INSTR(); 3043} 3044 3045/**************************************************************************** 3046REMARKS: 3047Handles opcode 0x38 3048****************************************************************************/ 3049void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1)) 3050{ 3051 int mod, rl, rh; 3052 uint destoffset; 3053 u8 *destreg, *srcreg; 3054 u8 destval; 3055 3056 START_OF_INSTR(); 3057 DECODE_PRINTF("CMP\t"); 3058 FETCH_DECODE_MODRM(mod, rh, rl); 3059 switch (mod) { 3060 case 0: 3061 destoffset = decode_rm00_address(rl); 3062 DECODE_PRINTF(","); 3063 destval = fetch_data_byte(destoffset); 3064 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3065 DECODE_PRINTF("\n"); 3066 TRACE_AND_STEP(); 3067 cmp_byte(destval, *srcreg); 3068 break; 3069 case 1: 3070 destoffset = decode_rm01_address(rl); 3071 DECODE_PRINTF(","); 3072 destval = fetch_data_byte(destoffset); 3073 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3074 DECODE_PRINTF("\n"); 3075 TRACE_AND_STEP(); 3076 cmp_byte(destval, *srcreg); 3077 break; 3078 case 2: 3079 destoffset = decode_rm10_address(rl); 3080 DECODE_PRINTF(","); 3081 destval = fetch_data_byte(destoffset); 3082 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3083 DECODE_PRINTF("\n"); 3084 TRACE_AND_STEP(); 3085 cmp_byte(destval, *srcreg); 3086 break; 3087 case 3: /* register to register */ 3088 destreg = DECODE_RM_BYTE_REGISTER(rl); 3089 DECODE_PRINTF(","); 3090 srcreg = DECODE_RM_BYTE_REGISTER(rh); 3091 DECODE_PRINTF("\n"); 3092 TRACE_AND_STEP(); 3093 cmp_byte(*destreg, *srcreg); 3094 break; 3095 } 3096 DECODE_CLEAR_SEGOVR(); 3097 END_OF_INSTR(); 3098} 3099 3100/**************************************************************************** 3101REMARKS: 3102Handles opcode 0x39 3103****************************************************************************/ 3104void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1)) 3105{ 3106 int mod, rl, rh; 3107 uint destoffset; 3108 3109 START_OF_INSTR(); 3110 DECODE_PRINTF("CMP\t"); 3111 FETCH_DECODE_MODRM(mod, rh, rl); 3112 switch (mod) { 3113 case 0: 3114 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3115 u32 destval; 3116 u32 *srcreg; 3117 3118 destoffset = decode_rm00_address(rl); 3119 DECODE_PRINTF(","); 3120 destval = fetch_data_long(destoffset); 3121 srcreg = DECODE_RM_LONG_REGISTER(rh); 3122 DECODE_PRINTF("\n"); 3123 TRACE_AND_STEP(); 3124 cmp_long(destval, *srcreg); 3125 } else { 3126 u16 destval; 3127 u16 *srcreg; 3128 3129 destoffset = decode_rm00_address(rl); 3130 DECODE_PRINTF(","); 3131 destval = fetch_data_word(destoffset); 3132 srcreg = DECODE_RM_WORD_REGISTER(rh); 3133 DECODE_PRINTF("\n"); 3134 TRACE_AND_STEP(); 3135 cmp_word(destval, *srcreg); 3136 } 3137 break; 3138 case 1: 3139 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3140 u32 destval; 3141 u32 *srcreg; 3142 3143 destoffset = decode_rm01_address(rl); 3144 DECODE_PRINTF(","); 3145 destval = fetch_data_long(destoffset); 3146 srcreg = DECODE_RM_LONG_REGISTER(rh); 3147 DECODE_PRINTF("\n"); 3148 TRACE_AND_STEP(); 3149 cmp_long(destval, *srcreg); 3150 } else { 3151 u16 destval; 3152 u16 *srcreg; 3153 3154 destoffset = decode_rm01_address(rl); 3155 DECODE_PRINTF(","); 3156 destval = fetch_data_word(destoffset); 3157 srcreg = DECODE_RM_WORD_REGISTER(rh); 3158 DECODE_PRINTF("\n"); 3159 TRACE_AND_STEP(); 3160 cmp_word(destval, *srcreg); 3161 } 3162 break; 3163 case 2: 3164 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3165 u32 destval; 3166 u32 *srcreg; 3167 3168 destoffset = decode_rm10_address(rl); 3169 DECODE_PRINTF(","); 3170 destval = fetch_data_long(destoffset); 3171 srcreg = DECODE_RM_LONG_REGISTER(rh); 3172 DECODE_PRINTF("\n"); 3173 TRACE_AND_STEP(); 3174 cmp_long(destval, *srcreg); 3175 } else { 3176 u16 destval; 3177 u16 *srcreg; 3178 3179 destoffset = decode_rm10_address(rl); 3180 DECODE_PRINTF(","); 3181 destval = fetch_data_word(destoffset); 3182 srcreg = DECODE_RM_WORD_REGISTER(rh); 3183 DECODE_PRINTF("\n"); 3184 TRACE_AND_STEP(); 3185 cmp_word(destval, *srcreg); 3186 } 3187 break; 3188 case 3: /* register to register */ 3189 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3190 u32 *destreg,*srcreg; 3191 3192 destreg = DECODE_RM_LONG_REGISTER(rl); 3193 DECODE_PRINTF(","); 3194 srcreg = DECODE_RM_LONG_REGISTER(rh); 3195 DECODE_PRINTF("\n"); 3196 TRACE_AND_STEP(); 3197 cmp_long(*destreg, *srcreg); 3198 } else { 3199 u16 *destreg,*srcreg; 3200 3201 destreg = DECODE_RM_WORD_REGISTER(rl); 3202 DECODE_PRINTF(","); 3203 srcreg = DECODE_RM_WORD_REGISTER(rh); 3204 DECODE_PRINTF("\n"); 3205 TRACE_AND_STEP(); 3206 cmp_word(*destreg, *srcreg); 3207 } 3208 break; 3209 } 3210 DECODE_CLEAR_SEGOVR(); 3211 END_OF_INSTR(); 3212} 3213 3214/**************************************************************************** 3215REMARKS: 3216Handles opcode 0x3a 3217****************************************************************************/ 3218void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1)) 3219{ 3220 int mod, rl, rh; 3221 u8 *destreg, *srcreg; 3222 uint srcoffset; 3223 u8 srcval; 3224 3225 START_OF_INSTR(); 3226 DECODE_PRINTF("CMP\t"); 3227 FETCH_DECODE_MODRM(mod, rh, rl); 3228 switch (mod) { 3229 case 0: 3230 destreg = DECODE_RM_BYTE_REGISTER(rh); 3231 DECODE_PRINTF(","); 3232 srcoffset = decode_rm00_address(rl); 3233 srcval = fetch_data_byte(srcoffset); 3234 DECODE_PRINTF("\n"); 3235 TRACE_AND_STEP(); 3236 cmp_byte(*destreg, srcval); 3237 break; 3238 case 1: 3239 destreg = DECODE_RM_BYTE_REGISTER(rh); 3240 DECODE_PRINTF(","); 3241 srcoffset = decode_rm01_address(rl); 3242 srcval = fetch_data_byte(srcoffset); 3243 DECODE_PRINTF("\n"); 3244 TRACE_AND_STEP(); 3245 cmp_byte(*destreg, srcval); 3246 break; 3247 case 2: 3248 destreg = DECODE_RM_BYTE_REGISTER(rh); 3249 DECODE_PRINTF(","); 3250 srcoffset = decode_rm10_address(rl); 3251 srcval = fetch_data_byte(srcoffset); 3252 DECODE_PRINTF("\n"); 3253 TRACE_AND_STEP(); 3254 cmp_byte(*destreg, srcval); 3255 break; 3256 case 3: /* register to register */ 3257 destreg = DECODE_RM_BYTE_REGISTER(rh); 3258 DECODE_PRINTF(","); 3259 srcreg = DECODE_RM_BYTE_REGISTER(rl); 3260 DECODE_PRINTF("\n"); 3261 TRACE_AND_STEP(); 3262 cmp_byte(*destreg, *srcreg); 3263 break; 3264 } 3265 DECODE_CLEAR_SEGOVR(); 3266 END_OF_INSTR(); 3267} 3268 3269/**************************************************************************** 3270REMARKS: 3271Handles opcode 0x3b 3272****************************************************************************/ 3273void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1)) 3274{ 3275 int mod, rl, rh; 3276 uint srcoffset; 3277 3278 START_OF_INSTR(); 3279 DECODE_PRINTF("CMP\t"); 3280 FETCH_DECODE_MODRM(mod, rh, rl); 3281 switch (mod) { 3282 case 0: 3283 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3284 u32 *destreg; 3285 u32 srcval; 3286 3287 destreg = DECODE_RM_LONG_REGISTER(rh); 3288 DECODE_PRINTF(","); 3289 srcoffset = decode_rm00_address(rl); 3290 srcval = fetch_data_long(srcoffset); 3291 DECODE_PRINTF("\n"); 3292 TRACE_AND_STEP(); 3293 cmp_long(*destreg, srcval); 3294 } else { 3295 u16 *destreg; 3296 u16 srcval; 3297 3298 destreg = DECODE_RM_WORD_REGISTER(rh); 3299 DECODE_PRINTF(","); 3300 srcoffset = decode_rm00_address(rl); 3301 srcval = fetch_data_word(srcoffset); 3302 DECODE_PRINTF("\n"); 3303 TRACE_AND_STEP(); 3304 cmp_word(*destreg, srcval); 3305 } 3306 break; 3307 case 1: 3308 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3309 u32 *destreg; 3310 u32 srcval; 3311 3312 destreg = DECODE_RM_LONG_REGISTER(rh); 3313 DECODE_PRINTF(","); 3314 srcoffset = decode_rm01_address(rl); 3315 srcval = fetch_data_long(srcoffset); 3316 DECODE_PRINTF("\n"); 3317 TRACE_AND_STEP(); 3318 cmp_long(*destreg, srcval); 3319 } else { 3320 u16 *destreg; 3321 u16 srcval; 3322 3323 destreg = DECODE_RM_WORD_REGISTER(rh); 3324 DECODE_PRINTF(","); 3325 srcoffset = decode_rm01_address(rl); 3326 srcval = fetch_data_word(srcoffset); 3327 DECODE_PRINTF("\n"); 3328 TRACE_AND_STEP(); 3329 cmp_word(*destreg, srcval); 3330 } 3331 break; 3332 case 2: 3333 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3334 u32 *destreg; 3335 u32 srcval; 3336 3337 destreg = DECODE_RM_LONG_REGISTER(rh); 3338 DECODE_PRINTF(","); 3339 srcoffset = decode_rm10_address(rl); 3340 srcval = fetch_data_long(srcoffset); 3341 DECODE_PRINTF("\n"); 3342 TRACE_AND_STEP(); 3343 cmp_long(*destreg, srcval); 3344 } else { 3345 u16 *destreg; 3346 u16 srcval; 3347 3348 destreg = DECODE_RM_WORD_REGISTER(rh); 3349 DECODE_PRINTF(","); 3350 srcoffset = decode_rm10_address(rl); 3351 srcval = fetch_data_word(srcoffset); 3352 DECODE_PRINTF("\n"); 3353 TRACE_AND_STEP(); 3354 cmp_word(*destreg, srcval); 3355 } 3356 break; 3357 case 3: /* register to register */ 3358 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3359 u32 *destreg,*srcreg; 3360 3361 destreg = DECODE_RM_LONG_REGISTER(rh); 3362 DECODE_PRINTF(","); 3363 srcreg = DECODE_RM_LONG_REGISTER(rl); 3364 DECODE_PRINTF("\n"); 3365 TRACE_AND_STEP(); 3366 cmp_long(*destreg, *srcreg); 3367 } else { 3368 u16 *destreg,*srcreg; 3369 3370 destreg = DECODE_RM_WORD_REGISTER(rh); 3371 DECODE_PRINTF(","); 3372 srcreg = DECODE_RM_WORD_REGISTER(rl); 3373 DECODE_PRINTF("\n"); 3374 TRACE_AND_STEP(); 3375 cmp_word(*destreg, *srcreg); 3376 } 3377 break; 3378 } 3379 DECODE_CLEAR_SEGOVR(); 3380 END_OF_INSTR(); 3381} 3382 3383/**************************************************************************** 3384REMARKS: 3385Handles opcode 0x3c 3386****************************************************************************/ 3387void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 3388{ 3389 u8 srcval; 3390 3391 START_OF_INSTR(); 3392 DECODE_PRINTF("CMP\tAL,"); 3393 srcval = fetch_byte_imm(); 3394 DECODE_PRINTF2("%x\n", srcval); 3395 TRACE_AND_STEP(); 3396 cmp_byte(M.x86.R_AL, srcval); 3397 DECODE_CLEAR_SEGOVR(); 3398 END_OF_INSTR(); 3399} 3400 3401/**************************************************************************** 3402REMARKS: 3403Handles opcode 0x3d 3404****************************************************************************/ 3405void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 3406{ 3407 u32 srcval; 3408 3409 START_OF_INSTR(); 3410 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3411 DECODE_PRINTF("CMP\tEAX,"); 3412 srcval = fetch_long_imm(); 3413 } else { 3414 DECODE_PRINTF("CMP\tAX,"); 3415 srcval = fetch_word_imm(); 3416 } 3417 DECODE_PRINTF2("%x\n", srcval); 3418 TRACE_AND_STEP(); 3419 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3420 cmp_long(M.x86.R_EAX, srcval); 3421 } else { 3422 cmp_word(M.x86.R_AX, (u16)srcval); 3423 } 3424 DECODE_CLEAR_SEGOVR(); 3425 END_OF_INSTR(); 3426} 3427 3428/**************************************************************************** 3429REMARKS: 3430Handles opcode 0x3e 3431****************************************************************************/ 3432void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 3433{ 3434 START_OF_INSTR(); 3435 DECODE_PRINTF("DS:\n"); 3436 TRACE_AND_STEP(); 3437 M.x86.mode |= SYSMODE_SEGOVR_DS; 3438 /* NO DECODE_CLEAR_SEGOVR! */ 3439 END_OF_INSTR(); 3440} 3441 3442/**************************************************************************** 3443REMARKS: 3444Handles opcode 0x3f 3445****************************************************************************/ 3446void x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 3447{ 3448 START_OF_INSTR(); 3449 DECODE_PRINTF("AAS\n"); 3450 TRACE_AND_STEP(); 3451 M.x86.R_AX = aas_word(M.x86.R_AX); 3452 DECODE_CLEAR_SEGOVR(); 3453 END_OF_INSTR(); 3454} 3455 3456/**************************************************************************** 3457REMARKS: 3458Handles opcode 0x40 3459****************************************************************************/ 3460void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1)) 3461{ 3462 START_OF_INSTR(); 3463 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3464 DECODE_PRINTF("INC\tEAX\n"); 3465 } else { 3466 DECODE_PRINTF("INC\tAX\n"); 3467 } 3468 TRACE_AND_STEP(); 3469 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3470 M.x86.R_EAX = inc_long(M.x86.R_EAX); 3471 } else { 3472 M.x86.R_AX = inc_word(M.x86.R_AX); 3473 } 3474 DECODE_CLEAR_SEGOVR(); 3475 END_OF_INSTR(); 3476} 3477 3478/**************************************************************************** 3479REMARKS: 3480Handles opcode 0x41 3481****************************************************************************/ 3482void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1)) 3483{ 3484 START_OF_INSTR(); 3485 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3486 DECODE_PRINTF("INC\tECX\n"); 3487 } else { 3488 DECODE_PRINTF("INC\tCX\n"); 3489 } 3490 TRACE_AND_STEP(); 3491 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3492 M.x86.R_ECX = inc_long(M.x86.R_ECX); 3493 } else { 3494 M.x86.R_CX = inc_word(M.x86.R_CX); 3495 } 3496 DECODE_CLEAR_SEGOVR(); 3497 END_OF_INSTR(); 3498} 3499 3500/**************************************************************************** 3501REMARKS: 3502Handles opcode 0x42 3503****************************************************************************/ 3504void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1)) 3505{ 3506 START_OF_INSTR(); 3507 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3508 DECODE_PRINTF("INC\tEDX\n"); 3509 } else { 3510 DECODE_PRINTF("INC\tDX\n"); 3511 } 3512 TRACE_AND_STEP(); 3513 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3514 M.x86.R_EDX = inc_long(M.x86.R_EDX); 3515 } else { 3516 M.x86.R_DX = inc_word(M.x86.R_DX); 3517 } 3518 DECODE_CLEAR_SEGOVR(); 3519 END_OF_INSTR(); 3520} 3521 3522/**************************************************************************** 3523REMARKS: 3524Handles opcode 0x43 3525****************************************************************************/ 3526void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1)) 3527{ 3528 START_OF_INSTR(); 3529 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3530 DECODE_PRINTF("INC\tEBX\n"); 3531 } else { 3532 DECODE_PRINTF("INC\tBX\n"); 3533 } 3534 TRACE_AND_STEP(); 3535 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3536 M.x86.R_EBX = inc_long(M.x86.R_EBX); 3537 } else { 3538 M.x86.R_BX = inc_word(M.x86.R_BX); 3539 } 3540 DECODE_CLEAR_SEGOVR(); 3541 END_OF_INSTR(); 3542} 3543 3544/**************************************************************************** 3545REMARKS: 3546Handles opcode 0x44 3547****************************************************************************/ 3548void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1)) 3549{ 3550 START_OF_INSTR(); 3551 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3552 DECODE_PRINTF("INC\tESP\n"); 3553 } else { 3554 DECODE_PRINTF("INC\tSP\n"); 3555 } 3556 TRACE_AND_STEP(); 3557 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3558 M.x86.R_ESP = inc_long(M.x86.R_ESP); 3559 } else { 3560 M.x86.R_SP = inc_word(M.x86.R_SP); 3561 } 3562 DECODE_CLEAR_SEGOVR(); 3563 END_OF_INSTR(); 3564} 3565 3566/**************************************************************************** 3567REMARKS: 3568Handles opcode 0x45 3569****************************************************************************/ 3570void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1)) 3571{ 3572 START_OF_INSTR(); 3573 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3574 DECODE_PRINTF("INC\tEBP\n"); 3575 } else { 3576 DECODE_PRINTF("INC\tBP\n"); 3577 } 3578 TRACE_AND_STEP(); 3579 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3580 M.x86.R_EBP = inc_long(M.x86.R_EBP); 3581 } else { 3582 M.x86.R_BP = inc_word(M.x86.R_BP); 3583 } 3584 DECODE_CLEAR_SEGOVR(); 3585 END_OF_INSTR(); 3586} 3587 3588/**************************************************************************** 3589REMARKS: 3590Handles opcode 0x46 3591****************************************************************************/ 3592void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1)) 3593{ 3594 START_OF_INSTR(); 3595 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3596 DECODE_PRINTF("INC\tESI\n"); 3597 } else { 3598 DECODE_PRINTF("INC\tSI\n"); 3599 } 3600 TRACE_AND_STEP(); 3601 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3602 M.x86.R_ESI = inc_long(M.x86.R_ESI); 3603 } else { 3604 M.x86.R_SI = inc_word(M.x86.R_SI); 3605 } 3606 DECODE_CLEAR_SEGOVR(); 3607 END_OF_INSTR(); 3608} 3609 3610/**************************************************************************** 3611REMARKS: 3612Handles opcode 0x47 3613****************************************************************************/ 3614void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1)) 3615{ 3616 START_OF_INSTR(); 3617 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3618 DECODE_PRINTF("INC\tEDI\n"); 3619 } else { 3620 DECODE_PRINTF("INC\tDI\n"); 3621 } 3622 TRACE_AND_STEP(); 3623 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3624 M.x86.R_EDI = inc_long(M.x86.R_EDI); 3625 } else { 3626 M.x86.R_DI = inc_word(M.x86.R_DI); 3627 } 3628 DECODE_CLEAR_SEGOVR(); 3629 END_OF_INSTR(); 3630} 3631 3632/**************************************************************************** 3633REMARKS: 3634Handles opcode 0x48 3635****************************************************************************/ 3636void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1)) 3637{ 3638 START_OF_INSTR(); 3639 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3640 DECODE_PRINTF("DEC\tEAX\n"); 3641 } else { 3642 DECODE_PRINTF("DEC\tAX\n"); 3643 } 3644 TRACE_AND_STEP(); 3645 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3646 M.x86.R_EAX = dec_long(M.x86.R_EAX); 3647 } else { 3648 M.x86.R_AX = dec_word(M.x86.R_AX); 3649 } 3650 DECODE_CLEAR_SEGOVR(); 3651 END_OF_INSTR(); 3652} 3653 3654/**************************************************************************** 3655REMARKS: 3656Handles opcode 0x49 3657****************************************************************************/ 3658void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1)) 3659{ 3660 START_OF_INSTR(); 3661 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3662 DECODE_PRINTF("DEC\tECX\n"); 3663 } else { 3664 DECODE_PRINTF("DEC\tCX\n"); 3665 } 3666 TRACE_AND_STEP(); 3667 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3668 M.x86.R_ECX = dec_long(M.x86.R_ECX); 3669 } else { 3670 M.x86.R_CX = dec_word(M.x86.R_CX); 3671 } 3672 DECODE_CLEAR_SEGOVR(); 3673 END_OF_INSTR(); 3674} 3675 3676/**************************************************************************** 3677REMARKS: 3678Handles opcode 0x4a 3679****************************************************************************/ 3680void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1)) 3681{ 3682 START_OF_INSTR(); 3683 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3684 DECODE_PRINTF("DEC\tEDX\n"); 3685 } else { 3686 DECODE_PRINTF("DEC\tDX\n"); 3687 } 3688 TRACE_AND_STEP(); 3689 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3690 M.x86.R_EDX = dec_long(M.x86.R_EDX); 3691 } else { 3692 M.x86.R_DX = dec_word(M.x86.R_DX); 3693 } 3694 DECODE_CLEAR_SEGOVR(); 3695 END_OF_INSTR(); 3696} 3697 3698/**************************************************************************** 3699REMARKS: 3700Handles opcode 0x4b 3701****************************************************************************/ 3702void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1)) 3703{ 3704 START_OF_INSTR(); 3705 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3706 DECODE_PRINTF("DEC\tEBX\n"); 3707 } else { 3708 DECODE_PRINTF("DEC\tBX\n"); 3709 } 3710 TRACE_AND_STEP(); 3711 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3712 M.x86.R_EBX = dec_long(M.x86.R_EBX); 3713 } else { 3714 M.x86.R_BX = dec_word(M.x86.R_BX); 3715 } 3716 DECODE_CLEAR_SEGOVR(); 3717 END_OF_INSTR(); 3718} 3719 3720/**************************************************************************** 3721REMARKS: 3722Handles opcode 0x4c 3723****************************************************************************/ 3724void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1)) 3725{ 3726 START_OF_INSTR(); 3727 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3728 DECODE_PRINTF("DEC\tESP\n"); 3729 } else { 3730 DECODE_PRINTF("DEC\tSP\n"); 3731 } 3732 TRACE_AND_STEP(); 3733 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3734 M.x86.R_ESP = dec_long(M.x86.R_ESP); 3735 } else { 3736 M.x86.R_SP = dec_word(M.x86.R_SP); 3737 } 3738 DECODE_CLEAR_SEGOVR(); 3739 END_OF_INSTR(); 3740} 3741 3742/**************************************************************************** 3743REMARKS: 3744Handles opcode 0x4d 3745****************************************************************************/ 3746void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1)) 3747{ 3748 START_OF_INSTR(); 3749 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3750 DECODE_PRINTF("DEC\tEBP\n"); 3751 } else { 3752 DECODE_PRINTF("DEC\tBP\n"); 3753 } 3754 TRACE_AND_STEP(); 3755 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3756 M.x86.R_EBP = dec_long(M.x86.R_EBP); 3757 } else { 3758 M.x86.R_BP = dec_word(M.x86.R_BP); 3759 } 3760 DECODE_CLEAR_SEGOVR(); 3761 END_OF_INSTR(); 3762} 3763 3764/**************************************************************************** 3765REMARKS: 3766Handles opcode 0x4e 3767****************************************************************************/ 3768void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1)) 3769{ 3770 START_OF_INSTR(); 3771 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3772 DECODE_PRINTF("DEC\tESI\n"); 3773 } else { 3774 DECODE_PRINTF("DEC\tSI\n"); 3775 } 3776 TRACE_AND_STEP(); 3777 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3778 M.x86.R_ESI = dec_long(M.x86.R_ESI); 3779 } else { 3780 M.x86.R_SI = dec_word(M.x86.R_SI); 3781 } 3782 DECODE_CLEAR_SEGOVR(); 3783 END_OF_INSTR(); 3784} 3785 3786/**************************************************************************** 3787REMARKS: 3788Handles opcode 0x4f 3789****************************************************************************/ 3790void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1)) 3791{ 3792 START_OF_INSTR(); 3793 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3794 DECODE_PRINTF("DEC\tEDI\n"); 3795 } else { 3796 DECODE_PRINTF("DEC\tDI\n"); 3797 } 3798 TRACE_AND_STEP(); 3799 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3800 M.x86.R_EDI = dec_long(M.x86.R_EDI); 3801 } else { 3802 M.x86.R_DI = dec_word(M.x86.R_DI); 3803 } 3804 DECODE_CLEAR_SEGOVR(); 3805 END_OF_INSTR(); 3806} 3807 3808/**************************************************************************** 3809REMARKS: 3810Handles opcode 0x50 3811****************************************************************************/ 3812void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1)) 3813{ 3814 START_OF_INSTR(); 3815 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3816 DECODE_PRINTF("PUSH\tEAX\n"); 3817 } else { 3818 DECODE_PRINTF("PUSH\tAX\n"); 3819 } 3820 TRACE_AND_STEP(); 3821 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3822 push_long(M.x86.R_EAX); 3823 } else { 3824 push_word(M.x86.R_AX); 3825 } 3826 DECODE_CLEAR_SEGOVR(); 3827 END_OF_INSTR(); 3828} 3829 3830/**************************************************************************** 3831REMARKS: 3832Handles opcode 0x51 3833****************************************************************************/ 3834void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1)) 3835{ 3836 START_OF_INSTR(); 3837 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3838 DECODE_PRINTF("PUSH\tECX\n"); 3839 } else { 3840 DECODE_PRINTF("PUSH\tCX\n"); 3841 } 3842 TRACE_AND_STEP(); 3843 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3844 push_long(M.x86.R_ECX); 3845 } else { 3846 push_word(M.x86.R_CX); 3847 } 3848 DECODE_CLEAR_SEGOVR(); 3849 END_OF_INSTR(); 3850} 3851 3852/**************************************************************************** 3853REMARKS: 3854Handles opcode 0x52 3855****************************************************************************/ 3856void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1)) 3857{ 3858 START_OF_INSTR(); 3859 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3860 DECODE_PRINTF("PUSH\tEDX\n"); 3861 } else { 3862 DECODE_PRINTF("PUSH\tDX\n"); 3863 } 3864 TRACE_AND_STEP(); 3865 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3866 push_long(M.x86.R_EDX); 3867 } else { 3868 push_word(M.x86.R_DX); 3869 } 3870 DECODE_CLEAR_SEGOVR(); 3871 END_OF_INSTR(); 3872} 3873 3874/**************************************************************************** 3875REMARKS: 3876Handles opcode 0x53 3877****************************************************************************/ 3878void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1)) 3879{ 3880 START_OF_INSTR(); 3881 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3882 DECODE_PRINTF("PUSH\tEBX\n"); 3883 } else { 3884 DECODE_PRINTF("PUSH\tBX\n"); 3885 } 3886 TRACE_AND_STEP(); 3887 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3888 push_long(M.x86.R_EBX); 3889 } else { 3890 push_word(M.x86.R_BX); 3891 } 3892 DECODE_CLEAR_SEGOVR(); 3893 END_OF_INSTR(); 3894} 3895 3896/**************************************************************************** 3897REMARKS: 3898Handles opcode 0x54 3899****************************************************************************/ 3900void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1)) 3901{ 3902 START_OF_INSTR(); 3903 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3904 DECODE_PRINTF("PUSH\tESP\n"); 3905 } else { 3906 DECODE_PRINTF("PUSH\tSP\n"); 3907 } 3908 TRACE_AND_STEP(); 3909 /* Always push (E)SP, since we are emulating an i386 and above 3910 * processor. This is necessary as some BIOS'es use this to check 3911 * what type of processor is in the system. 3912 */ 3913 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3914 push_long(M.x86.R_ESP); 3915 } else { 3916 push_word((u16)(M.x86.R_SP)); 3917 } 3918 DECODE_CLEAR_SEGOVR(); 3919 END_OF_INSTR(); 3920} 3921 3922/**************************************************************************** 3923REMARKS: 3924Handles opcode 0x55 3925****************************************************************************/ 3926void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1)) 3927{ 3928 START_OF_INSTR(); 3929 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3930 DECODE_PRINTF("PUSH\tEBP\n"); 3931 } else { 3932 DECODE_PRINTF("PUSH\tBP\n"); 3933 } 3934 TRACE_AND_STEP(); 3935 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3936 push_long(M.x86.R_EBP); 3937 } else { 3938 push_word(M.x86.R_BP); 3939 } 3940 DECODE_CLEAR_SEGOVR(); 3941 END_OF_INSTR(); 3942} 3943 3944/**************************************************************************** 3945REMARKS: 3946Handles opcode 0x56 3947****************************************************************************/ 3948void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1)) 3949{ 3950 START_OF_INSTR(); 3951 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3952 DECODE_PRINTF("PUSH\tESI\n"); 3953 } else { 3954 DECODE_PRINTF("PUSH\tSI\n"); 3955 } 3956 TRACE_AND_STEP(); 3957 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3958 push_long(M.x86.R_ESI); 3959 } else { 3960 push_word(M.x86.R_SI); 3961 } 3962 DECODE_CLEAR_SEGOVR(); 3963 END_OF_INSTR(); 3964} 3965 3966/**************************************************************************** 3967REMARKS: 3968Handles opcode 0x57 3969****************************************************************************/ 3970void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1)) 3971{ 3972 START_OF_INSTR(); 3973 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3974 DECODE_PRINTF("PUSH\tEDI\n"); 3975 } else { 3976 DECODE_PRINTF("PUSH\tDI\n"); 3977 } 3978 TRACE_AND_STEP(); 3979 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3980 push_long(M.x86.R_EDI); 3981 } else { 3982 push_word(M.x86.R_DI); 3983 } 3984 DECODE_CLEAR_SEGOVR(); 3985 END_OF_INSTR(); 3986} 3987 3988/**************************************************************************** 3989REMARKS: 3990Handles opcode 0x58 3991****************************************************************************/ 3992void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1)) 3993{ 3994 START_OF_INSTR(); 3995 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3996 DECODE_PRINTF("POP\tEAX\n"); 3997 } else { 3998 DECODE_PRINTF("POP\tAX\n"); 3999 } 4000 TRACE_AND_STEP(); 4001 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4002 M.x86.R_EAX = pop_long(); 4003 } else { 4004 M.x86.R_AX = pop_word(); 4005 } 4006 DECODE_CLEAR_SEGOVR(); 4007 END_OF_INSTR(); 4008} 4009 4010/**************************************************************************** 4011REMARKS: 4012Handles opcode 0x59 4013****************************************************************************/ 4014void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1)) 4015{ 4016 START_OF_INSTR(); 4017 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4018 DECODE_PRINTF("POP\tECX\n"); 4019 } else { 4020 DECODE_PRINTF("POP\tCX\n"); 4021 } 4022 TRACE_AND_STEP(); 4023 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4024 M.x86.R_ECX = pop_long(); 4025 } else { 4026 M.x86.R_CX = pop_word(); 4027 } 4028 DECODE_CLEAR_SEGOVR(); 4029 END_OF_INSTR(); 4030} 4031 4032/**************************************************************************** 4033REMARKS: 4034Handles opcode 0x5a 4035****************************************************************************/ 4036void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1)) 4037{ 4038 START_OF_INSTR(); 4039 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4040 DECODE_PRINTF("POP\tEDX\n"); 4041 } else { 4042 DECODE_PRINTF("POP\tDX\n"); 4043 } 4044 TRACE_AND_STEP(); 4045 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4046 M.x86.R_EDX = pop_long(); 4047 } else { 4048 M.x86.R_DX = pop_word(); 4049 } 4050 DECODE_CLEAR_SEGOVR(); 4051 END_OF_INSTR(); 4052} 4053 4054/**************************************************************************** 4055REMARKS: 4056Handles opcode 0x5b 4057****************************************************************************/ 4058void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1)) 4059{ 4060 START_OF_INSTR(); 4061 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4062 DECODE_PRINTF("POP\tEBX\n"); 4063 } else { 4064 DECODE_PRINTF("POP\tBX\n"); 4065 } 4066 TRACE_AND_STEP(); 4067 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4068 M.x86.R_EBX = pop_long(); 4069 } else { 4070 M.x86.R_BX = pop_word(); 4071 } 4072 DECODE_CLEAR_SEGOVR(); 4073 END_OF_INSTR(); 4074} 4075 4076/**************************************************************************** 4077REMARKS: 4078Handles opcode 0x5c 4079****************************************************************************/ 4080void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1)) 4081{ 4082 START_OF_INSTR(); 4083 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4084 DECODE_PRINTF("POP\tESP\n"); 4085 } else { 4086 DECODE_PRINTF("POP\tSP\n"); 4087 } 4088 TRACE_AND_STEP(); 4089 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4090 M.x86.R_ESP = pop_long(); 4091 } else { 4092 M.x86.R_SP = pop_word(); 4093 } 4094 DECODE_CLEAR_SEGOVR(); 4095 END_OF_INSTR(); 4096} 4097 4098/**************************************************************************** 4099REMARKS: 4100Handles opcode 0x5d 4101****************************************************************************/ 4102void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1)) 4103{ 4104 START_OF_INSTR(); 4105 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4106 DECODE_PRINTF("POP\tEBP\n"); 4107 } else { 4108 DECODE_PRINTF("POP\tBP\n"); 4109 } 4110 TRACE_AND_STEP(); 4111 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4112 M.x86.R_EBP = pop_long(); 4113 } else { 4114 M.x86.R_BP = pop_word(); 4115 } 4116 DECODE_CLEAR_SEGOVR(); 4117 END_OF_INSTR(); 4118} 4119 4120/**************************************************************************** 4121REMARKS: 4122Handles opcode 0x5e 4123****************************************************************************/ 4124void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1)) 4125{ 4126 START_OF_INSTR(); 4127 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4128 DECODE_PRINTF("POP\tESI\n"); 4129 } else { 4130 DECODE_PRINTF("POP\tSI\n"); 4131 } 4132 TRACE_AND_STEP(); 4133 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4134 M.x86.R_ESI = pop_long(); 4135 } else { 4136 M.x86.R_SI = pop_word(); 4137 } 4138 DECODE_CLEAR_SEGOVR(); 4139 END_OF_INSTR(); 4140} 4141 4142/**************************************************************************** 4143REMARKS: 4144Handles opcode 0x5f 4145****************************************************************************/ 4146void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1)) 4147{ 4148 START_OF_INSTR(); 4149 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4150 DECODE_PRINTF("POP\tEDI\n"); 4151 } else { 4152 DECODE_PRINTF("POP\tDI\n"); 4153 } 4154 TRACE_AND_STEP(); 4155 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4156 M.x86.R_EDI = pop_long(); 4157 } else { 4158 M.x86.R_DI = pop_word(); 4159 } 4160 DECODE_CLEAR_SEGOVR(); 4161 END_OF_INSTR(); 4162} 4163 4164/**************************************************************************** 4165REMARKS: 4166Handles opcode 0x60 4167****************************************************************************/ 4168void x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 4169{ 4170 START_OF_INSTR(); 4171 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4172 DECODE_PRINTF("PUSHAD\n"); 4173 } else { 4174 DECODE_PRINTF("PUSHA\n"); 4175 } 4176 TRACE_AND_STEP(); 4177 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4178 u32 old_sp = M.x86.R_ESP; 4179 4180 push_long(M.x86.R_EAX); 4181 push_long(M.x86.R_ECX); 4182 push_long(M.x86.R_EDX); 4183 push_long(M.x86.R_EBX); 4184 push_long(old_sp); 4185 push_long(M.x86.R_EBP); 4186 push_long(M.x86.R_ESI); 4187 push_long(M.x86.R_EDI); 4188 } else { 4189 u16 old_sp = M.x86.R_SP; 4190 4191 push_word(M.x86.R_AX); 4192 push_word(M.x86.R_CX); 4193 push_word(M.x86.R_DX); 4194 push_word(M.x86.R_BX); 4195 push_word(old_sp); 4196 push_word(M.x86.R_BP); 4197 push_word(M.x86.R_SI); 4198 push_word(M.x86.R_DI); 4199 } 4200 DECODE_CLEAR_SEGOVR(); 4201 END_OF_INSTR(); 4202} 4203 4204/**************************************************************************** 4205REMARKS: 4206Handles opcode 0x61 4207****************************************************************************/ 4208void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 4209{ 4210 START_OF_INSTR(); 4211 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4212 DECODE_PRINTF("POPAD\n"); 4213 } else { 4214 DECODE_PRINTF("POPA\n"); 4215 } 4216 TRACE_AND_STEP(); 4217 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4218 M.x86.R_EDI = pop_long(); 4219 M.x86.R_ESI = pop_long(); 4220 M.x86.R_EBP = pop_long(); 4221 M.x86.R_ESP += 4; /* skip ESP */ 4222 M.x86.R_EBX = pop_long(); 4223 M.x86.R_EDX = pop_long(); 4224 M.x86.R_ECX = pop_long(); 4225 M.x86.R_EAX = pop_long(); 4226 } else { 4227 M.x86.R_DI = pop_word(); 4228 M.x86.R_SI = pop_word(); 4229 M.x86.R_BP = pop_word(); 4230 M.x86.R_SP += 2; /* skip SP */ 4231 M.x86.R_BX = pop_word(); 4232 M.x86.R_DX = pop_word(); 4233 M.x86.R_CX = pop_word(); 4234 M.x86.R_AX = pop_word(); 4235 } 4236 DECODE_CLEAR_SEGOVR(); 4237 END_OF_INSTR(); 4238} 4239 4240/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4241/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 4242 4243/**************************************************************************** 4244REMARKS: 4245Handles opcode 0x64 4246****************************************************************************/ 4247void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 4248{ 4249 START_OF_INSTR(); 4250 DECODE_PRINTF("FS:\n"); 4251 TRACE_AND_STEP(); 4252 M.x86.mode |= SYSMODE_SEGOVR_FS; 4253 /* 4254 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4255 * opcode subroutines we do not want to do this. 4256 */ 4257 END_OF_INSTR(); 4258} 4259 4260/**************************************************************************** 4261REMARKS: 4262Handles opcode 0x65 4263****************************************************************************/ 4264void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 4265{ 4266 START_OF_INSTR(); 4267 DECODE_PRINTF("GS:\n"); 4268 TRACE_AND_STEP(); 4269 M.x86.mode |= SYSMODE_SEGOVR_GS; 4270 /* 4271 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 4272 * opcode subroutines we do not want to do this. 4273 */ 4274 END_OF_INSTR(); 4275} 4276 4277/**************************************************************************** 4278REMARKS: 4279Handles opcode 0x66 - prefix for 32-bit register 4280****************************************************************************/ 4281void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 4282{ 4283 START_OF_INSTR(); 4284 DECODE_PRINTF("DATA:\n"); 4285 TRACE_AND_STEP(); 4286 M.x86.mode |= SYSMODE_PREFIX_DATA; 4287 /* note no DECODE_CLEAR_SEGOVR here. */ 4288 END_OF_INSTR(); 4289} 4290 4291/**************************************************************************** 4292REMARKS: 4293Handles opcode 0x67 - prefix for 32-bit address 4294****************************************************************************/ 4295void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 4296{ 4297 START_OF_INSTR(); 4298 DECODE_PRINTF("ADDR:\n"); 4299 TRACE_AND_STEP(); 4300 M.x86.mode |= SYSMODE_PREFIX_ADDR; 4301 /* note no DECODE_CLEAR_SEGOVR here. */ 4302 END_OF_INSTR(); 4303} 4304 4305/**************************************************************************** 4306REMARKS: 4307Handles opcode 0x68 4308****************************************************************************/ 4309void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 4310{ 4311 u32 imm; 4312 4313 START_OF_INSTR(); 4314 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4315 imm = fetch_long_imm(); 4316 } else { 4317 imm = fetch_word_imm(); 4318 } 4319 DECODE_PRINTF2("PUSH\t%x\n", imm); 4320 TRACE_AND_STEP(); 4321 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4322 push_long(imm); 4323 } else { 4324 push_word((u16)imm); 4325 } 4326 DECODE_CLEAR_SEGOVR(); 4327 END_OF_INSTR(); 4328} 4329 4330/**************************************************************************** 4331REMARKS: 4332Handles opcode 0x69 4333****************************************************************************/ 4334void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 4335{ 4336 int mod, rl, rh; 4337 uint srcoffset; 4338 4339 START_OF_INSTR(); 4340 DECODE_PRINTF("IMUL\t"); 4341 FETCH_DECODE_MODRM(mod, rh, rl); 4342 switch (mod) { 4343 case 0: 4344 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4345 u32 *destreg; 4346 u32 srcval; 4347 u32 res_lo,res_hi; 4348 s32 imm; 4349 4350 destreg = DECODE_RM_LONG_REGISTER(rh); 4351 DECODE_PRINTF(","); 4352 srcoffset = decode_rm00_address(rl); 4353 srcval = fetch_data_long(srcoffset); 4354 imm = fetch_long_imm(); 4355 DECODE_PRINTF2(",%d\n", (s32)imm); 4356 TRACE_AND_STEP(); 4357 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4358 if (res_hi != 0) { 4359 SET_FLAG(F_CF); 4360 SET_FLAG(F_OF); 4361 } else { 4362 CLEAR_FLAG(F_CF); 4363 CLEAR_FLAG(F_OF); 4364 } 4365 *destreg = (u32)res_lo; 4366 } else { 4367 u16 *destreg; 4368 u16 srcval; 4369 u32 res; 4370 s16 imm; 4371 4372 destreg = DECODE_RM_WORD_REGISTER(rh); 4373 DECODE_PRINTF(","); 4374 srcoffset = decode_rm00_address(rl); 4375 srcval = fetch_data_word(srcoffset); 4376 imm = fetch_word_imm(); 4377 DECODE_PRINTF2(",%d\n", (s32)imm); 4378 TRACE_AND_STEP(); 4379 res = (s16)srcval * (s16)imm; 4380 if (res > 0xFFFF) { 4381 SET_FLAG(F_CF); 4382 SET_FLAG(F_OF); 4383 } else { 4384 CLEAR_FLAG(F_CF); 4385 CLEAR_FLAG(F_OF); 4386 } 4387 *destreg = (u16)res; 4388 } 4389 break; 4390 case 1: 4391 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4392 u32 *destreg; 4393 u32 srcval; 4394 u32 res_lo,res_hi; 4395 s32 imm; 4396 4397 destreg = DECODE_RM_LONG_REGISTER(rh); 4398 DECODE_PRINTF(","); 4399 srcoffset = decode_rm01_address(rl); 4400 srcval = fetch_data_long(srcoffset); 4401 imm = fetch_long_imm(); 4402 DECODE_PRINTF2(",%d\n", (s32)imm); 4403 TRACE_AND_STEP(); 4404 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4405 if (res_hi != 0) { 4406 SET_FLAG(F_CF); 4407 SET_FLAG(F_OF); 4408 } else { 4409 CLEAR_FLAG(F_CF); 4410 CLEAR_FLAG(F_OF); 4411 } 4412 *destreg = (u32)res_lo; 4413 } else { 4414 u16 *destreg; 4415 u16 srcval; 4416 u32 res; 4417 s16 imm; 4418 4419 destreg = DECODE_RM_WORD_REGISTER(rh); 4420 DECODE_PRINTF(","); 4421 srcoffset = decode_rm01_address(rl); 4422 srcval = fetch_data_word(srcoffset); 4423 imm = fetch_word_imm(); 4424 DECODE_PRINTF2(",%d\n", (s32)imm); 4425 TRACE_AND_STEP(); 4426 res = (s16)srcval * (s16)imm; 4427 if (res > 0xFFFF) { 4428 SET_FLAG(F_CF); 4429 SET_FLAG(F_OF); 4430 } else { 4431 CLEAR_FLAG(F_CF); 4432 CLEAR_FLAG(F_OF); 4433 } 4434 *destreg = (u16)res; 4435 } 4436 break; 4437 case 2: 4438 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4439 u32 *destreg; 4440 u32 srcval; 4441 u32 res_lo,res_hi; 4442 s32 imm; 4443 4444 destreg = DECODE_RM_LONG_REGISTER(rh); 4445 DECODE_PRINTF(","); 4446 srcoffset = decode_rm10_address(rl); 4447 srcval = fetch_data_long(srcoffset); 4448 imm = fetch_long_imm(); 4449 DECODE_PRINTF2(",%d\n", (s32)imm); 4450 TRACE_AND_STEP(); 4451 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4452 if (res_hi != 0) { 4453 SET_FLAG(F_CF); 4454 SET_FLAG(F_OF); 4455 } else { 4456 CLEAR_FLAG(F_CF); 4457 CLEAR_FLAG(F_OF); 4458 } 4459 *destreg = (u32)res_lo; 4460 } else { 4461 u16 *destreg; 4462 u16 srcval; 4463 u32 res; 4464 s16 imm; 4465 4466 destreg = DECODE_RM_WORD_REGISTER(rh); 4467 DECODE_PRINTF(","); 4468 srcoffset = decode_rm10_address(rl); 4469 srcval = fetch_data_word(srcoffset); 4470 imm = fetch_word_imm(); 4471 DECODE_PRINTF2(",%d\n", (s32)imm); 4472 TRACE_AND_STEP(); 4473 res = (s16)srcval * (s16)imm; 4474 if (res > 0xFFFF) { 4475 SET_FLAG(F_CF); 4476 SET_FLAG(F_OF); 4477 } else { 4478 CLEAR_FLAG(F_CF); 4479 CLEAR_FLAG(F_OF); 4480 } 4481 *destreg = (u16)res; 4482 } 4483 break; 4484 case 3: /* register to register */ 4485 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4486 u32 *destreg,*srcreg; 4487 u32 res_lo,res_hi; 4488 s32 imm; 4489 4490 destreg = DECODE_RM_LONG_REGISTER(rh); 4491 DECODE_PRINTF(","); 4492 srcreg = DECODE_RM_LONG_REGISTER(rl); 4493 imm = fetch_long_imm(); 4494 DECODE_PRINTF2(",%d\n", (s32)imm); 4495 TRACE_AND_STEP(); 4496 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4497 if (res_hi != 0) { 4498 SET_FLAG(F_CF); 4499 SET_FLAG(F_OF); 4500 } else { 4501 CLEAR_FLAG(F_CF); 4502 CLEAR_FLAG(F_OF); 4503 } 4504 *destreg = (u32)res_lo; 4505 } else { 4506 u16 *destreg,*srcreg; 4507 u32 res; 4508 s16 imm; 4509 4510 destreg = DECODE_RM_WORD_REGISTER(rh); 4511 DECODE_PRINTF(","); 4512 srcreg = DECODE_RM_WORD_REGISTER(rl); 4513 imm = fetch_word_imm(); 4514 DECODE_PRINTF2(",%d\n", (s32)imm); 4515 res = (s16)*srcreg * (s16)imm; 4516 if (res > 0xFFFF) { 4517 SET_FLAG(F_CF); 4518 SET_FLAG(F_OF); 4519 } else { 4520 CLEAR_FLAG(F_CF); 4521 CLEAR_FLAG(F_OF); 4522 } 4523 *destreg = (u16)res; 4524 } 4525 break; 4526 } 4527 DECODE_CLEAR_SEGOVR(); 4528 END_OF_INSTR(); 4529} 4530 4531/**************************************************************************** 4532REMARKS: 4533Handles opcode 0x6a 4534****************************************************************************/ 4535void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 4536{ 4537 s16 imm; 4538 4539 START_OF_INSTR(); 4540 imm = (s8)fetch_byte_imm(); 4541 DECODE_PRINTF2("PUSH\t%d\n", imm); 4542 TRACE_AND_STEP(); 4543 push_word(imm); 4544 DECODE_CLEAR_SEGOVR(); 4545 END_OF_INSTR(); 4546} 4547 4548/**************************************************************************** 4549REMARKS: 4550Handles opcode 0x6b 4551****************************************************************************/ 4552void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 4553{ 4554 int mod, rl, rh; 4555 uint srcoffset; 4556 s8 imm; 4557 4558 START_OF_INSTR(); 4559 DECODE_PRINTF("IMUL\t"); 4560 FETCH_DECODE_MODRM(mod, rh, rl); 4561 switch (mod) { 4562 case 0: 4563 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4564 u32 *destreg; 4565 u32 srcval; 4566 u32 res_lo,res_hi; 4567 4568 destreg = DECODE_RM_LONG_REGISTER(rh); 4569 DECODE_PRINTF(","); 4570 srcoffset = decode_rm00_address(rl); 4571 srcval = fetch_data_long(srcoffset); 4572 imm = fetch_byte_imm(); 4573 DECODE_PRINTF2(",%d\n", (s32)imm); 4574 TRACE_AND_STEP(); 4575 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4576 if (res_hi != 0) { 4577 SET_FLAG(F_CF); 4578 SET_FLAG(F_OF); 4579 } else { 4580 CLEAR_FLAG(F_CF); 4581 CLEAR_FLAG(F_OF); 4582 } 4583 *destreg = (u32)res_lo; 4584 } else { 4585 u16 *destreg; 4586 u16 srcval; 4587 u32 res; 4588 4589 destreg = DECODE_RM_WORD_REGISTER(rh); 4590 DECODE_PRINTF(","); 4591 srcoffset = decode_rm00_address(rl); 4592 srcval = fetch_data_word(srcoffset); 4593 imm = fetch_byte_imm(); 4594 DECODE_PRINTF2(",%d\n", (s32)imm); 4595 TRACE_AND_STEP(); 4596 res = (s16)srcval * (s16)imm; 4597 if (res > 0xFFFF) { 4598 SET_FLAG(F_CF); 4599 SET_FLAG(F_OF); 4600 } else { 4601 CLEAR_FLAG(F_CF); 4602 CLEAR_FLAG(F_OF); 4603 } 4604 *destreg = (u16)res; 4605 } 4606 break; 4607 case 1: 4608 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4609 u32 *destreg; 4610 u32 srcval; 4611 u32 res_lo,res_hi; 4612 4613 destreg = DECODE_RM_LONG_REGISTER(rh); 4614 DECODE_PRINTF(","); 4615 srcoffset = decode_rm01_address(rl); 4616 srcval = fetch_data_long(srcoffset); 4617 imm = fetch_byte_imm(); 4618 DECODE_PRINTF2(",%d\n", (s32)imm); 4619 TRACE_AND_STEP(); 4620 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4621 if (res_hi != 0) { 4622 SET_FLAG(F_CF); 4623 SET_FLAG(F_OF); 4624 } else { 4625 CLEAR_FLAG(F_CF); 4626 CLEAR_FLAG(F_OF); 4627 } 4628 *destreg = (u32)res_lo; 4629 } else { 4630 u16 *destreg; 4631 u16 srcval; 4632 u32 res; 4633 4634 destreg = DECODE_RM_WORD_REGISTER(rh); 4635 DECODE_PRINTF(","); 4636 srcoffset = decode_rm01_address(rl); 4637 srcval = fetch_data_word(srcoffset); 4638 imm = fetch_byte_imm(); 4639 DECODE_PRINTF2(",%d\n", (s32)imm); 4640 TRACE_AND_STEP(); 4641 res = (s16)srcval * (s16)imm; 4642 if (res > 0xFFFF) { 4643 SET_FLAG(F_CF); 4644 SET_FLAG(F_OF); 4645 } else { 4646 CLEAR_FLAG(F_CF); 4647 CLEAR_FLAG(F_OF); 4648 } 4649 *destreg = (u16)res; 4650 } 4651 break; 4652 case 2: 4653 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4654 u32 *destreg; 4655 u32 srcval; 4656 u32 res_lo,res_hi; 4657 4658 destreg = DECODE_RM_LONG_REGISTER(rh); 4659 DECODE_PRINTF(","); 4660 srcoffset = decode_rm10_address(rl); 4661 srcval = fetch_data_long(srcoffset); 4662 imm = fetch_byte_imm(); 4663 DECODE_PRINTF2(",%d\n", (s32)imm); 4664 TRACE_AND_STEP(); 4665 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 4666 if (res_hi != 0) { 4667 SET_FLAG(F_CF); 4668 SET_FLAG(F_OF); 4669 } else { 4670 CLEAR_FLAG(F_CF); 4671 CLEAR_FLAG(F_OF); 4672 } 4673 *destreg = (u32)res_lo; 4674 } else { 4675 u16 *destreg; 4676 u16 srcval; 4677 u32 res; 4678 4679 destreg = DECODE_RM_WORD_REGISTER(rh); 4680 DECODE_PRINTF(","); 4681 srcoffset = decode_rm10_address(rl); 4682 srcval = fetch_data_word(srcoffset); 4683 imm = fetch_byte_imm(); 4684 DECODE_PRINTF2(",%d\n", (s32)imm); 4685 TRACE_AND_STEP(); 4686 res = (s16)srcval * (s16)imm; 4687 if (res > 0xFFFF) { 4688 SET_FLAG(F_CF); 4689 SET_FLAG(F_OF); 4690 } else { 4691 CLEAR_FLAG(F_CF); 4692 CLEAR_FLAG(F_OF); 4693 } 4694 *destreg = (u16)res; 4695 } 4696 break; 4697 case 3: /* register to register */ 4698 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4699 u32 *destreg,*srcreg; 4700 u32 res_lo,res_hi; 4701 4702 destreg = DECODE_RM_LONG_REGISTER(rh); 4703 DECODE_PRINTF(","); 4704 srcreg = DECODE_RM_LONG_REGISTER(rl); 4705 imm = fetch_byte_imm(); 4706 DECODE_PRINTF2(",%d\n", (s32)imm); 4707 TRACE_AND_STEP(); 4708 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 4709 if (res_hi != 0) { 4710 SET_FLAG(F_CF); 4711 SET_FLAG(F_OF); 4712 } else { 4713 CLEAR_FLAG(F_CF); 4714 CLEAR_FLAG(F_OF); 4715 } 4716 *destreg = (u32)res_lo; 4717 } else { 4718 u16 *destreg,*srcreg; 4719 u32 res; 4720 4721 destreg = DECODE_RM_WORD_REGISTER(rh); 4722 DECODE_PRINTF(","); 4723 srcreg = DECODE_RM_WORD_REGISTER(rl); 4724 imm = fetch_byte_imm(); 4725 DECODE_PRINTF2(",%d\n", (s32)imm); 4726 res = (s16)*srcreg * (s16)imm; 4727 if (res > 0xFFFF) { 4728 SET_FLAG(F_CF); 4729 SET_FLAG(F_OF); 4730 } else { 4731 CLEAR_FLAG(F_CF); 4732 CLEAR_FLAG(F_OF); 4733 } 4734 *destreg = (u16)res; 4735 } 4736 break; 4737 } 4738 DECODE_CLEAR_SEGOVR(); 4739 END_OF_INSTR(); 4740} 4741 4742/**************************************************************************** 4743REMARKS: 4744Handles opcode 0x6c 4745****************************************************************************/ 4746void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 4747{ 4748 START_OF_INSTR(); 4749 DECODE_PRINTF("INSB\n"); 4750 ins(1); 4751 TRACE_AND_STEP(); 4752 DECODE_CLEAR_SEGOVR(); 4753 END_OF_INSTR(); 4754} 4755 4756/**************************************************************************** 4757REMARKS: 4758Handles opcode 0x6d 4759****************************************************************************/ 4760void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 4761{ 4762 START_OF_INSTR(); 4763 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4764 DECODE_PRINTF("INSD\n"); 4765 ins(4); 4766 } else { 4767 DECODE_PRINTF("INSW\n"); 4768 ins(2); 4769 } 4770 TRACE_AND_STEP(); 4771 DECODE_CLEAR_SEGOVR(); 4772 END_OF_INSTR(); 4773} 4774 4775/**************************************************************************** 4776REMARKS: 4777Handles opcode 0x6e 4778****************************************************************************/ 4779void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 4780{ 4781 START_OF_INSTR(); 4782 DECODE_PRINTF("OUTSB\n"); 4783 outs(1); 4784 TRACE_AND_STEP(); 4785 DECODE_CLEAR_SEGOVR(); 4786 END_OF_INSTR(); 4787} 4788 4789/**************************************************************************** 4790REMARKS: 4791Handles opcode 0x6f 4792****************************************************************************/ 4793void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 4794{ 4795 START_OF_INSTR(); 4796 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4797 DECODE_PRINTF("OUTSD\n"); 4798 outs(4); 4799 } else { 4800 DECODE_PRINTF("OUTSW\n"); 4801 outs(2); 4802 } 4803 TRACE_AND_STEP(); 4804 DECODE_CLEAR_SEGOVR(); 4805 END_OF_INSTR(); 4806} 4807 4808/**************************************************************************** 4809REMARKS: 4810Handles opcode 0x70 4811****************************************************************************/ 4812void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1)) 4813{ 4814 s8 offset; 4815 u16 target; 4816 4817 /* jump to byte offset if overflow flag is set */ 4818 START_OF_INSTR(); 4819 DECODE_PRINTF("JO\t"); 4820 offset = (s8)fetch_byte_imm(); 4821 target = (u16)(M.x86.R_IP + (s16)offset); 4822 DECODE_PRINTF2("%x\n", target); 4823 TRACE_AND_STEP(); 4824 if (ACCESS_FLAG(F_OF)) 4825 M.x86.R_IP = target; 4826 DECODE_CLEAR_SEGOVR(); 4827 END_OF_INSTR(); 4828} 4829 4830/**************************************************************************** 4831REMARKS: 4832Handles opcode 0x71 4833****************************************************************************/ 4834void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1)) 4835{ 4836 s8 offset; 4837 u16 target; 4838 4839 /* jump to byte offset if overflow is not set */ 4840 START_OF_INSTR(); 4841 DECODE_PRINTF("JNO\t"); 4842 offset = (s8)fetch_byte_imm(); 4843 target = (u16)(M.x86.R_IP + (s16)offset); 4844 DECODE_PRINTF2("%x\n", target); 4845 TRACE_AND_STEP(); 4846 if (!ACCESS_FLAG(F_OF)) 4847 M.x86.R_IP = target; 4848 DECODE_CLEAR_SEGOVR(); 4849 END_OF_INSTR(); 4850} 4851 4852/**************************************************************************** 4853REMARKS: 4854Handles opcode 0x72 4855****************************************************************************/ 4856void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1)) 4857{ 4858 s8 offset; 4859 u16 target; 4860 4861 /* jump to byte offset if carry flag is set. */ 4862 START_OF_INSTR(); 4863 DECODE_PRINTF("JB\t"); 4864 offset = (s8)fetch_byte_imm(); 4865 target = (u16)(M.x86.R_IP + (s16)offset); 4866 DECODE_PRINTF2("%x\n", target); 4867 TRACE_AND_STEP(); 4868 if (ACCESS_FLAG(F_CF)) 4869 M.x86.R_IP = target; 4870 DECODE_CLEAR_SEGOVR(); 4871 END_OF_INSTR(); 4872} 4873 4874/**************************************************************************** 4875REMARKS: 4876Handles opcode 0x73 4877****************************************************************************/ 4878void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1)) 4879{ 4880 s8 offset; 4881 u16 target; 4882 4883 /* jump to byte offset if carry flag is clear. */ 4884 START_OF_INSTR(); 4885 DECODE_PRINTF("JNB\t"); 4886 offset = (s8)fetch_byte_imm(); 4887 target = (u16)(M.x86.R_IP + (s16)offset); 4888 DECODE_PRINTF2("%x\n", target); 4889 TRACE_AND_STEP(); 4890 if (!ACCESS_FLAG(F_CF)) 4891 M.x86.R_IP = target; 4892 DECODE_CLEAR_SEGOVR(); 4893 END_OF_INSTR(); 4894} 4895 4896/**************************************************************************** 4897REMARKS: 4898Handles opcode 0x74 4899****************************************************************************/ 4900void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1)) 4901{ 4902 s8 offset; 4903 u16 target; 4904 4905 /* jump to byte offset if zero flag is set. */ 4906 START_OF_INSTR(); 4907 DECODE_PRINTF("JZ\t"); 4908 offset = (s8)fetch_byte_imm(); 4909 target = (u16)(M.x86.R_IP + (s16)offset); 4910 DECODE_PRINTF2("%x\n", target); 4911 TRACE_AND_STEP(); 4912 if (ACCESS_FLAG(F_ZF)) 4913 M.x86.R_IP = target; 4914 DECODE_CLEAR_SEGOVR(); 4915 END_OF_INSTR(); 4916} 4917 4918/**************************************************************************** 4919REMARKS: 4920Handles opcode 0x75 4921****************************************************************************/ 4922void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1)) 4923{ 4924 s8 offset; 4925 u16 target; 4926 4927 /* jump to byte offset if zero flag is clear. */ 4928 START_OF_INSTR(); 4929 DECODE_PRINTF("JNZ\t"); 4930 offset = (s8)fetch_byte_imm(); 4931 target = (u16)(M.x86.R_IP + (s16)offset); 4932 DECODE_PRINTF2("%x\n", target); 4933 TRACE_AND_STEP(); 4934 if (!ACCESS_FLAG(F_ZF)) 4935 M.x86.R_IP = target; 4936 DECODE_CLEAR_SEGOVR(); 4937 END_OF_INSTR(); 4938} 4939 4940/**************************************************************************** 4941REMARKS: 4942Handles opcode 0x76 4943****************************************************************************/ 4944void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1)) 4945{ 4946 s8 offset; 4947 u16 target; 4948 4949 /* jump to byte offset if carry flag is set or if the zero 4950 flag is set. */ 4951 START_OF_INSTR(); 4952 DECODE_PRINTF("JBE\t"); 4953 offset = (s8)fetch_byte_imm(); 4954 target = (u16)(M.x86.R_IP + (s16)offset); 4955 DECODE_PRINTF2("%x\n", target); 4956 TRACE_AND_STEP(); 4957 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) 4958 M.x86.R_IP = target; 4959 DECODE_CLEAR_SEGOVR(); 4960 END_OF_INSTR(); 4961} 4962 4963/**************************************************************************** 4964REMARKS: 4965Handles opcode 0x77 4966****************************************************************************/ 4967void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1)) 4968{ 4969 s8 offset; 4970 u16 target; 4971 4972 /* jump to byte offset if carry flag is clear and if the zero 4973 flag is clear */ 4974 START_OF_INSTR(); 4975 DECODE_PRINTF("JNBE\t"); 4976 offset = (s8)fetch_byte_imm(); 4977 target = (u16)(M.x86.R_IP + (s16)offset); 4978 DECODE_PRINTF2("%x\n", target); 4979 TRACE_AND_STEP(); 4980 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))) 4981 M.x86.R_IP = target; 4982 DECODE_CLEAR_SEGOVR(); 4983 END_OF_INSTR(); 4984} 4985 4986/**************************************************************************** 4987REMARKS: 4988Handles opcode 0x78 4989****************************************************************************/ 4990void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1)) 4991{ 4992 s8 offset; 4993 u16 target; 4994 4995 /* jump to byte offset if sign flag is set */ 4996 START_OF_INSTR(); 4997 DECODE_PRINTF("JS\t"); 4998 offset = (s8)fetch_byte_imm(); 4999 target = (u16)(M.x86.R_IP + (s16)offset); 5000 DECODE_PRINTF2("%x\n", target); 5001 TRACE_AND_STEP(); 5002 if (ACCESS_FLAG(F_SF)) 5003 M.x86.R_IP = target; 5004 DECODE_CLEAR_SEGOVR(); 5005 END_OF_INSTR(); 5006} 5007 5008/**************************************************************************** 5009REMARKS: 5010Handles opcode 0x79 5011****************************************************************************/ 5012void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1)) 5013{ 5014 s8 offset; 5015 u16 target; 5016 5017 /* jump to byte offset if sign flag is clear */ 5018 START_OF_INSTR(); 5019 DECODE_PRINTF("JNS\t"); 5020 offset = (s8)fetch_byte_imm(); 5021 target = (u16)(M.x86.R_IP + (s16)offset); 5022 DECODE_PRINTF2("%x\n", target); 5023 TRACE_AND_STEP(); 5024 if (!ACCESS_FLAG(F_SF)) 5025 M.x86.R_IP = target; 5026 DECODE_CLEAR_SEGOVR(); 5027 END_OF_INSTR(); 5028} 5029 5030/**************************************************************************** 5031REMARKS: 5032Handles opcode 0x7a 5033****************************************************************************/ 5034void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1)) 5035{ 5036 s8 offset; 5037 u16 target; 5038 5039 /* jump to byte offset if parity flag is set (even parity) */ 5040 START_OF_INSTR(); 5041 DECODE_PRINTF("JP\t"); 5042 offset = (s8)fetch_byte_imm(); 5043 target = (u16)(M.x86.R_IP + (s16)offset); 5044 DECODE_PRINTF2("%x\n", target); 5045 TRACE_AND_STEP(); 5046 if (ACCESS_FLAG(F_PF)) 5047 M.x86.R_IP = target; 5048 DECODE_CLEAR_SEGOVR(); 5049 END_OF_INSTR(); 5050} 5051 5052/**************************************************************************** 5053REMARKS: 5054Handles opcode 0x7b 5055****************************************************************************/ 5056void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1)) 5057{ 5058 s8 offset; 5059 u16 target; 5060 5061 /* jump to byte offset if parity flag is clear (odd parity) */ 5062 START_OF_INSTR(); 5063 DECODE_PRINTF("JNP\t"); 5064 offset = (s8)fetch_byte_imm(); 5065 target = (u16)(M.x86.R_IP + (s16)offset); 5066 DECODE_PRINTF2("%x\n", target); 5067 TRACE_AND_STEP(); 5068 if (!ACCESS_FLAG(F_PF)) 5069 M.x86.R_IP = target; 5070 DECODE_CLEAR_SEGOVR(); 5071 END_OF_INSTR(); 5072} 5073 5074/**************************************************************************** 5075REMARKS: 5076Handles opcode 0x7c 5077****************************************************************************/ 5078void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1)) 5079{ 5080 s8 offset; 5081 u16 target; 5082 int sf, of; 5083 5084 /* jump to byte offset if sign flag not equal to overflow flag. */ 5085 START_OF_INSTR(); 5086 DECODE_PRINTF("JL\t"); 5087 offset = (s8)fetch_byte_imm(); 5088 target = (u16)(M.x86.R_IP + (s16)offset); 5089 DECODE_PRINTF2("%x\n", target); 5090 TRACE_AND_STEP(); 5091 sf = ACCESS_FLAG(F_SF) != 0; 5092 of = ACCESS_FLAG(F_OF) != 0; 5093 if (sf ^ of) 5094 M.x86.R_IP = target; 5095 DECODE_CLEAR_SEGOVR(); 5096 END_OF_INSTR(); 5097} 5098 5099/**************************************************************************** 5100REMARKS: 5101Handles opcode 0x7d 5102****************************************************************************/ 5103void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1)) 5104{ 5105 s8 offset; 5106 u16 target; 5107 int sf, of; 5108 5109 /* jump to byte offset if sign flag not equal to overflow flag. */ 5110 START_OF_INSTR(); 5111 DECODE_PRINTF("JNL\t"); 5112 offset = (s8)fetch_byte_imm(); 5113 target = (u16)(M.x86.R_IP + (s16)offset); 5114 DECODE_PRINTF2("%x\n", target); 5115 TRACE_AND_STEP(); 5116 sf = ACCESS_FLAG(F_SF) != 0; 5117 of = ACCESS_FLAG(F_OF) != 0; 5118 /* note: inverse of above, but using == instead of xor. */ 5119 if (sf == of) 5120 M.x86.R_IP = target; 5121 DECODE_CLEAR_SEGOVR(); 5122 END_OF_INSTR(); 5123} 5124 5125/**************************************************************************** 5126REMARKS: 5127Handles opcode 0x7e 5128****************************************************************************/ 5129void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1)) 5130{ 5131 s8 offset; 5132 u16 target; 5133 int sf, of; 5134 5135 /* jump to byte offset if sign flag not equal to overflow flag 5136 or the zero flag is set */ 5137 START_OF_INSTR(); 5138 DECODE_PRINTF("JLE\t"); 5139 offset = (s8)fetch_byte_imm(); 5140 target = (u16)(M.x86.R_IP + (s16)offset); 5141 DECODE_PRINTF2("%x\n", target); 5142 TRACE_AND_STEP(); 5143 sf = ACCESS_FLAG(F_SF) != 0; 5144 of = ACCESS_FLAG(F_OF) != 0; 5145 if ((sf ^ of) || ACCESS_FLAG(F_ZF)) 5146 M.x86.R_IP = target; 5147 DECODE_CLEAR_SEGOVR(); 5148 END_OF_INSTR(); 5149} 5150 5151/**************************************************************************** 5152REMARKS: 5153Handles opcode 0x7f 5154****************************************************************************/ 5155void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1)) 5156{ 5157 s8 offset; 5158 u16 target; 5159 int sf, of; 5160 5161 /* jump to byte offset if sign flag equal to overflow flag. 5162 and the zero flag is clear */ 5163 START_OF_INSTR(); 5164 DECODE_PRINTF("JNLE\t"); 5165 offset = (s8)fetch_byte_imm(); 5166 target = (u16)(M.x86.R_IP + (s16)offset); 5167 DECODE_PRINTF2("%x\n", target); 5168 TRACE_AND_STEP(); 5169 sf = ACCESS_FLAG(F_SF) != 0; 5170 of = ACCESS_FLAG(F_OF) != 0; 5171 if ((sf == of) && !ACCESS_FLAG(F_ZF)) 5172 M.x86.R_IP = target; 5173 DECODE_CLEAR_SEGOVR(); 5174 END_OF_INSTR(); 5175} 5176 5177static u8 (*opc80_byte_operation[])(u8 d, u8 s) = 5178{ 5179 add_byte, /* 00 */ 5180 or_byte, /* 01 */ 5181 adc_byte, /* 02 */ 5182 sbb_byte, /* 03 */ 5183 and_byte, /* 04 */ 5184 sub_byte, /* 05 */ 5185 xor_byte, /* 06 */ 5186 cmp_byte, /* 07 */ 5187}; 5188 5189/**************************************************************************** 5190REMARKS: 5191Handles opcode 0x80 5192****************************************************************************/ 5193void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5194{ 5195 int mod, rl, rh; 5196 u8 *destreg; 5197 uint destoffset; 5198 u8 imm; 5199 u8 destval; 5200 5201 /* 5202 * Weirdo special case instruction format. Part of the opcode 5203 * held below in "RH". Doubly nested case would result, except 5204 * that the decoded instruction 5205 */ 5206 START_OF_INSTR(); 5207 FETCH_DECODE_MODRM(mod, rh, rl); 5208#ifdef DEBUG 5209 if (DEBUG_DECODE()) { 5210 5211 switch (rh) { 5212 case 0: 5213 DECODE_PRINTF("ADD\t"); 5214 break; 5215 case 1: 5216 DECODE_PRINTF("OR\t"); 5217 break; 5218 case 2: 5219 DECODE_PRINTF("ADC\t"); 5220 break; 5221 case 3: 5222 DECODE_PRINTF("SBB\t"); 5223 break; 5224 case 4: 5225 DECODE_PRINTF("AND\t"); 5226 break; 5227 case 5: 5228 DECODE_PRINTF("SUB\t"); 5229 break; 5230 case 6: 5231 DECODE_PRINTF("XOR\t"); 5232 break; 5233 case 7: 5234 DECODE_PRINTF("CMP\t"); 5235 break; 5236 } 5237 } 5238#endif 5239 /* know operation, decode the mod byte to find the addressing 5240 mode. */ 5241 switch (mod) { 5242 case 0: 5243 DECODE_PRINTF("BYTE PTR "); 5244 destoffset = decode_rm00_address(rl); 5245 DECODE_PRINTF(","); 5246 destval = fetch_data_byte(destoffset); 5247 imm = fetch_byte_imm(); 5248 DECODE_PRINTF2("%x\n", imm); 5249 TRACE_AND_STEP(); 5250 destval = (*opc80_byte_operation[rh]) (destval, imm); 5251 if (rh != 7) 5252 store_data_byte(destoffset, destval); 5253 break; 5254 case 1: 5255 DECODE_PRINTF("BYTE PTR "); 5256 destoffset = decode_rm01_address(rl); 5257 DECODE_PRINTF(","); 5258 destval = fetch_data_byte(destoffset); 5259 imm = fetch_byte_imm(); 5260 DECODE_PRINTF2("%x\n", imm); 5261 TRACE_AND_STEP(); 5262 destval = (*opc80_byte_operation[rh]) (destval, imm); 5263 if (rh != 7) 5264 store_data_byte(destoffset, destval); 5265 break; 5266 case 2: 5267 DECODE_PRINTF("BYTE PTR "); 5268 destoffset = decode_rm10_address(rl); 5269 DECODE_PRINTF(","); 5270 destval = fetch_data_byte(destoffset); 5271 imm = fetch_byte_imm(); 5272 DECODE_PRINTF2("%x\n", imm); 5273 TRACE_AND_STEP(); 5274 destval = (*opc80_byte_operation[rh]) (destval, imm); 5275 if (rh != 7) 5276 store_data_byte(destoffset, destval); 5277 break; 5278 case 3: /* register to register */ 5279 destreg = DECODE_RM_BYTE_REGISTER(rl); 5280 DECODE_PRINTF(","); 5281 imm = fetch_byte_imm(); 5282 DECODE_PRINTF2("%x\n", imm); 5283 TRACE_AND_STEP(); 5284 destval = (*opc80_byte_operation[rh]) (*destreg, imm); 5285 if (rh != 7) 5286 *destreg = destval; 5287 break; 5288 } 5289 DECODE_CLEAR_SEGOVR(); 5290 END_OF_INSTR(); 5291} 5292 5293static u16 (*opc81_word_operation[])(u16 d, u16 s) = 5294{ 5295 add_word, /*00 */ 5296 or_word, /*01 */ 5297 adc_word, /*02 */ 5298 sbb_word, /*03 */ 5299 and_word, /*04 */ 5300 sub_word, /*05 */ 5301 xor_word, /*06 */ 5302 cmp_word, /*07 */ 5303}; 5304 5305static u32 (*opc81_long_operation[])(u32 d, u32 s) = 5306{ 5307 add_long, /*00 */ 5308 or_long, /*01 */ 5309 adc_long, /*02 */ 5310 sbb_long, /*03 */ 5311 and_long, /*04 */ 5312 sub_long, /*05 */ 5313 xor_long, /*06 */ 5314 cmp_long, /*07 */ 5315}; 5316 5317/**************************************************************************** 5318REMARKS: 5319Handles opcode 0x81 5320****************************************************************************/ 5321void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5322{ 5323 int mod, rl, rh; 5324 uint destoffset; 5325 5326 /* 5327 * Weirdo special case instruction format. Part of the opcode 5328 * held below in "RH". Doubly nested case would result, except 5329 * that the decoded instruction 5330 */ 5331 START_OF_INSTR(); 5332 FETCH_DECODE_MODRM(mod, rh, rl); 5333#ifdef DEBUG 5334 if (DEBUG_DECODE()) { 5335 5336 switch (rh) { 5337 case 0: 5338 DECODE_PRINTF("ADD\t"); 5339 break; 5340 case 1: 5341 DECODE_PRINTF("OR\t"); 5342 break; 5343 case 2: 5344 DECODE_PRINTF("ADC\t"); 5345 break; 5346 case 3: 5347 DECODE_PRINTF("SBB\t"); 5348 break; 5349 case 4: 5350 DECODE_PRINTF("AND\t"); 5351 break; 5352 case 5: 5353 DECODE_PRINTF("SUB\t"); 5354 break; 5355 case 6: 5356 DECODE_PRINTF("XOR\t"); 5357 break; 5358 case 7: 5359 DECODE_PRINTF("CMP\t"); 5360 break; 5361 } 5362 } 5363#endif 5364 /* 5365 * Know operation, decode the mod byte to find the addressing 5366 * mode. 5367 */ 5368 switch (mod) { 5369 case 0: 5370 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5371 u32 destval,imm; 5372 5373 DECODE_PRINTF("DWORD PTR "); 5374 destoffset = decode_rm00_address(rl); 5375 DECODE_PRINTF(","); 5376 destval = fetch_data_long(destoffset); 5377 imm = fetch_long_imm(); 5378 DECODE_PRINTF2("%x\n", imm); 5379 TRACE_AND_STEP(); 5380 destval = (*opc81_long_operation[rh]) (destval, imm); 5381 if (rh != 7) 5382 store_data_long(destoffset, destval); 5383 } else { 5384 u16 destval,imm; 5385 5386 DECODE_PRINTF("WORD PTR "); 5387 destoffset = decode_rm00_address(rl); 5388 DECODE_PRINTF(","); 5389 destval = fetch_data_word(destoffset); 5390 imm = fetch_word_imm(); 5391 DECODE_PRINTF2("%x\n", imm); 5392 TRACE_AND_STEP(); 5393 destval = (*opc81_word_operation[rh]) (destval, imm); 5394 if (rh != 7) 5395 store_data_word(destoffset, destval); 5396 } 5397 break; 5398 case 1: 5399 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5400 u32 destval,imm; 5401 5402 DECODE_PRINTF("DWORD PTR "); 5403 destoffset = decode_rm01_address(rl); 5404 DECODE_PRINTF(","); 5405 destval = fetch_data_long(destoffset); 5406 imm = fetch_long_imm(); 5407 DECODE_PRINTF2("%x\n", imm); 5408 TRACE_AND_STEP(); 5409 destval = (*opc81_long_operation[rh]) (destval, imm); 5410 if (rh != 7) 5411 store_data_long(destoffset, destval); 5412 } else { 5413 u16 destval,imm; 5414 5415 DECODE_PRINTF("WORD PTR "); 5416 destoffset = decode_rm01_address(rl); 5417 DECODE_PRINTF(","); 5418 destval = fetch_data_word(destoffset); 5419 imm = fetch_word_imm(); 5420 DECODE_PRINTF2("%x\n", imm); 5421 TRACE_AND_STEP(); 5422 destval = (*opc81_word_operation[rh]) (destval, imm); 5423 if (rh != 7) 5424 store_data_word(destoffset, destval); 5425 } 5426 break; 5427 case 2: 5428 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5429 u32 destval,imm; 5430 5431 DECODE_PRINTF("DWORD PTR "); 5432 destoffset = decode_rm10_address(rl); 5433 DECODE_PRINTF(","); 5434 destval = fetch_data_long(destoffset); 5435 imm = fetch_long_imm(); 5436 DECODE_PRINTF2("%x\n", imm); 5437 TRACE_AND_STEP(); 5438 destval = (*opc81_long_operation[rh]) (destval, imm); 5439 if (rh != 7) 5440 store_data_long(destoffset, destval); 5441 } else { 5442 u16 destval,imm; 5443 5444 DECODE_PRINTF("WORD PTR "); 5445 destoffset = decode_rm10_address(rl); 5446 DECODE_PRINTF(","); 5447 destval = fetch_data_word(destoffset); 5448 imm = fetch_word_imm(); 5449 DECODE_PRINTF2("%x\n", imm); 5450 TRACE_AND_STEP(); 5451 destval = (*opc81_word_operation[rh]) (destval, imm); 5452 if (rh != 7) 5453 store_data_word(destoffset, destval); 5454 } 5455 break; 5456 case 3: /* register to register */ 5457 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5458 u32 *destreg; 5459 u32 destval,imm; 5460 5461 destreg = DECODE_RM_LONG_REGISTER(rl); 5462 DECODE_PRINTF(","); 5463 imm = fetch_long_imm(); 5464 DECODE_PRINTF2("%x\n", imm); 5465 TRACE_AND_STEP(); 5466 destval = (*opc81_long_operation[rh]) (*destreg, imm); 5467 if (rh != 7) 5468 *destreg = destval; 5469 } else { 5470 u16 *destreg; 5471 u16 destval,imm; 5472 5473 destreg = DECODE_RM_WORD_REGISTER(rl); 5474 DECODE_PRINTF(","); 5475 imm = fetch_word_imm(); 5476 DECODE_PRINTF2("%x\n", imm); 5477 TRACE_AND_STEP(); 5478 destval = (*opc81_word_operation[rh]) (*destreg, imm); 5479 if (rh != 7) 5480 *destreg = destval; 5481 } 5482 break; 5483 } 5484 DECODE_CLEAR_SEGOVR(); 5485 END_OF_INSTR(); 5486} 5487 5488static u8 (*opc82_byte_operation[])(u8 s, u8 d) = 5489{ 5490 add_byte, /*00 */ 5491 or_byte, /*01 *//*YYY UNUSED ???? */ 5492 adc_byte, /*02 */ 5493 sbb_byte, /*03 */ 5494 and_byte, /*04 *//*YYY UNUSED ???? */ 5495 sub_byte, /*05 */ 5496 xor_byte, /*06 *//*YYY UNUSED ???? */ 5497 cmp_byte, /*07 */ 5498}; 5499 5500/**************************************************************************** 5501REMARKS: 5502Handles opcode 0x82 5503****************************************************************************/ 5504void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 5505{ 5506 int mod, rl, rh; 5507 u8 *destreg; 5508 uint destoffset; 5509 u8 imm; 5510 u8 destval; 5511 5512 /* 5513 * Weirdo special case instruction format. Part of the opcode 5514 * held below in "RH". Doubly nested case would result, except 5515 * that the decoded instruction Similar to opcode 81, except that 5516 * the immediate byte is sign extended to a word length. 5517 */ 5518 START_OF_INSTR(); 5519 FETCH_DECODE_MODRM(mod, rh, rl); 5520#ifdef DEBUG 5521 if (DEBUG_DECODE()) { 5522 switch (rh) { 5523 case 0: 5524 DECODE_PRINTF("ADD\t"); 5525 break; 5526 case 1: 5527 DECODE_PRINTF("OR\t"); 5528 break; 5529 case 2: 5530 DECODE_PRINTF("ADC\t"); 5531 break; 5532 case 3: 5533 DECODE_PRINTF("SBB\t"); 5534 break; 5535 case 4: 5536 DECODE_PRINTF("AND\t"); 5537 break; 5538 case 5: 5539 DECODE_PRINTF("SUB\t"); 5540 break; 5541 case 6: 5542 DECODE_PRINTF("XOR\t"); 5543 break; 5544 case 7: 5545 DECODE_PRINTF("CMP\t"); 5546 break; 5547 } 5548 } 5549#endif 5550 /* know operation, decode the mod byte to find the addressing 5551 mode. */ 5552 switch (mod) { 5553 case 0: 5554 DECODE_PRINTF("BYTE PTR "); 5555 destoffset = decode_rm00_address(rl); 5556 destval = fetch_data_byte(destoffset); 5557 imm = fetch_byte_imm(); 5558 DECODE_PRINTF2(",%x\n", imm); 5559 TRACE_AND_STEP(); 5560 destval = (*opc82_byte_operation[rh]) (destval, imm); 5561 if (rh != 7) 5562 store_data_byte(destoffset, destval); 5563 break; 5564 case 1: 5565 DECODE_PRINTF("BYTE PTR "); 5566 destoffset = decode_rm01_address(rl); 5567 destval = fetch_data_byte(destoffset); 5568 imm = fetch_byte_imm(); 5569 DECODE_PRINTF2(",%x\n", imm); 5570 TRACE_AND_STEP(); 5571 destval = (*opc82_byte_operation[rh]) (destval, imm); 5572 if (rh != 7) 5573 store_data_byte(destoffset, destval); 5574 break; 5575 case 2: 5576 DECODE_PRINTF("BYTE PTR "); 5577 destoffset = decode_rm10_address(rl); 5578 destval = fetch_data_byte(destoffset); 5579 imm = fetch_byte_imm(); 5580 DECODE_PRINTF2(",%x\n", imm); 5581 TRACE_AND_STEP(); 5582 destval = (*opc82_byte_operation[rh]) (destval, imm); 5583 if (rh != 7) 5584 store_data_byte(destoffset, destval); 5585 break; 5586 case 3: /* register to register */ 5587 destreg = DECODE_RM_BYTE_REGISTER(rl); 5588 imm = fetch_byte_imm(); 5589 DECODE_PRINTF2(",%x\n", imm); 5590 TRACE_AND_STEP(); 5591 destval = (*opc82_byte_operation[rh]) (*destreg, imm); 5592 if (rh != 7) 5593 *destreg = destval; 5594 break; 5595 } 5596 DECODE_CLEAR_SEGOVR(); 5597 END_OF_INSTR(); 5598} 5599 5600static u16 (*opc83_word_operation[])(u16 s, u16 d) = 5601{ 5602 add_word, /*00 */ 5603 or_word, /*01 *//*YYY UNUSED ???? */ 5604 adc_word, /*02 */ 5605 sbb_word, /*03 */ 5606 and_word, /*04 *//*YYY UNUSED ???? */ 5607 sub_word, /*05 */ 5608 xor_word, /*06 *//*YYY UNUSED ???? */ 5609 cmp_word, /*07 */ 5610}; 5611 5612static u32 (*opc83_long_operation[])(u32 s, u32 d) = 5613{ 5614 add_long, /*00 */ 5615 or_long, /*01 *//*YYY UNUSED ???? */ 5616 adc_long, /*02 */ 5617 sbb_long, /*03 */ 5618 and_long, /*04 *//*YYY UNUSED ???? */ 5619 sub_long, /*05 */ 5620 xor_long, /*06 *//*YYY UNUSED ???? */ 5621 cmp_long, /*07 */ 5622}; 5623 5624/**************************************************************************** 5625REMARKS: 5626Handles opcode 0x83 5627****************************************************************************/ 5628void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 5629{ 5630 int mod, rl, rh; 5631 uint destoffset; 5632 5633 /* 5634 * Weirdo special case instruction format. Part of the opcode 5635 * held below in "RH". Doubly nested case would result, except 5636 * that the decoded instruction Similar to opcode 81, except that 5637 * the immediate byte is sign extended to a word length. 5638 */ 5639 START_OF_INSTR(); 5640 FETCH_DECODE_MODRM(mod, rh, rl); 5641#ifdef DEBUG 5642 if (DEBUG_DECODE()) { 5643 switch (rh) { 5644 case 0: 5645 DECODE_PRINTF("ADD\t"); 5646 break; 5647 case 1: 5648 DECODE_PRINTF("OR\t"); 5649 break; 5650 case 2: 5651 DECODE_PRINTF("ADC\t"); 5652 break; 5653 case 3: 5654 DECODE_PRINTF("SBB\t"); 5655 break; 5656 case 4: 5657 DECODE_PRINTF("AND\t"); 5658 break; 5659 case 5: 5660 DECODE_PRINTF("SUB\t"); 5661 break; 5662 case 6: 5663 DECODE_PRINTF("XOR\t"); 5664 break; 5665 case 7: 5666 DECODE_PRINTF("CMP\t"); 5667 break; 5668 } 5669 } 5670#endif 5671 /* know operation, decode the mod byte to find the addressing 5672 mode. */ 5673 switch (mod) { 5674 case 0: 5675 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5676 u32 destval,imm; 5677 5678 DECODE_PRINTF("DWORD PTR "); 5679 destoffset = decode_rm00_address(rl); 5680 destval = fetch_data_long(destoffset); 5681 imm = (s8) fetch_byte_imm(); 5682 DECODE_PRINTF2(",%x\n", imm); 5683 TRACE_AND_STEP(); 5684 destval = (*opc83_long_operation[rh]) (destval, imm); 5685 if (rh != 7) 5686 store_data_long(destoffset, destval); 5687 } else { 5688 u16 destval,imm; 5689 5690 DECODE_PRINTF("WORD PTR "); 5691 destoffset = decode_rm00_address(rl); 5692 destval = fetch_data_word(destoffset); 5693 imm = (s8) fetch_byte_imm(); 5694 DECODE_PRINTF2(",%x\n", imm); 5695 TRACE_AND_STEP(); 5696 destval = (*opc83_word_operation[rh]) (destval, imm); 5697 if (rh != 7) 5698 store_data_word(destoffset, destval); 5699 } 5700 break; 5701 case 1: 5702 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5703 u32 destval,imm; 5704 5705 DECODE_PRINTF("DWORD PTR "); 5706 destoffset = decode_rm01_address(rl); 5707 destval = fetch_data_long(destoffset); 5708 imm = (s8) fetch_byte_imm(); 5709 DECODE_PRINTF2(",%x\n", imm); 5710 TRACE_AND_STEP(); 5711 destval = (*opc83_long_operation[rh]) (destval, imm); 5712 if (rh != 7) 5713 store_data_long(destoffset, destval); 5714 } else { 5715 u16 destval,imm; 5716 5717 DECODE_PRINTF("WORD PTR "); 5718 destoffset = decode_rm01_address(rl); 5719 destval = fetch_data_word(destoffset); 5720 imm = (s8) fetch_byte_imm(); 5721 DECODE_PRINTF2(",%x\n", imm); 5722 TRACE_AND_STEP(); 5723 destval = (*opc83_word_operation[rh]) (destval, imm); 5724 if (rh != 7) 5725 store_data_word(destoffset, destval); 5726 } 5727 break; 5728 case 2: 5729 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5730 u32 destval,imm; 5731 5732 DECODE_PRINTF("DWORD PTR "); 5733 destoffset = decode_rm10_address(rl); 5734 destval = fetch_data_long(destoffset); 5735 imm = (s8) fetch_byte_imm(); 5736 DECODE_PRINTF2(",%x\n", imm); 5737 TRACE_AND_STEP(); 5738 destval = (*opc83_long_operation[rh]) (destval, imm); 5739 if (rh != 7) 5740 store_data_long(destoffset, destval); 5741 } else { 5742 u16 destval,imm; 5743 5744 DECODE_PRINTF("WORD PTR "); 5745 destoffset = decode_rm10_address(rl); 5746 destval = fetch_data_word(destoffset); 5747 imm = (s8) fetch_byte_imm(); 5748 DECODE_PRINTF2(",%x\n", imm); 5749 TRACE_AND_STEP(); 5750 destval = (*opc83_word_operation[rh]) (destval, imm); 5751 if (rh != 7) 5752 store_data_word(destoffset, destval); 5753 } 5754 break; 5755 case 3: /* register to register */ 5756 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5757 u32 *destreg; 5758 u32 destval,imm; 5759 5760 destreg = DECODE_RM_LONG_REGISTER(rl); 5761 imm = (s8) fetch_byte_imm(); 5762 DECODE_PRINTF2(",%x\n", imm); 5763 TRACE_AND_STEP(); 5764 destval = (*opc83_long_operation[rh]) (*destreg, imm); 5765 if (rh != 7) 5766 *destreg = destval; 5767 } else { 5768 u16 *destreg; 5769 u16 destval,imm; 5770 5771 destreg = DECODE_RM_WORD_REGISTER(rl); 5772 imm = (s8) fetch_byte_imm(); 5773 DECODE_PRINTF2(",%x\n", imm); 5774 TRACE_AND_STEP(); 5775 destval = (*opc83_word_operation[rh]) (*destreg, imm); 5776 if (rh != 7) 5777 *destreg = destval; 5778 } 5779 break; 5780 } 5781 DECODE_CLEAR_SEGOVR(); 5782 END_OF_INSTR(); 5783} 5784 5785/**************************************************************************** 5786REMARKS: 5787Handles opcode 0x84 5788****************************************************************************/ 5789void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5790{ 5791 int mod, rl, rh; 5792 u8 *destreg, *srcreg; 5793 uint destoffset; 5794 u8 destval; 5795 5796 START_OF_INSTR(); 5797 DECODE_PRINTF("TEST\t"); 5798 FETCH_DECODE_MODRM(mod, rh, rl); 5799 switch (mod) { 5800 case 0: 5801 destoffset = decode_rm00_address(rl); 5802 DECODE_PRINTF(","); 5803 destval = fetch_data_byte(destoffset); 5804 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5805 DECODE_PRINTF("\n"); 5806 TRACE_AND_STEP(); 5807 test_byte(destval, *srcreg); 5808 break; 5809 case 1: 5810 destoffset = decode_rm01_address(rl); 5811 DECODE_PRINTF(","); 5812 destval = fetch_data_byte(destoffset); 5813 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5814 DECODE_PRINTF("\n"); 5815 TRACE_AND_STEP(); 5816 test_byte(destval, *srcreg); 5817 break; 5818 case 2: 5819 destoffset = decode_rm10_address(rl); 5820 DECODE_PRINTF(","); 5821 destval = fetch_data_byte(destoffset); 5822 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5823 DECODE_PRINTF("\n"); 5824 TRACE_AND_STEP(); 5825 test_byte(destval, *srcreg); 5826 break; 5827 case 3: /* register to register */ 5828 destreg = DECODE_RM_BYTE_REGISTER(rl); 5829 DECODE_PRINTF(","); 5830 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5831 DECODE_PRINTF("\n"); 5832 TRACE_AND_STEP(); 5833 test_byte(*destreg, *srcreg); 5834 break; 5835 } 5836 DECODE_CLEAR_SEGOVR(); 5837 END_OF_INSTR(); 5838} 5839 5840/**************************************************************************** 5841REMARKS: 5842Handles opcode 0x85 5843****************************************************************************/ 5844void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 5845{ 5846 int mod, rl, rh; 5847 uint destoffset; 5848 5849 START_OF_INSTR(); 5850 DECODE_PRINTF("TEST\t"); 5851 FETCH_DECODE_MODRM(mod, rh, rl); 5852 switch (mod) { 5853 case 0: 5854 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5855 u32 destval; 5856 u32 *srcreg; 5857 5858 destoffset = decode_rm00_address(rl); 5859 DECODE_PRINTF(","); 5860 destval = fetch_data_long(destoffset); 5861 srcreg = DECODE_RM_LONG_REGISTER(rh); 5862 DECODE_PRINTF("\n"); 5863 TRACE_AND_STEP(); 5864 test_long(destval, *srcreg); 5865 } else { 5866 u16 destval; 5867 u16 *srcreg; 5868 5869 destoffset = decode_rm00_address(rl); 5870 DECODE_PRINTF(","); 5871 destval = fetch_data_word(destoffset); 5872 srcreg = DECODE_RM_WORD_REGISTER(rh); 5873 DECODE_PRINTF("\n"); 5874 TRACE_AND_STEP(); 5875 test_word(destval, *srcreg); 5876 } 5877 break; 5878 case 1: 5879 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5880 u32 destval; 5881 u32 *srcreg; 5882 5883 destoffset = decode_rm01_address(rl); 5884 DECODE_PRINTF(","); 5885 destval = fetch_data_long(destoffset); 5886 srcreg = DECODE_RM_LONG_REGISTER(rh); 5887 DECODE_PRINTF("\n"); 5888 TRACE_AND_STEP(); 5889 test_long(destval, *srcreg); 5890 } else { 5891 u16 destval; 5892 u16 *srcreg; 5893 5894 destoffset = decode_rm01_address(rl); 5895 DECODE_PRINTF(","); 5896 destval = fetch_data_word(destoffset); 5897 srcreg = DECODE_RM_WORD_REGISTER(rh); 5898 DECODE_PRINTF("\n"); 5899 TRACE_AND_STEP(); 5900 test_word(destval, *srcreg); 5901 } 5902 break; 5903 case 2: 5904 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5905 u32 destval; 5906 u32 *srcreg; 5907 5908 destoffset = decode_rm10_address(rl); 5909 DECODE_PRINTF(","); 5910 destval = fetch_data_long(destoffset); 5911 srcreg = DECODE_RM_LONG_REGISTER(rh); 5912 DECODE_PRINTF("\n"); 5913 TRACE_AND_STEP(); 5914 test_long(destval, *srcreg); 5915 } else { 5916 u16 destval; 5917 u16 *srcreg; 5918 5919 destoffset = decode_rm10_address(rl); 5920 DECODE_PRINTF(","); 5921 destval = fetch_data_word(destoffset); 5922 srcreg = DECODE_RM_WORD_REGISTER(rh); 5923 DECODE_PRINTF("\n"); 5924 TRACE_AND_STEP(); 5925 test_word(destval, *srcreg); 5926 } 5927 break; 5928 case 3: /* register to register */ 5929 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5930 u32 *destreg,*srcreg; 5931 5932 destreg = DECODE_RM_LONG_REGISTER(rl); 5933 DECODE_PRINTF(","); 5934 srcreg = DECODE_RM_LONG_REGISTER(rh); 5935 DECODE_PRINTF("\n"); 5936 TRACE_AND_STEP(); 5937 test_long(*destreg, *srcreg); 5938 } else { 5939 u16 *destreg,*srcreg; 5940 5941 destreg = DECODE_RM_WORD_REGISTER(rl); 5942 DECODE_PRINTF(","); 5943 srcreg = DECODE_RM_WORD_REGISTER(rh); 5944 DECODE_PRINTF("\n"); 5945 TRACE_AND_STEP(); 5946 test_word(*destreg, *srcreg); 5947 } 5948 break; 5949 } 5950 DECODE_CLEAR_SEGOVR(); 5951 END_OF_INSTR(); 5952} 5953 5954/**************************************************************************** 5955REMARKS: 5956Handles opcode 0x86 5957****************************************************************************/ 5958void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 5959{ 5960 int mod, rl, rh; 5961 u8 *destreg, *srcreg; 5962 uint destoffset; 5963 u8 destval; 5964 u8 tmp; 5965 5966 START_OF_INSTR(); 5967 DECODE_PRINTF("XCHG\t"); 5968 FETCH_DECODE_MODRM(mod, rh, rl); 5969 switch (mod) { 5970 case 0: 5971 destoffset = decode_rm00_address(rl); 5972 DECODE_PRINTF(","); 5973 destval = fetch_data_byte(destoffset); 5974 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5975 DECODE_PRINTF("\n"); 5976 TRACE_AND_STEP(); 5977 tmp = *srcreg; 5978 *srcreg = destval; 5979 destval = tmp; 5980 store_data_byte(destoffset, destval); 5981 break; 5982 case 1: 5983 destoffset = decode_rm01_address(rl); 5984 DECODE_PRINTF(","); 5985 destval = fetch_data_byte(destoffset); 5986 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5987 DECODE_PRINTF("\n"); 5988 TRACE_AND_STEP(); 5989 tmp = *srcreg; 5990 *srcreg = destval; 5991 destval = tmp; 5992 store_data_byte(destoffset, destval); 5993 break; 5994 case 2: 5995 destoffset = decode_rm10_address(rl); 5996 DECODE_PRINTF(","); 5997 destval = fetch_data_byte(destoffset); 5998 srcreg = DECODE_RM_BYTE_REGISTER(rh); 5999 DECODE_PRINTF("\n"); 6000 TRACE_AND_STEP(); 6001 tmp = *srcreg; 6002 *srcreg = destval; 6003 destval = tmp; 6004 store_data_byte(destoffset, destval); 6005 break; 6006 case 3: /* register to register */ 6007 destreg = DECODE_RM_BYTE_REGISTER(rl); 6008 DECODE_PRINTF(","); 6009 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6010 DECODE_PRINTF("\n"); 6011 TRACE_AND_STEP(); 6012 tmp = *srcreg; 6013 *srcreg = *destreg; 6014 *destreg = tmp; 6015 break; 6016 } 6017 DECODE_CLEAR_SEGOVR(); 6018 END_OF_INSTR(); 6019} 6020 6021/**************************************************************************** 6022REMARKS: 6023Handles opcode 0x87 6024****************************************************************************/ 6025void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 6026{ 6027 int mod, rl, rh; 6028 uint destoffset; 6029 6030 START_OF_INSTR(); 6031 DECODE_PRINTF("XCHG\t"); 6032 FETCH_DECODE_MODRM(mod, rh, rl); 6033 switch (mod) { 6034 case 0: 6035 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6036 u32 *srcreg; 6037 u32 destval,tmp; 6038 6039 destoffset = decode_rm00_address(rl); 6040 DECODE_PRINTF(","); 6041 destval = fetch_data_long(destoffset); 6042 srcreg = DECODE_RM_LONG_REGISTER(rh); 6043 DECODE_PRINTF("\n"); 6044 TRACE_AND_STEP(); 6045 tmp = *srcreg; 6046 *srcreg = destval; 6047 destval = tmp; 6048 store_data_long(destoffset, destval); 6049 } else { 6050 u16 *srcreg; 6051 u16 destval,tmp; 6052 6053 destoffset = decode_rm00_address(rl); 6054 DECODE_PRINTF(","); 6055 destval = fetch_data_word(destoffset); 6056 srcreg = DECODE_RM_WORD_REGISTER(rh); 6057 DECODE_PRINTF("\n"); 6058 TRACE_AND_STEP(); 6059 tmp = *srcreg; 6060 *srcreg = destval; 6061 destval = tmp; 6062 store_data_word(destoffset, destval); 6063 } 6064 break; 6065 case 1: 6066 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6067 u32 *srcreg; 6068 u32 destval,tmp; 6069 6070 destoffset = decode_rm01_address(rl); 6071 DECODE_PRINTF(","); 6072 destval = fetch_data_long(destoffset); 6073 srcreg = DECODE_RM_LONG_REGISTER(rh); 6074 DECODE_PRINTF("\n"); 6075 TRACE_AND_STEP(); 6076 tmp = *srcreg; 6077 *srcreg = destval; 6078 destval = tmp; 6079 store_data_long(destoffset, destval); 6080 } else { 6081 u16 *srcreg; 6082 u16 destval,tmp; 6083 6084 destoffset = decode_rm01_address(rl); 6085 DECODE_PRINTF(","); 6086 destval = fetch_data_word(destoffset); 6087 srcreg = DECODE_RM_WORD_REGISTER(rh); 6088 DECODE_PRINTF("\n"); 6089 TRACE_AND_STEP(); 6090 tmp = *srcreg; 6091 *srcreg = destval; 6092 destval = tmp; 6093 store_data_word(destoffset, destval); 6094 } 6095 break; 6096 case 2: 6097 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6098 u32 *srcreg; 6099 u32 destval,tmp; 6100 6101 destoffset = decode_rm10_address(rl); 6102 DECODE_PRINTF(","); 6103 destval = fetch_data_long(destoffset); 6104 srcreg = DECODE_RM_LONG_REGISTER(rh); 6105 DECODE_PRINTF("\n"); 6106 TRACE_AND_STEP(); 6107 tmp = *srcreg; 6108 *srcreg = destval; 6109 destval = tmp; 6110 store_data_long(destoffset, destval); 6111 } else { 6112 u16 *srcreg; 6113 u16 destval,tmp; 6114 6115 destoffset = decode_rm10_address(rl); 6116 DECODE_PRINTF(","); 6117 destval = fetch_data_word(destoffset); 6118 srcreg = DECODE_RM_WORD_REGISTER(rh); 6119 DECODE_PRINTF("\n"); 6120 TRACE_AND_STEP(); 6121 tmp = *srcreg; 6122 *srcreg = destval; 6123 destval = tmp; 6124 store_data_word(destoffset, destval); 6125 } 6126 break; 6127 case 3: /* register to register */ 6128 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6129 u32 *destreg,*srcreg; 6130 u32 tmp; 6131 6132 destreg = DECODE_RM_LONG_REGISTER(rl); 6133 DECODE_PRINTF(","); 6134 srcreg = DECODE_RM_LONG_REGISTER(rh); 6135 DECODE_PRINTF("\n"); 6136 TRACE_AND_STEP(); 6137 tmp = *srcreg; 6138 *srcreg = *destreg; 6139 *destreg = tmp; 6140 } else { 6141 u16 *destreg,*srcreg; 6142 u16 tmp; 6143 6144 destreg = DECODE_RM_WORD_REGISTER(rl); 6145 DECODE_PRINTF(","); 6146 srcreg = DECODE_RM_WORD_REGISTER(rh); 6147 DECODE_PRINTF("\n"); 6148 TRACE_AND_STEP(); 6149 tmp = *srcreg; 6150 *srcreg = *destreg; 6151 *destreg = tmp; 6152 } 6153 break; 6154 } 6155 DECODE_CLEAR_SEGOVR(); 6156 END_OF_INSTR(); 6157} 6158 6159/**************************************************************************** 6160REMARKS: 6161Handles opcode 0x88 6162****************************************************************************/ 6163void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 6164{ 6165 int mod, rl, rh; 6166 u8 *destreg, *srcreg; 6167 uint destoffset; 6168 6169 START_OF_INSTR(); 6170 DECODE_PRINTF("MOV\t"); 6171 FETCH_DECODE_MODRM(mod, rh, rl); 6172 switch (mod) { 6173 case 0: 6174 destoffset = decode_rm00_address(rl); 6175 DECODE_PRINTF(","); 6176 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6177 DECODE_PRINTF("\n"); 6178 TRACE_AND_STEP(); 6179 store_data_byte(destoffset, *srcreg); 6180 break; 6181 case 1: 6182 destoffset = decode_rm01_address(rl); 6183 DECODE_PRINTF(","); 6184 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6185 DECODE_PRINTF("\n"); 6186 TRACE_AND_STEP(); 6187 store_data_byte(destoffset, *srcreg); 6188 break; 6189 case 2: 6190 destoffset = decode_rm10_address(rl); 6191 DECODE_PRINTF(","); 6192 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6193 DECODE_PRINTF("\n"); 6194 TRACE_AND_STEP(); 6195 store_data_byte(destoffset, *srcreg); 6196 break; 6197 case 3: /* register to register */ 6198 destreg = DECODE_RM_BYTE_REGISTER(rl); 6199 DECODE_PRINTF(","); 6200 srcreg = DECODE_RM_BYTE_REGISTER(rh); 6201 DECODE_PRINTF("\n"); 6202 TRACE_AND_STEP(); 6203 *destreg = *srcreg; 6204 break; 6205 } 6206 DECODE_CLEAR_SEGOVR(); 6207 END_OF_INSTR(); 6208} 6209 6210/**************************************************************************** 6211REMARKS: 6212Handles opcode 0x89 6213****************************************************************************/ 6214void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 6215{ 6216 int mod, rl, rh; 6217 uint destoffset; 6218 6219 START_OF_INSTR(); 6220 DECODE_PRINTF("MOV\t"); 6221 FETCH_DECODE_MODRM(mod, rh, rl); 6222 switch (mod) { 6223 case 0: 6224 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6225 u32 *srcreg; 6226 6227 destoffset = decode_rm00_address(rl); 6228 DECODE_PRINTF(","); 6229 srcreg = DECODE_RM_LONG_REGISTER(rh); 6230 DECODE_PRINTF("\n"); 6231 TRACE_AND_STEP(); 6232 store_data_long(destoffset, *srcreg); 6233 } else { 6234 u16 *srcreg; 6235 6236 destoffset = decode_rm00_address(rl); 6237 DECODE_PRINTF(","); 6238 srcreg = DECODE_RM_WORD_REGISTER(rh); 6239 DECODE_PRINTF("\n"); 6240 TRACE_AND_STEP(); 6241 store_data_word(destoffset, *srcreg); 6242 } 6243 break; 6244 case 1: 6245 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6246 u32 *srcreg; 6247 6248 destoffset = decode_rm01_address(rl); 6249 DECODE_PRINTF(","); 6250 srcreg = DECODE_RM_LONG_REGISTER(rh); 6251 DECODE_PRINTF("\n"); 6252 TRACE_AND_STEP(); 6253 store_data_long(destoffset, *srcreg); 6254 } else { 6255 u16 *srcreg; 6256 6257 destoffset = decode_rm01_address(rl); 6258 DECODE_PRINTF(","); 6259 srcreg = DECODE_RM_WORD_REGISTER(rh); 6260 DECODE_PRINTF("\n"); 6261 TRACE_AND_STEP(); 6262 store_data_word(destoffset, *srcreg); 6263 } 6264 break; 6265 case 2: 6266 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6267 u32 *srcreg; 6268 6269 destoffset = decode_rm10_address(rl); 6270 DECODE_PRINTF(","); 6271 srcreg = DECODE_RM_LONG_REGISTER(rh); 6272 DECODE_PRINTF("\n"); 6273 TRACE_AND_STEP(); 6274 store_data_long(destoffset, *srcreg); 6275 } else { 6276 u16 *srcreg; 6277 6278 destoffset = decode_rm10_address(rl); 6279 DECODE_PRINTF(","); 6280 srcreg = DECODE_RM_WORD_REGISTER(rh); 6281 DECODE_PRINTF("\n"); 6282 TRACE_AND_STEP(); 6283 store_data_word(destoffset, *srcreg); 6284 } 6285 break; 6286 case 3: /* register to register */ 6287 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6288 u32 *destreg,*srcreg; 6289 6290 destreg = DECODE_RM_LONG_REGISTER(rl); 6291 DECODE_PRINTF(","); 6292 srcreg = DECODE_RM_LONG_REGISTER(rh); 6293 DECODE_PRINTF("\n"); 6294 TRACE_AND_STEP(); 6295 *destreg = *srcreg; 6296 } else { 6297 u16 *destreg,*srcreg; 6298 6299 destreg = DECODE_RM_WORD_REGISTER(rl); 6300 DECODE_PRINTF(","); 6301 srcreg = DECODE_RM_WORD_REGISTER(rh); 6302 DECODE_PRINTF("\n"); 6303 TRACE_AND_STEP(); 6304 *destreg = *srcreg; 6305 } 6306 break; 6307 } 6308 DECODE_CLEAR_SEGOVR(); 6309 END_OF_INSTR(); 6310} 6311 6312/**************************************************************************** 6313REMARKS: 6314Handles opcode 0x8a 6315****************************************************************************/ 6316void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 6317{ 6318 int mod, rl, rh; 6319 u8 *destreg, *srcreg; 6320 uint srcoffset; 6321 u8 srcval; 6322 6323 START_OF_INSTR(); 6324 DECODE_PRINTF("MOV\t"); 6325 FETCH_DECODE_MODRM(mod, rh, rl); 6326 switch (mod) { 6327 case 0: 6328 destreg = DECODE_RM_BYTE_REGISTER(rh); 6329 DECODE_PRINTF(","); 6330 srcoffset = decode_rm00_address(rl); 6331 srcval = fetch_data_byte(srcoffset); 6332 DECODE_PRINTF("\n"); 6333 TRACE_AND_STEP(); 6334 *destreg = srcval; 6335 break; 6336 case 1: 6337 destreg = DECODE_RM_BYTE_REGISTER(rh); 6338 DECODE_PRINTF(","); 6339 srcoffset = decode_rm01_address(rl); 6340 srcval = fetch_data_byte(srcoffset); 6341 DECODE_PRINTF("\n"); 6342 TRACE_AND_STEP(); 6343 *destreg = srcval; 6344 break; 6345 case 2: 6346 destreg = DECODE_RM_BYTE_REGISTER(rh); 6347 DECODE_PRINTF(","); 6348 srcoffset = decode_rm10_address(rl); 6349 srcval = fetch_data_byte(srcoffset); 6350 DECODE_PRINTF("\n"); 6351 TRACE_AND_STEP(); 6352 *destreg = srcval; 6353 break; 6354 case 3: /* register to register */ 6355 destreg = DECODE_RM_BYTE_REGISTER(rh); 6356 DECODE_PRINTF(","); 6357 srcreg = DECODE_RM_BYTE_REGISTER(rl); 6358 DECODE_PRINTF("\n"); 6359 TRACE_AND_STEP(); 6360 *destreg = *srcreg; 6361 break; 6362 } 6363 DECODE_CLEAR_SEGOVR(); 6364 END_OF_INSTR(); 6365} 6366 6367/**************************************************************************** 6368REMARKS: 6369Handles opcode 0x8b 6370****************************************************************************/ 6371void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 6372{ 6373 int mod, rl, rh; 6374 uint srcoffset; 6375 6376 START_OF_INSTR(); 6377 DECODE_PRINTF("MOV\t"); 6378 FETCH_DECODE_MODRM(mod, rh, rl); 6379 switch (mod) { 6380 case 0: 6381 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6382 u32 *destreg; 6383 u32 srcval; 6384 6385 destreg = DECODE_RM_LONG_REGISTER(rh); 6386 DECODE_PRINTF(","); 6387 srcoffset = decode_rm00_address(rl); 6388 srcval = fetch_data_long(srcoffset); 6389 DECODE_PRINTF("\n"); 6390 TRACE_AND_STEP(); 6391 *destreg = srcval; 6392 } else { 6393 u16 *destreg; 6394 u16 srcval; 6395 6396 destreg = DECODE_RM_WORD_REGISTER(rh); 6397 DECODE_PRINTF(","); 6398 srcoffset = decode_rm00_address(rl); 6399 srcval = fetch_data_word(srcoffset); 6400 DECODE_PRINTF("\n"); 6401 TRACE_AND_STEP(); 6402 *destreg = srcval; 6403 } 6404 break; 6405 case 1: 6406 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6407 u32 *destreg; 6408 u32 srcval; 6409 6410 destreg = DECODE_RM_LONG_REGISTER(rh); 6411 DECODE_PRINTF(","); 6412 srcoffset = decode_rm01_address(rl); 6413 srcval = fetch_data_long(srcoffset); 6414 DECODE_PRINTF("\n"); 6415 TRACE_AND_STEP(); 6416 *destreg = srcval; 6417 } else { 6418 u16 *destreg; 6419 u16 srcval; 6420 6421 destreg = DECODE_RM_WORD_REGISTER(rh); 6422 DECODE_PRINTF(","); 6423 srcoffset = decode_rm01_address(rl); 6424 srcval = fetch_data_word(srcoffset); 6425 DECODE_PRINTF("\n"); 6426 TRACE_AND_STEP(); 6427 *destreg = srcval; 6428 } 6429 break; 6430 case 2: 6431 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6432 u32 *destreg; 6433 u32 srcval; 6434 6435 destreg = DECODE_RM_LONG_REGISTER(rh); 6436 DECODE_PRINTF(","); 6437 srcoffset = decode_rm10_address(rl); 6438 srcval = fetch_data_long(srcoffset); 6439 DECODE_PRINTF("\n"); 6440 TRACE_AND_STEP(); 6441 *destreg = srcval; 6442 } else { 6443 u16 *destreg; 6444 u16 srcval; 6445 6446 destreg = DECODE_RM_WORD_REGISTER(rh); 6447 DECODE_PRINTF(","); 6448 srcoffset = decode_rm10_address(rl); 6449 srcval = fetch_data_word(srcoffset); 6450 DECODE_PRINTF("\n"); 6451 TRACE_AND_STEP(); 6452 *destreg = srcval; 6453 } 6454 break; 6455 case 3: /* register to register */ 6456 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6457 u32 *destreg, *srcreg; 6458 6459 destreg = DECODE_RM_LONG_REGISTER(rh); 6460 DECODE_PRINTF(","); 6461 srcreg = DECODE_RM_LONG_REGISTER(rl); 6462 DECODE_PRINTF("\n"); 6463 TRACE_AND_STEP(); 6464 *destreg = *srcreg; 6465 } else { 6466 u16 *destreg, *srcreg; 6467 6468 destreg = DECODE_RM_WORD_REGISTER(rh); 6469 DECODE_PRINTF(","); 6470 srcreg = DECODE_RM_WORD_REGISTER(rl); 6471 DECODE_PRINTF("\n"); 6472 TRACE_AND_STEP(); 6473 *destreg = *srcreg; 6474 } 6475 break; 6476 } 6477 DECODE_CLEAR_SEGOVR(); 6478 END_OF_INSTR(); 6479} 6480 6481/**************************************************************************** 6482REMARKS: 6483Handles opcode 0x8c 6484****************************************************************************/ 6485void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 6486{ 6487 int mod, rl, rh; 6488 u16 *destreg, *srcreg; 6489 uint destoffset; 6490 u16 destval; 6491 6492 START_OF_INSTR(); 6493 DECODE_PRINTF("MOV\t"); 6494 FETCH_DECODE_MODRM(mod, rh, rl); 6495 switch (mod) { 6496 case 0: 6497 destoffset = decode_rm00_address(rl); 6498 DECODE_PRINTF(","); 6499 srcreg = decode_rm_seg_register(rh); 6500 DECODE_PRINTF("\n"); 6501 TRACE_AND_STEP(); 6502 destval = *srcreg; 6503 store_data_word(destoffset, destval); 6504 break; 6505 case 1: 6506 destoffset = decode_rm01_address(rl); 6507 DECODE_PRINTF(","); 6508 srcreg = decode_rm_seg_register(rh); 6509 DECODE_PRINTF("\n"); 6510 TRACE_AND_STEP(); 6511 destval = *srcreg; 6512 store_data_word(destoffset, destval); 6513 break; 6514 case 2: 6515 destoffset = decode_rm10_address(rl); 6516 DECODE_PRINTF(","); 6517 srcreg = decode_rm_seg_register(rh); 6518 DECODE_PRINTF("\n"); 6519 TRACE_AND_STEP(); 6520 destval = *srcreg; 6521 store_data_word(destoffset, destval); 6522 break; 6523 case 3: /* register to register */ 6524 destreg = DECODE_RM_WORD_REGISTER(rl); 6525 DECODE_PRINTF(","); 6526 srcreg = decode_rm_seg_register(rh); 6527 DECODE_PRINTF("\n"); 6528 TRACE_AND_STEP(); 6529 *destreg = *srcreg; 6530 break; 6531 } 6532 DECODE_CLEAR_SEGOVR(); 6533 END_OF_INSTR(); 6534} 6535 6536/**************************************************************************** 6537REMARKS: 6538Handles opcode 0x8d 6539****************************************************************************/ 6540void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 6541{ 6542 int mod, rl, rh; 6543 u16 *srcreg; 6544 uint destoffset; 6545 6546/* 6547 * TODO: Need to handle address size prefix! 6548 * 6549 * lea eax,[eax+ebx*2] ?? 6550 */ 6551 6552 START_OF_INSTR(); 6553 DECODE_PRINTF("LEA\t"); 6554 FETCH_DECODE_MODRM(mod, rh, rl); 6555 switch (mod) { 6556 case 0: 6557 srcreg = DECODE_RM_WORD_REGISTER(rh); 6558 DECODE_PRINTF(","); 6559 destoffset = decode_rm00_address(rl); 6560 DECODE_PRINTF("\n"); 6561 TRACE_AND_STEP(); 6562 *srcreg = (u16)destoffset; 6563 break; 6564 case 1: 6565 srcreg = DECODE_RM_WORD_REGISTER(rh); 6566 DECODE_PRINTF(","); 6567 destoffset = decode_rm01_address(rl); 6568 DECODE_PRINTF("\n"); 6569 TRACE_AND_STEP(); 6570 *srcreg = (u16)destoffset; 6571 break; 6572 case 2: 6573 srcreg = DECODE_RM_WORD_REGISTER(rh); 6574 DECODE_PRINTF(","); 6575 destoffset = decode_rm10_address(rl); 6576 DECODE_PRINTF("\n"); 6577 TRACE_AND_STEP(); 6578 *srcreg = (u16)destoffset; 6579 break; 6580 case 3: /* register to register */ 6581 /* undefined. Do nothing. */ 6582 break; 6583 } 6584 DECODE_CLEAR_SEGOVR(); 6585 END_OF_INSTR(); 6586} 6587 6588/**************************************************************************** 6589REMARKS: 6590Handles opcode 0x8e 6591****************************************************************************/ 6592void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 6593{ 6594 int mod, rl, rh; 6595 u16 *destreg, *srcreg; 6596 uint srcoffset; 6597 u16 srcval; 6598 6599 START_OF_INSTR(); 6600 DECODE_PRINTF("MOV\t"); 6601 FETCH_DECODE_MODRM(mod, rh, rl); 6602 switch (mod) { 6603 case 0: 6604 destreg = decode_rm_seg_register(rh); 6605 DECODE_PRINTF(","); 6606 srcoffset = decode_rm00_address(rl); 6607 srcval = fetch_data_word(srcoffset); 6608 DECODE_PRINTF("\n"); 6609 TRACE_AND_STEP(); 6610 *destreg = srcval; 6611 break; 6612 case 1: 6613 destreg = decode_rm_seg_register(rh); 6614 DECODE_PRINTF(","); 6615 srcoffset = decode_rm01_address(rl); 6616 srcval = fetch_data_word(srcoffset); 6617 DECODE_PRINTF("\n"); 6618 TRACE_AND_STEP(); 6619 *destreg = srcval; 6620 break; 6621 case 2: 6622 destreg = decode_rm_seg_register(rh); 6623 DECODE_PRINTF(","); 6624 srcoffset = decode_rm10_address(rl); 6625 srcval = fetch_data_word(srcoffset); 6626 DECODE_PRINTF("\n"); 6627 TRACE_AND_STEP(); 6628 *destreg = srcval; 6629 break; 6630 case 3: /* register to register */ 6631 destreg = decode_rm_seg_register(rh); 6632 DECODE_PRINTF(","); 6633 srcreg = DECODE_RM_WORD_REGISTER(rl); 6634 DECODE_PRINTF("\n"); 6635 TRACE_AND_STEP(); 6636 *destreg = *srcreg; 6637 break; 6638 } 6639 /* 6640 * Clean up, and reset all the R_xSP pointers to the correct 6641 * locations. This is about 3x too much overhead (doing all the 6642 * segreg ptrs when only one is needed, but this instruction 6643 * *cannot* be that common, and this isn't too much work anyway. 6644 */ 6645 DECODE_CLEAR_SEGOVR(); 6646 END_OF_INSTR(); 6647} 6648 6649/**************************************************************************** 6650REMARKS: 6651Handles opcode 0x8f 6652****************************************************************************/ 6653void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 6654{ 6655 int mod, rl, rh; 6656 uint destoffset; 6657 6658 START_OF_INSTR(); 6659 DECODE_PRINTF("POP\t"); 6660 FETCH_DECODE_MODRM(mod, rh, rl); 6661 if (rh != 0) { 6662 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 6663 HALT_SYS(); 6664 } 6665 switch (mod) { 6666 case 0: 6667 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6668 u32 destval; 6669 6670 destoffset = decode_rm00_address(rl); 6671 DECODE_PRINTF("\n"); 6672 TRACE_AND_STEP(); 6673 destval = pop_long(); 6674 store_data_long(destoffset, destval); 6675 } else { 6676 u16 destval; 6677 6678 destoffset = decode_rm00_address(rl); 6679 DECODE_PRINTF("\n"); 6680 TRACE_AND_STEP(); 6681 destval = pop_word(); 6682 store_data_word(destoffset, destval); 6683 } 6684 break; 6685 case 1: 6686 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6687 u32 destval; 6688 6689 destoffset = decode_rm01_address(rl); 6690 DECODE_PRINTF("\n"); 6691 TRACE_AND_STEP(); 6692 destval = pop_long(); 6693 store_data_long(destoffset, destval); 6694 } else { 6695 u16 destval; 6696 6697 destoffset = decode_rm01_address(rl); 6698 DECODE_PRINTF("\n"); 6699 TRACE_AND_STEP(); 6700 destval = pop_word(); 6701 store_data_word(destoffset, destval); 6702 } 6703 break; 6704 case 2: 6705 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6706 u32 destval; 6707 6708 destoffset = decode_rm10_address(rl); 6709 DECODE_PRINTF("\n"); 6710 TRACE_AND_STEP(); 6711 destval = pop_long(); 6712 store_data_long(destoffset, destval); 6713 } else { 6714 u16 destval; 6715 6716 destoffset = decode_rm10_address(rl); 6717 DECODE_PRINTF("\n"); 6718 TRACE_AND_STEP(); 6719 destval = pop_word(); 6720 store_data_word(destoffset, destval); 6721 } 6722 break; 6723 case 3: /* register to register */ 6724 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6725 u32 *destreg; 6726 6727 destreg = DECODE_RM_LONG_REGISTER(rl); 6728 DECODE_PRINTF("\n"); 6729 TRACE_AND_STEP(); 6730 *destreg = pop_long(); 6731 } else { 6732 u16 *destreg; 6733 6734 destreg = DECODE_RM_WORD_REGISTER(rl); 6735 DECODE_PRINTF("\n"); 6736 TRACE_AND_STEP(); 6737 *destreg = pop_word(); 6738 } 6739 break; 6740 } 6741 DECODE_CLEAR_SEGOVR(); 6742 END_OF_INSTR(); 6743} 6744 6745/**************************************************************************** 6746REMARKS: 6747Handles opcode 0x90 6748****************************************************************************/ 6749void x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 6750{ 6751 START_OF_INSTR(); 6752 DECODE_PRINTF("NOP\n"); 6753 TRACE_AND_STEP(); 6754 DECODE_CLEAR_SEGOVR(); 6755 END_OF_INSTR(); 6756} 6757 6758/**************************************************************************** 6759REMARKS: 6760Handles opcode 0x91 6761****************************************************************************/ 6762void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1)) 6763{ 6764 u32 tmp; 6765 6766 START_OF_INSTR(); 6767 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6768 DECODE_PRINTF("XCHG\tEAX,ECX\n"); 6769 } else { 6770 DECODE_PRINTF("XCHG\tAX,CX\n"); 6771 } 6772 TRACE_AND_STEP(); 6773 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6774 tmp = M.x86.R_EAX; 6775 M.x86.R_EAX = M.x86.R_ECX; 6776 M.x86.R_ECX = tmp; 6777 } else { 6778 tmp = M.x86.R_AX; 6779 M.x86.R_AX = M.x86.R_CX; 6780 M.x86.R_CX = (u16)tmp; 6781 } 6782 DECODE_CLEAR_SEGOVR(); 6783 END_OF_INSTR(); 6784} 6785 6786/**************************************************************************** 6787REMARKS: 6788Handles opcode 0x92 6789****************************************************************************/ 6790void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1)) 6791{ 6792 u32 tmp; 6793 6794 START_OF_INSTR(); 6795 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6796 DECODE_PRINTF("XCHG\tEAX,EDX\n"); 6797 } else { 6798 DECODE_PRINTF("XCHG\tAX,DX\n"); 6799 } 6800 TRACE_AND_STEP(); 6801 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6802 tmp = M.x86.R_EAX; 6803 M.x86.R_EAX = M.x86.R_EDX; 6804 M.x86.R_EDX = tmp; 6805 } else { 6806 tmp = M.x86.R_AX; 6807 M.x86.R_AX = M.x86.R_DX; 6808 M.x86.R_DX = (u16)tmp; 6809 } 6810 DECODE_CLEAR_SEGOVR(); 6811 END_OF_INSTR(); 6812} 6813 6814/**************************************************************************** 6815REMARKS: 6816Handles opcode 0x93 6817****************************************************************************/ 6818void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1)) 6819{ 6820 u32 tmp; 6821 6822 START_OF_INSTR(); 6823 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6824 DECODE_PRINTF("XCHG\tEAX,EBX\n"); 6825 } else { 6826 DECODE_PRINTF("XCHG\tAX,BX\n"); 6827 } 6828 TRACE_AND_STEP(); 6829 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6830 tmp = M.x86.R_EAX; 6831 M.x86.R_EAX = M.x86.R_EBX; 6832 M.x86.R_EBX = tmp; 6833 } else { 6834 tmp = M.x86.R_AX; 6835 M.x86.R_AX = M.x86.R_BX; 6836 M.x86.R_BX = (u16)tmp; 6837 } 6838 DECODE_CLEAR_SEGOVR(); 6839 END_OF_INSTR(); 6840} 6841 6842/**************************************************************************** 6843REMARKS: 6844Handles opcode 0x94 6845****************************************************************************/ 6846void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1)) 6847{ 6848 u32 tmp; 6849 6850 START_OF_INSTR(); 6851 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6852 DECODE_PRINTF("XCHG\tEAX,ESP\n"); 6853 } else { 6854 DECODE_PRINTF("XCHG\tAX,SP\n"); 6855 } 6856 TRACE_AND_STEP(); 6857 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6858 tmp = M.x86.R_EAX; 6859 M.x86.R_EAX = M.x86.R_ESP; 6860 M.x86.R_ESP = tmp; 6861 } else { 6862 tmp = M.x86.R_AX; 6863 M.x86.R_AX = M.x86.R_SP; 6864 M.x86.R_SP = (u16)tmp; 6865 } 6866 DECODE_CLEAR_SEGOVR(); 6867 END_OF_INSTR(); 6868} 6869 6870/**************************************************************************** 6871REMARKS: 6872Handles opcode 0x95 6873****************************************************************************/ 6874void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1)) 6875{ 6876 u32 tmp; 6877 6878 START_OF_INSTR(); 6879 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6880 DECODE_PRINTF("XCHG\tEAX,EBP\n"); 6881 } else { 6882 DECODE_PRINTF("XCHG\tAX,BP\n"); 6883 } 6884 TRACE_AND_STEP(); 6885 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6886 tmp = M.x86.R_EAX; 6887 M.x86.R_EAX = M.x86.R_EBP; 6888 M.x86.R_EBP = tmp; 6889 } else { 6890 tmp = M.x86.R_AX; 6891 M.x86.R_AX = M.x86.R_BP; 6892 M.x86.R_BP = (u16)tmp; 6893 } 6894 DECODE_CLEAR_SEGOVR(); 6895 END_OF_INSTR(); 6896} 6897 6898/**************************************************************************** 6899REMARKS: 6900Handles opcode 0x96 6901****************************************************************************/ 6902void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1)) 6903{ 6904 u32 tmp; 6905 6906 START_OF_INSTR(); 6907 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6908 DECODE_PRINTF("XCHG\tEAX,ESI\n"); 6909 } else { 6910 DECODE_PRINTF("XCHG\tAX,SI\n"); 6911 } 6912 TRACE_AND_STEP(); 6913 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6914 tmp = M.x86.R_EAX; 6915 M.x86.R_EAX = M.x86.R_ESI; 6916 M.x86.R_ESI = tmp; 6917 } else { 6918 tmp = M.x86.R_AX; 6919 M.x86.R_AX = M.x86.R_SI; 6920 M.x86.R_SI = (u16)tmp; 6921 } 6922 DECODE_CLEAR_SEGOVR(); 6923 END_OF_INSTR(); 6924} 6925 6926/**************************************************************************** 6927REMARKS: 6928Handles opcode 0x97 6929****************************************************************************/ 6930void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1)) 6931{ 6932 u32 tmp; 6933 6934 START_OF_INSTR(); 6935 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6936 DECODE_PRINTF("XCHG\tEAX,EDI\n"); 6937 } else { 6938 DECODE_PRINTF("XCHG\tAX,DI\n"); 6939 } 6940 TRACE_AND_STEP(); 6941 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6942 tmp = M.x86.R_EAX; 6943 M.x86.R_EAX = M.x86.R_EDI; 6944 M.x86.R_EDI = tmp; 6945 } else { 6946 tmp = M.x86.R_AX; 6947 M.x86.R_AX = M.x86.R_DI; 6948 M.x86.R_DI = (u16)tmp; 6949 } 6950 DECODE_CLEAR_SEGOVR(); 6951 END_OF_INSTR(); 6952} 6953 6954/**************************************************************************** 6955REMARKS: 6956Handles opcode 0x98 6957****************************************************************************/ 6958void x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 6959{ 6960 START_OF_INSTR(); 6961 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6962 DECODE_PRINTF("CWDE\n"); 6963 } else { 6964 DECODE_PRINTF("CBW\n"); 6965 } 6966 TRACE_AND_STEP(); 6967 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6968 if (M.x86.R_AX & 0x8000) { 6969 M.x86.R_EAX |= 0xffff0000; 6970 } else { 6971 M.x86.R_EAX &= 0x0000ffff; 6972 } 6973 } else { 6974 if (M.x86.R_AL & 0x80) { 6975 M.x86.R_AH = 0xff; 6976 } else { 6977 M.x86.R_AH = 0x0; 6978 } 6979 } 6980 DECODE_CLEAR_SEGOVR(); 6981 END_OF_INSTR(); 6982} 6983 6984/**************************************************************************** 6985REMARKS: 6986Handles opcode 0x99 6987****************************************************************************/ 6988void x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 6989{ 6990 START_OF_INSTR(); 6991 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6992 DECODE_PRINTF("CDQ\n"); 6993 } else { 6994 DECODE_PRINTF("CWD\n"); 6995 } 6996 DECODE_PRINTF("CWD\n"); 6997 TRACE_AND_STEP(); 6998 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 6999 if (M.x86.R_EAX & 0x80000000) { 7000 M.x86.R_EDX = 0xffffffff; 7001 } else { 7002 M.x86.R_EDX = 0x0; 7003 } 7004 } else { 7005 if (M.x86.R_AX & 0x8000) { 7006 M.x86.R_DX = 0xffff; 7007 } else { 7008 M.x86.R_DX = 0x0; 7009 } 7010 } 7011 DECODE_CLEAR_SEGOVR(); 7012 END_OF_INSTR(); 7013} 7014 7015/**************************************************************************** 7016REMARKS: 7017Handles opcode 0x9a 7018****************************************************************************/ 7019void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 7020{ 7021 u16 farseg, faroff; 7022 7023 START_OF_INSTR(); 7024 DECODE_PRINTF("CALL\t"); 7025 faroff = fetch_word_imm(); 7026 farseg = fetch_word_imm(); 7027 DECODE_PRINTF2("%04x:", farseg); 7028 DECODE_PRINTF2("%04x\n", faroff); 7029 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 7030 7031 TRACE_AND_STEP(); 7032 push_word(M.x86.R_CS); 7033 M.x86.R_CS = farseg; 7034 push_word(M.x86.R_IP); 7035 M.x86.R_IP = faroff; 7036 DECODE_CLEAR_SEGOVR(); 7037 END_OF_INSTR(); 7038} 7039 7040/**************************************************************************** 7041REMARKS: 7042Handles opcode 0x9b 7043****************************************************************************/ 7044void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 7045{ 7046 START_OF_INSTR(); 7047 DECODE_PRINTF("WAIT"); 7048 TRACE_AND_STEP(); 7049 /* NADA. */ 7050 DECODE_CLEAR_SEGOVR(); 7051 END_OF_INSTR(); 7052} 7053 7054/**************************************************************************** 7055REMARKS: 7056Handles opcode 0x9c 7057****************************************************************************/ 7058void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 7059{ 7060 u32 flags; 7061 7062 START_OF_INSTR(); 7063 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7064 DECODE_PRINTF("PUSHFD\n"); 7065 } else { 7066 DECODE_PRINTF("PUSHF\n"); 7067 } 7068 TRACE_AND_STEP(); 7069 7070 /* clear out *all* bits not representing flags, and turn on real bits */ 7071 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 7072 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7073 push_long(flags); 7074 } else { 7075 push_word((u16)flags); 7076 } 7077 DECODE_CLEAR_SEGOVR(); 7078 END_OF_INSTR(); 7079} 7080 7081/**************************************************************************** 7082REMARKS: 7083Handles opcode 0x9d 7084****************************************************************************/ 7085void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 7086{ 7087 START_OF_INSTR(); 7088 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7089 DECODE_PRINTF("POPFD\n"); 7090 } else { 7091 DECODE_PRINTF("POPF\n"); 7092 } 7093 TRACE_AND_STEP(); 7094 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7095 M.x86.R_EFLG = pop_long(); 7096 } else { 7097 M.x86.R_FLG = pop_word(); 7098 } 7099 DECODE_CLEAR_SEGOVR(); 7100 END_OF_INSTR(); 7101} 7102 7103/**************************************************************************** 7104REMARKS: 7105Handles opcode 0x9e 7106****************************************************************************/ 7107void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 7108{ 7109 START_OF_INSTR(); 7110 DECODE_PRINTF("SAHF\n"); 7111 TRACE_AND_STEP(); 7112 /* clear the lower bits of the flag register */ 7113 M.x86.R_FLG &= 0xffffff00; 7114 /* or in the AH register into the flags register */ 7115 M.x86.R_FLG |= M.x86.R_AH; 7116 DECODE_CLEAR_SEGOVR(); 7117 END_OF_INSTR(); 7118} 7119 7120/**************************************************************************** 7121REMARKS: 7122Handles opcode 0x9f 7123****************************************************************************/ 7124void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 7125{ 7126 START_OF_INSTR(); 7127 DECODE_PRINTF("LAHF\n"); 7128 TRACE_AND_STEP(); 7129 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 7130 /*undocumented TC++ behavior??? Nope. It's documented, but 7131 you have too look real hard to notice it. */ 7132 M.x86.R_AH |= 0x2; 7133 DECODE_CLEAR_SEGOVR(); 7134 END_OF_INSTR(); 7135} 7136 7137/**************************************************************************** 7138REMARKS: 7139Handles opcode 0xa0 7140****************************************************************************/ 7141void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 7142{ 7143 u16 offset; 7144 7145 START_OF_INSTR(); 7146 DECODE_PRINTF("MOV\tAL,"); 7147 offset = fetch_word_imm(); 7148 DECODE_PRINTF2("[%04x]\n", offset); 7149 TRACE_AND_STEP(); 7150 M.x86.R_AL = fetch_data_byte(offset); 7151 DECODE_CLEAR_SEGOVR(); 7152 END_OF_INSTR(); 7153} 7154 7155/**************************************************************************** 7156REMARKS: 7157Handles opcode 0xa1 7158****************************************************************************/ 7159void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 7160{ 7161 u16 offset; 7162 7163 START_OF_INSTR(); 7164 offset = fetch_word_imm(); 7165 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7166 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 7167 } else { 7168 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 7169 } 7170 TRACE_AND_STEP(); 7171 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7172 M.x86.R_EAX = fetch_data_long(offset); 7173 } else { 7174 M.x86.R_AX = fetch_data_word(offset); 7175 } 7176 DECODE_CLEAR_SEGOVR(); 7177 END_OF_INSTR(); 7178} 7179 7180/**************************************************************************** 7181REMARKS: 7182Handles opcode 0xa2 7183****************************************************************************/ 7184void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 7185{ 7186 u16 offset; 7187 7188 START_OF_INSTR(); 7189 DECODE_PRINTF("MOV\t"); 7190 offset = fetch_word_imm(); 7191 DECODE_PRINTF2("[%04x],AL\n", offset); 7192 TRACE_AND_STEP(); 7193 store_data_byte(offset, M.x86.R_AL); 7194 DECODE_CLEAR_SEGOVR(); 7195 END_OF_INSTR(); 7196} 7197 7198/**************************************************************************** 7199REMARKS: 7200Handles opcode 0xa3 7201****************************************************************************/ 7202void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 7203{ 7204 u16 offset; 7205 7206 START_OF_INSTR(); 7207 offset = fetch_word_imm(); 7208 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7209 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 7210 } else { 7211 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 7212 } 7213 TRACE_AND_STEP(); 7214 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7215 store_data_long(offset, M.x86.R_EAX); 7216 } else { 7217 store_data_word(offset, M.x86.R_AX); 7218 } 7219 DECODE_CLEAR_SEGOVR(); 7220 END_OF_INSTR(); 7221} 7222 7223/**************************************************************************** 7224REMARKS: 7225Handles opcode 0xa4 7226****************************************************************************/ 7227void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 7228{ 7229 u8 val; 7230 u32 count; 7231 int inc; 7232 7233 START_OF_INSTR(); 7234 DECODE_PRINTF("MOVS\tBYTE\n"); 7235 if (ACCESS_FLAG(F_DF)) /* down */ 7236 inc = -1; 7237 else 7238 inc = 1; 7239 TRACE_AND_STEP(); 7240 count = 1; 7241 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7242 /* dont care whether REPE or REPNE */ 7243 /* move them until CX is ZERO. */ 7244 count = M.x86.R_CX; 7245 M.x86.R_CX = 0; 7246 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7247 } 7248 while (count--) { 7249 val = fetch_data_byte(M.x86.R_SI); 7250 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 7251 M.x86.R_SI += inc; 7252 M.x86.R_DI += inc; 7253 } 7254 DECODE_CLEAR_SEGOVR(); 7255 END_OF_INSTR(); 7256} 7257 7258/**************************************************************************** 7259REMARKS: 7260Handles opcode 0xa5 7261****************************************************************************/ 7262void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 7263{ 7264 u32 val; 7265 int inc; 7266 u32 count; 7267 7268 START_OF_INSTR(); 7269 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7270 DECODE_PRINTF("MOVS\tDWORD\n"); 7271 if (ACCESS_FLAG(F_DF)) /* down */ 7272 inc = -4; 7273 else 7274 inc = 4; 7275 } else { 7276 DECODE_PRINTF("MOVS\tWORD\n"); 7277 if (ACCESS_FLAG(F_DF)) /* down */ 7278 inc = -2; 7279 else 7280 inc = 2; 7281 } 7282 TRACE_AND_STEP(); 7283 count = 1; 7284 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7285 /* dont care whether REPE or REPNE */ 7286 /* move them until CX is ZERO. */ 7287 count = M.x86.R_CX; 7288 M.x86.R_CX = 0; 7289 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7290 } 7291 while (count--) { 7292 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7293 val = fetch_data_long(M.x86.R_SI); 7294 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 7295 } else { 7296 val = fetch_data_word(M.x86.R_SI); 7297 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 7298 } 7299 M.x86.R_SI += inc; 7300 M.x86.R_DI += inc; 7301 } 7302 DECODE_CLEAR_SEGOVR(); 7303 END_OF_INSTR(); 7304} 7305 7306/**************************************************************************** 7307REMARKS: 7308Handles opcode 0xa6 7309****************************************************************************/ 7310void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 7311{ 7312 s8 val1, val2; 7313 int inc; 7314 7315 START_OF_INSTR(); 7316 DECODE_PRINTF("CMPS\tBYTE\n"); 7317 TRACE_AND_STEP(); 7318 if (ACCESS_FLAG(F_DF)) /* down */ 7319 inc = -1; 7320 else 7321 inc = 1; 7322 7323 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7324 /* REPE */ 7325 /* move them until CX is ZERO. */ 7326 while (M.x86.R_CX != 0) { 7327 val1 = fetch_data_byte(M.x86.R_SI); 7328 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7329 cmp_byte(val1, val2); 7330 M.x86.R_CX -= 1; 7331 M.x86.R_SI += inc; 7332 M.x86.R_DI += inc; 7333 if (ACCESS_FLAG(F_ZF) == 0) 7334 break; 7335 } 7336 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7337 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7338 /* REPNE */ 7339 /* move them until CX is ZERO. */ 7340 while (M.x86.R_CX != 0) { 7341 val1 = fetch_data_byte(M.x86.R_SI); 7342 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7343 cmp_byte(val1, val2); 7344 M.x86.R_CX -= 1; 7345 M.x86.R_SI += inc; 7346 M.x86.R_DI += inc; 7347 if (ACCESS_FLAG(F_ZF)) 7348 break; /* zero flag set means equal */ 7349 } 7350 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7351 } else { 7352 val1 = fetch_data_byte(M.x86.R_SI); 7353 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7354 cmp_byte(val1, val2); 7355 M.x86.R_SI += inc; 7356 M.x86.R_DI += inc; 7357 } 7358 DECODE_CLEAR_SEGOVR(); 7359 END_OF_INSTR(); 7360} 7361 7362/**************************************************************************** 7363REMARKS: 7364Handles opcode 0xa7 7365****************************************************************************/ 7366void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 7367{ 7368 u32 val1,val2; 7369 int inc; 7370 7371 START_OF_INSTR(); 7372 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7373 DECODE_PRINTF("CMPS\tDWORD\n"); 7374 if (ACCESS_FLAG(F_DF)) /* down */ 7375 inc = -4; 7376 else 7377 inc = 4; 7378 } else { 7379 DECODE_PRINTF("CMPS\tWORD\n"); 7380 if (ACCESS_FLAG(F_DF)) /* down */ 7381 inc = -2; 7382 else 7383 inc = 2; 7384 } 7385 TRACE_AND_STEP(); 7386 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7387 /* REPE */ 7388 /* move them until CX is ZERO. */ 7389 while (M.x86.R_CX != 0) { 7390 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7391 val1 = fetch_data_long(M.x86.R_SI); 7392 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7393 cmp_long(val1, val2); 7394 } else { 7395 val1 = fetch_data_word(M.x86.R_SI); 7396 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7397 cmp_word((u16)val1, (u16)val2); 7398 } 7399 M.x86.R_CX -= 1; 7400 M.x86.R_SI += inc; 7401 M.x86.R_DI += inc; 7402 if (ACCESS_FLAG(F_ZF) == 0) 7403 break; 7404 } 7405 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7406 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7407 /* REPNE */ 7408 /* move them until CX is ZERO. */ 7409 while (M.x86.R_CX != 0) { 7410 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7411 val1 = fetch_data_long(M.x86.R_SI); 7412 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7413 cmp_long(val1, val2); 7414 } else { 7415 val1 = fetch_data_word(M.x86.R_SI); 7416 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7417 cmp_word((u16)val1, (u16)val2); 7418 } 7419 M.x86.R_CX -= 1; 7420 M.x86.R_SI += inc; 7421 M.x86.R_DI += inc; 7422 if (ACCESS_FLAG(F_ZF)) 7423 break; /* zero flag set means equal */ 7424 } 7425 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7426 } else { 7427 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7428 val1 = fetch_data_long(M.x86.R_SI); 7429 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7430 cmp_long(val1, val2); 7431 } else { 7432 val1 = fetch_data_word(M.x86.R_SI); 7433 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7434 cmp_word((u16)val1, (u16)val2); 7435 } 7436 M.x86.R_SI += inc; 7437 M.x86.R_DI += inc; 7438 } 7439 DECODE_CLEAR_SEGOVR(); 7440 END_OF_INSTR(); 7441} 7442 7443/**************************************************************************** 7444REMARKS: 7445Handles opcode 0xa8 7446****************************************************************************/ 7447void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 7448{ 7449 int imm; 7450 7451 START_OF_INSTR(); 7452 DECODE_PRINTF("TEST\tAL,"); 7453 imm = fetch_byte_imm(); 7454 DECODE_PRINTF2("%04x\n", imm); 7455 TRACE_AND_STEP(); 7456 test_byte(M.x86.R_AL, (u8)imm); 7457 DECODE_CLEAR_SEGOVR(); 7458 END_OF_INSTR(); 7459} 7460 7461/**************************************************************************** 7462REMARKS: 7463Handles opcode 0xa9 7464****************************************************************************/ 7465void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 7466{ 7467 u32 srcval; 7468 7469 START_OF_INSTR(); 7470 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7471 DECODE_PRINTF("TEST\tEAX,"); 7472 srcval = fetch_long_imm(); 7473 } else { 7474 DECODE_PRINTF("TEST\tAX,"); 7475 srcval = fetch_word_imm(); 7476 } 7477 DECODE_PRINTF2("%x\n", srcval); 7478 TRACE_AND_STEP(); 7479 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7480 test_long(M.x86.R_EAX, srcval); 7481 } else { 7482 test_word(M.x86.R_AX, (u16)srcval); 7483 } 7484 DECODE_CLEAR_SEGOVR(); 7485 END_OF_INSTR(); 7486} 7487 7488/**************************************************************************** 7489REMARKS: 7490Handles opcode 0xaa 7491****************************************************************************/ 7492void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 7493{ 7494 int inc; 7495 7496 START_OF_INSTR(); 7497 DECODE_PRINTF("STOS\tBYTE\n"); 7498 if (ACCESS_FLAG(F_DF)) /* down */ 7499 inc = -1; 7500 else 7501 inc = 1; 7502 TRACE_AND_STEP(); 7503 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7504 /* dont care whether REPE or REPNE */ 7505 /* move them until CX is ZERO. */ 7506 while (M.x86.R_CX != 0) { 7507 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7508 M.x86.R_CX -= 1; 7509 M.x86.R_DI += inc; 7510 } 7511 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7512 } else { 7513 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 7514 M.x86.R_DI += inc; 7515 } 7516 DECODE_CLEAR_SEGOVR(); 7517 END_OF_INSTR(); 7518} 7519 7520/**************************************************************************** 7521REMARKS: 7522Handles opcode 0xab 7523****************************************************************************/ 7524void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 7525{ 7526 int inc; 7527 u32 count; 7528 7529 START_OF_INSTR(); 7530 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7531 DECODE_PRINTF("STOS\tDWORD\n"); 7532 if (ACCESS_FLAG(F_DF)) /* down */ 7533 inc = -4; 7534 else 7535 inc = 4; 7536 } else { 7537 DECODE_PRINTF("STOS\tWORD\n"); 7538 if (ACCESS_FLAG(F_DF)) /* down */ 7539 inc = -2; 7540 else 7541 inc = 2; 7542 } 7543 TRACE_AND_STEP(); 7544 count = 1; 7545 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7546 /* dont care whether REPE or REPNE */ 7547 /* move them until CX is ZERO. */ 7548 count = M.x86.R_CX; 7549 M.x86.R_CX = 0; 7550 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7551 } 7552 while (count--) { 7553 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7554 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 7555 } else { 7556 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 7557 } 7558 M.x86.R_DI += inc; 7559 } 7560 DECODE_CLEAR_SEGOVR(); 7561 END_OF_INSTR(); 7562} 7563 7564/**************************************************************************** 7565REMARKS: 7566Handles opcode 0xac 7567****************************************************************************/ 7568void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 7569{ 7570 int inc; 7571 7572 START_OF_INSTR(); 7573 DECODE_PRINTF("LODS\tBYTE\n"); 7574 TRACE_AND_STEP(); 7575 if (ACCESS_FLAG(F_DF)) /* down */ 7576 inc = -1; 7577 else 7578 inc = 1; 7579 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7580 /* dont care whether REPE or REPNE */ 7581 /* move them until CX is ZERO. */ 7582 while (M.x86.R_CX != 0) { 7583 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7584 M.x86.R_CX -= 1; 7585 M.x86.R_SI += inc; 7586 } 7587 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7588 } else { 7589 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 7590 M.x86.R_SI += inc; 7591 } 7592 DECODE_CLEAR_SEGOVR(); 7593 END_OF_INSTR(); 7594} 7595 7596/**************************************************************************** 7597REMARKS: 7598Handles opcode 0xad 7599****************************************************************************/ 7600void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 7601{ 7602 int inc; 7603 u32 count; 7604 7605 START_OF_INSTR(); 7606 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7607 DECODE_PRINTF("LODS\tDWORD\n"); 7608 if (ACCESS_FLAG(F_DF)) /* down */ 7609 inc = -4; 7610 else 7611 inc = 4; 7612 } else { 7613 DECODE_PRINTF("LODS\tWORD\n"); 7614 if (ACCESS_FLAG(F_DF)) /* down */ 7615 inc = -2; 7616 else 7617 inc = 2; 7618 } 7619 TRACE_AND_STEP(); 7620 count = 1; 7621 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 7622 /* dont care whether REPE or REPNE */ 7623 /* move them until CX is ZERO. */ 7624 count = M.x86.R_CX; 7625 M.x86.R_CX = 0; 7626 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 7627 } 7628 while (count--) { 7629 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7630 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 7631 } else { 7632 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 7633 } 7634 M.x86.R_SI += inc; 7635 } 7636 DECODE_CLEAR_SEGOVR(); 7637 END_OF_INSTR(); 7638} 7639 7640/**************************************************************************** 7641REMARKS: 7642Handles opcode 0xae 7643****************************************************************************/ 7644void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 7645{ 7646 s8 val2; 7647 int inc; 7648 7649 START_OF_INSTR(); 7650 DECODE_PRINTF("SCAS\tBYTE\n"); 7651 TRACE_AND_STEP(); 7652 if (ACCESS_FLAG(F_DF)) /* down */ 7653 inc = -1; 7654 else 7655 inc = 1; 7656 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7657 /* REPE */ 7658 /* move them until CX is ZERO. */ 7659 while (M.x86.R_CX != 0) { 7660 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7661 cmp_byte(M.x86.R_AL, val2); 7662 M.x86.R_CX -= 1; 7663 M.x86.R_DI += inc; 7664 if (ACCESS_FLAG(F_ZF) == 0) 7665 break; 7666 } 7667 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7668 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7669 /* REPNE */ 7670 /* move them until CX is ZERO. */ 7671 while (M.x86.R_CX != 0) { 7672 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7673 cmp_byte(M.x86.R_AL, val2); 7674 M.x86.R_CX -= 1; 7675 M.x86.R_DI += inc; 7676 if (ACCESS_FLAG(F_ZF)) 7677 break; /* zero flag set means equal */ 7678 } 7679 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7680 } else { 7681 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 7682 cmp_byte(M.x86.R_AL, val2); 7683 M.x86.R_DI += inc; 7684 } 7685 DECODE_CLEAR_SEGOVR(); 7686 END_OF_INSTR(); 7687} 7688 7689/**************************************************************************** 7690REMARKS: 7691Handles opcode 0xaf 7692****************************************************************************/ 7693void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 7694{ 7695 int inc; 7696 u32 val; 7697 7698 START_OF_INSTR(); 7699 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7700 DECODE_PRINTF("SCAS\tDWORD\n"); 7701 if (ACCESS_FLAG(F_DF)) /* down */ 7702 inc = -4; 7703 else 7704 inc = 4; 7705 } else { 7706 DECODE_PRINTF("SCAS\tWORD\n"); 7707 if (ACCESS_FLAG(F_DF)) /* down */ 7708 inc = -2; 7709 else 7710 inc = 2; 7711 } 7712 TRACE_AND_STEP(); 7713 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 7714 /* REPE */ 7715 /* move them until CX is ZERO. */ 7716 while (M.x86.R_CX != 0) { 7717 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7718 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7719 cmp_long(M.x86.R_EAX, val); 7720 } else { 7721 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7722 cmp_word(M.x86.R_AX, (u16)val); 7723 } 7724 M.x86.R_CX -= 1; 7725 M.x86.R_DI += inc; 7726 if (ACCESS_FLAG(F_ZF) == 0) 7727 break; 7728 } 7729 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 7730 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 7731 /* REPNE */ 7732 /* move them until CX is ZERO. */ 7733 while (M.x86.R_CX != 0) { 7734 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7735 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7736 cmp_long(M.x86.R_EAX, val); 7737 } else { 7738 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7739 cmp_word(M.x86.R_AX, (u16)val); 7740 } 7741 M.x86.R_CX -= 1; 7742 M.x86.R_DI += inc; 7743 if (ACCESS_FLAG(F_ZF)) 7744 break; /* zero flag set means equal */ 7745 } 7746 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 7747 } else { 7748 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7749 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 7750 cmp_long(M.x86.R_EAX, val); 7751 } else { 7752 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 7753 cmp_word(M.x86.R_AX, (u16)val); 7754 } 7755 M.x86.R_DI += inc; 7756 } 7757 DECODE_CLEAR_SEGOVR(); 7758 END_OF_INSTR(); 7759} 7760 7761/**************************************************************************** 7762REMARKS: 7763Handles opcode 0xb0 7764****************************************************************************/ 7765void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 7766{ 7767 u8 imm; 7768 7769 START_OF_INSTR(); 7770 DECODE_PRINTF("MOV\tAL,"); 7771 imm = fetch_byte_imm(); 7772 DECODE_PRINTF2("%x\n", imm); 7773 TRACE_AND_STEP(); 7774 M.x86.R_AL = imm; 7775 DECODE_CLEAR_SEGOVR(); 7776 END_OF_INSTR(); 7777} 7778 7779/**************************************************************************** 7780REMARKS: 7781Handles opcode 0xb1 7782****************************************************************************/ 7783void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1)) 7784{ 7785 u8 imm; 7786 7787 START_OF_INSTR(); 7788 DECODE_PRINTF("MOV\tCL,"); 7789 imm = fetch_byte_imm(); 7790 DECODE_PRINTF2("%x\n", imm); 7791 TRACE_AND_STEP(); 7792 M.x86.R_CL = imm; 7793 DECODE_CLEAR_SEGOVR(); 7794 END_OF_INSTR(); 7795} 7796 7797/**************************************************************************** 7798REMARKS: 7799Handles opcode 0xb2 7800****************************************************************************/ 7801void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1)) 7802{ 7803 u8 imm; 7804 7805 START_OF_INSTR(); 7806 DECODE_PRINTF("MOV\tDL,"); 7807 imm = fetch_byte_imm(); 7808 DECODE_PRINTF2("%x\n", imm); 7809 TRACE_AND_STEP(); 7810 M.x86.R_DL = imm; 7811 DECODE_CLEAR_SEGOVR(); 7812 END_OF_INSTR(); 7813} 7814 7815/**************************************************************************** 7816REMARKS: 7817Handles opcode 0xb3 7818****************************************************************************/ 7819void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1)) 7820{ 7821 u8 imm; 7822 7823 START_OF_INSTR(); 7824 DECODE_PRINTF("MOV\tBL,"); 7825 imm = fetch_byte_imm(); 7826 DECODE_PRINTF2("%x\n", imm); 7827 TRACE_AND_STEP(); 7828 M.x86.R_BL = imm; 7829 DECODE_CLEAR_SEGOVR(); 7830 END_OF_INSTR(); 7831} 7832 7833/**************************************************************************** 7834REMARKS: 7835Handles opcode 0xb4 7836****************************************************************************/ 7837void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1)) 7838{ 7839 u8 imm; 7840 7841 START_OF_INSTR(); 7842 DECODE_PRINTF("MOV\tAH,"); 7843 imm = fetch_byte_imm(); 7844 DECODE_PRINTF2("%x\n", imm); 7845 TRACE_AND_STEP(); 7846 M.x86.R_AH = imm; 7847 DECODE_CLEAR_SEGOVR(); 7848 END_OF_INSTR(); 7849} 7850 7851/**************************************************************************** 7852REMARKS: 7853Handles opcode 0xb5 7854****************************************************************************/ 7855void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1)) 7856{ 7857 u8 imm; 7858 7859 START_OF_INSTR(); 7860 DECODE_PRINTF("MOV\tCH,"); 7861 imm = fetch_byte_imm(); 7862 DECODE_PRINTF2("%x\n", imm); 7863 TRACE_AND_STEP(); 7864 M.x86.R_CH = imm; 7865 DECODE_CLEAR_SEGOVR(); 7866 END_OF_INSTR(); 7867} 7868 7869/**************************************************************************** 7870REMARKS: 7871Handles opcode 0xb6 7872****************************************************************************/ 7873void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1)) 7874{ 7875 u8 imm; 7876 7877 START_OF_INSTR(); 7878 DECODE_PRINTF("MOV\tDH,"); 7879 imm = fetch_byte_imm(); 7880 DECODE_PRINTF2("%x\n", imm); 7881 TRACE_AND_STEP(); 7882 M.x86.R_DH = imm; 7883 DECODE_CLEAR_SEGOVR(); 7884 END_OF_INSTR(); 7885} 7886 7887/**************************************************************************** 7888REMARKS: 7889Handles opcode 0xb7 7890****************************************************************************/ 7891void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1)) 7892{ 7893 u8 imm; 7894 7895 START_OF_INSTR(); 7896 DECODE_PRINTF("MOV\tBH,"); 7897 imm = fetch_byte_imm(); 7898 DECODE_PRINTF2("%x\n", imm); 7899 TRACE_AND_STEP(); 7900 M.x86.R_BH = imm; 7901 DECODE_CLEAR_SEGOVR(); 7902 END_OF_INSTR(); 7903} 7904 7905/**************************************************************************** 7906REMARKS: 7907Handles opcode 0xb8 7908****************************************************************************/ 7909void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 7910{ 7911 u32 srcval; 7912 7913 START_OF_INSTR(); 7914 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7915 DECODE_PRINTF("MOV\tEAX,"); 7916 srcval = fetch_long_imm(); 7917 } else { 7918 DECODE_PRINTF("MOV\tAX,"); 7919 srcval = fetch_word_imm(); 7920 } 7921 DECODE_PRINTF2("%x\n", srcval); 7922 TRACE_AND_STEP(); 7923 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7924 M.x86.R_EAX = srcval; 7925 } else { 7926 M.x86.R_AX = (u16)srcval; 7927 } 7928 DECODE_CLEAR_SEGOVR(); 7929 END_OF_INSTR(); 7930} 7931 7932/**************************************************************************** 7933REMARKS: 7934Handles opcode 0xb9 7935****************************************************************************/ 7936void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1)) 7937{ 7938 u32 srcval; 7939 7940 START_OF_INSTR(); 7941 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7942 DECODE_PRINTF("MOV\tECX,"); 7943 srcval = fetch_long_imm(); 7944 } else { 7945 DECODE_PRINTF("MOV\tCX,"); 7946 srcval = fetch_word_imm(); 7947 } 7948 DECODE_PRINTF2("%x\n", srcval); 7949 TRACE_AND_STEP(); 7950 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7951 M.x86.R_ECX = srcval; 7952 } else { 7953 M.x86.R_CX = (u16)srcval; 7954 } 7955 DECODE_CLEAR_SEGOVR(); 7956 END_OF_INSTR(); 7957} 7958 7959/**************************************************************************** 7960REMARKS: 7961Handles opcode 0xba 7962****************************************************************************/ 7963void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1)) 7964{ 7965 u32 srcval; 7966 7967 START_OF_INSTR(); 7968 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7969 DECODE_PRINTF("MOV\tEDX,"); 7970 srcval = fetch_long_imm(); 7971 } else { 7972 DECODE_PRINTF("MOV\tDX,"); 7973 srcval = fetch_word_imm(); 7974 } 7975 DECODE_PRINTF2("%x\n", srcval); 7976 TRACE_AND_STEP(); 7977 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7978 M.x86.R_EDX = srcval; 7979 } else { 7980 M.x86.R_DX = (u16)srcval; 7981 } 7982 DECODE_CLEAR_SEGOVR(); 7983 END_OF_INSTR(); 7984} 7985 7986/**************************************************************************** 7987REMARKS: 7988Handles opcode 0xbb 7989****************************************************************************/ 7990void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1)) 7991{ 7992 u32 srcval; 7993 7994 START_OF_INSTR(); 7995 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 7996 DECODE_PRINTF("MOV\tEBX,"); 7997 srcval = fetch_long_imm(); 7998 } else { 7999 DECODE_PRINTF("MOV\tBX,"); 8000 srcval = fetch_word_imm(); 8001 } 8002 DECODE_PRINTF2("%x\n", srcval); 8003 TRACE_AND_STEP(); 8004 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8005 M.x86.R_EBX = srcval; 8006 } else { 8007 M.x86.R_BX = (u16)srcval; 8008 } 8009 DECODE_CLEAR_SEGOVR(); 8010 END_OF_INSTR(); 8011} 8012 8013/**************************************************************************** 8014REMARKS: 8015Handles opcode 0xbc 8016****************************************************************************/ 8017void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1)) 8018{ 8019 u32 srcval; 8020 8021 START_OF_INSTR(); 8022 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8023 DECODE_PRINTF("MOV\tESP,"); 8024 srcval = fetch_long_imm(); 8025 } else { 8026 DECODE_PRINTF("MOV\tSP,"); 8027 srcval = fetch_word_imm(); 8028 } 8029 DECODE_PRINTF2("%x\n", srcval); 8030 TRACE_AND_STEP(); 8031 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8032 M.x86.R_ESP = srcval; 8033 } else { 8034 M.x86.R_SP = (u16)srcval; 8035 } 8036 DECODE_CLEAR_SEGOVR(); 8037 END_OF_INSTR(); 8038} 8039 8040/**************************************************************************** 8041REMARKS: 8042Handles opcode 0xbd 8043****************************************************************************/ 8044void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1)) 8045{ 8046 u32 srcval; 8047 8048 START_OF_INSTR(); 8049 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8050 DECODE_PRINTF("MOV\tEBP,"); 8051 srcval = fetch_long_imm(); 8052 } else { 8053 DECODE_PRINTF("MOV\tBP,"); 8054 srcval = fetch_word_imm(); 8055 } 8056 DECODE_PRINTF2("%x\n", srcval); 8057 TRACE_AND_STEP(); 8058 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8059 M.x86.R_EBP = srcval; 8060 } else { 8061 M.x86.R_BP = (u16)srcval; 8062 } 8063 DECODE_CLEAR_SEGOVR(); 8064 END_OF_INSTR(); 8065} 8066 8067/**************************************************************************** 8068REMARKS: 8069Handles opcode 0xbe 8070****************************************************************************/ 8071void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1)) 8072{ 8073 u32 srcval; 8074 8075 START_OF_INSTR(); 8076 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8077 DECODE_PRINTF("MOV\tESI,"); 8078 srcval = fetch_long_imm(); 8079 } else { 8080 DECODE_PRINTF("MOV\tSI,"); 8081 srcval = fetch_word_imm(); 8082 } 8083 DECODE_PRINTF2("%x\n", srcval); 8084 TRACE_AND_STEP(); 8085 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8086 M.x86.R_ESI = srcval; 8087 } else { 8088 M.x86.R_SI = (u16)srcval; 8089 } 8090 DECODE_CLEAR_SEGOVR(); 8091 END_OF_INSTR(); 8092} 8093 8094/**************************************************************************** 8095REMARKS: 8096Handles opcode 0xbf 8097****************************************************************************/ 8098void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1)) 8099{ 8100 u32 srcval; 8101 8102 START_OF_INSTR(); 8103 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8104 DECODE_PRINTF("MOV\tEDI,"); 8105 srcval = fetch_long_imm(); 8106 } else { 8107 DECODE_PRINTF("MOV\tDI,"); 8108 srcval = fetch_word_imm(); 8109 } 8110 DECODE_PRINTF2("%x\n", srcval); 8111 TRACE_AND_STEP(); 8112 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8113 M.x86.R_EDI = srcval; 8114 } else { 8115 M.x86.R_DI = (u16)srcval; 8116 } 8117 DECODE_CLEAR_SEGOVR(); 8118 END_OF_INSTR(); 8119} 8120 8121/* used by opcodes c0, d0, and d2. */ 8122static u8(*opcD0_byte_operation[])(u8 d, u8 s) = 8123{ 8124 rol_byte, 8125 ror_byte, 8126 rcl_byte, 8127 rcr_byte, 8128 shl_byte, 8129 shr_byte, 8130 shl_byte, /* sal_byte === shl_byte by definition */ 8131 sar_byte, 8132}; 8133 8134/**************************************************************************** 8135REMARKS: 8136Handles opcode 0xc0 8137****************************************************************************/ 8138void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 8139{ 8140 int mod, rl, rh; 8141 u8 *destreg; 8142 uint destoffset; 8143 u8 destval; 8144 u8 amt; 8145 8146 /* 8147 * Yet another weirdo special case instruction format. Part of 8148 * the opcode held below in "RH". Doubly nested case would 8149 * result, except that the decoded instruction 8150 */ 8151 START_OF_INSTR(); 8152 FETCH_DECODE_MODRM(mod, rh, rl); 8153#ifdef DEBUG 8154 if (DEBUG_DECODE()) { 8155 8156 switch (rh) { 8157 case 0: 8158 DECODE_PRINTF("ROL\t"); 8159 break; 8160 case 1: 8161 DECODE_PRINTF("ROR\t"); 8162 break; 8163 case 2: 8164 DECODE_PRINTF("RCL\t"); 8165 break; 8166 case 3: 8167 DECODE_PRINTF("RCR\t"); 8168 break; 8169 case 4: 8170 DECODE_PRINTF("SHL\t"); 8171 break; 8172 case 5: 8173 DECODE_PRINTF("SHR\t"); 8174 break; 8175 case 6: 8176 DECODE_PRINTF("SAL\t"); 8177 break; 8178 case 7: 8179 DECODE_PRINTF("SAR\t"); 8180 break; 8181 } 8182 } 8183#endif 8184 /* know operation, decode the mod byte to find the addressing 8185 mode. */ 8186 switch (mod) { 8187 case 0: 8188 DECODE_PRINTF("BYTE PTR "); 8189 destoffset = decode_rm00_address(rl); 8190 amt = fetch_byte_imm(); 8191 DECODE_PRINTF2(",%x\n", amt); 8192 destval = fetch_data_byte(destoffset); 8193 TRACE_AND_STEP(); 8194 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8195 store_data_byte(destoffset, destval); 8196 break; 8197 case 1: 8198 DECODE_PRINTF("BYTE PTR "); 8199 destoffset = decode_rm01_address(rl); 8200 amt = fetch_byte_imm(); 8201 DECODE_PRINTF2(",%x\n", amt); 8202 destval = fetch_data_byte(destoffset); 8203 TRACE_AND_STEP(); 8204 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8205 store_data_byte(destoffset, destval); 8206 break; 8207 case 2: 8208 DECODE_PRINTF("BYTE PTR "); 8209 destoffset = decode_rm10_address(rl); 8210 amt = fetch_byte_imm(); 8211 DECODE_PRINTF2(",%x\n", amt); 8212 destval = fetch_data_byte(destoffset); 8213 TRACE_AND_STEP(); 8214 destval = (*opcD0_byte_operation[rh]) (destval, amt); 8215 store_data_byte(destoffset, destval); 8216 break; 8217 case 3: /* register to register */ 8218 destreg = DECODE_RM_BYTE_REGISTER(rl); 8219 amt = fetch_byte_imm(); 8220 DECODE_PRINTF2(",%x\n", amt); 8221 TRACE_AND_STEP(); 8222 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 8223 *destreg = destval; 8224 break; 8225 } 8226 DECODE_CLEAR_SEGOVR(); 8227 END_OF_INSTR(); 8228} 8229 8230/* used by opcodes c1, d1, and d3. */ 8231static u16(*opcD1_word_operation[])(u16 s, u8 d) = 8232{ 8233 rol_word, 8234 ror_word, 8235 rcl_word, 8236 rcr_word, 8237 shl_word, 8238 shr_word, 8239 shl_word, /* sal_byte === shl_byte by definition */ 8240 sar_word, 8241}; 8242 8243/* used by opcodes c1, d1, and d3. */ 8244static u32 (*opcD1_long_operation[])(u32 s, u8 d) = 8245{ 8246 rol_long, 8247 ror_long, 8248 rcl_long, 8249 rcr_long, 8250 shl_long, 8251 shr_long, 8252 shl_long, /* sal_byte === shl_byte by definition */ 8253 sar_long, 8254}; 8255 8256/**************************************************************************** 8257REMARKS: 8258Handles opcode 0xc1 8259****************************************************************************/ 8260void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 8261{ 8262 int mod, rl, rh; 8263 uint destoffset; 8264 u8 amt; 8265 8266 /* 8267 * Yet another weirdo special case instruction format. Part of 8268 * the opcode held below in "RH". Doubly nested case would 8269 * result, except that the decoded instruction 8270 */ 8271 START_OF_INSTR(); 8272 FETCH_DECODE_MODRM(mod, rh, rl); 8273#ifdef DEBUG 8274 if (DEBUG_DECODE()) { 8275 8276 switch (rh) { 8277 case 0: 8278 DECODE_PRINTF("ROL\t"); 8279 break; 8280 case 1: 8281 DECODE_PRINTF("ROR\t"); 8282 break; 8283 case 2: 8284 DECODE_PRINTF("RCL\t"); 8285 break; 8286 case 3: 8287 DECODE_PRINTF("RCR\t"); 8288 break; 8289 case 4: 8290 DECODE_PRINTF("SHL\t"); 8291 break; 8292 case 5: 8293 DECODE_PRINTF("SHR\t"); 8294 break; 8295 case 6: 8296 DECODE_PRINTF("SAL\t"); 8297 break; 8298 case 7: 8299 DECODE_PRINTF("SAR\t"); 8300 break; 8301 } 8302 } 8303#endif 8304 /* know operation, decode the mod byte to find the addressing 8305 mode. */ 8306 switch (mod) { 8307 case 0: 8308 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8309 u32 destval; 8310 8311 DECODE_PRINTF("DWORD PTR "); 8312 destoffset = decode_rm00_address(rl); 8313 amt = fetch_byte_imm(); 8314 DECODE_PRINTF2(",%x\n", amt); 8315 destval = fetch_data_long(destoffset); 8316 TRACE_AND_STEP(); 8317 destval = (*opcD1_long_operation[rh]) (destval, amt); 8318 store_data_long(destoffset, destval); 8319 } else { 8320 u16 destval; 8321 8322 DECODE_PRINTF("WORD PTR "); 8323 destoffset = decode_rm00_address(rl); 8324 amt = fetch_byte_imm(); 8325 DECODE_PRINTF2(",%x\n", amt); 8326 destval = fetch_data_word(destoffset); 8327 TRACE_AND_STEP(); 8328 destval = (*opcD1_word_operation[rh]) (destval, amt); 8329 store_data_word(destoffset, destval); 8330 } 8331 break; 8332 case 1: 8333 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8334 u32 destval; 8335 8336 DECODE_PRINTF("DWORD PTR "); 8337 destoffset = decode_rm01_address(rl); 8338 amt = fetch_byte_imm(); 8339 DECODE_PRINTF2(",%x\n", amt); 8340 destval = fetch_data_long(destoffset); 8341 TRACE_AND_STEP(); 8342 destval = (*opcD1_long_operation[rh]) (destval, amt); 8343 store_data_long(destoffset, destval); 8344 } else { 8345 u16 destval; 8346 8347 DECODE_PRINTF("WORD PTR "); 8348 destoffset = decode_rm01_address(rl); 8349 amt = fetch_byte_imm(); 8350 DECODE_PRINTF2(",%x\n", amt); 8351 destval = fetch_data_word(destoffset); 8352 TRACE_AND_STEP(); 8353 destval = (*opcD1_word_operation[rh]) (destval, amt); 8354 store_data_word(destoffset, destval); 8355 } 8356 break; 8357 case 2: 8358 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8359 u32 destval; 8360 8361 DECODE_PRINTF("DWORD PTR "); 8362 destoffset = decode_rm10_address(rl); 8363 amt = fetch_byte_imm(); 8364 DECODE_PRINTF2(",%x\n", amt); 8365 destval = fetch_data_long(destoffset); 8366 TRACE_AND_STEP(); 8367 destval = (*opcD1_long_operation[rh]) (destval, amt); 8368 store_data_long(destoffset, destval); 8369 } else { 8370 u16 destval; 8371 8372 DECODE_PRINTF("WORD PTR "); 8373 destoffset = decode_rm10_address(rl); 8374 amt = fetch_byte_imm(); 8375 DECODE_PRINTF2(",%x\n", amt); 8376 destval = fetch_data_word(destoffset); 8377 TRACE_AND_STEP(); 8378 destval = (*opcD1_word_operation[rh]) (destval, amt); 8379 store_data_word(destoffset, destval); 8380 } 8381 break; 8382 case 3: /* register to register */ 8383 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8384 u32 *destreg; 8385 8386 destreg = DECODE_RM_LONG_REGISTER(rl); 8387 amt = fetch_byte_imm(); 8388 DECODE_PRINTF2(",%x\n", amt); 8389 TRACE_AND_STEP(); 8390 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 8391 } else { 8392 u16 *destreg; 8393 8394 destreg = DECODE_RM_WORD_REGISTER(rl); 8395 amt = fetch_byte_imm(); 8396 DECODE_PRINTF2(",%x\n", amt); 8397 TRACE_AND_STEP(); 8398 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 8399 } 8400 break; 8401 } 8402 DECODE_CLEAR_SEGOVR(); 8403 END_OF_INSTR(); 8404} 8405 8406/**************************************************************************** 8407REMARKS: 8408Handles opcode 0xc2 8409****************************************************************************/ 8410void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 8411{ 8412 u16 imm; 8413 8414 START_OF_INSTR(); 8415 DECODE_PRINTF("RET\t"); 8416 imm = fetch_word_imm(); 8417 DECODE_PRINTF2("%x\n", imm); 8418 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8419 TRACE_AND_STEP(); 8420 M.x86.R_IP = pop_word(); 8421 M.x86.R_SP += imm; 8422 DECODE_CLEAR_SEGOVR(); 8423 END_OF_INSTR(); 8424} 8425 8426/**************************************************************************** 8427REMARKS: 8428Handles opcode 0xc3 8429****************************************************************************/ 8430void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 8431{ 8432 START_OF_INSTR(); 8433 DECODE_PRINTF("RET\n"); 8434 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 8435 TRACE_AND_STEP(); 8436 M.x86.R_IP = pop_word(); 8437 DECODE_CLEAR_SEGOVR(); 8438 END_OF_INSTR(); 8439} 8440 8441/**************************************************************************** 8442REMARKS: 8443Handles opcode 0xc4 8444****************************************************************************/ 8445void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 8446{ 8447 int mod, rh, rl; 8448 u16 *dstreg; 8449 uint srcoffset; 8450 8451 START_OF_INSTR(); 8452 DECODE_PRINTF("LES\t"); 8453 FETCH_DECODE_MODRM(mod, rh, rl); 8454 switch (mod) { 8455 case 0: 8456 dstreg = DECODE_RM_WORD_REGISTER(rh); 8457 DECODE_PRINTF(","); 8458 srcoffset = decode_rm00_address(rl); 8459 DECODE_PRINTF("\n"); 8460 TRACE_AND_STEP(); 8461 *dstreg = fetch_data_word(srcoffset); 8462 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8463 break; 8464 case 1: 8465 dstreg = DECODE_RM_WORD_REGISTER(rh); 8466 DECODE_PRINTF(","); 8467 srcoffset = decode_rm01_address(rl); 8468 DECODE_PRINTF("\n"); 8469 TRACE_AND_STEP(); 8470 *dstreg = fetch_data_word(srcoffset); 8471 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8472 break; 8473 case 2: 8474 dstreg = DECODE_RM_WORD_REGISTER(rh); 8475 DECODE_PRINTF(","); 8476 srcoffset = decode_rm10_address(rl); 8477 DECODE_PRINTF("\n"); 8478 TRACE_AND_STEP(); 8479 *dstreg = fetch_data_word(srcoffset); 8480 M.x86.R_ES = fetch_data_word(srcoffset + 2); 8481 break; 8482 case 3: /* register to register */ 8483 /* UNDEFINED! */ 8484 TRACE_AND_STEP(); 8485 } 8486 DECODE_CLEAR_SEGOVR(); 8487 END_OF_INSTR(); 8488} 8489 8490/**************************************************************************** 8491REMARKS: 8492Handles opcode 0xc5 8493****************************************************************************/ 8494void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 8495{ 8496 int mod, rh, rl; 8497 u16 *dstreg; 8498 uint srcoffset; 8499 8500 START_OF_INSTR(); 8501 DECODE_PRINTF("LDS\t"); 8502 FETCH_DECODE_MODRM(mod, rh, rl); 8503 switch (mod) { 8504 case 0: 8505 dstreg = DECODE_RM_WORD_REGISTER(rh); 8506 DECODE_PRINTF(","); 8507 srcoffset = decode_rm00_address(rl); 8508 DECODE_PRINTF("\n"); 8509 TRACE_AND_STEP(); 8510 *dstreg = fetch_data_word(srcoffset); 8511 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8512 break; 8513 case 1: 8514 dstreg = DECODE_RM_WORD_REGISTER(rh); 8515 DECODE_PRINTF(","); 8516 srcoffset = decode_rm01_address(rl); 8517 DECODE_PRINTF("\n"); 8518 TRACE_AND_STEP(); 8519 *dstreg = fetch_data_word(srcoffset); 8520 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8521 break; 8522 case 2: 8523 dstreg = DECODE_RM_WORD_REGISTER(rh); 8524 DECODE_PRINTF(","); 8525 srcoffset = decode_rm10_address(rl); 8526 DECODE_PRINTF("\n"); 8527 TRACE_AND_STEP(); 8528 *dstreg = fetch_data_word(srcoffset); 8529 M.x86.R_DS = fetch_data_word(srcoffset + 2); 8530 break; 8531 case 3: /* register to register */ 8532 /* UNDEFINED! */ 8533 TRACE_AND_STEP(); 8534 } 8535 DECODE_CLEAR_SEGOVR(); 8536 END_OF_INSTR(); 8537} 8538 8539/**************************************************************************** 8540REMARKS: 8541Handles opcode 0xc6 8542****************************************************************************/ 8543void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 8544{ 8545 int mod, rl, rh; 8546 u8 *destreg; 8547 uint destoffset; 8548 u8 imm; 8549 8550 START_OF_INSTR(); 8551 DECODE_PRINTF("MOV\t"); 8552 FETCH_DECODE_MODRM(mod, rh, rl); 8553 if (rh != 0) { 8554 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 8555 HALT_SYS(); 8556 } 8557 switch (mod) { 8558 case 0: 8559 DECODE_PRINTF("BYTE PTR "); 8560 destoffset = decode_rm00_address(rl); 8561 imm = fetch_byte_imm(); 8562 DECODE_PRINTF2(",%2x\n", imm); 8563 TRACE_AND_STEP(); 8564 store_data_byte(destoffset, imm); 8565 break; 8566 case 1: 8567 DECODE_PRINTF("BYTE PTR "); 8568 destoffset = decode_rm01_address(rl); 8569 imm = fetch_byte_imm(); 8570 DECODE_PRINTF2(",%2x\n", imm); 8571 TRACE_AND_STEP(); 8572 store_data_byte(destoffset, imm); 8573 break; 8574 case 2: 8575 DECODE_PRINTF("BYTE PTR "); 8576 destoffset = decode_rm10_address(rl); 8577 imm = fetch_byte_imm(); 8578 DECODE_PRINTF2(",%2x\n", imm); 8579 TRACE_AND_STEP(); 8580 store_data_byte(destoffset, imm); 8581 break; 8582 case 3: /* register to register */ 8583 destreg = DECODE_RM_BYTE_REGISTER(rl); 8584 imm = fetch_byte_imm(); 8585 DECODE_PRINTF2(",%2x\n", imm); 8586 TRACE_AND_STEP(); 8587 *destreg = imm; 8588 break; 8589 } 8590 DECODE_CLEAR_SEGOVR(); 8591 END_OF_INSTR(); 8592} 8593 8594/**************************************************************************** 8595REMARKS: 8596Handles opcode 0xc7 8597****************************************************************************/ 8598void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 8599{ 8600 int mod, rl, rh; 8601 uint destoffset; 8602 8603 START_OF_INSTR(); 8604 DECODE_PRINTF("MOV\t"); 8605 FETCH_DECODE_MODRM(mod, rh, rl); 8606 if (rh != 0) { 8607 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 8608 HALT_SYS(); 8609 } 8610 switch (mod) { 8611 case 0: 8612 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8613 u32 imm; 8614 8615 DECODE_PRINTF("DWORD PTR "); 8616 destoffset = decode_rm00_address(rl); 8617 imm = fetch_long_imm(); 8618 DECODE_PRINTF2(",%x\n", imm); 8619 TRACE_AND_STEP(); 8620 store_data_long(destoffset, imm); 8621 } else { 8622 u16 imm; 8623 8624 DECODE_PRINTF("WORD PTR "); 8625 destoffset = decode_rm00_address(rl); 8626 imm = fetch_word_imm(); 8627 DECODE_PRINTF2(",%x\n", imm); 8628 TRACE_AND_STEP(); 8629 store_data_word(destoffset, imm); 8630 } 8631 break; 8632 case 1: 8633 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8634 u32 imm; 8635 8636 DECODE_PRINTF("DWORD PTR "); 8637 destoffset = decode_rm01_address(rl); 8638 imm = fetch_long_imm(); 8639 DECODE_PRINTF2(",%x\n", imm); 8640 TRACE_AND_STEP(); 8641 store_data_long(destoffset, imm); 8642 } else { 8643 u16 imm; 8644 8645 DECODE_PRINTF("WORD PTR "); 8646 destoffset = decode_rm01_address(rl); 8647 imm = fetch_word_imm(); 8648 DECODE_PRINTF2(",%x\n", imm); 8649 TRACE_AND_STEP(); 8650 store_data_word(destoffset, imm); 8651 } 8652 break; 8653 case 2: 8654 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8655 u32 imm; 8656 8657 DECODE_PRINTF("DWORD PTR "); 8658 destoffset = decode_rm10_address(rl); 8659 imm = fetch_long_imm(); 8660 DECODE_PRINTF2(",%x\n", imm); 8661 TRACE_AND_STEP(); 8662 store_data_long(destoffset, imm); 8663 } else { 8664 u16 imm; 8665 8666 DECODE_PRINTF("WORD PTR "); 8667 destoffset = decode_rm10_address(rl); 8668 imm = fetch_word_imm(); 8669 DECODE_PRINTF2(",%x\n", imm); 8670 TRACE_AND_STEP(); 8671 store_data_word(destoffset, imm); 8672 } 8673 break; 8674 case 3: /* register to register */ 8675 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 8676 u32 *destreg; 8677 u32 imm; 8678 8679 destreg = DECODE_RM_LONG_REGISTER(rl); 8680 imm = fetch_long_imm(); 8681 DECODE_PRINTF2(",%x\n", imm); 8682 TRACE_AND_STEP(); 8683 *destreg = imm; 8684 } else { 8685 u16 *destreg; 8686 u16 imm; 8687 8688 destreg = DECODE_RM_WORD_REGISTER(rl); 8689 imm = fetch_word_imm(); 8690 DECODE_PRINTF2(",%x\n", imm); 8691 TRACE_AND_STEP(); 8692 *destreg = imm; 8693 } 8694 break; 8695 } 8696 DECODE_CLEAR_SEGOVR(); 8697 END_OF_INSTR(); 8698} 8699 8700/**************************************************************************** 8701REMARKS: 8702Handles opcode 0xc8 8703****************************************************************************/ 8704void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 8705{ 8706 u16 local,frame_pointer; 8707 u8 nesting; 8708 int i; 8709 8710 START_OF_INSTR(); 8711 local = fetch_word_imm(); 8712 nesting = fetch_byte_imm(); 8713 DECODE_PRINTF2("ENTER %x\n", local); 8714 DECODE_PRINTF2(",%x\n", nesting); 8715 TRACE_AND_STEP(); 8716 push_word(M.x86.R_BP); 8717 frame_pointer = M.x86.R_SP; 8718 if (nesting > 0) { 8719 for (i = 1; i < nesting; i++) { 8720 M.x86.R_BP -= 2; 8721 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 8722 } 8723 push_word(frame_pointer); 8724 } 8725 M.x86.R_BP = frame_pointer; 8726 M.x86.R_SP = (u16)(M.x86.R_SP - local); 8727 DECODE_CLEAR_SEGOVR(); 8728 END_OF_INSTR(); 8729} 8730 8731/**************************************************************************** 8732REMARKS: 8733Handles opcode 0xc9 8734****************************************************************************/ 8735void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 8736{ 8737 START_OF_INSTR(); 8738 DECODE_PRINTF("LEAVE\n"); 8739 TRACE_AND_STEP(); 8740 M.x86.R_SP = M.x86.R_BP; 8741 M.x86.R_BP = pop_word(); 8742 DECODE_CLEAR_SEGOVR(); 8743 END_OF_INSTR(); 8744} 8745 8746/**************************************************************************** 8747REMARKS: 8748Handles opcode 0xca 8749****************************************************************************/ 8750void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 8751{ 8752 u16 imm; 8753 8754 START_OF_INSTR(); 8755 DECODE_PRINTF("RETF\t"); 8756 imm = fetch_word_imm(); 8757 DECODE_PRINTF2("%x\n", imm); 8758 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8759 TRACE_AND_STEP(); 8760 M.x86.R_IP = pop_word(); 8761 M.x86.R_CS = pop_word(); 8762 M.x86.R_SP += imm; 8763 DECODE_CLEAR_SEGOVR(); 8764 END_OF_INSTR(); 8765} 8766 8767/**************************************************************************** 8768REMARKS: 8769Handles opcode 0xcb 8770****************************************************************************/ 8771void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 8772{ 8773 START_OF_INSTR(); 8774 DECODE_PRINTF("RETF\n"); 8775 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 8776 TRACE_AND_STEP(); 8777 M.x86.R_IP = pop_word(); 8778 M.x86.R_CS = pop_word(); 8779 DECODE_CLEAR_SEGOVR(); 8780 END_OF_INSTR(); 8781} 8782 8783/**************************************************************************** 8784REMARKS: 8785Handles opcode 0xcc 8786****************************************************************************/ 8787void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 8788{ 8789 u16 tmp; 8790 8791 START_OF_INSTR(); 8792 DECODE_PRINTF("INT 3\n"); 8793 tmp = (u16) mem_access_word(3 * 4 + 2); 8794 /* access the segment register */ 8795 TRACE_AND_STEP(); 8796 if (_X86EMU_intrTab[3]) { 8797 (*_X86EMU_intrTab[3])(3); 8798 } else { 8799 push_word((u16)M.x86.R_FLG); 8800 CLEAR_FLAG(F_IF); 8801 CLEAR_FLAG(F_TF); 8802 push_word(M.x86.R_CS); 8803 M.x86.R_CS = mem_access_word(3 * 4 + 2); 8804 push_word(M.x86.R_IP); 8805 M.x86.R_IP = mem_access_word(3 * 4); 8806 } 8807 DECODE_CLEAR_SEGOVR(); 8808 END_OF_INSTR(); 8809} 8810 8811/**************************************************************************** 8812REMARKS: 8813Handles opcode 0xcd 8814****************************************************************************/ 8815void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 8816{ 8817 u16 tmp; 8818 u8 intnum; 8819 8820 START_OF_INSTR(); 8821 DECODE_PRINTF("INT\t"); 8822 intnum = fetch_byte_imm(); 8823 DECODE_PRINTF2("%x\n", intnum); 8824 tmp = mem_access_word(intnum * 4 + 2); 8825 TRACE_AND_STEP(); 8826 if (_X86EMU_intrTab[intnum]) { 8827 (*_X86EMU_intrTab[intnum])(intnum); 8828 } else { 8829 push_word((u16)M.x86.R_FLG); 8830 CLEAR_FLAG(F_IF); 8831 CLEAR_FLAG(F_TF); 8832 push_word(M.x86.R_CS); 8833 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 8834 push_word(M.x86.R_IP); 8835 M.x86.R_IP = mem_access_word(intnum * 4); 8836 } 8837 DECODE_CLEAR_SEGOVR(); 8838 END_OF_INSTR(); 8839} 8840 8841/**************************************************************************** 8842REMARKS: 8843Handles opcode 0xce 8844****************************************************************************/ 8845void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 8846{ 8847 u16 tmp; 8848 8849 START_OF_INSTR(); 8850 DECODE_PRINTF("INTO\n"); 8851 TRACE_AND_STEP(); 8852 if (ACCESS_FLAG(F_OF)) { 8853 tmp = mem_access_word(4 * 4 + 2); 8854 if (_X86EMU_intrTab[4]) { 8855 (*_X86EMU_intrTab[4])(4); 8856 } else { 8857 push_word((u16)M.x86.R_FLG); 8858 CLEAR_FLAG(F_IF); 8859 CLEAR_FLAG(F_TF); 8860 push_word(M.x86.R_CS); 8861 M.x86.R_CS = mem_access_word(4 * 4 + 2); 8862 push_word(M.x86.R_IP); 8863 M.x86.R_IP = mem_access_word(4 * 4); 8864 } 8865 } 8866 DECODE_CLEAR_SEGOVR(); 8867 END_OF_INSTR(); 8868} 8869 8870/**************************************************************************** 8871REMARKS: 8872Handles opcode 0xcf 8873****************************************************************************/ 8874void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 8875{ 8876 START_OF_INSTR(); 8877 DECODE_PRINTF("IRET\n"); 8878 8879 TRACE_AND_STEP(); 8880 8881 M.x86.R_IP = pop_word(); 8882 M.x86.R_CS = pop_word(); 8883 M.x86.R_FLG = pop_word(); 8884 DECODE_CLEAR_SEGOVR(); 8885 END_OF_INSTR(); 8886} 8887 8888/**************************************************************************** 8889REMARKS: 8890Handles opcode 0xd0 8891****************************************************************************/ 8892void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 8893{ 8894 int mod, rl, rh; 8895 u8 *destreg; 8896 uint destoffset; 8897 u8 destval; 8898 8899 /* 8900 * Yet another weirdo special case instruction format. Part of 8901 * the opcode held below in "RH". Doubly nested case would 8902 * result, except that the decoded instruction 8903 */ 8904 START_OF_INSTR(); 8905 FETCH_DECODE_MODRM(mod, rh, rl); 8906#ifdef DEBUG 8907 if (DEBUG_DECODE()) { 8908 switch (rh) { 8909 case 0: 8910 DECODE_PRINTF("ROL\t"); 8911 break; 8912 case 1: 8913 DECODE_PRINTF("ROR\t"); 8914 break; 8915 case 2: 8916 DECODE_PRINTF("RCL\t"); 8917 break; 8918 case 3: 8919 DECODE_PRINTF("RCR\t"); 8920 break; 8921 case 4: 8922 DECODE_PRINTF("SHL\t"); 8923 break; 8924 case 5: 8925 DECODE_PRINTF("SHR\t"); 8926 break; 8927 case 6: 8928 DECODE_PRINTF("SAL\t"); 8929 break; 8930 case 7: 8931 DECODE_PRINTF("SAR\t"); 8932 break; 8933 } 8934 } 8935#endif 8936 /* know operation, decode the mod byte to find the addressing 8937 mode. */ 8938 switch (mod) { 8939 case 0: 8940 DECODE_PRINTF("BYTE PTR "); 8941 destoffset = decode_rm00_address(rl); 8942 DECODE_PRINTF(",1\n"); 8943 destval = fetch_data_byte(destoffset); 8944 TRACE_AND_STEP(); 8945 destval = (*opcD0_byte_operation[rh]) (destval, 1); 8946 store_data_byte(destoffset, destval); 8947 break; 8948 case 1: 8949 DECODE_PRINTF("BYTE PTR "); 8950 destoffset = decode_rm01_address(rl); 8951 DECODE_PRINTF(",1\n"); 8952 destval = fetch_data_byte(destoffset); 8953 TRACE_AND_STEP(); 8954 destval = (*opcD0_byte_operation[rh]) (destval, 1); 8955 store_data_byte(destoffset, destval); 8956 break; 8957 case 2: 8958 DECODE_PRINTF("BYTE PTR "); 8959 destoffset = decode_rm10_address(rl); 8960 DECODE_PRINTF(",1\n"); 8961 destval = fetch_data_byte(destoffset); 8962 TRACE_AND_STEP(); 8963 destval = (*opcD0_byte_operation[rh]) (destval, 1); 8964 store_data_byte(destoffset, destval); 8965 break; 8966 case 3: /* register to register */ 8967 destreg = DECODE_RM_BYTE_REGISTER(rl); 8968 DECODE_PRINTF(",1\n"); 8969 TRACE_AND_STEP(); 8970 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 8971 *destreg = destval; 8972 break; 8973 } 8974 DECODE_CLEAR_SEGOVR(); 8975 END_OF_INSTR(); 8976} 8977 8978/**************************************************************************** 8979REMARKS: 8980Handles opcode 0xd1 8981****************************************************************************/ 8982void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 8983{ 8984 int mod, rl, rh; 8985 uint destoffset; 8986 8987 /* 8988 * Yet another weirdo special case instruction format. Part of 8989 * the opcode held below in "RH". Doubly nested case would 8990 * result, except that the decoded instruction 8991 */ 8992 START_OF_INSTR(); 8993 FETCH_DECODE_MODRM(mod, rh, rl); 8994#ifdef DEBUG 8995 if (DEBUG_DECODE()) { 8996 switch (rh) { 8997 case 0: 8998 DECODE_PRINTF("ROL\t"); 8999 break; 9000 case 1: 9001 DECODE_PRINTF("ROR\t"); 9002 break; 9003 case 2: 9004 DECODE_PRINTF("RCL\t"); 9005 break; 9006 case 3: 9007 DECODE_PRINTF("RCR\t"); 9008 break; 9009 case 4: 9010 DECODE_PRINTF("SHL\t"); 9011 break; 9012 case 5: 9013 DECODE_PRINTF("SHR\t"); 9014 break; 9015 case 6: 9016 DECODE_PRINTF("SAL\t"); 9017 break; 9018 case 7: 9019 DECODE_PRINTF("SAR\t"); 9020 break; 9021 } 9022 } 9023#endif 9024 /* know operation, decode the mod byte to find the addressing 9025 mode. */ 9026 switch (mod) { 9027 case 0: 9028 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9029 u32 destval; 9030 9031 DECODE_PRINTF("DWORD PTR "); 9032 destoffset = decode_rm00_address(rl); 9033 DECODE_PRINTF(",1\n"); 9034 destval = fetch_data_long(destoffset); 9035 TRACE_AND_STEP(); 9036 destval = (*opcD1_long_operation[rh]) (destval, 1); 9037 store_data_long(destoffset, destval); 9038 } else { 9039 u16 destval; 9040 9041 DECODE_PRINTF("WORD PTR "); 9042 destoffset = decode_rm00_address(rl); 9043 DECODE_PRINTF(",1\n"); 9044 destval = fetch_data_word(destoffset); 9045 TRACE_AND_STEP(); 9046 destval = (*opcD1_word_operation[rh]) (destval, 1); 9047 store_data_word(destoffset, destval); 9048 } 9049 break; 9050 case 1: 9051 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9052 u32 destval; 9053 9054 DECODE_PRINTF("DWORD PTR "); 9055 destoffset = decode_rm01_address(rl); 9056 DECODE_PRINTF(",1\n"); 9057 destval = fetch_data_long(destoffset); 9058 TRACE_AND_STEP(); 9059 destval = (*opcD1_long_operation[rh]) (destval, 1); 9060 store_data_long(destoffset, destval); 9061 } else { 9062 u16 destval; 9063 9064 DECODE_PRINTF("WORD PTR "); 9065 destoffset = decode_rm01_address(rl); 9066 DECODE_PRINTF(",1\n"); 9067 destval = fetch_data_word(destoffset); 9068 TRACE_AND_STEP(); 9069 destval = (*opcD1_word_operation[rh]) (destval, 1); 9070 store_data_word(destoffset, destval); 9071 } 9072 break; 9073 case 2: 9074 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9075 u32 destval; 9076 9077 DECODE_PRINTF("DWORD PTR "); 9078 destoffset = decode_rm10_address(rl); 9079 DECODE_PRINTF(",1\n"); 9080 destval = fetch_data_long(destoffset); 9081 TRACE_AND_STEP(); 9082 destval = (*opcD1_long_operation[rh]) (destval, 1); 9083 store_data_long(destoffset, destval); 9084 } else { 9085 u16 destval; 9086 9087 DECODE_PRINTF("BYTE PTR "); 9088 destoffset = decode_rm10_address(rl); 9089 DECODE_PRINTF(",1\n"); 9090 destval = fetch_data_word(destoffset); 9091 TRACE_AND_STEP(); 9092 destval = (*opcD1_word_operation[rh]) (destval, 1); 9093 store_data_word(destoffset, destval); 9094 } 9095 break; 9096 case 3: /* register to register */ 9097 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9098 u32 destval; 9099 u32 *destreg; 9100 9101 destreg = DECODE_RM_LONG_REGISTER(rl); 9102 DECODE_PRINTF(",1\n"); 9103 TRACE_AND_STEP(); 9104 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 9105 *destreg = destval; 9106 } else { 9107 u16 destval; 9108 u16 *destreg; 9109 9110 destreg = DECODE_RM_WORD_REGISTER(rl); 9111 DECODE_PRINTF(",1\n"); 9112 TRACE_AND_STEP(); 9113 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 9114 *destreg = destval; 9115 } 9116 break; 9117 } 9118 DECODE_CLEAR_SEGOVR(); 9119 END_OF_INSTR(); 9120} 9121 9122/**************************************************************************** 9123REMARKS: 9124Handles opcode 0xd2 9125****************************************************************************/ 9126void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 9127{ 9128 int mod, rl, rh; 9129 u8 *destreg; 9130 uint destoffset; 9131 u8 destval; 9132 u8 amt; 9133 9134 /* 9135 * Yet another weirdo special case instruction format. Part of 9136 * the opcode held below in "RH". Doubly nested case would 9137 * result, except that the decoded instruction 9138 */ 9139 START_OF_INSTR(); 9140 FETCH_DECODE_MODRM(mod, rh, rl); 9141#ifdef DEBUG 9142 if (DEBUG_DECODE()) { 9143 switch (rh) { 9144 case 0: 9145 DECODE_PRINTF("ROL\t"); 9146 break; 9147 case 1: 9148 DECODE_PRINTF("ROR\t"); 9149 break; 9150 case 2: 9151 DECODE_PRINTF("RCL\t"); 9152 break; 9153 case 3: 9154 DECODE_PRINTF("RCR\t"); 9155 break; 9156 case 4: 9157 DECODE_PRINTF("SHL\t"); 9158 break; 9159 case 5: 9160 DECODE_PRINTF("SHR\t"); 9161 break; 9162 case 6: 9163 DECODE_PRINTF("SAL\t"); 9164 break; 9165 case 7: 9166 DECODE_PRINTF("SAR\t"); 9167 break; 9168 } 9169 } 9170#endif 9171 /* know operation, decode the mod byte to find the addressing 9172 mode. */ 9173 amt = M.x86.R_CL; 9174 switch (mod) { 9175 case 0: 9176 DECODE_PRINTF("BYTE PTR "); 9177 destoffset = decode_rm00_address(rl); 9178 DECODE_PRINTF(",CL\n"); 9179 destval = fetch_data_byte(destoffset); 9180 TRACE_AND_STEP(); 9181 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9182 store_data_byte(destoffset, destval); 9183 break; 9184 case 1: 9185 DECODE_PRINTF("BYTE PTR "); 9186 destoffset = decode_rm01_address(rl); 9187 DECODE_PRINTF(",CL\n"); 9188 destval = fetch_data_byte(destoffset); 9189 TRACE_AND_STEP(); 9190 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9191 store_data_byte(destoffset, destval); 9192 break; 9193 case 2: 9194 DECODE_PRINTF("BYTE PTR "); 9195 destoffset = decode_rm10_address(rl); 9196 DECODE_PRINTF(",CL\n"); 9197 destval = fetch_data_byte(destoffset); 9198 TRACE_AND_STEP(); 9199 destval = (*opcD0_byte_operation[rh]) (destval, amt); 9200 store_data_byte(destoffset, destval); 9201 break; 9202 case 3: /* register to register */ 9203 destreg = DECODE_RM_BYTE_REGISTER(rl); 9204 DECODE_PRINTF(",CL\n"); 9205 TRACE_AND_STEP(); 9206 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 9207 *destreg = destval; 9208 break; 9209 } 9210 DECODE_CLEAR_SEGOVR(); 9211 END_OF_INSTR(); 9212} 9213 9214/**************************************************************************** 9215REMARKS: 9216Handles opcode 0xd3 9217****************************************************************************/ 9218void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 9219{ 9220 int mod, rl, rh; 9221 uint destoffset; 9222 u8 amt; 9223 9224 /* 9225 * Yet another weirdo special case instruction format. Part of 9226 * the opcode held below in "RH". Doubly nested case would 9227 * result, except that the decoded instruction 9228 */ 9229 START_OF_INSTR(); 9230 FETCH_DECODE_MODRM(mod, rh, rl); 9231#ifdef DEBUG 9232 if (DEBUG_DECODE()) { 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 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9267 u32 destval; 9268 9269 DECODE_PRINTF("DWORD PTR "); 9270 destoffset = decode_rm00_address(rl); 9271 DECODE_PRINTF(",CL\n"); 9272 destval = fetch_data_long(destoffset); 9273 TRACE_AND_STEP(); 9274 destval = (*opcD1_long_operation[rh]) (destval, amt); 9275 store_data_long(destoffset, destval); 9276 } else { 9277 u16 destval; 9278 9279 DECODE_PRINTF("WORD PTR "); 9280 destoffset = decode_rm00_address(rl); 9281 DECODE_PRINTF(",CL\n"); 9282 destval = fetch_data_word(destoffset); 9283 TRACE_AND_STEP(); 9284 destval = (*opcD1_word_operation[rh]) (destval, amt); 9285 store_data_word(destoffset, destval); 9286 } 9287 break; 9288 case 1: 9289 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9290 u32 destval; 9291 9292 DECODE_PRINTF("DWORD PTR "); 9293 destoffset = decode_rm01_address(rl); 9294 DECODE_PRINTF(",CL\n"); 9295 destval = fetch_data_long(destoffset); 9296 TRACE_AND_STEP(); 9297 destval = (*opcD1_long_operation[rh]) (destval, amt); 9298 store_data_long(destoffset, destval); 9299 } else { 9300 u16 destval; 9301 9302 DECODE_PRINTF("WORD PTR "); 9303 destoffset = decode_rm01_address(rl); 9304 DECODE_PRINTF(",CL\n"); 9305 destval = fetch_data_word(destoffset); 9306 TRACE_AND_STEP(); 9307 destval = (*opcD1_word_operation[rh]) (destval, amt); 9308 store_data_word(destoffset, destval); 9309 } 9310 break; 9311 case 2: 9312 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9313 u32 destval; 9314 9315 DECODE_PRINTF("DWORD PTR "); 9316 destoffset = decode_rm10_address(rl); 9317 DECODE_PRINTF(",CL\n"); 9318 destval = fetch_data_long(destoffset); 9319 TRACE_AND_STEP(); 9320 destval = (*opcD1_long_operation[rh]) (destval, amt); 9321 store_data_long(destoffset, destval); 9322 } else { 9323 u16 destval; 9324 9325 DECODE_PRINTF("WORD PTR "); 9326 destoffset = decode_rm10_address(rl); 9327 DECODE_PRINTF(",CL\n"); 9328 destval = fetch_data_word(destoffset); 9329 TRACE_AND_STEP(); 9330 destval = (*opcD1_word_operation[rh]) (destval, amt); 9331 store_data_word(destoffset, destval); 9332 } 9333 break; 9334 case 3: /* register to register */ 9335 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9336 u32 *destreg; 9337 9338 destreg = DECODE_RM_LONG_REGISTER(rl); 9339 DECODE_PRINTF(",CL\n"); 9340 TRACE_AND_STEP(); 9341 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 9342 } else { 9343 u16 *destreg; 9344 9345 destreg = DECODE_RM_WORD_REGISTER(rl); 9346 DECODE_PRINTF(",CL\n"); 9347 TRACE_AND_STEP(); 9348 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 9349 } 9350 break; 9351 } 9352 DECODE_CLEAR_SEGOVR(); 9353 END_OF_INSTR(); 9354} 9355 9356/**************************************************************************** 9357REMARKS: 9358Handles opcode 0xd4 9359****************************************************************************/ 9360void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 9361{ 9362 u8 a; 9363 9364 START_OF_INSTR(); 9365 DECODE_PRINTF("AAM\n"); 9366 a = fetch_byte_imm(); /* this is a stupid encoding. */ 9367 if (a != 10) { 9368 DECODE_PRINTF("ERROR DECODING AAM\n"); 9369 TRACE_REGS(); 9370 HALT_SYS(); 9371 } 9372 TRACE_AND_STEP(); 9373 /* note the type change here --- returning AL and AH in AX. */ 9374 M.x86.R_AX = aam_word(M.x86.R_AL); 9375 DECODE_CLEAR_SEGOVR(); 9376 END_OF_INSTR(); 9377} 9378 9379/**************************************************************************** 9380REMARKS: 9381Handles opcode 0xd5 9382****************************************************************************/ 9383void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 9384{ 9385 u8 a; 9386 9387 START_OF_INSTR(); 9388 DECODE_PRINTF("AAD\n"); 9389 a = fetch_byte_imm(); 9390 TRACE_AND_STEP(); 9391 M.x86.R_AX = aad_word(M.x86.R_AX); 9392 DECODE_CLEAR_SEGOVR(); 9393 END_OF_INSTR(); 9394} 9395 9396/* opcode 0xd6 ILLEGAL OPCODE */ 9397 9398/**************************************************************************** 9399REMARKS: 9400Handles opcode 0xd7 9401****************************************************************************/ 9402void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 9403{ 9404 u16 addr; 9405 9406 START_OF_INSTR(); 9407 DECODE_PRINTF("XLAT\n"); 9408 TRACE_AND_STEP(); 9409 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 9410 M.x86.R_AL = fetch_data_byte(addr); 9411 DECODE_CLEAR_SEGOVR(); 9412 END_OF_INSTR(); 9413} 9414 9415/* instuctions D8 .. DF are in i87_ops.c */ 9416 9417/**************************************************************************** 9418REMARKS: 9419Handles opcode 0xe0 9420****************************************************************************/ 9421void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 9422{ 9423 s16 ip; 9424 9425 START_OF_INSTR(); 9426 DECODE_PRINTF("LOOPNE\t"); 9427 ip = (s8) fetch_byte_imm(); 9428 ip += (s16) M.x86.R_IP; 9429 DECODE_PRINTF2("%04x\n", ip); 9430 TRACE_AND_STEP(); 9431 M.x86.R_CX -= 1; 9432 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 9433 M.x86.R_IP = ip; 9434 DECODE_CLEAR_SEGOVR(); 9435 END_OF_INSTR(); 9436} 9437 9438/**************************************************************************** 9439REMARKS: 9440Handles opcode 0xe1 9441****************************************************************************/ 9442void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 9443{ 9444 s16 ip; 9445 9446 START_OF_INSTR(); 9447 DECODE_PRINTF("LOOPE\t"); 9448 ip = (s8) fetch_byte_imm(); 9449 ip += (s16) M.x86.R_IP; 9450 DECODE_PRINTF2("%04x\n", ip); 9451 TRACE_AND_STEP(); 9452 M.x86.R_CX -= 1; 9453 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 9454 M.x86.R_IP = ip; 9455 DECODE_CLEAR_SEGOVR(); 9456 END_OF_INSTR(); 9457} 9458 9459/**************************************************************************** 9460REMARKS: 9461Handles opcode 0xe2 9462****************************************************************************/ 9463void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 9464{ 9465 s16 ip; 9466 9467 START_OF_INSTR(); 9468 DECODE_PRINTF("LOOP\t"); 9469 ip = (s8) fetch_byte_imm(); 9470 ip += (s16) M.x86.R_IP; 9471 DECODE_PRINTF2("%04x\n", ip); 9472 TRACE_AND_STEP(); 9473 M.x86.R_CX -= 1; 9474 if (M.x86.R_CX != 0) 9475 M.x86.R_IP = ip; 9476 DECODE_CLEAR_SEGOVR(); 9477 END_OF_INSTR(); 9478} 9479 9480/**************************************************************************** 9481REMARKS: 9482Handles opcode 0xe3 9483****************************************************************************/ 9484void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 9485{ 9486 u16 target; 9487 s8 offset; 9488 9489 /* jump to byte offset if overflow flag is set */ 9490 START_OF_INSTR(); 9491 DECODE_PRINTF("JCXZ\t"); 9492 offset = (s8)fetch_byte_imm(); 9493 target = (u16)(M.x86.R_IP + offset); 9494 DECODE_PRINTF2("%x\n", target); 9495 TRACE_AND_STEP(); 9496 if (M.x86.R_CX == 0) 9497 M.x86.R_IP = target; 9498 DECODE_CLEAR_SEGOVR(); 9499 END_OF_INSTR(); 9500} 9501 9502/**************************************************************************** 9503REMARKS: 9504Handles opcode 0xe4 9505****************************************************************************/ 9506void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 9507{ 9508 u8 port; 9509 9510 START_OF_INSTR(); 9511 DECODE_PRINTF("IN\t"); 9512 port = (u8) fetch_byte_imm(); 9513 DECODE_PRINTF2("%x,AL\n", port); 9514 TRACE_AND_STEP(); 9515 M.x86.R_AL = (*sys_inb)(port); 9516 DECODE_CLEAR_SEGOVR(); 9517 END_OF_INSTR(); 9518} 9519 9520/**************************************************************************** 9521REMARKS: 9522Handles opcode 0xe5 9523****************************************************************************/ 9524void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 9525{ 9526 u8 port; 9527 9528 START_OF_INSTR(); 9529 DECODE_PRINTF("IN\t"); 9530 port = (u8) fetch_byte_imm(); 9531 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9532 DECODE_PRINTF2("EAX,%x\n", port); 9533 } else { 9534 DECODE_PRINTF2("AX,%x\n", port); 9535 } 9536 TRACE_AND_STEP(); 9537 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9538 M.x86.R_EAX = (*sys_inl)(port); 9539 } else { 9540 M.x86.R_AX = (*sys_inw)(port); 9541 } 9542 DECODE_CLEAR_SEGOVR(); 9543 END_OF_INSTR(); 9544} 9545 9546/**************************************************************************** 9547REMARKS: 9548Handles opcode 0xe6 9549****************************************************************************/ 9550void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 9551{ 9552 u8 port; 9553 9554 START_OF_INSTR(); 9555 DECODE_PRINTF("OUT\t"); 9556 port = (u8) fetch_byte_imm(); 9557 DECODE_PRINTF2("%x,AL\n", port); 9558 TRACE_AND_STEP(); 9559 (*sys_outb)(port, M.x86.R_AL); 9560 DECODE_CLEAR_SEGOVR(); 9561 END_OF_INSTR(); 9562} 9563 9564/**************************************************************************** 9565REMARKS: 9566Handles opcode 0xe7 9567****************************************************************************/ 9568void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 9569{ 9570 u8 port; 9571 9572 START_OF_INSTR(); 9573 DECODE_PRINTF("OUT\t"); 9574 port = (u8) fetch_byte_imm(); 9575 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9576 DECODE_PRINTF2("%x,EAX\n", port); 9577 } else { 9578 DECODE_PRINTF2("%x,AX\n", port); 9579 } 9580 TRACE_AND_STEP(); 9581 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9582 (*sys_outl)(port, M.x86.R_EAX); 9583 } else { 9584 (*sys_outw)(port, M.x86.R_AX); 9585 } 9586 DECODE_CLEAR_SEGOVR(); 9587 END_OF_INSTR(); 9588} 9589 9590/**************************************************************************** 9591REMARKS: 9592Handles opcode 0xe8 9593****************************************************************************/ 9594void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 9595{ 9596 s16 ip; 9597 9598 START_OF_INSTR(); 9599 DECODE_PRINTF("CALL\t"); 9600 ip = (s16) fetch_word_imm(); 9601 ip += (s16) M.x86.R_IP; /* CHECK SIGN */ 9602 DECODE_PRINTF2("%04x\n", ip); 9603 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, ""); 9604 TRACE_AND_STEP(); 9605 push_word(M.x86.R_IP); 9606 M.x86.R_IP = ip; 9607 DECODE_CLEAR_SEGOVR(); 9608 END_OF_INSTR(); 9609} 9610 9611/**************************************************************************** 9612REMARKS: 9613Handles opcode 0xe9 9614****************************************************************************/ 9615void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 9616{ 9617 int ip; 9618 9619 START_OF_INSTR(); 9620 DECODE_PRINTF("JMP\t"); 9621 ip = (s16)fetch_word_imm(); 9622 ip += (s16)M.x86.R_IP; 9623 DECODE_PRINTF2("%04x\n", ip); 9624 TRACE_AND_STEP(); 9625 M.x86.R_IP = (u16)ip; 9626 DECODE_CLEAR_SEGOVR(); 9627 END_OF_INSTR(); 9628} 9629 9630/**************************************************************************** 9631REMARKS: 9632Handles opcode 0xea 9633****************************************************************************/ 9634void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 9635{ 9636 u16 cs, ip; 9637 9638 START_OF_INSTR(); 9639 DECODE_PRINTF("JMP\tFAR "); 9640 ip = fetch_word_imm(); 9641 cs = fetch_word_imm(); 9642 DECODE_PRINTF2("%04x:", cs); 9643 DECODE_PRINTF2("%04x\n", ip); 9644 TRACE_AND_STEP(); 9645 M.x86.R_IP = ip; 9646 M.x86.R_CS = cs; 9647 DECODE_CLEAR_SEGOVR(); 9648 END_OF_INSTR(); 9649} 9650 9651/**************************************************************************** 9652REMARKS: 9653Handles opcode 0xeb 9654****************************************************************************/ 9655void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 9656{ 9657 u16 target; 9658 s8 offset; 9659 9660 START_OF_INSTR(); 9661 DECODE_PRINTF("JMP\t"); 9662 offset = (s8)fetch_byte_imm(); 9663 target = (u16)(M.x86.R_IP + offset); 9664 DECODE_PRINTF2("%x\n", target); 9665 TRACE_AND_STEP(); 9666 M.x86.R_IP = target; 9667 DECODE_CLEAR_SEGOVR(); 9668 END_OF_INSTR(); 9669} 9670 9671/**************************************************************************** 9672REMARKS: 9673Handles opcode 0xec 9674****************************************************************************/ 9675void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 9676{ 9677 START_OF_INSTR(); 9678 DECODE_PRINTF("IN\tAL,DX\n"); 9679 TRACE_AND_STEP(); 9680 M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 9681 DECODE_CLEAR_SEGOVR(); 9682 END_OF_INSTR(); 9683} 9684 9685/**************************************************************************** 9686REMARKS: 9687Handles opcode 0xed 9688****************************************************************************/ 9689void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 9690{ 9691 START_OF_INSTR(); 9692 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9693 DECODE_PRINTF("IN\tEAX,DX\n"); 9694 } else { 9695 DECODE_PRINTF("IN\tAX,DX\n"); 9696 } 9697 TRACE_AND_STEP(); 9698 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9699 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 9700 } else { 9701 M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 9702 } 9703 DECODE_CLEAR_SEGOVR(); 9704 END_OF_INSTR(); 9705} 9706 9707/**************************************************************************** 9708REMARKS: 9709Handles opcode 0xee 9710****************************************************************************/ 9711void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 9712{ 9713 START_OF_INSTR(); 9714 DECODE_PRINTF("OUT\tDX,AL\n"); 9715 TRACE_AND_STEP(); 9716 (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 9717 DECODE_CLEAR_SEGOVR(); 9718 END_OF_INSTR(); 9719} 9720 9721/**************************************************************************** 9722REMARKS: 9723Handles opcode 0xef 9724****************************************************************************/ 9725void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 9726{ 9727 START_OF_INSTR(); 9728 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9729 DECODE_PRINTF("OUT\tDX,EAX\n"); 9730 } else { 9731 DECODE_PRINTF("OUT\tDX,AX\n"); 9732 } 9733 TRACE_AND_STEP(); 9734 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 9735 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 9736 } else { 9737 (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 9738 } 9739 DECODE_CLEAR_SEGOVR(); 9740 END_OF_INSTR(); 9741} 9742 9743/**************************************************************************** 9744REMARKS: 9745Handles opcode 0xf0 9746****************************************************************************/ 9747void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 9748{ 9749 START_OF_INSTR(); 9750 DECODE_PRINTF("LOCK:\n"); 9751 TRACE_AND_STEP(); 9752 DECODE_CLEAR_SEGOVR(); 9753 END_OF_INSTR(); 9754} 9755 9756/*opcode 0xf1 ILLEGAL OPERATION */ 9757 9758/**************************************************************************** 9759REMARKS: 9760Handles opcode 0xf2 9761****************************************************************************/ 9762void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 9763{ 9764 START_OF_INSTR(); 9765 DECODE_PRINTF("REPNE\n"); 9766 TRACE_AND_STEP(); 9767 M.x86.mode |= SYSMODE_PREFIX_REPNE; 9768 DECODE_CLEAR_SEGOVR(); 9769 END_OF_INSTR(); 9770} 9771 9772/**************************************************************************** 9773REMARKS: 9774Handles opcode 0xf3 9775****************************************************************************/ 9776void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 9777{ 9778 START_OF_INSTR(); 9779 DECODE_PRINTF("REPE\n"); 9780 TRACE_AND_STEP(); 9781 M.x86.mode |= SYSMODE_PREFIX_REPE; 9782 DECODE_CLEAR_SEGOVR(); 9783 END_OF_INSTR(); 9784} 9785 9786/**************************************************************************** 9787REMARKS: 9788Handles opcode 0xf4 9789****************************************************************************/ 9790void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 9791{ 9792 START_OF_INSTR(); 9793 DECODE_PRINTF("HALT\n"); 9794 TRACE_AND_STEP(); 9795 HALT_SYS(); 9796 DECODE_CLEAR_SEGOVR(); 9797 END_OF_INSTR(); 9798} 9799 9800/**************************************************************************** 9801REMARKS: 9802Handles opcode 0xf5 9803****************************************************************************/ 9804void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 9805{ 9806 /* complement the carry flag. */ 9807 START_OF_INSTR(); 9808 DECODE_PRINTF("CMC\n"); 9809 TRACE_AND_STEP(); 9810 TOGGLE_FLAG(F_CF); 9811 DECODE_CLEAR_SEGOVR(); 9812 END_OF_INSTR(); 9813} 9814 9815/**************************************************************************** 9816REMARKS: 9817Handles opcode 0xf6 9818****************************************************************************/ 9819void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 9820{ 9821 int mod, rl, rh; 9822 u8 *destreg; 9823 uint destoffset; 9824 u8 destval, srcval; 9825 9826 /* long, drawn out code follows. Double switch for a total 9827 of 32 cases. */ 9828 START_OF_INSTR(); 9829 FETCH_DECODE_MODRM(mod, rh, rl); 9830 switch (mod) { 9831 case 0: /* mod=00 */ 9832 switch (rh) { 9833 case 0: /* test byte imm */ 9834 DECODE_PRINTF("TEST\tBYTE PTR "); 9835 destoffset = decode_rm00_address(rl); 9836 DECODE_PRINTF(","); 9837 srcval = fetch_byte_imm(); 9838 DECODE_PRINTF2("%02x\n", srcval); 9839 destval = fetch_data_byte(destoffset); 9840 TRACE_AND_STEP(); 9841 test_byte(destval, srcval); 9842 break; 9843 case 1: 9844 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 9845 HALT_SYS(); 9846 break; 9847 case 2: 9848 DECODE_PRINTF("NOT\tBYTE PTR "); 9849 destoffset = decode_rm00_address(rl); 9850 DECODE_PRINTF("\n"); 9851 destval = fetch_data_byte(destoffset); 9852 TRACE_AND_STEP(); 9853 destval = not_byte(destval); 9854 store_data_byte(destoffset, destval); 9855 break; 9856 case 3: 9857 DECODE_PRINTF("NEG\tBYTE PTR "); 9858 destoffset = decode_rm00_address(rl); 9859 DECODE_PRINTF("\n"); 9860 destval = fetch_data_byte(destoffset); 9861 TRACE_AND_STEP(); 9862 destval = neg_byte(destval); 9863 store_data_byte(destoffset, destval); 9864 break; 9865 case 4: 9866 DECODE_PRINTF("MUL\tBYTE PTR "); 9867 destoffset = decode_rm00_address(rl); 9868 DECODE_PRINTF("\n"); 9869 destval = fetch_data_byte(destoffset); 9870 TRACE_AND_STEP(); 9871 mul_byte(destval); 9872 break; 9873 case 5: 9874 DECODE_PRINTF("IMUL\tBYTE PTR "); 9875 destoffset = decode_rm00_address(rl); 9876 DECODE_PRINTF("\n"); 9877 destval = fetch_data_byte(destoffset); 9878 TRACE_AND_STEP(); 9879 imul_byte(destval); 9880 break; 9881 case 6: 9882 DECODE_PRINTF("DIV\tBYTE PTR "); 9883 destoffset = decode_rm00_address(rl); 9884 DECODE_PRINTF("\n"); 9885 destval = fetch_data_byte(destoffset); 9886 TRACE_AND_STEP(); 9887 div_byte(destval); 9888 break; 9889 case 7: 9890 DECODE_PRINTF("IDIV\tBYTE PTR "); 9891 destoffset = decode_rm00_address(rl); 9892 DECODE_PRINTF("\n"); 9893 destval = fetch_data_byte(destoffset); 9894 TRACE_AND_STEP(); 9895 idiv_byte(destval); 9896 break; 9897 } 9898 break; /* end mod==00 */ 9899 case 1: /* mod=01 */ 9900 switch (rh) { 9901 case 0: /* test byte imm */ 9902 DECODE_PRINTF("TEST\tBYTE PTR "); 9903 destoffset = decode_rm01_address(rl); 9904 DECODE_PRINTF(","); 9905 srcval = fetch_byte_imm(); 9906 DECODE_PRINTF2("%02x\n", srcval); 9907 destval = fetch_data_byte(destoffset); 9908 TRACE_AND_STEP(); 9909 test_byte(destval, srcval); 9910 break; 9911 case 1: 9912 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 9913 HALT_SYS(); 9914 break; 9915 case 2: 9916 DECODE_PRINTF("NOT\tBYTE PTR "); 9917 destoffset = decode_rm01_address(rl); 9918 DECODE_PRINTF("\n"); 9919 destval = fetch_data_byte(destoffset); 9920 TRACE_AND_STEP(); 9921 destval = not_byte(destval); 9922 store_data_byte(destoffset, destval); 9923 break; 9924 case 3: 9925 DECODE_PRINTF("NEG\tBYTE PTR "); 9926 destoffset = decode_rm01_address(rl); 9927 DECODE_PRINTF("\n"); 9928 destval = fetch_data_byte(destoffset); 9929 TRACE_AND_STEP(); 9930 destval = neg_byte(destval); 9931 store_data_byte(destoffset, destval); 9932 break; 9933 case 4: 9934 DECODE_PRINTF("MUL\tBYTE PTR "); 9935 destoffset = decode_rm01_address(rl); 9936 DECODE_PRINTF("\n"); 9937 destval = fetch_data_byte(destoffset); 9938 TRACE_AND_STEP(); 9939 mul_byte(destval); 9940 break; 9941 case 5: 9942 DECODE_PRINTF("IMUL\tBYTE PTR "); 9943 destoffset = decode_rm01_address(rl); 9944 DECODE_PRINTF("\n"); 9945 destval = fetch_data_byte(destoffset); 9946 TRACE_AND_STEP(); 9947 imul_byte(destval); 9948 break; 9949 case 6: 9950 DECODE_PRINTF("DIV\tBYTE PTR "); 9951 destoffset = decode_rm01_address(rl); 9952 DECODE_PRINTF("\n"); 9953 destval = fetch_data_byte(destoffset); 9954 TRACE_AND_STEP(); 9955 div_byte(destval); 9956 break; 9957 case 7: 9958 DECODE_PRINTF("IDIV\tBYTE PTR "); 9959 destoffset = decode_rm01_address(rl); 9960 DECODE_PRINTF("\n"); 9961 destval = fetch_data_byte(destoffset); 9962 TRACE_AND_STEP(); 9963 idiv_byte(destval); 9964 break; 9965 } 9966 break; /* end mod==01 */ 9967 case 2: /* mod=10 */ 9968 switch (rh) { 9969 case 0: /* test byte imm */ 9970 DECODE_PRINTF("TEST\tBYTE PTR "); 9971 destoffset = decode_rm10_address(rl); 9972 DECODE_PRINTF(","); 9973 srcval = fetch_byte_imm(); 9974 DECODE_PRINTF2("%02x\n", srcval); 9975 destval = fetch_data_byte(destoffset); 9976 TRACE_AND_STEP(); 9977 test_byte(destval, srcval); 9978 break; 9979 case 1: 9980 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 9981 HALT_SYS(); 9982 break; 9983 case 2: 9984 DECODE_PRINTF("NOT\tBYTE PTR "); 9985 destoffset = decode_rm10_address(rl); 9986 DECODE_PRINTF("\n"); 9987 destval = fetch_data_byte(destoffset); 9988 TRACE_AND_STEP(); 9989 destval = not_byte(destval); 9990 store_data_byte(destoffset, destval); 9991 break; 9992 case 3: 9993 DECODE_PRINTF("NEG\tBYTE PTR "); 9994 destoffset = decode_rm10_address(rl); 9995 DECODE_PRINTF("\n"); 9996 destval = fetch_data_byte(destoffset); 9997 TRACE_AND_STEP(); 9998 destval = neg_byte(destval); 9999 store_data_byte(destoffset, destval); 10000 break; 10001 case 4: 10002 DECODE_PRINTF("MUL\tBYTE PTR "); 10003 destoffset = decode_rm10_address(rl); 10004 DECODE_PRINTF("\n"); 10005 destval = fetch_data_byte(destoffset); 10006 TRACE_AND_STEP(); 10007 mul_byte(destval); 10008 break; 10009 case 5: 10010 DECODE_PRINTF("IMUL\tBYTE PTR "); 10011 destoffset = decode_rm10_address(rl); 10012 DECODE_PRINTF("\n"); 10013 destval = fetch_data_byte(destoffset); 10014 TRACE_AND_STEP(); 10015 imul_byte(destval); 10016 break; 10017 case 6: 10018 DECODE_PRINTF("DIV\tBYTE PTR "); 10019 destoffset = decode_rm10_address(rl); 10020 DECODE_PRINTF("\n"); 10021 destval = fetch_data_byte(destoffset); 10022 TRACE_AND_STEP(); 10023 div_byte(destval); 10024 break; 10025 case 7: 10026 DECODE_PRINTF("IDIV\tBYTE PTR "); 10027 destoffset = decode_rm10_address(rl); 10028 DECODE_PRINTF("\n"); 10029 destval = fetch_data_byte(destoffset); 10030 TRACE_AND_STEP(); 10031 idiv_byte(destval); 10032 break; 10033 } 10034 break; /* end mod==10 */ 10035 case 3: /* mod=11 */ 10036 switch (rh) { 10037 case 0: /* test byte imm */ 10038 DECODE_PRINTF("TEST\t"); 10039 destreg = DECODE_RM_BYTE_REGISTER(rl); 10040 DECODE_PRINTF(","); 10041 srcval = fetch_byte_imm(); 10042 DECODE_PRINTF2("%02x\n", srcval); 10043 TRACE_AND_STEP(); 10044 test_byte(*destreg, srcval); 10045 break; 10046 case 1: 10047 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10048 HALT_SYS(); 10049 break; 10050 case 2: 10051 DECODE_PRINTF("NOT\t"); 10052 destreg = DECODE_RM_BYTE_REGISTER(rl); 10053 DECODE_PRINTF("\n"); 10054 TRACE_AND_STEP(); 10055 *destreg = not_byte(*destreg); 10056 break; 10057 case 3: 10058 DECODE_PRINTF("NEG\t"); 10059 destreg = DECODE_RM_BYTE_REGISTER(rl); 10060 DECODE_PRINTF("\n"); 10061 TRACE_AND_STEP(); 10062 *destreg = neg_byte(*destreg); 10063 break; 10064 case 4: 10065 DECODE_PRINTF("MUL\t"); 10066 destreg = DECODE_RM_BYTE_REGISTER(rl); 10067 DECODE_PRINTF("\n"); 10068 TRACE_AND_STEP(); 10069 mul_byte(*destreg); /*!!! */ 10070 break; 10071 case 5: 10072 DECODE_PRINTF("IMUL\t"); 10073 destreg = DECODE_RM_BYTE_REGISTER(rl); 10074 DECODE_PRINTF("\n"); 10075 TRACE_AND_STEP(); 10076 imul_byte(*destreg); 10077 break; 10078 case 6: 10079 DECODE_PRINTF("DIV\t"); 10080 destreg = DECODE_RM_BYTE_REGISTER(rl); 10081 DECODE_PRINTF("\n"); 10082 TRACE_AND_STEP(); 10083 div_byte(*destreg); 10084 break; 10085 case 7: 10086 DECODE_PRINTF("IDIV\t"); 10087 destreg = DECODE_RM_BYTE_REGISTER(rl); 10088 DECODE_PRINTF("\n"); 10089 TRACE_AND_STEP(); 10090 idiv_byte(*destreg); 10091 break; 10092 } 10093 break; /* end mod==11 */ 10094 } 10095 DECODE_CLEAR_SEGOVR(); 10096 END_OF_INSTR(); 10097} 10098 10099/**************************************************************************** 10100REMARKS: 10101Handles opcode 0xf7 10102****************************************************************************/ 10103void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 10104{ 10105 int mod, rl, rh; 10106 uint destoffset; 10107 10108 /* long, drawn out code follows. Double switch for a total 10109 of 32 cases. */ 10110 START_OF_INSTR(); 10111 FETCH_DECODE_MODRM(mod, rh, rl); 10112 switch (mod) { 10113 case 0: /* mod=00 */ 10114 switch (rh) { 10115 case 0: /* test word imm */ 10116 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10117 u32 destval,srcval; 10118 10119 DECODE_PRINTF("TEST\tDWORD PTR "); 10120 destoffset = decode_rm00_address(rl); 10121 DECODE_PRINTF(","); 10122 srcval = fetch_long_imm(); 10123 DECODE_PRINTF2("%x\n", srcval); 10124 destval = fetch_data_long(destoffset); 10125 TRACE_AND_STEP(); 10126 test_long(destval, srcval); 10127 } else { 10128 u16 destval,srcval; 10129 10130 DECODE_PRINTF("TEST\tWORD PTR "); 10131 destoffset = decode_rm00_address(rl); 10132 DECODE_PRINTF(","); 10133 srcval = fetch_word_imm(); 10134 DECODE_PRINTF2("%x\n", srcval); 10135 destval = fetch_data_word(destoffset); 10136 TRACE_AND_STEP(); 10137 test_word(destval, srcval); 10138 } 10139 break; 10140 case 1: 10141 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 10142 HALT_SYS(); 10143 break; 10144 case 2: 10145 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10146 u32 destval; 10147 10148 DECODE_PRINTF("NOT\tDWORD PTR "); 10149 destoffset = decode_rm00_address(rl); 10150 DECODE_PRINTF("\n"); 10151 destval = fetch_data_long(destoffset); 10152 TRACE_AND_STEP(); 10153 destval = not_long(destval); 10154 store_data_long(destoffset, destval); 10155 } else { 10156 u16 destval; 10157 10158 DECODE_PRINTF("NOT\tWORD PTR "); 10159 destoffset = decode_rm00_address(rl); 10160 DECODE_PRINTF("\n"); 10161 destval = fetch_data_word(destoffset); 10162 TRACE_AND_STEP(); 10163 destval = not_word(destval); 10164 store_data_word(destoffset, destval); 10165 } 10166 break; 10167 case 3: 10168 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10169 u32 destval; 10170 10171 DECODE_PRINTF("NEG\tDWORD PTR "); 10172 destoffset = decode_rm00_address(rl); 10173 DECODE_PRINTF("\n"); 10174 destval = fetch_data_long(destoffset); 10175 TRACE_AND_STEP(); 10176 destval = neg_long(destval); 10177 store_data_long(destoffset, destval); 10178 } else { 10179 u16 destval; 10180 10181 DECODE_PRINTF("NEG\tWORD PTR "); 10182 destoffset = decode_rm00_address(rl); 10183 DECODE_PRINTF("\n"); 10184 destval = fetch_data_word(destoffset); 10185 TRACE_AND_STEP(); 10186 destval = neg_word(destval); 10187 store_data_word(destoffset, destval); 10188 } 10189 break; 10190 case 4: 10191 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10192 u32 destval; 10193 10194 DECODE_PRINTF("MUL\tDWORD PTR "); 10195 destoffset = decode_rm00_address(rl); 10196 DECODE_PRINTF("\n"); 10197 destval = fetch_data_long(destoffset); 10198 TRACE_AND_STEP(); 10199 mul_long(destval); 10200 } else { 10201 u16 destval; 10202 10203 DECODE_PRINTF("MUL\tWORD PTR "); 10204 destoffset = decode_rm00_address(rl); 10205 DECODE_PRINTF("\n"); 10206 destval = fetch_data_word(destoffset); 10207 TRACE_AND_STEP(); 10208 mul_word(destval); 10209 } 10210 break; 10211 case 5: 10212 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10213 u32 destval; 10214 10215 DECODE_PRINTF("IMUL\tDWORD PTR "); 10216 destoffset = decode_rm00_address(rl); 10217 DECODE_PRINTF("\n"); 10218 destval = fetch_data_long(destoffset); 10219 TRACE_AND_STEP(); 10220 imul_long(destval); 10221 } else { 10222 u16 destval; 10223 10224 DECODE_PRINTF("IMUL\tWORD PTR "); 10225 destoffset = decode_rm00_address(rl); 10226 DECODE_PRINTF("\n"); 10227 destval = fetch_data_word(destoffset); 10228 TRACE_AND_STEP(); 10229 imul_word(destval); 10230 } 10231 break; 10232 case 6: 10233 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10234 u32 destval; 10235 10236 DECODE_PRINTF("DIV\tDWORD PTR "); 10237 destoffset = decode_rm00_address(rl); 10238 DECODE_PRINTF("\n"); 10239 destval = fetch_data_long(destoffset); 10240 TRACE_AND_STEP(); 10241 div_long(destval); 10242 } else { 10243 u16 destval; 10244 10245 DECODE_PRINTF("DIV\tWORD PTR "); 10246 destoffset = decode_rm00_address(rl); 10247 DECODE_PRINTF("\n"); 10248 destval = fetch_data_word(destoffset); 10249 TRACE_AND_STEP(); 10250 div_word(destval); 10251 } 10252 break; 10253 case 7: 10254 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10255 u32 destval; 10256 10257 DECODE_PRINTF("IDIV\tDWORD PTR "); 10258 destoffset = decode_rm00_address(rl); 10259 DECODE_PRINTF("\n"); 10260 destval = fetch_data_long(destoffset); 10261 TRACE_AND_STEP(); 10262 idiv_long(destval); 10263 } else { 10264 u16 destval; 10265 10266 DECODE_PRINTF("IDIV\tWORD PTR "); 10267 destoffset = decode_rm00_address(rl); 10268 DECODE_PRINTF("\n"); 10269 destval = fetch_data_word(destoffset); 10270 TRACE_AND_STEP(); 10271 idiv_word(destval); 10272 } 10273 break; 10274 } 10275 break; /* end mod==00 */ 10276 case 1: /* mod=01 */ 10277 switch (rh) { 10278 case 0: /* test word imm */ 10279 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10280 u32 destval,srcval; 10281 10282 DECODE_PRINTF("TEST\tDWORD PTR "); 10283 destoffset = decode_rm01_address(rl); 10284 DECODE_PRINTF(","); 10285 srcval = fetch_long_imm(); 10286 DECODE_PRINTF2("%x\n", srcval); 10287 destval = fetch_data_long(destoffset); 10288 TRACE_AND_STEP(); 10289 test_long(destval, srcval); 10290 } else { 10291 u16 destval,srcval; 10292 10293 DECODE_PRINTF("TEST\tWORD PTR "); 10294 destoffset = decode_rm01_address(rl); 10295 DECODE_PRINTF(","); 10296 srcval = fetch_word_imm(); 10297 DECODE_PRINTF2("%x\n", srcval); 10298 destval = fetch_data_word(destoffset); 10299 TRACE_AND_STEP(); 10300 test_word(destval, srcval); 10301 } 10302 break; 10303 case 1: 10304 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n"); 10305 HALT_SYS(); 10306 break; 10307 case 2: 10308 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10309 u32 destval; 10310 10311 DECODE_PRINTF("NOT\tDWORD PTR "); 10312 destoffset = decode_rm01_address(rl); 10313 DECODE_PRINTF("\n"); 10314 destval = fetch_data_long(destoffset); 10315 TRACE_AND_STEP(); 10316 destval = not_long(destval); 10317 store_data_long(destoffset, destval); 10318 } else { 10319 u16 destval; 10320 10321 DECODE_PRINTF("NOT\tWORD PTR "); 10322 destoffset = decode_rm01_address(rl); 10323 DECODE_PRINTF("\n"); 10324 destval = fetch_data_word(destoffset); 10325 TRACE_AND_STEP(); 10326 destval = not_word(destval); 10327 store_data_word(destoffset, destval); 10328 } 10329 break; 10330 case 3: 10331 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10332 u32 destval; 10333 10334 DECODE_PRINTF("NEG\tDWORD PTR "); 10335 destoffset = decode_rm01_address(rl); 10336 DECODE_PRINTF("\n"); 10337 destval = fetch_data_long(destoffset); 10338 TRACE_AND_STEP(); 10339 destval = neg_long(destval); 10340 store_data_long(destoffset, destval); 10341 } else { 10342 u16 destval; 10343 10344 DECODE_PRINTF("NEG\tWORD PTR "); 10345 destoffset = decode_rm01_address(rl); 10346 DECODE_PRINTF("\n"); 10347 destval = fetch_data_word(destoffset); 10348 TRACE_AND_STEP(); 10349 destval = neg_word(destval); 10350 store_data_word(destoffset, destval); 10351 } 10352 break; 10353 case 4: 10354 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10355 u32 destval; 10356 10357 DECODE_PRINTF("MUL\tDWORD PTR "); 10358 destoffset = decode_rm01_address(rl); 10359 DECODE_PRINTF("\n"); 10360 destval = fetch_data_long(destoffset); 10361 TRACE_AND_STEP(); 10362 mul_long(destval); 10363 } else { 10364 u16 destval; 10365 10366 DECODE_PRINTF("MUL\tWORD PTR "); 10367 destoffset = decode_rm01_address(rl); 10368 DECODE_PRINTF("\n"); 10369 destval = fetch_data_word(destoffset); 10370 TRACE_AND_STEP(); 10371 mul_word(destval); 10372 } 10373 break; 10374 case 5: 10375 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10376 u32 destval; 10377 10378 DECODE_PRINTF("IMUL\tDWORD PTR "); 10379 destoffset = decode_rm01_address(rl); 10380 DECODE_PRINTF("\n"); 10381 destval = fetch_data_long(destoffset); 10382 TRACE_AND_STEP(); 10383 imul_long(destval); 10384 } else { 10385 u16 destval; 10386 10387 DECODE_PRINTF("IMUL\tWORD PTR "); 10388 destoffset = decode_rm01_address(rl); 10389 DECODE_PRINTF("\n"); 10390 destval = fetch_data_word(destoffset); 10391 TRACE_AND_STEP(); 10392 imul_word(destval); 10393 } 10394 break; 10395 case 6: 10396 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10397 u32 destval; 10398 10399 DECODE_PRINTF("DIV\tDWORD PTR "); 10400 destoffset = decode_rm01_address(rl); 10401 DECODE_PRINTF("\n"); 10402 destval = fetch_data_long(destoffset); 10403 TRACE_AND_STEP(); 10404 div_long(destval); 10405 } else { 10406 u16 destval; 10407 10408 DECODE_PRINTF("DIV\tWORD PTR "); 10409 destoffset = decode_rm01_address(rl); 10410 DECODE_PRINTF("\n"); 10411 destval = fetch_data_word(destoffset); 10412 TRACE_AND_STEP(); 10413 div_word(destval); 10414 } 10415 break; 10416 case 7: 10417 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10418 u32 destval; 10419 10420 DECODE_PRINTF("IDIV\tDWORD PTR "); 10421 destoffset = decode_rm01_address(rl); 10422 DECODE_PRINTF("\n"); 10423 destval = fetch_data_long(destoffset); 10424 TRACE_AND_STEP(); 10425 idiv_long(destval); 10426 } else { 10427 u16 destval; 10428 10429 DECODE_PRINTF("IDIV\tWORD PTR "); 10430 destoffset = decode_rm01_address(rl); 10431 DECODE_PRINTF("\n"); 10432 destval = fetch_data_word(destoffset); 10433 TRACE_AND_STEP(); 10434 idiv_word(destval); 10435 } 10436 break; 10437 } 10438 break; /* end mod==01 */ 10439 case 2: /* mod=10 */ 10440 switch (rh) { 10441 case 0: /* test word imm */ 10442 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10443 u32 destval,srcval; 10444 10445 DECODE_PRINTF("TEST\tDWORD PTR "); 10446 destoffset = decode_rm10_address(rl); 10447 DECODE_PRINTF(","); 10448 srcval = fetch_long_imm(); 10449 DECODE_PRINTF2("%x\n", srcval); 10450 destval = fetch_data_long(destoffset); 10451 TRACE_AND_STEP(); 10452 test_long(destval, srcval); 10453 } else { 10454 u16 destval,srcval; 10455 10456 DECODE_PRINTF("TEST\tWORD PTR "); 10457 destoffset = decode_rm10_address(rl); 10458 DECODE_PRINTF(","); 10459 srcval = fetch_word_imm(); 10460 DECODE_PRINTF2("%x\n", srcval); 10461 destval = fetch_data_word(destoffset); 10462 TRACE_AND_STEP(); 10463 test_word(destval, srcval); 10464 } 10465 break; 10466 case 1: 10467 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n"); 10468 HALT_SYS(); 10469 break; 10470 case 2: 10471 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10472 u32 destval; 10473 10474 DECODE_PRINTF("NOT\tDWORD PTR "); 10475 destoffset = decode_rm10_address(rl); 10476 DECODE_PRINTF("\n"); 10477 destval = fetch_data_long(destoffset); 10478 TRACE_AND_STEP(); 10479 destval = not_long(destval); 10480 store_data_long(destoffset, destval); 10481 } else { 10482 u16 destval; 10483 10484 DECODE_PRINTF("NOT\tWORD PTR "); 10485 destoffset = decode_rm10_address(rl); 10486 DECODE_PRINTF("\n"); 10487 destval = fetch_data_word(destoffset); 10488 TRACE_AND_STEP(); 10489 destval = not_word(destval); 10490 store_data_word(destoffset, destval); 10491 } 10492 break; 10493 case 3: 10494 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10495 u32 destval; 10496 10497 DECODE_PRINTF("NEG\tDWORD PTR "); 10498 destoffset = decode_rm10_address(rl); 10499 DECODE_PRINTF("\n"); 10500 destval = fetch_data_long(destoffset); 10501 TRACE_AND_STEP(); 10502 destval = neg_long(destval); 10503 store_data_long(destoffset, destval); 10504 } else { 10505 u16 destval; 10506 10507 DECODE_PRINTF("NEG\tWORD PTR "); 10508 destoffset = decode_rm10_address(rl); 10509 DECODE_PRINTF("\n"); 10510 destval = fetch_data_word(destoffset); 10511 TRACE_AND_STEP(); 10512 destval = neg_word(destval); 10513 store_data_word(destoffset, destval); 10514 } 10515 break; 10516 case 4: 10517 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10518 u32 destval; 10519 10520 DECODE_PRINTF("MUL\tDWORD PTR "); 10521 destoffset = decode_rm10_address(rl); 10522 DECODE_PRINTF("\n"); 10523 destval = fetch_data_long(destoffset); 10524 TRACE_AND_STEP(); 10525 mul_long(destval); 10526 } else { 10527 u16 destval; 10528 10529 DECODE_PRINTF("MUL\tWORD PTR "); 10530 destoffset = decode_rm10_address(rl); 10531 DECODE_PRINTF("\n"); 10532 destval = fetch_data_word(destoffset); 10533 TRACE_AND_STEP(); 10534 mul_word(destval); 10535 } 10536 break; 10537 case 5: 10538 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10539 u32 destval; 10540 10541 DECODE_PRINTF("IMUL\tDWORD PTR "); 10542 destoffset = decode_rm10_address(rl); 10543 DECODE_PRINTF("\n"); 10544 destval = fetch_data_long(destoffset); 10545 TRACE_AND_STEP(); 10546 imul_long(destval); 10547 } else { 10548 u16 destval; 10549 10550 DECODE_PRINTF("IMUL\tWORD PTR "); 10551 destoffset = decode_rm10_address(rl); 10552 DECODE_PRINTF("\n"); 10553 destval = fetch_data_word(destoffset); 10554 TRACE_AND_STEP(); 10555 imul_word(destval); 10556 } 10557 break; 10558 case 6: 10559 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10560 u32 destval; 10561 10562 DECODE_PRINTF("DIV\tDWORD PTR "); 10563 destoffset = decode_rm10_address(rl); 10564 DECODE_PRINTF("\n"); 10565 destval = fetch_data_long(destoffset); 10566 TRACE_AND_STEP(); 10567 div_long(destval); 10568 } else { 10569 u16 destval; 10570 10571 DECODE_PRINTF("DIV\tWORD PTR "); 10572 destoffset = decode_rm10_address(rl); 10573 DECODE_PRINTF("\n"); 10574 destval = fetch_data_word(destoffset); 10575 TRACE_AND_STEP(); 10576 div_word(destval); 10577 } 10578 break; 10579 case 7: 10580 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10581 u32 destval; 10582 10583 DECODE_PRINTF("IDIV\tDWORD PTR "); 10584 destoffset = decode_rm10_address(rl); 10585 DECODE_PRINTF("\n"); 10586 destval = fetch_data_long(destoffset); 10587 TRACE_AND_STEP(); 10588 idiv_long(destval); 10589 } else { 10590 u16 destval; 10591 10592 DECODE_PRINTF("IDIV\tWORD PTR "); 10593 destoffset = decode_rm10_address(rl); 10594 DECODE_PRINTF("\n"); 10595 destval = fetch_data_word(destoffset); 10596 TRACE_AND_STEP(); 10597 idiv_word(destval); 10598 } 10599 break; 10600 } 10601 break; /* end mod==10 */ 10602 case 3: /* mod=11 */ 10603 switch (rh) { 10604 case 0: /* test word imm */ 10605 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10606 u32 *destreg; 10607 u32 srcval; 10608 10609 DECODE_PRINTF("TEST\t"); 10610 destreg = DECODE_RM_LONG_REGISTER(rl); 10611 DECODE_PRINTF(","); 10612 srcval = fetch_long_imm(); 10613 DECODE_PRINTF2("%x\n", srcval); 10614 TRACE_AND_STEP(); 10615 test_long(*destreg, srcval); 10616 } else { 10617 u16 *destreg; 10618 u16 srcval; 10619 10620 DECODE_PRINTF("TEST\t"); 10621 destreg = DECODE_RM_WORD_REGISTER(rl); 10622 DECODE_PRINTF(","); 10623 srcval = fetch_word_imm(); 10624 DECODE_PRINTF2("%x\n", srcval); 10625 TRACE_AND_STEP(); 10626 test_word(*destreg, srcval); 10627 } 10628 break; 10629 case 1: 10630 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 10631 HALT_SYS(); 10632 break; 10633 case 2: 10634 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10635 u32 *destreg; 10636 10637 DECODE_PRINTF("NOT\t"); 10638 destreg = DECODE_RM_LONG_REGISTER(rl); 10639 DECODE_PRINTF("\n"); 10640 TRACE_AND_STEP(); 10641 *destreg = not_long(*destreg); 10642 } else { 10643 u16 *destreg; 10644 10645 DECODE_PRINTF("NOT\t"); 10646 destreg = DECODE_RM_WORD_REGISTER(rl); 10647 DECODE_PRINTF("\n"); 10648 TRACE_AND_STEP(); 10649 *destreg = not_word(*destreg); 10650 } 10651 break; 10652 case 3: 10653 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10654 u32 *destreg; 10655 10656 DECODE_PRINTF("NEG\t"); 10657 destreg = DECODE_RM_LONG_REGISTER(rl); 10658 DECODE_PRINTF("\n"); 10659 TRACE_AND_STEP(); 10660 *destreg = neg_long(*destreg); 10661 } else { 10662 u16 *destreg; 10663 10664 DECODE_PRINTF("NEG\t"); 10665 destreg = DECODE_RM_WORD_REGISTER(rl); 10666 DECODE_PRINTF("\n"); 10667 TRACE_AND_STEP(); 10668 *destreg = neg_word(*destreg); 10669 } 10670 break; 10671 case 4: 10672 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10673 u32 *destreg; 10674 10675 DECODE_PRINTF("MUL\t"); 10676 destreg = DECODE_RM_LONG_REGISTER(rl); 10677 DECODE_PRINTF("\n"); 10678 TRACE_AND_STEP(); 10679 mul_long(*destreg); /*!!! */ 10680 } else { 10681 u16 *destreg; 10682 10683 DECODE_PRINTF("MUL\t"); 10684 destreg = DECODE_RM_WORD_REGISTER(rl); 10685 DECODE_PRINTF("\n"); 10686 TRACE_AND_STEP(); 10687 mul_word(*destreg); /*!!! */ 10688 } 10689 break; 10690 case 5: 10691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10692 u32 *destreg; 10693 10694 DECODE_PRINTF("IMUL\t"); 10695 destreg = DECODE_RM_LONG_REGISTER(rl); 10696 DECODE_PRINTF("\n"); 10697 TRACE_AND_STEP(); 10698 imul_long(*destreg); 10699 } else { 10700 u16 *destreg; 10701 10702 DECODE_PRINTF("IMUL\t"); 10703 destreg = DECODE_RM_WORD_REGISTER(rl); 10704 DECODE_PRINTF("\n"); 10705 TRACE_AND_STEP(); 10706 imul_word(*destreg); 10707 } 10708 break; 10709 case 6: 10710 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10711 u32 *destreg; 10712 10713 DECODE_PRINTF("DIV\t"); 10714 destreg = DECODE_RM_LONG_REGISTER(rl); 10715 DECODE_PRINTF("\n"); 10716 TRACE_AND_STEP(); 10717 div_long(*destreg); 10718 } else { 10719 u16 *destreg; 10720 10721 DECODE_PRINTF("DIV\t"); 10722 destreg = DECODE_RM_WORD_REGISTER(rl); 10723 DECODE_PRINTF("\n"); 10724 TRACE_AND_STEP(); 10725 div_word(*destreg); 10726 } 10727 break; 10728 case 7: 10729 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10730 u32 *destreg; 10731 10732 DECODE_PRINTF("IDIV\t"); 10733 destreg = DECODE_RM_LONG_REGISTER(rl); 10734 DECODE_PRINTF("\n"); 10735 TRACE_AND_STEP(); 10736 idiv_long(*destreg); 10737 } else { 10738 u16 *destreg; 10739 10740 DECODE_PRINTF("IDIV\t"); 10741 destreg = DECODE_RM_WORD_REGISTER(rl); 10742 DECODE_PRINTF("\n"); 10743 TRACE_AND_STEP(); 10744 idiv_word(*destreg); 10745 } 10746 break; 10747 } 10748 break; /* end mod==11 */ 10749 } 10750 DECODE_CLEAR_SEGOVR(); 10751 END_OF_INSTR(); 10752} 10753 10754/**************************************************************************** 10755REMARKS: 10756Handles opcode 0xf8 10757****************************************************************************/ 10758void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 10759{ 10760 /* clear the carry flag. */ 10761 START_OF_INSTR(); 10762 DECODE_PRINTF("CLC\n"); 10763 TRACE_AND_STEP(); 10764 CLEAR_FLAG(F_CF); 10765 DECODE_CLEAR_SEGOVR(); 10766 END_OF_INSTR(); 10767} 10768 10769/**************************************************************************** 10770REMARKS: 10771Handles opcode 0xf9 10772****************************************************************************/ 10773void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 10774{ 10775 /* set the carry flag. */ 10776 START_OF_INSTR(); 10777 DECODE_PRINTF("STC\n"); 10778 TRACE_AND_STEP(); 10779 SET_FLAG(F_CF); 10780 DECODE_CLEAR_SEGOVR(); 10781 END_OF_INSTR(); 10782} 10783 10784/**************************************************************************** 10785REMARKS: 10786Handles opcode 0xfa 10787****************************************************************************/ 10788void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 10789{ 10790 /* clear interrupts. */ 10791 START_OF_INSTR(); 10792 DECODE_PRINTF("CLI\n"); 10793 TRACE_AND_STEP(); 10794 CLEAR_FLAG(F_IF); 10795 DECODE_CLEAR_SEGOVR(); 10796 END_OF_INSTR(); 10797} 10798 10799/**************************************************************************** 10800REMARKS: 10801Handles opcode 0xfb 10802****************************************************************************/ 10803void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 10804{ 10805 /* enable interrupts. */ 10806 START_OF_INSTR(); 10807 DECODE_PRINTF("STI\n"); 10808 TRACE_AND_STEP(); 10809 SET_FLAG(F_IF); 10810 DECODE_CLEAR_SEGOVR(); 10811 END_OF_INSTR(); 10812} 10813 10814/**************************************************************************** 10815REMARKS: 10816Handles opcode 0xfc 10817****************************************************************************/ 10818void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 10819{ 10820 /* clear interrupts. */ 10821 START_OF_INSTR(); 10822 DECODE_PRINTF("CLD\n"); 10823 TRACE_AND_STEP(); 10824 CLEAR_FLAG(F_DF); 10825 DECODE_CLEAR_SEGOVR(); 10826 END_OF_INSTR(); 10827} 10828 10829/**************************************************************************** 10830REMARKS: 10831Handles opcode 0xfd 10832****************************************************************************/ 10833void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 10834{ 10835 /* clear interrupts. */ 10836 START_OF_INSTR(); 10837 DECODE_PRINTF("STD\n"); 10838 TRACE_AND_STEP(); 10839 SET_FLAG(F_DF); 10840 DECODE_CLEAR_SEGOVR(); 10841 END_OF_INSTR(); 10842} 10843 10844/**************************************************************************** 10845REMARKS: 10846Handles opcode 0xfe 10847****************************************************************************/ 10848void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 10849{ 10850 int mod, rh, rl; 10851 u8 destval; 10852 uint destoffset; 10853 u8 *destreg; 10854 10855 /* Yet another special case instruction. */ 10856 START_OF_INSTR(); 10857 FETCH_DECODE_MODRM(mod, rh, rl); 10858#ifdef DEBUG 10859 if (DEBUG_DECODE()) { 10860 10861 switch (rh) { 10862 case 0: 10863 DECODE_PRINTF("INC\t"); 10864 break; 10865 case 1: 10866 DECODE_PRINTF("DEC\t"); 10867 break; 10868 case 2: 10869 case 3: 10870 case 4: 10871 case 5: 10872 case 6: 10873 case 7: 10874 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 10875 HALT_SYS(); 10876 break; 10877 } 10878 } 10879#endif 10880 switch (mod) { 10881 case 0: 10882 DECODE_PRINTF("BYTE PTR "); 10883 destoffset = decode_rm00_address(rl); 10884 DECODE_PRINTF("\n"); 10885 switch (rh) { 10886 case 0: /* inc word ptr ... */ 10887 destval = fetch_data_byte(destoffset); 10888 TRACE_AND_STEP(); 10889 destval = inc_byte(destval); 10890 store_data_byte(destoffset, destval); 10891 break; 10892 case 1: /* dec word ptr ... */ 10893 destval = fetch_data_byte(destoffset); 10894 TRACE_AND_STEP(); 10895 destval = dec_byte(destval); 10896 store_data_byte(destoffset, destval); 10897 break; 10898 } 10899 break; 10900 case 1: 10901 DECODE_PRINTF("BYTE PTR "); 10902 destoffset = decode_rm01_address(rl); 10903 DECODE_PRINTF("\n"); 10904 switch (rh) { 10905 case 0: 10906 destval = fetch_data_byte(destoffset); 10907 TRACE_AND_STEP(); 10908 destval = inc_byte(destval); 10909 store_data_byte(destoffset, destval); 10910 break; 10911 case 1: 10912 destval = fetch_data_byte(destoffset); 10913 TRACE_AND_STEP(); 10914 destval = dec_byte(destval); 10915 store_data_byte(destoffset, destval); 10916 break; 10917 } 10918 break; 10919 case 2: 10920 DECODE_PRINTF("BYTE PTR "); 10921 destoffset = decode_rm10_address(rl); 10922 DECODE_PRINTF("\n"); 10923 switch (rh) { 10924 case 0: 10925 destval = fetch_data_byte(destoffset); 10926 TRACE_AND_STEP(); 10927 destval = inc_byte(destval); 10928 store_data_byte(destoffset, destval); 10929 break; 10930 case 1: 10931 destval = fetch_data_byte(destoffset); 10932 TRACE_AND_STEP(); 10933 destval = dec_byte(destval); 10934 store_data_byte(destoffset, destval); 10935 break; 10936 } 10937 break; 10938 case 3: 10939 destreg = DECODE_RM_BYTE_REGISTER(rl); 10940 DECODE_PRINTF("\n"); 10941 switch (rh) { 10942 case 0: 10943 TRACE_AND_STEP(); 10944 *destreg = inc_byte(*destreg); 10945 break; 10946 case 1: 10947 TRACE_AND_STEP(); 10948 *destreg = dec_byte(*destreg); 10949 break; 10950 } 10951 break; 10952 } 10953 DECODE_CLEAR_SEGOVR(); 10954 END_OF_INSTR(); 10955} 10956 10957/**************************************************************************** 10958REMARKS: 10959Handles opcode 0xff 10960****************************************************************************/ 10961void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 10962{ 10963 int mod, rh, rl; 10964 uint destoffset = 0; 10965 u16 *destreg; 10966 u16 destval,destval2; 10967 10968 /* Yet another special case instruction. */ 10969 START_OF_INSTR(); 10970 FETCH_DECODE_MODRM(mod, rh, rl); 10971#ifdef DEBUG 10972 if (DEBUG_DECODE()) { 10973 10974 switch (rh) { 10975 case 0: 10976 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10977 DECODE_PRINTF("INC\tDWORD PTR "); 10978 } else { 10979 DECODE_PRINTF("INC\tWORD PTR "); 10980 } 10981 break; 10982 case 1: 10983 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 10984 DECODE_PRINTF("DEC\tDWORD PTR "); 10985 } else { 10986 DECODE_PRINTF("DEC\tWORD PTR "); 10987 } 10988 break; 10989 case 2: 10990 DECODE_PRINTF("CALL\t "); 10991 break; 10992 case 3: 10993 DECODE_PRINTF("CALL\tFAR "); 10994 break; 10995 case 4: 10996 DECODE_PRINTF("JMP\t"); 10997 break; 10998 case 5: 10999 DECODE_PRINTF("JMP\tFAR "); 11000 break; 11001 case 6: 11002 DECODE_PRINTF("PUSH\t"); 11003 break; 11004 case 7: 11005 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 11006 HALT_SYS(); 11007 break; 11008 } 11009 } 11010#endif 11011 switch (mod) { 11012 case 0: 11013 destoffset = decode_rm00_address(rl); 11014 DECODE_PRINTF("\n"); 11015 switch (rh) { 11016 case 0: /* inc word ptr ... */ 11017 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11018 u32 destval; 11019 11020 destval = fetch_data_long(destoffset); 11021 TRACE_AND_STEP(); 11022 destval = inc_long(destval); 11023 store_data_long(destoffset, destval); 11024 } else { 11025 u16 destval; 11026 11027 destval = fetch_data_word(destoffset); 11028 TRACE_AND_STEP(); 11029 destval = inc_word(destval); 11030 store_data_word(destoffset, destval); 11031 } 11032 break; 11033 case 1: /* dec word ptr ... */ 11034 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11035 u32 destval; 11036 11037 destval = fetch_data_long(destoffset); 11038 TRACE_AND_STEP(); 11039 destval = dec_long(destval); 11040 store_data_long(destoffset, destval); 11041 } else { 11042 u16 destval; 11043 11044 destval = fetch_data_word(destoffset); 11045 TRACE_AND_STEP(); 11046 destval = dec_word(destval); 11047 store_data_word(destoffset, destval); 11048 } 11049 break; 11050 case 2: /* call word ptr ... */ 11051 destval = fetch_data_word(destoffset); 11052 TRACE_AND_STEP(); 11053 push_word(M.x86.R_IP); 11054 M.x86.R_IP = destval; 11055 break; 11056 case 3: /* call far ptr ... */ 11057 destval = fetch_data_word(destoffset); 11058 destval2 = fetch_data_word(destoffset + 2); 11059 TRACE_AND_STEP(); 11060 push_word(M.x86.R_CS); 11061 M.x86.R_CS = destval2; 11062 push_word(M.x86.R_IP); 11063 M.x86.R_IP = destval; 11064 break; 11065 case 4: /* jmp word ptr ... */ 11066 destval = fetch_data_word(destoffset); 11067 TRACE_AND_STEP(); 11068 M.x86.R_IP = destval; 11069 break; 11070 case 5: /* jmp far ptr ... */ 11071 destval = fetch_data_word(destoffset); 11072 destval2 = fetch_data_word(destoffset + 2); 11073 TRACE_AND_STEP(); 11074 M.x86.R_IP = destval; 11075 M.x86.R_CS = destval2; 11076 break; 11077 case 6: /* push word ptr ... */ 11078 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11079 u32 destval; 11080 11081 destval = fetch_data_long(destoffset); 11082 TRACE_AND_STEP(); 11083 push_long(destval); 11084 } else { 11085 u16 destval; 11086 11087 destval = fetch_data_word(destoffset); 11088 TRACE_AND_STEP(); 11089 push_word(destval); 11090 } 11091 break; 11092 } 11093 break; 11094 case 1: 11095 destoffset = decode_rm01_address(rl); 11096 DECODE_PRINTF("\n"); 11097 switch (rh) { 11098 case 0: 11099 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11100 u32 destval; 11101 11102 destval = fetch_data_long(destoffset); 11103 TRACE_AND_STEP(); 11104 destval = inc_long(destval); 11105 store_data_long(destoffset, destval); 11106 } else { 11107 u16 destval; 11108 11109 destval = fetch_data_word(destoffset); 11110 TRACE_AND_STEP(); 11111 destval = inc_word(destval); 11112 store_data_word(destoffset, destval); 11113 } 11114 break; 11115 case 1: 11116 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11117 u32 destval; 11118 11119 destval = fetch_data_long(destoffset); 11120 TRACE_AND_STEP(); 11121 destval = dec_long(destval); 11122 store_data_long(destoffset, destval); 11123 } else { 11124 u16 destval; 11125 11126 destval = fetch_data_word(destoffset); 11127 TRACE_AND_STEP(); 11128 destval = dec_word(destval); 11129 store_data_word(destoffset, destval); 11130 } 11131 break; 11132 case 2: /* call word ptr ... */ 11133 destval = fetch_data_word(destoffset); 11134 TRACE_AND_STEP(); 11135 push_word(M.x86.R_IP); 11136 M.x86.R_IP = destval; 11137 break; 11138 case 3: /* call far ptr ... */ 11139 destval = fetch_data_word(destoffset); 11140 destval2 = fetch_data_word(destoffset + 2); 11141 TRACE_AND_STEP(); 11142 push_word(M.x86.R_CS); 11143 M.x86.R_CS = destval2; 11144 push_word(M.x86.R_IP); 11145 M.x86.R_IP = destval; 11146 break; 11147 case 4: /* jmp word ptr ... */ 11148 destval = fetch_data_word(destoffset); 11149 TRACE_AND_STEP(); 11150 M.x86.R_IP = destval; 11151 break; 11152 case 5: /* jmp far ptr ... */ 11153 destval = fetch_data_word(destoffset); 11154 destval2 = fetch_data_word(destoffset + 2); 11155 TRACE_AND_STEP(); 11156 M.x86.R_IP = destval; 11157 M.x86.R_CS = destval2; 11158 break; 11159 case 6: /* push word ptr ... */ 11160 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11161 u32 destval; 11162 11163 destval = fetch_data_long(destoffset); 11164 TRACE_AND_STEP(); 11165 push_long(destval); 11166 } else { 11167 u16 destval; 11168 11169 destval = fetch_data_word(destoffset); 11170 TRACE_AND_STEP(); 11171 push_word(destval); 11172 } 11173 break; 11174 } 11175 break; 11176 case 2: 11177 destoffset = decode_rm10_address(rl); 11178 DECODE_PRINTF("\n"); 11179 switch (rh) { 11180 case 0: 11181 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11182 u32 destval; 11183 11184 destval = fetch_data_long(destoffset); 11185 TRACE_AND_STEP(); 11186 destval = inc_long(destval); 11187 store_data_long(destoffset, destval); 11188 } else { 11189 u16 destval; 11190 11191 destval = fetch_data_word(destoffset); 11192 TRACE_AND_STEP(); 11193 destval = inc_word(destval); 11194 store_data_word(destoffset, destval); 11195 } 11196 break; 11197 case 1: 11198 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11199 u32 destval; 11200 11201 destval = fetch_data_long(destoffset); 11202 TRACE_AND_STEP(); 11203 destval = dec_long(destval); 11204 store_data_long(destoffset, destval); 11205 } else { 11206 u16 destval; 11207 11208 destval = fetch_data_word(destoffset); 11209 TRACE_AND_STEP(); 11210 destval = dec_word(destval); 11211 store_data_word(destoffset, destval); 11212 } 11213 break; 11214 case 2: /* call word ptr ... */ 11215 destval = fetch_data_word(destoffset); 11216 TRACE_AND_STEP(); 11217 push_word(M.x86.R_IP); 11218 M.x86.R_IP = destval; 11219 break; 11220 case 3: /* call far ptr ... */ 11221 destval = fetch_data_word(destoffset); 11222 destval2 = fetch_data_word(destoffset + 2); 11223 TRACE_AND_STEP(); 11224 push_word(M.x86.R_CS); 11225 M.x86.R_CS = destval2; 11226 push_word(M.x86.R_IP); 11227 M.x86.R_IP = destval; 11228 break; 11229 case 4: /* jmp word ptr ... */ 11230 destval = fetch_data_word(destoffset); 11231 TRACE_AND_STEP(); 11232 M.x86.R_IP = destval; 11233 break; 11234 case 5: /* jmp far ptr ... */ 11235 destval = fetch_data_word(destoffset); 11236 destval2 = fetch_data_word(destoffset + 2); 11237 TRACE_AND_STEP(); 11238 M.x86.R_IP = destval; 11239 M.x86.R_CS = destval2; 11240 break; 11241 case 6: /* push word ptr ... */ 11242 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11243 u32 destval; 11244 11245 destval = fetch_data_long(destoffset); 11246 TRACE_AND_STEP(); 11247 push_long(destval); 11248 } else { 11249 u16 destval; 11250 11251 destval = fetch_data_word(destoffset); 11252 TRACE_AND_STEP(); 11253 push_word(destval); 11254 } 11255 break; 11256 } 11257 break; 11258 case 3: 11259 switch (rh) { 11260 case 0: 11261 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11262 u32 *destreg; 11263 11264 destreg = DECODE_RM_LONG_REGISTER(rl); 11265 DECODE_PRINTF("\n"); 11266 TRACE_AND_STEP(); 11267 *destreg = inc_long(*destreg); 11268 } else { 11269 u16 *destreg; 11270 11271 destreg = DECODE_RM_WORD_REGISTER(rl); 11272 DECODE_PRINTF("\n"); 11273 TRACE_AND_STEP(); 11274 *destreg = inc_word(*destreg); 11275 } 11276 break; 11277 case 1: 11278 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11279 u32 *destreg; 11280 11281 destreg = DECODE_RM_LONG_REGISTER(rl); 11282 DECODE_PRINTF("\n"); 11283 TRACE_AND_STEP(); 11284 *destreg = dec_long(*destreg); 11285 } else { 11286 u16 *destreg; 11287 11288 destreg = DECODE_RM_WORD_REGISTER(rl); 11289 DECODE_PRINTF("\n"); 11290 TRACE_AND_STEP(); 11291 *destreg = dec_word(*destreg); 11292 } 11293 break; 11294 case 2: /* call word ptr ... */ 11295 destreg = DECODE_RM_WORD_REGISTER(rl); 11296 DECODE_PRINTF("\n"); 11297 TRACE_AND_STEP(); 11298 push_word(M.x86.R_IP); 11299 M.x86.R_IP = *destreg; 11300 break; 11301 case 3: /* jmp far ptr ... */ 11302 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11303 TRACE_AND_STEP(); 11304 HALT_SYS(); 11305 break; 11306 11307 case 4: /* jmp ... */ 11308 destreg = DECODE_RM_WORD_REGISTER(rl); 11309 DECODE_PRINTF("\n"); 11310 TRACE_AND_STEP(); 11311 M.x86.R_IP = (u16) (*destreg); 11312 break; 11313 case 5: /* jmp far ptr ... */ 11314 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 11315 TRACE_AND_STEP(); 11316 HALT_SYS(); 11317 break; 11318 case 6: 11319 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 11320 u32 *destreg; 11321 11322 destreg = DECODE_RM_LONG_REGISTER(rl); 11323 DECODE_PRINTF("\n"); 11324 TRACE_AND_STEP(); 11325 push_long(*destreg); 11326 } else { 11327 u16 *destreg; 11328 11329 destreg = DECODE_RM_WORD_REGISTER(rl); 11330 DECODE_PRINTF("\n"); 11331 TRACE_AND_STEP(); 11332 push_word(*destreg); 11333 } 11334 break; 11335 } 11336 break; 11337 } 11338 DECODE_CLEAR_SEGOVR(); 11339 END_OF_INSTR(); 11340} 11341 11342/*************************************************************************** 11343 * Single byte operation code table: 11344 **************************************************************************/ 11345void (*x86emu_optab[256])(u8) = 11346{ 11347/* 0x00 */ x86emuOp_add_byte_RM_R, 11348/* 0x01 */ x86emuOp_add_word_RM_R, 11349/* 0x02 */ x86emuOp_add_byte_R_RM, 11350/* 0x03 */ x86emuOp_add_word_R_RM, 11351/* 0x04 */ x86emuOp_add_byte_AL_IMM, 11352/* 0x05 */ x86emuOp_add_word_AX_IMM, 11353/* 0x06 */ x86emuOp_push_ES, 11354/* 0x07 */ x86emuOp_pop_ES, 11355 11356/* 0x08 */ x86emuOp_or_byte_RM_R, 11357/* 0x09 */ x86emuOp_or_word_RM_R, 11358/* 0x0a */ x86emuOp_or_byte_R_RM, 11359/* 0x0b */ x86emuOp_or_word_R_RM, 11360/* 0x0c */ x86emuOp_or_byte_AL_IMM, 11361/* 0x0d */ x86emuOp_or_word_AX_IMM, 11362/* 0x0e */ x86emuOp_push_CS, 11363/* 0x0f */ x86emuOp_two_byte, 11364 11365/* 0x10 */ x86emuOp_adc_byte_RM_R, 11366/* 0x11 */ x86emuOp_adc_word_RM_R, 11367/* 0x12 */ x86emuOp_adc_byte_R_RM, 11368/* 0x13 */ x86emuOp_adc_word_R_RM, 11369/* 0x14 */ x86emuOp_adc_byte_AL_IMM, 11370/* 0x15 */ x86emuOp_adc_word_AX_IMM, 11371/* 0x16 */ x86emuOp_push_SS, 11372/* 0x17 */ x86emuOp_pop_SS, 11373 11374/* 0x18 */ x86emuOp_sbb_byte_RM_R, 11375/* 0x19 */ x86emuOp_sbb_word_RM_R, 11376/* 0x1a */ x86emuOp_sbb_byte_R_RM, 11377/* 0x1b */ x86emuOp_sbb_word_R_RM, 11378/* 0x1c */ x86emuOp_sbb_byte_AL_IMM, 11379/* 0x1d */ x86emuOp_sbb_word_AX_IMM, 11380/* 0x1e */ x86emuOp_push_DS, 11381/* 0x1f */ x86emuOp_pop_DS, 11382 11383/* 0x20 */ x86emuOp_and_byte_RM_R, 11384/* 0x21 */ x86emuOp_and_word_RM_R, 11385/* 0x22 */ x86emuOp_and_byte_R_RM, 11386/* 0x23 */ x86emuOp_and_word_R_RM, 11387/* 0x24 */ x86emuOp_and_byte_AL_IMM, 11388/* 0x25 */ x86emuOp_and_word_AX_IMM, 11389/* 0x26 */ x86emuOp_segovr_ES, 11390/* 0x27 */ x86emuOp_daa, 11391 11392/* 0x28 */ x86emuOp_sub_byte_RM_R, 11393/* 0x29 */ x86emuOp_sub_word_RM_R, 11394/* 0x2a */ x86emuOp_sub_byte_R_RM, 11395/* 0x2b */ x86emuOp_sub_word_R_RM, 11396/* 0x2c */ x86emuOp_sub_byte_AL_IMM, 11397/* 0x2d */ x86emuOp_sub_word_AX_IMM, 11398/* 0x2e */ x86emuOp_segovr_CS, 11399/* 0x2f */ x86emuOp_das, 11400 11401/* 0x30 */ x86emuOp_xor_byte_RM_R, 11402/* 0x31 */ x86emuOp_xor_word_RM_R, 11403/* 0x32 */ x86emuOp_xor_byte_R_RM, 11404/* 0x33 */ x86emuOp_xor_word_R_RM, 11405/* 0x34 */ x86emuOp_xor_byte_AL_IMM, 11406/* 0x35 */ x86emuOp_xor_word_AX_IMM, 11407/* 0x36 */ x86emuOp_segovr_SS, 11408/* 0x37 */ x86emuOp_aaa, 11409 11410/* 0x38 */ x86emuOp_cmp_byte_RM_R, 11411/* 0x39 */ x86emuOp_cmp_word_RM_R, 11412/* 0x3a */ x86emuOp_cmp_byte_R_RM, 11413/* 0x3b */ x86emuOp_cmp_word_R_RM, 11414/* 0x3c */ x86emuOp_cmp_byte_AL_IMM, 11415/* 0x3d */ x86emuOp_cmp_word_AX_IMM, 11416/* 0x3e */ x86emuOp_segovr_DS, 11417/* 0x3f */ x86emuOp_aas, 11418 11419/* 0x40 */ x86emuOp_inc_AX, 11420/* 0x41 */ x86emuOp_inc_CX, 11421/* 0x42 */ x86emuOp_inc_DX, 11422/* 0x43 */ x86emuOp_inc_BX, 11423/* 0x44 */ x86emuOp_inc_SP, 11424/* 0x45 */ x86emuOp_inc_BP, 11425/* 0x46 */ x86emuOp_inc_SI, 11426/* 0x47 */ x86emuOp_inc_DI, 11427 11428/* 0x48 */ x86emuOp_dec_AX, 11429/* 0x49 */ x86emuOp_dec_CX, 11430/* 0x4a */ x86emuOp_dec_DX, 11431/* 0x4b */ x86emuOp_dec_BX, 11432/* 0x4c */ x86emuOp_dec_SP, 11433/* 0x4d */ x86emuOp_dec_BP, 11434/* 0x4e */ x86emuOp_dec_SI, 11435/* 0x4f */ x86emuOp_dec_DI, 11436 11437/* 0x50 */ x86emuOp_push_AX, 11438/* 0x51 */ x86emuOp_push_CX, 11439/* 0x52 */ x86emuOp_push_DX, 11440/* 0x53 */ x86emuOp_push_BX, 11441/* 0x54 */ x86emuOp_push_SP, 11442/* 0x55 */ x86emuOp_push_BP, 11443/* 0x56 */ x86emuOp_push_SI, 11444/* 0x57 */ x86emuOp_push_DI, 11445 11446/* 0x58 */ x86emuOp_pop_AX, 11447/* 0x59 */ x86emuOp_pop_CX, 11448/* 0x5a */ x86emuOp_pop_DX, 11449/* 0x5b */ x86emuOp_pop_BX, 11450/* 0x5c */ x86emuOp_pop_SP, 11451/* 0x5d */ x86emuOp_pop_BP, 11452/* 0x5e */ x86emuOp_pop_SI, 11453/* 0x5f */ x86emuOp_pop_DI, 11454 11455/* 0x60 */ x86emuOp_push_all, 11456/* 0x61 */ x86emuOp_pop_all, 11457/* 0x62 */ x86emuOp_illegal_op, /* bound */ 11458/* 0x63 */ x86emuOp_illegal_op, /* arpl */ 11459/* 0x64 */ x86emuOp_segovr_FS, 11460/* 0x65 */ x86emuOp_segovr_GS, 11461/* 0x66 */ x86emuOp_prefix_data, 11462/* 0x67 */ x86emuOp_prefix_addr, 11463 11464/* 0x68 */ x86emuOp_push_word_IMM, 11465/* 0x69 */ x86emuOp_imul_word_IMM, 11466/* 0x6a */ x86emuOp_push_byte_IMM, 11467/* 0x6b */ x86emuOp_imul_byte_IMM, 11468/* 0x6c */ x86emuOp_ins_byte, 11469/* 0x6d */ x86emuOp_ins_word, 11470/* 0x6e */ x86emuOp_outs_byte, 11471/* 0x6f */ x86emuOp_outs_word, 11472 11473/* 0x70 */ x86emuOp_jump_near_O, 11474/* 0x71 */ x86emuOp_jump_near_NO, 11475/* 0x72 */ x86emuOp_jump_near_B, 11476/* 0x73 */ x86emuOp_jump_near_NB, 11477/* 0x74 */ x86emuOp_jump_near_Z, 11478/* 0x75 */ x86emuOp_jump_near_NZ, 11479/* 0x76 */ x86emuOp_jump_near_BE, 11480/* 0x77 */ x86emuOp_jump_near_NBE, 11481 11482/* 0x78 */ x86emuOp_jump_near_S, 11483/* 0x79 */ x86emuOp_jump_near_NS, 11484/* 0x7a */ x86emuOp_jump_near_P, 11485/* 0x7b */ x86emuOp_jump_near_NP, 11486/* 0x7c */ x86emuOp_jump_near_L, 11487/* 0x7d */ x86emuOp_jump_near_NL, 11488/* 0x7e */ x86emuOp_jump_near_LE, 11489/* 0x7f */ x86emuOp_jump_near_NLE, 11490 11491/* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 11492/* 0x81 */ x86emuOp_opc81_word_RM_IMM, 11493/* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 11494/* 0x83 */ x86emuOp_opc83_word_RM_IMM, 11495/* 0x84 */ x86emuOp_test_byte_RM_R, 11496/* 0x85 */ x86emuOp_test_word_RM_R, 11497/* 0x86 */ x86emuOp_xchg_byte_RM_R, 11498/* 0x87 */ x86emuOp_xchg_word_RM_R, 11499 11500/* 0x88 */ x86emuOp_mov_byte_RM_R, 11501/* 0x89 */ x86emuOp_mov_word_RM_R, 11502/* 0x8a */ x86emuOp_mov_byte_R_RM, 11503/* 0x8b */ x86emuOp_mov_word_R_RM, 11504/* 0x8c */ x86emuOp_mov_word_RM_SR, 11505/* 0x8d */ x86emuOp_lea_word_R_M, 11506/* 0x8e */ x86emuOp_mov_word_SR_RM, 11507/* 0x8f */ x86emuOp_pop_RM, 11508 11509/* 0x90 */ x86emuOp_nop, 11510/* 0x91 */ x86emuOp_xchg_word_AX_CX, 11511/* 0x92 */ x86emuOp_xchg_word_AX_DX, 11512/* 0x93 */ x86emuOp_xchg_word_AX_BX, 11513/* 0x94 */ x86emuOp_xchg_word_AX_SP, 11514/* 0x95 */ x86emuOp_xchg_word_AX_BP, 11515/* 0x96 */ x86emuOp_xchg_word_AX_SI, 11516/* 0x97 */ x86emuOp_xchg_word_AX_DI, 11517 11518/* 0x98 */ x86emuOp_cbw, 11519/* 0x99 */ x86emuOp_cwd, 11520/* 0x9a */ x86emuOp_call_far_IMM, 11521/* 0x9b */ x86emuOp_wait, 11522/* 0x9c */ x86emuOp_pushf_word, 11523/* 0x9d */ x86emuOp_popf_word, 11524/* 0x9e */ x86emuOp_sahf, 11525/* 0x9f */ x86emuOp_lahf, 11526 11527/* 0xa0 */ x86emuOp_mov_AL_M_IMM, 11528/* 0xa1 */ x86emuOp_mov_AX_M_IMM, 11529/* 0xa2 */ x86emuOp_mov_M_AL_IMM, 11530/* 0xa3 */ x86emuOp_mov_M_AX_IMM, 11531/* 0xa4 */ x86emuOp_movs_byte, 11532/* 0xa5 */ x86emuOp_movs_word, 11533/* 0xa6 */ x86emuOp_cmps_byte, 11534/* 0xa7 */ x86emuOp_cmps_word, 11535/* 0xa8 */ x86emuOp_test_AL_IMM, 11536/* 0xa9 */ x86emuOp_test_AX_IMM, 11537/* 0xaa */ x86emuOp_stos_byte, 11538/* 0xab */ x86emuOp_stos_word, 11539/* 0xac */ x86emuOp_lods_byte, 11540/* 0xad */ x86emuOp_lods_word, 11541/* 0xac */ x86emuOp_scas_byte, 11542/* 0xad */ x86emuOp_scas_word, 11543 11544 11545/* 0xb0 */ x86emuOp_mov_byte_AL_IMM, 11546/* 0xb1 */ x86emuOp_mov_byte_CL_IMM, 11547/* 0xb2 */ x86emuOp_mov_byte_DL_IMM, 11548/* 0xb3 */ x86emuOp_mov_byte_BL_IMM, 11549/* 0xb4 */ x86emuOp_mov_byte_AH_IMM, 11550/* 0xb5 */ x86emuOp_mov_byte_CH_IMM, 11551/* 0xb6 */ x86emuOp_mov_byte_DH_IMM, 11552/* 0xb7 */ x86emuOp_mov_byte_BH_IMM, 11553 11554/* 0xb8 */ x86emuOp_mov_word_AX_IMM, 11555/* 0xb9 */ x86emuOp_mov_word_CX_IMM, 11556/* 0xba */ x86emuOp_mov_word_DX_IMM, 11557/* 0xbb */ x86emuOp_mov_word_BX_IMM, 11558/* 0xbc */ x86emuOp_mov_word_SP_IMM, 11559/* 0xbd */ x86emuOp_mov_word_BP_IMM, 11560/* 0xbe */ x86emuOp_mov_word_SI_IMM, 11561/* 0xbf */ x86emuOp_mov_word_DI_IMM, 11562 11563/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 11564/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 11565/* 0xc2 */ x86emuOp_ret_near_IMM, 11566/* 0xc3 */ x86emuOp_ret_near, 11567/* 0xc4 */ x86emuOp_les_R_IMM, 11568/* 0xc5 */ x86emuOp_lds_R_IMM, 11569/* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 11570/* 0xc7 */ x86emuOp_mov_word_RM_IMM, 11571/* 0xc8 */ x86emuOp_enter, 11572/* 0xc9 */ x86emuOp_leave, 11573/* 0xca */ x86emuOp_ret_far_IMM, 11574/* 0xcb */ x86emuOp_ret_far, 11575/* 0xcc */ x86emuOp_int3, 11576/* 0xcd */ x86emuOp_int_IMM, 11577/* 0xce */ x86emuOp_into, 11578/* 0xcf */ x86emuOp_iret, 11579 11580/* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 11581/* 0xd1 */ x86emuOp_opcD1_word_RM_1, 11582/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 11583/* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 11584/* 0xd4 */ x86emuOp_aam, 11585/* 0xd5 */ x86emuOp_aad, 11586/* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 11587/* 0xd7 */ x86emuOp_xlat, 11588/* 0xd8 */ x86emuOp_esc_coprocess_d8, 11589/* 0xd9 */ x86emuOp_esc_coprocess_d9, 11590/* 0xda */ x86emuOp_esc_coprocess_da, 11591/* 0xdb */ x86emuOp_esc_coprocess_db, 11592/* 0xdc */ x86emuOp_esc_coprocess_dc, 11593/* 0xdd */ x86emuOp_esc_coprocess_dd, 11594/* 0xde */ x86emuOp_esc_coprocess_de, 11595/* 0xdf */ x86emuOp_esc_coprocess_df, 11596 11597/* 0xe0 */ x86emuOp_loopne, 11598/* 0xe1 */ x86emuOp_loope, 11599/* 0xe2 */ x86emuOp_loop, 11600/* 0xe3 */ x86emuOp_jcxz, 11601/* 0xe4 */ x86emuOp_in_byte_AL_IMM, 11602/* 0xe5 */ x86emuOp_in_word_AX_IMM, 11603/* 0xe6 */ x86emuOp_out_byte_IMM_AL, 11604/* 0xe7 */ x86emuOp_out_word_IMM_AX, 11605 11606/* 0xe8 */ x86emuOp_call_near_IMM, 11607/* 0xe9 */ x86emuOp_jump_near_IMM, 11608/* 0xea */ x86emuOp_jump_far_IMM, 11609/* 0xeb */ x86emuOp_jump_byte_IMM, 11610/* 0xec */ x86emuOp_in_byte_AL_DX, 11611/* 0xed */ x86emuOp_in_word_AX_DX, 11612/* 0xee */ x86emuOp_out_byte_DX_AL, 11613/* 0xef */ x86emuOp_out_word_DX_AX, 11614 11615/* 0xf0 */ x86emuOp_lock, 11616/* 0xf1 */ x86emuOp_illegal_op, 11617/* 0xf2 */ x86emuOp_repne, 11618/* 0xf3 */ x86emuOp_repe, 11619/* 0xf4 */ x86emuOp_halt, 11620/* 0xf5 */ x86emuOp_cmc, 11621/* 0xf6 */ x86emuOp_opcF6_byte_RM, 11622/* 0xf7 */ x86emuOp_opcF7_word_RM, 11623 11624/* 0xf8 */ x86emuOp_clc, 11625/* 0xf9 */ x86emuOp_stc, 11626/* 0xfa */ x86emuOp_cli, 11627/* 0xfb */ x86emuOp_sti, 11628/* 0xfc */ x86emuOp_cld, 11629/* 0xfd */ x86emuOp_std, 11630/* 0xfe */ x86emuOp_opcFE_byte_RM, 11631/* 0xff */ x86emuOp_opcFF_word_RM, 11632}; 11633