1 /**************************************************************************** 2 * Realmode X86 Emulator Library 3 * 4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. 5 * Jason Jin <Jason.jin@freescale.com> 6 * 7 * Copyright (C) 1991-2004 SciTech Software, Inc. 8 * Copyright (C) David Mosberger-Tang 9 * Copyright (C) 1999 Egbert Eich 10 * 11 * ======================================================================== 12 * 13 * Permission to use, copy, modify, distribute, and sell this software and 14 * its documentation for any purpose is hereby granted without fee, 15 * provided that the above copyright notice appear in all copies and that 16 * both that copyright notice and this permission notice appear in 17 * supporting documentation, and that the name of the authors not be used 18 * in advertising or publicity pertaining to distribution of the software 19 * without specific, written prior permission. The authors makes no 20 * representations about the suitability of this software for any purpose. 21 * It is provided "as is" without express or implied warranty. 22 * 23 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 24 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 25 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 26 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 27 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 28 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 29 * PERFORMANCE OF THIS SOFTWARE. 30 * 31 * ======================================================================== 32 * 33 * Language: ANSI C 34 * Environment: Any 35 * Developer: Kendall Bennett 36 * 37 * Description: This file includes subroutines to implement the decoding 38 * and emulation of all the x86 processor instructions. 39 * 40 * There are approximately 250 subroutines in here, which correspond 41 * to the 256 byte-"opcodes" found on the 8086. The table which 42 * dispatches this is found in the files optab.[ch]. 43 * 44 * Each opcode proc has a comment preceeding it which gives it's table 45 * address. Several opcodes are missing (undefined) in the table. 46 * 47 * Each proc includes information for decoding (DECODE_PRINTF and 48 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc 49 * functions (START_OF_INSTR, END_OF_INSTR). 50 * 51 * Many of the procedures are *VERY* similar in coding. This has 52 * allowed for a very large amount of code to be generated in a fairly 53 * short amount of time (i.e. cut, paste, and modify). The result is 54 * that much of the code below could have been folded into subroutines 55 * for a large reduction in size of this file. The downside would be 56 * that there would be a penalty in execution speed. The file could 57 * also have been *MUCH* larger by inlining certain functions which 58 * were called. This could have resulted even faster execution. The 59 * prime directive I used to decide whether to inline the code or to 60 * modularize it, was basically: 1) no unnecessary subroutine calls, 61 * 2) no routines more than about 200 lines in size, and 3) modularize 62 * any code that I might not get right the first time. The fetch_* 63 * subroutines fall into the latter category. The The decode_* fall 64 * into the second category. The coding of the "switch(mod){ .... }" 65 * in many of the subroutines below falls into the first category. 66 * Especially, the coding of {add,and,or,sub,...}_{byte,word} 67 * subroutines are an especially glaring case of the third guideline. 68 * Since so much of the code is cloned from other modules (compare 69 * opcode #00 to opcode #01), making the basic operations subroutine 70 * calls is especially important; otherwise mistakes in coding an 71 * "add" would represent a nightmare in maintenance. 72 * 73 * Jason ported this file to u-boot. place all the function pointer in 74 * the got2 sector. Removed some opcode. 75 * 76 ****************************************************************************/ 77 78 #include <common.h> 79 #include "x86emu/x86emui.h" 80 81 /*----------------------------- Implementation ----------------------------*/ 82 83 /* constant arrays to do several instructions in just one function */ 84 85 #ifdef DEBUG 86 static char *x86emu_GenOpName[8] = { 87 "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"}; 88 #endif 89 90 /* used by several opcodes */ 91 static u8 (*genop_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) = 92 { 93 add_byte, /* 00 */ 94 or_byte, /* 01 */ 95 adc_byte, /* 02 */ 96 sbb_byte, /* 03 */ 97 and_byte, /* 04 */ 98 sub_byte, /* 05 */ 99 xor_byte, /* 06 */ 100 cmp_byte, /* 07 */ 101 }; 102 103 static u16 (*genop_word_operation[])(u16 d, u16 s) __attribute__ ((section(GOT2_TYPE))) = 104 { 105 add_word, /*00 */ 106 or_word, /*01 */ 107 adc_word, /*02 */ 108 sbb_word, /*03 */ 109 and_word, /*04 */ 110 sub_word, /*05 */ 111 xor_word, /*06 */ 112 cmp_word, /*07 */ 113 }; 114 115 static u32 (*genop_long_operation[])(u32 d, u32 s) __attribute__ ((section(GOT2_TYPE))) = 116 { 117 add_long, /*00 */ 118 or_long, /*01 */ 119 adc_long, /*02 */ 120 sbb_long, /*03 */ 121 and_long, /*04 */ 122 sub_long, /*05 */ 123 xor_long, /*06 */ 124 cmp_long, /*07 */ 125 }; 126 127 /* used by opcodes 80, c0, d0, and d2. */ 128 static u8(*opcD0_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) = 129 { 130 rol_byte, 131 ror_byte, 132 rcl_byte, 133 rcr_byte, 134 shl_byte, 135 shr_byte, 136 shl_byte, /* sal_byte === shl_byte by definition */ 137 sar_byte, 138 }; 139 140 /* used by opcodes c1, d1, and d3. */ 141 static u16(*opcD1_word_operation[])(u16 s, u8 d) __attribute__ ((section(GOT2_TYPE))) = 142 { 143 rol_word, 144 ror_word, 145 rcl_word, 146 rcr_word, 147 shl_word, 148 shr_word, 149 shl_word, /* sal_byte === shl_byte by definition */ 150 sar_word, 151 }; 152 153 /* used by opcodes c1, d1, and d3. */ 154 static u32 (*opcD1_long_operation[])(u32 s, u8 d) __attribute__ ((section(GOT2_TYPE))) = 155 { 156 rol_long, 157 ror_long, 158 rcl_long, 159 rcr_long, 160 shl_long, 161 shr_long, 162 shl_long, /* sal_byte === shl_byte by definition */ 163 sar_long, 164 }; 165 166 #ifdef DEBUG 167 168 static char *opF6_names[8] = 169 { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" }; 170 171 #endif 172 173 /**************************************************************************** 174 PARAMETERS: 175 op1 - Instruction op code 176 177 REMARKS: 178 Handles illegal opcodes. 179 ****************************************************************************/ 180 void x86emuOp_illegal_op( 181 u8 op1) 182 { 183 START_OF_INSTR(); 184 if (M.x86.R_SP != 0) { 185 DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); 186 TRACE_REGS(); 187 DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", 188 M.x86.R_CS, M.x86.R_IP-1,op1)); 189 HALT_SYS(); 190 } 191 else { 192 /* If we get here, it means the stack pointer is back to zero 193 * so we are just returning from an emulator service call 194 * so therte is no need to display an error message. We trap 195 * the emulator with an 0xF1 opcode to finish the service 196 * call. 197 */ 198 X86EMU_halt_sys(); 199 } 200 END_OF_INSTR(); 201 } 202 203 /**************************************************************************** 204 REMARKS: 205 Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 206 ****************************************************************************/ 207 void x86emuOp_genop_byte_RM_R(u8 op1) 208 { 209 int mod, rl, rh; 210 uint destoffset; 211 u8 *destreg, *srcreg; 212 u8 destval; 213 214 op1 = (op1 >> 3) & 0x7; 215 216 START_OF_INSTR(); 217 DECODE_PRINTF(x86emu_GenOpName[op1]); 218 DECODE_PRINTF("\t"); 219 FETCH_DECODE_MODRM(mod, rh, rl); 220 if(mod<3) 221 { destoffset = decode_rmXX_address(mod,rl); 222 DECODE_PRINTF(","); 223 destval = fetch_data_byte(destoffset); 224 srcreg = DECODE_RM_BYTE_REGISTER(rh); 225 DECODE_PRINTF("\n"); 226 TRACE_AND_STEP(); 227 destval = genop_byte_operation[op1](destval, *srcreg); 228 store_data_byte(destoffset, destval); 229 } 230 else 231 { /* register to register */ 232 destreg = DECODE_RM_BYTE_REGISTER(rl); 233 DECODE_PRINTF(","); 234 srcreg = DECODE_RM_BYTE_REGISTER(rh); 235 DECODE_PRINTF("\n"); 236 TRACE_AND_STEP(); 237 *destreg = genop_byte_operation[op1](*destreg, *srcreg); 238 } 239 DECODE_CLEAR_SEGOVR(); 240 END_OF_INSTR(); 241 } 242 243 /**************************************************************************** 244 REMARKS: 245 Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39 246 ****************************************************************************/ 247 void x86emuOp_genop_word_RM_R(u8 op1) 248 { 249 int mod, rl, rh; 250 uint destoffset; 251 252 op1 = (op1 >> 3) & 0x7; 253 254 START_OF_INSTR(); 255 DECODE_PRINTF(x86emu_GenOpName[op1]); 256 DECODE_PRINTF("\t"); 257 FETCH_DECODE_MODRM(mod, rh, rl); 258 259 if(mod<3) { 260 destoffset = decode_rmXX_address(mod,rl); 261 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 262 u32 destval; 263 u32 *srcreg; 264 265 DECODE_PRINTF(","); 266 destval = fetch_data_long(destoffset); 267 srcreg = DECODE_RM_LONG_REGISTER(rh); 268 DECODE_PRINTF("\n"); 269 TRACE_AND_STEP(); 270 destval = genop_long_operation[op1](destval, *srcreg); 271 store_data_long(destoffset, destval); 272 } else { 273 u16 destval; 274 u16 *srcreg; 275 276 DECODE_PRINTF(","); 277 destval = fetch_data_word(destoffset); 278 srcreg = DECODE_RM_WORD_REGISTER(rh); 279 DECODE_PRINTF("\n"); 280 TRACE_AND_STEP(); 281 destval = genop_word_operation[op1](destval, *srcreg); 282 store_data_word(destoffset, destval); 283 } 284 } else { /* register to register */ 285 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 286 u32 *destreg,*srcreg; 287 288 destreg = DECODE_RM_LONG_REGISTER(rl); 289 DECODE_PRINTF(","); 290 srcreg = DECODE_RM_LONG_REGISTER(rh); 291 DECODE_PRINTF("\n"); 292 TRACE_AND_STEP(); 293 *destreg = genop_long_operation[op1](*destreg, *srcreg); 294 } else { 295 u16 *destreg,*srcreg; 296 297 destreg = DECODE_RM_WORD_REGISTER(rl); 298 DECODE_PRINTF(","); 299 srcreg = DECODE_RM_WORD_REGISTER(rh); 300 DECODE_PRINTF("\n"); 301 TRACE_AND_STEP(); 302 *destreg = genop_word_operation[op1](*destreg, *srcreg); 303 } 304 } 305 DECODE_CLEAR_SEGOVR(); 306 END_OF_INSTR(); 307 } 308 309 /**************************************************************************** 310 REMARKS: 311 Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a 312 ****************************************************************************/ 313 void x86emuOp_genop_byte_R_RM(u8 op1) 314 { 315 int mod, rl, rh; 316 u8 *destreg, *srcreg; 317 uint srcoffset; 318 u8 srcval; 319 320 op1 = (op1 >> 3) & 0x7; 321 322 START_OF_INSTR(); 323 DECODE_PRINTF(x86emu_GenOpName[op1]); 324 DECODE_PRINTF("\t"); 325 FETCH_DECODE_MODRM(mod, rh, rl); 326 if (mod < 3) { 327 destreg = DECODE_RM_BYTE_REGISTER(rh); 328 DECODE_PRINTF(","); 329 srcoffset = decode_rmXX_address(mod,rl); 330 srcval = fetch_data_byte(srcoffset); 331 } else { /* register to register */ 332 destreg = DECODE_RM_BYTE_REGISTER(rh); 333 DECODE_PRINTF(","); 334 srcreg = DECODE_RM_BYTE_REGISTER(rl); 335 srcval = *srcreg; 336 } 337 DECODE_PRINTF("\n"); 338 TRACE_AND_STEP(); 339 *destreg = genop_byte_operation[op1](*destreg, srcval); 340 341 DECODE_CLEAR_SEGOVR(); 342 END_OF_INSTR(); 343 } 344 345 /**************************************************************************** 346 REMARKS: 347 Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b 348 ****************************************************************************/ 349 void x86emuOp_genop_word_R_RM(u8 op1) 350 { 351 int mod, rl, rh; 352 uint srcoffset; 353 u32 *destreg32, srcval; 354 u16 *destreg; 355 356 op1 = (op1 >> 3) & 0x7; 357 358 START_OF_INSTR(); 359 DECODE_PRINTF(x86emu_GenOpName[op1]); 360 DECODE_PRINTF("\t"); 361 FETCH_DECODE_MODRM(mod, rh, rl); 362 if (mod < 3) { 363 srcoffset = decode_rmXX_address(mod,rl); 364 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 365 destreg32 = DECODE_RM_LONG_REGISTER(rh); 366 DECODE_PRINTF(","); 367 srcval = fetch_data_long(srcoffset); 368 DECODE_PRINTF("\n"); 369 TRACE_AND_STEP(); 370 *destreg32 = genop_long_operation[op1](*destreg32, srcval); 371 } else { 372 destreg = DECODE_RM_WORD_REGISTER(rh); 373 DECODE_PRINTF(","); 374 srcval = fetch_data_word(srcoffset); 375 DECODE_PRINTF("\n"); 376 TRACE_AND_STEP(); 377 *destreg = genop_word_operation[op1](*destreg, srcval); 378 } 379 } else { /* register to register */ 380 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 381 u32 *srcreg; 382 destreg32 = DECODE_RM_LONG_REGISTER(rh); 383 DECODE_PRINTF(","); 384 srcreg = DECODE_RM_LONG_REGISTER(rl); 385 DECODE_PRINTF("\n"); 386 TRACE_AND_STEP(); 387 *destreg32 = genop_long_operation[op1](*destreg32, *srcreg); 388 } else { 389 u16 *srcreg; 390 destreg = DECODE_RM_WORD_REGISTER(rh); 391 DECODE_PRINTF(","); 392 srcreg = DECODE_RM_WORD_REGISTER(rl); 393 DECODE_PRINTF("\n"); 394 TRACE_AND_STEP(); 395 *destreg = genop_word_operation[op1](*destreg, *srcreg); 396 } 397 } 398 DECODE_CLEAR_SEGOVR(); 399 END_OF_INSTR(); 400 } 401 402 /**************************************************************************** 403 REMARKS: 404 Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c 405 ****************************************************************************/ 406 void x86emuOp_genop_byte_AL_IMM(u8 op1) 407 { 408 u8 srcval; 409 410 op1 = (op1 >> 3) & 0x7; 411 412 START_OF_INSTR(); 413 DECODE_PRINTF(x86emu_GenOpName[op1]); 414 DECODE_PRINTF("\tAL,"); 415 srcval = fetch_byte_imm(); 416 DECODE_PRINTF2("%x\n", srcval); 417 TRACE_AND_STEP(); 418 M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval); 419 DECODE_CLEAR_SEGOVR(); 420 END_OF_INSTR(); 421 } 422 423 /**************************************************************************** 424 REMARKS: 425 Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d 426 ****************************************************************************/ 427 void x86emuOp_genop_word_AX_IMM(u8 op1) 428 { 429 u32 srcval; 430 431 op1 = (op1 >> 3) & 0x7; 432 433 START_OF_INSTR(); 434 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 435 DECODE_PRINTF(x86emu_GenOpName[op1]); 436 DECODE_PRINTF("\tEAX,"); 437 srcval = fetch_long_imm(); 438 } else { 439 DECODE_PRINTF(x86emu_GenOpName[op1]); 440 DECODE_PRINTF("\tAX,"); 441 srcval = fetch_word_imm(); 442 } 443 DECODE_PRINTF2("%x\n", srcval); 444 TRACE_AND_STEP(); 445 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 446 M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval); 447 } else { 448 M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval); 449 } 450 DECODE_CLEAR_SEGOVR(); 451 END_OF_INSTR(); 452 } 453 454 /**************************************************************************** 455 REMARKS: 456 Handles opcode 0x06 457 ****************************************************************************/ 458 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 459 { 460 START_OF_INSTR(); 461 DECODE_PRINTF("PUSH\tES\n"); 462 TRACE_AND_STEP(); 463 push_word(M.x86.R_ES); 464 DECODE_CLEAR_SEGOVR(); 465 END_OF_INSTR(); 466 } 467 468 /**************************************************************************** 469 REMARKS: 470 Handles opcode 0x07 471 ****************************************************************************/ 472 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 473 { 474 START_OF_INSTR(); 475 DECODE_PRINTF("POP\tES\n"); 476 TRACE_AND_STEP(); 477 M.x86.R_ES = pop_word(); 478 DECODE_CLEAR_SEGOVR(); 479 END_OF_INSTR(); 480 } 481 482 /**************************************************************************** 483 REMARKS: 484 Handles opcode 0x0e 485 ****************************************************************************/ 486 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 487 { 488 START_OF_INSTR(); 489 DECODE_PRINTF("PUSH\tCS\n"); 490 TRACE_AND_STEP(); 491 push_word(M.x86.R_CS); 492 DECODE_CLEAR_SEGOVR(); 493 END_OF_INSTR(); 494 } 495 496 /**************************************************************************** 497 REMARKS: 498 Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 499 ****************************************************************************/ 500 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 501 { 502 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 503 INC_DECODED_INST_LEN(1); 504 (*x86emu_optab2[op2])(op2); 505 } 506 507 /**************************************************************************** 508 REMARKS: 509 Handles opcode 0x16 510 ****************************************************************************/ 511 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 512 { 513 START_OF_INSTR(); 514 DECODE_PRINTF("PUSH\tSS\n"); 515 TRACE_AND_STEP(); 516 push_word(M.x86.R_SS); 517 DECODE_CLEAR_SEGOVR(); 518 END_OF_INSTR(); 519 } 520 521 /**************************************************************************** 522 REMARKS: 523 Handles opcode 0x17 524 ****************************************************************************/ 525 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 526 { 527 START_OF_INSTR(); 528 DECODE_PRINTF("POP\tSS\n"); 529 TRACE_AND_STEP(); 530 M.x86.R_SS = pop_word(); 531 DECODE_CLEAR_SEGOVR(); 532 END_OF_INSTR(); 533 } 534 535 /**************************************************************************** 536 REMARKS: 537 Handles opcode 0x1e 538 ****************************************************************************/ 539 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 540 { 541 START_OF_INSTR(); 542 DECODE_PRINTF("PUSH\tDS\n"); 543 TRACE_AND_STEP(); 544 push_word(M.x86.R_DS); 545 DECODE_CLEAR_SEGOVR(); 546 END_OF_INSTR(); 547 } 548 549 /**************************************************************************** 550 REMARKS: 551 Handles opcode 0x1f 552 ****************************************************************************/ 553 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 554 { 555 START_OF_INSTR(); 556 DECODE_PRINTF("POP\tDS\n"); 557 TRACE_AND_STEP(); 558 M.x86.R_DS = pop_word(); 559 DECODE_CLEAR_SEGOVR(); 560 END_OF_INSTR(); 561 } 562 563 /**************************************************************************** 564 REMARKS: 565 Handles opcode 0x26 566 ****************************************************************************/ 567 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 568 { 569 START_OF_INSTR(); 570 DECODE_PRINTF("ES:\n"); 571 TRACE_AND_STEP(); 572 M.x86.mode |= SYSMODE_SEGOVR_ES; 573 /* 574 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 575 * opcode subroutines we do not want to do this. 576 */ 577 END_OF_INSTR(); 578 } 579 580 /**************************************************************************** 581 REMARKS: 582 Handles opcode 0x27 583 ****************************************************************************/ 584 void x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 585 { 586 START_OF_INSTR(); 587 DECODE_PRINTF("DAA\n"); 588 TRACE_AND_STEP(); 589 M.x86.R_AL = daa_byte(M.x86.R_AL); 590 DECODE_CLEAR_SEGOVR(); 591 END_OF_INSTR(); 592 } 593 594 /**************************************************************************** 595 REMARKS: 596 Handles opcode 0x2e 597 ****************************************************************************/ 598 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 599 { 600 START_OF_INSTR(); 601 DECODE_PRINTF("CS:\n"); 602 TRACE_AND_STEP(); 603 M.x86.mode |= SYSMODE_SEGOVR_CS; 604 /* note no DECODE_CLEAR_SEGOVR here. */ 605 END_OF_INSTR(); 606 } 607 608 /**************************************************************************** 609 REMARKS: 610 Handles opcode 0x2f 611 ****************************************************************************/ 612 void x86emuOp_das(u8 X86EMU_UNUSED(op1)) 613 { 614 START_OF_INSTR(); 615 DECODE_PRINTF("DAS\n"); 616 TRACE_AND_STEP(); 617 M.x86.R_AL = das_byte(M.x86.R_AL); 618 DECODE_CLEAR_SEGOVR(); 619 END_OF_INSTR(); 620 } 621 622 /**************************************************************************** 623 REMARKS: 624 Handles opcode 0x36 625 ****************************************************************************/ 626 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 627 { 628 START_OF_INSTR(); 629 DECODE_PRINTF("SS:\n"); 630 TRACE_AND_STEP(); 631 M.x86.mode |= SYSMODE_SEGOVR_SS; 632 /* no DECODE_CLEAR_SEGOVR ! */ 633 END_OF_INSTR(); 634 } 635 636 /**************************************************************************** 637 REMARKS: 638 Handles opcode 0x37 639 ****************************************************************************/ 640 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 641 { 642 START_OF_INSTR(); 643 DECODE_PRINTF("AAA\n"); 644 TRACE_AND_STEP(); 645 M.x86.R_AX = aaa_word(M.x86.R_AX); 646 DECODE_CLEAR_SEGOVR(); 647 END_OF_INSTR(); 648 } 649 650 /**************************************************************************** 651 REMARKS: 652 Handles opcode 0x3e 653 ****************************************************************************/ 654 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 655 { 656 START_OF_INSTR(); 657 DECODE_PRINTF("DS:\n"); 658 TRACE_AND_STEP(); 659 M.x86.mode |= SYSMODE_SEGOVR_DS; 660 /* NO DECODE_CLEAR_SEGOVR! */ 661 END_OF_INSTR(); 662 } 663 664 /**************************************************************************** 665 REMARKS: 666 Handles opcode 0x3f 667 ****************************************************************************/ 668 void x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 669 { 670 START_OF_INSTR(); 671 DECODE_PRINTF("AAS\n"); 672 TRACE_AND_STEP(); 673 M.x86.R_AX = aas_word(M.x86.R_AX); 674 DECODE_CLEAR_SEGOVR(); 675 END_OF_INSTR(); 676 } 677 678 /**************************************************************************** 679 REMARKS: 680 Handles opcode 0x40 - 0x47 681 ****************************************************************************/ 682 void x86emuOp_inc_register(u8 op1) 683 { 684 START_OF_INSTR(); 685 op1 &= 0x7; 686 DECODE_PRINTF("INC\t"); 687 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 688 u32 *reg; 689 reg = DECODE_RM_LONG_REGISTER(op1); 690 DECODE_PRINTF("\n"); 691 TRACE_AND_STEP(); 692 *reg = inc_long(*reg); 693 } else { 694 u16 *reg; 695 reg = DECODE_RM_WORD_REGISTER(op1); 696 DECODE_PRINTF("\n"); 697 TRACE_AND_STEP(); 698 *reg = inc_word(*reg); 699 } 700 DECODE_CLEAR_SEGOVR(); 701 END_OF_INSTR(); 702 } 703 704 /**************************************************************************** 705 REMARKS: 706 Handles opcode 0x48 - 0x4F 707 ****************************************************************************/ 708 void x86emuOp_dec_register(u8 op1) 709 { 710 START_OF_INSTR(); 711 op1 &= 0x7; 712 DECODE_PRINTF("DEC\t"); 713 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 714 u32 *reg; 715 reg = DECODE_RM_LONG_REGISTER(op1); 716 DECODE_PRINTF("\n"); 717 TRACE_AND_STEP(); 718 *reg = dec_long(*reg); 719 } else { 720 u16 *reg; 721 reg = DECODE_RM_WORD_REGISTER(op1); 722 DECODE_PRINTF("\n"); 723 TRACE_AND_STEP(); 724 *reg = dec_word(*reg); 725 } 726 DECODE_CLEAR_SEGOVR(); 727 END_OF_INSTR(); 728 } 729 730 /**************************************************************************** 731 REMARKS: 732 Handles opcode 0x50 - 0x57 733 ****************************************************************************/ 734 void x86emuOp_push_register(u8 op1) 735 { 736 START_OF_INSTR(); 737 op1 &= 0x7; 738 DECODE_PRINTF("PUSH\t"); 739 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 740 u32 *reg; 741 reg = DECODE_RM_LONG_REGISTER(op1); 742 DECODE_PRINTF("\n"); 743 TRACE_AND_STEP(); 744 push_long(*reg); 745 } else { 746 u16 *reg; 747 reg = DECODE_RM_WORD_REGISTER(op1); 748 DECODE_PRINTF("\n"); 749 TRACE_AND_STEP(); 750 push_word(*reg); 751 } 752 DECODE_CLEAR_SEGOVR(); 753 END_OF_INSTR(); 754 } 755 756 /**************************************************************************** 757 REMARKS: 758 Handles opcode 0x58 - 0x5F 759 ****************************************************************************/ 760 void x86emuOp_pop_register(u8 op1) 761 { 762 START_OF_INSTR(); 763 op1 &= 0x7; 764 DECODE_PRINTF("POP\t"); 765 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 766 u32 *reg; 767 reg = DECODE_RM_LONG_REGISTER(op1); 768 DECODE_PRINTF("\n"); 769 TRACE_AND_STEP(); 770 *reg = pop_long(); 771 } else { 772 u16 *reg; 773 reg = DECODE_RM_WORD_REGISTER(op1); 774 DECODE_PRINTF("\n"); 775 TRACE_AND_STEP(); 776 *reg = pop_word(); 777 } 778 DECODE_CLEAR_SEGOVR(); 779 END_OF_INSTR(); 780 } 781 782 /**************************************************************************** 783 REMARKS: 784 Handles opcode 0x60 785 ****************************************************************************/ 786 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 787 { 788 START_OF_INSTR(); 789 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 790 DECODE_PRINTF("PUSHAD\n"); 791 } else { 792 DECODE_PRINTF("PUSHA\n"); 793 } 794 TRACE_AND_STEP(); 795 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 796 u32 old_sp = M.x86.R_ESP; 797 798 push_long(M.x86.R_EAX); 799 push_long(M.x86.R_ECX); 800 push_long(M.x86.R_EDX); 801 push_long(M.x86.R_EBX); 802 push_long(old_sp); 803 push_long(M.x86.R_EBP); 804 push_long(M.x86.R_ESI); 805 push_long(M.x86.R_EDI); 806 } else { 807 u16 old_sp = M.x86.R_SP; 808 809 push_word(M.x86.R_AX); 810 push_word(M.x86.R_CX); 811 push_word(M.x86.R_DX); 812 push_word(M.x86.R_BX); 813 push_word(old_sp); 814 push_word(M.x86.R_BP); 815 push_word(M.x86.R_SI); 816 push_word(M.x86.R_DI); 817 } 818 DECODE_CLEAR_SEGOVR(); 819 END_OF_INSTR(); 820 } 821 822 /**************************************************************************** 823 REMARKS: 824 Handles opcode 0x61 825 ****************************************************************************/ 826 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 827 { 828 START_OF_INSTR(); 829 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 830 DECODE_PRINTF("POPAD\n"); 831 } else { 832 DECODE_PRINTF("POPA\n"); 833 } 834 TRACE_AND_STEP(); 835 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 836 M.x86.R_EDI = pop_long(); 837 M.x86.R_ESI = pop_long(); 838 M.x86.R_EBP = pop_long(); 839 M.x86.R_ESP += 4; /* skip ESP */ 840 M.x86.R_EBX = pop_long(); 841 M.x86.R_EDX = pop_long(); 842 M.x86.R_ECX = pop_long(); 843 M.x86.R_EAX = pop_long(); 844 } else { 845 M.x86.R_DI = pop_word(); 846 M.x86.R_SI = pop_word(); 847 M.x86.R_BP = pop_word(); 848 M.x86.R_SP += 2; /* skip SP */ 849 M.x86.R_BX = pop_word(); 850 M.x86.R_DX = pop_word(); 851 M.x86.R_CX = pop_word(); 852 M.x86.R_AX = pop_word(); 853 } 854 DECODE_CLEAR_SEGOVR(); 855 END_OF_INSTR(); 856 } 857 858 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 859 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 860 861 /**************************************************************************** 862 REMARKS: 863 Handles opcode 0x64 864 ****************************************************************************/ 865 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 866 { 867 START_OF_INSTR(); 868 DECODE_PRINTF("FS:\n"); 869 TRACE_AND_STEP(); 870 M.x86.mode |= SYSMODE_SEGOVR_FS; 871 /* 872 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 873 * opcode subroutines we do not want to do this. 874 */ 875 END_OF_INSTR(); 876 } 877 878 /**************************************************************************** 879 REMARKS: 880 Handles opcode 0x65 881 ****************************************************************************/ 882 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 883 { 884 START_OF_INSTR(); 885 DECODE_PRINTF("GS:\n"); 886 TRACE_AND_STEP(); 887 M.x86.mode |= SYSMODE_SEGOVR_GS; 888 /* 889 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 890 * opcode subroutines we do not want to do this. 891 */ 892 END_OF_INSTR(); 893 } 894 895 /**************************************************************************** 896 REMARKS: 897 Handles opcode 0x66 - prefix for 32-bit register 898 ****************************************************************************/ 899 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 900 { 901 START_OF_INSTR(); 902 DECODE_PRINTF("DATA:\n"); 903 TRACE_AND_STEP(); 904 M.x86.mode |= SYSMODE_PREFIX_DATA; 905 /* note no DECODE_CLEAR_SEGOVR here. */ 906 END_OF_INSTR(); 907 } 908 909 /**************************************************************************** 910 REMARKS: 911 Handles opcode 0x67 - prefix for 32-bit address 912 ****************************************************************************/ 913 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 914 { 915 START_OF_INSTR(); 916 DECODE_PRINTF("ADDR:\n"); 917 TRACE_AND_STEP(); 918 M.x86.mode |= SYSMODE_PREFIX_ADDR; 919 /* note no DECODE_CLEAR_SEGOVR here. */ 920 END_OF_INSTR(); 921 } 922 923 /**************************************************************************** 924 REMARKS: 925 Handles opcode 0x68 926 ****************************************************************************/ 927 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 928 { 929 u32 imm; 930 931 START_OF_INSTR(); 932 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 933 imm = fetch_long_imm(); 934 } else { 935 imm = fetch_word_imm(); 936 } 937 DECODE_PRINTF2("PUSH\t%x\n", imm); 938 TRACE_AND_STEP(); 939 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 940 push_long(imm); 941 } else { 942 push_word((u16)imm); 943 } 944 DECODE_CLEAR_SEGOVR(); 945 END_OF_INSTR(); 946 } 947 948 /**************************************************************************** 949 REMARKS: 950 Handles opcode 0x69 951 ****************************************************************************/ 952 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 953 { 954 int mod, rl, rh; 955 uint srcoffset; 956 957 START_OF_INSTR(); 958 DECODE_PRINTF("IMUL\t"); 959 FETCH_DECODE_MODRM(mod, rh, rl); 960 if (mod < 3) { 961 srcoffset = decode_rmXX_address(mod, rl); 962 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 963 u32 *destreg; 964 u32 srcval; 965 u32 res_lo,res_hi; 966 s32 imm; 967 968 destreg = DECODE_RM_LONG_REGISTER(rh); 969 DECODE_PRINTF(","); 970 srcval = fetch_data_long(srcoffset); 971 imm = fetch_long_imm(); 972 DECODE_PRINTF2(",%d\n", (s32)imm); 973 TRACE_AND_STEP(); 974 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 975 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 976 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 977 CLEAR_FLAG(F_CF); 978 CLEAR_FLAG(F_OF); 979 } else { 980 SET_FLAG(F_CF); 981 SET_FLAG(F_OF); 982 } 983 *destreg = (u32)res_lo; 984 } else { 985 u16 *destreg; 986 u16 srcval; 987 u32 res; 988 s16 imm; 989 990 destreg = DECODE_RM_WORD_REGISTER(rh); 991 DECODE_PRINTF(","); 992 srcval = fetch_data_word(srcoffset); 993 imm = fetch_word_imm(); 994 DECODE_PRINTF2(",%d\n", (s32)imm); 995 TRACE_AND_STEP(); 996 res = (s16)srcval * (s16)imm; 997 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 998 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 999 CLEAR_FLAG(F_CF); 1000 CLEAR_FLAG(F_OF); 1001 } else { 1002 SET_FLAG(F_CF); 1003 SET_FLAG(F_OF); 1004 } 1005 *destreg = (u16)res; 1006 } 1007 } else { /* register to register */ 1008 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1009 u32 *destreg,*srcreg; 1010 u32 res_lo,res_hi; 1011 s32 imm; 1012 1013 destreg = DECODE_RM_LONG_REGISTER(rh); 1014 DECODE_PRINTF(","); 1015 srcreg = DECODE_RM_LONG_REGISTER(rl); 1016 imm = fetch_long_imm(); 1017 DECODE_PRINTF2(",%d\n", (s32)imm); 1018 TRACE_AND_STEP(); 1019 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 1020 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1021 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1022 CLEAR_FLAG(F_CF); 1023 CLEAR_FLAG(F_OF); 1024 } else { 1025 SET_FLAG(F_CF); 1026 SET_FLAG(F_OF); 1027 } 1028 *destreg = (u32)res_lo; 1029 } else { 1030 u16 *destreg,*srcreg; 1031 u32 res; 1032 s16 imm; 1033 1034 destreg = DECODE_RM_WORD_REGISTER(rh); 1035 DECODE_PRINTF(","); 1036 srcreg = DECODE_RM_WORD_REGISTER(rl); 1037 imm = fetch_word_imm(); 1038 DECODE_PRINTF2(",%d\n", (s32)imm); 1039 res = (s16)*srcreg * (s16)imm; 1040 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1041 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1042 CLEAR_FLAG(F_CF); 1043 CLEAR_FLAG(F_OF); 1044 } else { 1045 SET_FLAG(F_CF); 1046 SET_FLAG(F_OF); 1047 } 1048 *destreg = (u16)res; 1049 } 1050 } 1051 DECODE_CLEAR_SEGOVR(); 1052 END_OF_INSTR(); 1053 } 1054 1055 /**************************************************************************** 1056 REMARKS: 1057 Handles opcode 0x6a 1058 ****************************************************************************/ 1059 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 1060 { 1061 s16 imm; 1062 1063 START_OF_INSTR(); 1064 imm = (s8)fetch_byte_imm(); 1065 DECODE_PRINTF2("PUSH\t%d\n", imm); 1066 TRACE_AND_STEP(); 1067 push_word(imm); 1068 DECODE_CLEAR_SEGOVR(); 1069 END_OF_INSTR(); 1070 } 1071 1072 /**************************************************************************** 1073 REMARKS: 1074 Handles opcode 0x6b 1075 ****************************************************************************/ 1076 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 1077 { 1078 int mod, rl, rh; 1079 uint srcoffset; 1080 s8 imm; 1081 1082 START_OF_INSTR(); 1083 DECODE_PRINTF("IMUL\t"); 1084 FETCH_DECODE_MODRM(mod, rh, rl); 1085 if (mod < 3) { 1086 srcoffset = decode_rmXX_address(mod, rl); 1087 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1088 u32 *destreg; 1089 u32 srcval; 1090 u32 res_lo,res_hi; 1091 1092 destreg = DECODE_RM_LONG_REGISTER(rh); 1093 DECODE_PRINTF(","); 1094 srcval = fetch_data_long(srcoffset); 1095 imm = fetch_byte_imm(); 1096 DECODE_PRINTF2(",%d\n", (s32)imm); 1097 TRACE_AND_STEP(); 1098 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 1099 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1100 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1101 CLEAR_FLAG(F_CF); 1102 CLEAR_FLAG(F_OF); 1103 } else { 1104 SET_FLAG(F_CF); 1105 SET_FLAG(F_OF); 1106 } 1107 *destreg = (u32)res_lo; 1108 } else { 1109 u16 *destreg; 1110 u16 srcval; 1111 u32 res; 1112 1113 destreg = DECODE_RM_WORD_REGISTER(rh); 1114 DECODE_PRINTF(","); 1115 srcval = fetch_data_word(srcoffset); 1116 imm = fetch_byte_imm(); 1117 DECODE_PRINTF2(",%d\n", (s32)imm); 1118 TRACE_AND_STEP(); 1119 res = (s16)srcval * (s16)imm; 1120 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1121 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1122 CLEAR_FLAG(F_CF); 1123 CLEAR_FLAG(F_OF); 1124 } else { 1125 SET_FLAG(F_CF); 1126 SET_FLAG(F_OF); 1127 } 1128 *destreg = (u16)res; 1129 } 1130 } else { /* register to register */ 1131 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1132 u32 *destreg,*srcreg; 1133 u32 res_lo,res_hi; 1134 1135 destreg = DECODE_RM_LONG_REGISTER(rh); 1136 DECODE_PRINTF(","); 1137 srcreg = DECODE_RM_LONG_REGISTER(rl); 1138 imm = fetch_byte_imm(); 1139 DECODE_PRINTF2(",%d\n", (s32)imm); 1140 TRACE_AND_STEP(); 1141 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 1142 if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1143 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1144 CLEAR_FLAG(F_CF); 1145 CLEAR_FLAG(F_OF); 1146 } else { 1147 SET_FLAG(F_CF); 1148 SET_FLAG(F_OF); 1149 } 1150 *destreg = (u32)res_lo; 1151 } else { 1152 u16 *destreg,*srcreg; 1153 u32 res; 1154 1155 destreg = DECODE_RM_WORD_REGISTER(rh); 1156 DECODE_PRINTF(","); 1157 srcreg = DECODE_RM_WORD_REGISTER(rl); 1158 imm = fetch_byte_imm(); 1159 DECODE_PRINTF2(",%d\n", (s32)imm); 1160 TRACE_AND_STEP(); 1161 res = (s16)*srcreg * (s16)imm; 1162 if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1163 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1164 CLEAR_FLAG(F_CF); 1165 CLEAR_FLAG(F_OF); 1166 } else { 1167 SET_FLAG(F_CF); 1168 SET_FLAG(F_OF); 1169 } 1170 *destreg = (u16)res; 1171 } 1172 } 1173 DECODE_CLEAR_SEGOVR(); 1174 END_OF_INSTR(); 1175 } 1176 1177 /**************************************************************************** 1178 REMARKS: 1179 Handles opcode 0x6c 1180 ****************************************************************************/ 1181 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 1182 { 1183 START_OF_INSTR(); 1184 DECODE_PRINTF("INSB\n"); 1185 ins(1); 1186 TRACE_AND_STEP(); 1187 DECODE_CLEAR_SEGOVR(); 1188 END_OF_INSTR(); 1189 } 1190 1191 /**************************************************************************** 1192 REMARKS: 1193 Handles opcode 0x6d 1194 ****************************************************************************/ 1195 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 1196 { 1197 START_OF_INSTR(); 1198 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1199 DECODE_PRINTF("INSD\n"); 1200 ins(4); 1201 } else { 1202 DECODE_PRINTF("INSW\n"); 1203 ins(2); 1204 } 1205 TRACE_AND_STEP(); 1206 DECODE_CLEAR_SEGOVR(); 1207 END_OF_INSTR(); 1208 } 1209 1210 /**************************************************************************** 1211 REMARKS: 1212 Handles opcode 0x6e 1213 ****************************************************************************/ 1214 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 1215 { 1216 START_OF_INSTR(); 1217 DECODE_PRINTF("OUTSB\n"); 1218 outs(1); 1219 TRACE_AND_STEP(); 1220 DECODE_CLEAR_SEGOVR(); 1221 END_OF_INSTR(); 1222 } 1223 1224 /**************************************************************************** 1225 REMARKS: 1226 Handles opcode 0x6f 1227 ****************************************************************************/ 1228 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 1229 { 1230 START_OF_INSTR(); 1231 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1232 DECODE_PRINTF("OUTSD\n"); 1233 outs(4); 1234 } else { 1235 DECODE_PRINTF("OUTSW\n"); 1236 outs(2); 1237 } 1238 TRACE_AND_STEP(); 1239 DECODE_CLEAR_SEGOVR(); 1240 END_OF_INSTR(); 1241 } 1242 1243 /**************************************************************************** 1244 REMARKS: 1245 Handles opcode 0x70 - 0x7F 1246 ****************************************************************************/ 1247 int x86emu_check_jump_condition(u8 op); 1248 1249 void x86emuOp_jump_near_cond(u8 op1) 1250 { 1251 s8 offset; 1252 u16 target; 1253 int cond; 1254 1255 /* jump to byte offset if overflow flag is set */ 1256 START_OF_INSTR(); 1257 cond = x86emu_check_jump_condition(op1 & 0xF); 1258 offset = (s8)fetch_byte_imm(); 1259 target = (u16)(M.x86.R_IP + (s16)offset); 1260 DECODE_PRINTF2("%x\n", target); 1261 TRACE_AND_STEP(); 1262 if (cond) 1263 M.x86.R_IP = target; 1264 DECODE_CLEAR_SEGOVR(); 1265 END_OF_INSTR(); 1266 } 1267 1268 /**************************************************************************** 1269 REMARKS: 1270 Handles opcode 0x80 1271 ****************************************************************************/ 1272 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 1273 { 1274 int mod, rl, rh; 1275 u8 *destreg; 1276 uint destoffset; 1277 u8 imm; 1278 u8 destval; 1279 1280 /* 1281 * Weirdo special case instruction format. Part of the opcode 1282 * held below in "RH". Doubly nested case would result, except 1283 * that the decoded instruction 1284 */ 1285 START_OF_INSTR(); 1286 FETCH_DECODE_MODRM(mod, rh, rl); 1287 #ifdef DEBUG 1288 if (DEBUG_DECODE()) { 1289 /* XXX DECODE_PRINTF may be changed to something more 1290 general, so that it is important to leave the strings 1291 in the same format, even though the result is that the 1292 above test is done twice. */ 1293 1294 switch (rh) { 1295 case 0: 1296 DECODE_PRINTF("ADD\t"); 1297 break; 1298 case 1: 1299 DECODE_PRINTF("OR\t"); 1300 break; 1301 case 2: 1302 DECODE_PRINTF("ADC\t"); 1303 break; 1304 case 3: 1305 DECODE_PRINTF("SBB\t"); 1306 break; 1307 case 4: 1308 DECODE_PRINTF("AND\t"); 1309 break; 1310 case 5: 1311 DECODE_PRINTF("SUB\t"); 1312 break; 1313 case 6: 1314 DECODE_PRINTF("XOR\t"); 1315 break; 1316 case 7: 1317 DECODE_PRINTF("CMP\t"); 1318 break; 1319 } 1320 } 1321 #endif 1322 /* know operation, decode the mod byte to find the addressing 1323 mode. */ 1324 if (mod < 3) { 1325 DECODE_PRINTF("BYTE PTR "); 1326 destoffset = decode_rmXX_address(mod, rl); 1327 DECODE_PRINTF(","); 1328 destval = fetch_data_byte(destoffset); 1329 imm = fetch_byte_imm(); 1330 DECODE_PRINTF2("%x\n", imm); 1331 TRACE_AND_STEP(); 1332 destval = (*genop_byte_operation[rh]) (destval, imm); 1333 if (rh != 7) 1334 store_data_byte(destoffset, destval); 1335 } else { /* register to register */ 1336 destreg = DECODE_RM_BYTE_REGISTER(rl); 1337 DECODE_PRINTF(","); 1338 imm = fetch_byte_imm(); 1339 DECODE_PRINTF2("%x\n", imm); 1340 TRACE_AND_STEP(); 1341 destval = (*genop_byte_operation[rh]) (*destreg, imm); 1342 if (rh != 7) 1343 *destreg = destval; 1344 } 1345 DECODE_CLEAR_SEGOVR(); 1346 END_OF_INSTR(); 1347 } 1348 1349 /**************************************************************************** 1350 REMARKS: 1351 Handles opcode 0x81 1352 ****************************************************************************/ 1353 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 1354 { 1355 int mod, rl, rh; 1356 uint destoffset; 1357 1358 /* 1359 * Weirdo special case instruction format. Part of the opcode 1360 * held below in "RH". Doubly nested case would result, except 1361 * that the decoded instruction 1362 */ 1363 START_OF_INSTR(); 1364 FETCH_DECODE_MODRM(mod, rh, rl); 1365 #ifdef DEBUG 1366 if (DEBUG_DECODE()) { 1367 /* XXX DECODE_PRINTF may be changed to something more 1368 general, so that it is important to leave the strings 1369 in the same format, even though the result is that the 1370 above test is done twice. */ 1371 1372 switch (rh) { 1373 case 0: 1374 DECODE_PRINTF("ADD\t"); 1375 break; 1376 case 1: 1377 DECODE_PRINTF("OR\t"); 1378 break; 1379 case 2: 1380 DECODE_PRINTF("ADC\t"); 1381 break; 1382 case 3: 1383 DECODE_PRINTF("SBB\t"); 1384 break; 1385 case 4: 1386 DECODE_PRINTF("AND\t"); 1387 break; 1388 case 5: 1389 DECODE_PRINTF("SUB\t"); 1390 break; 1391 case 6: 1392 DECODE_PRINTF("XOR\t"); 1393 break; 1394 case 7: 1395 DECODE_PRINTF("CMP\t"); 1396 break; 1397 } 1398 } 1399 #endif 1400 /* 1401 * Know operation, decode the mod byte to find the addressing 1402 * mode. 1403 */ 1404 if (mod < 3) { 1405 DECODE_PRINTF("DWORD PTR "); 1406 destoffset = decode_rmXX_address(mod, rl); 1407 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1408 u32 destval,imm; 1409 1410 DECODE_PRINTF(","); 1411 destval = fetch_data_long(destoffset); 1412 imm = fetch_long_imm(); 1413 DECODE_PRINTF2("%x\n", imm); 1414 TRACE_AND_STEP(); 1415 destval = (*genop_long_operation[rh]) (destval, imm); 1416 if (rh != 7) 1417 store_data_long(destoffset, destval); 1418 } else { 1419 u16 destval,imm; 1420 1421 DECODE_PRINTF(","); 1422 destval = fetch_data_word(destoffset); 1423 imm = fetch_word_imm(); 1424 DECODE_PRINTF2("%x\n", imm); 1425 TRACE_AND_STEP(); 1426 destval = (*genop_word_operation[rh]) (destval, imm); 1427 if (rh != 7) 1428 store_data_word(destoffset, destval); 1429 } 1430 } else { /* register to register */ 1431 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1432 u32 *destreg; 1433 u32 destval,imm; 1434 1435 destreg = DECODE_RM_LONG_REGISTER(rl); 1436 DECODE_PRINTF(","); 1437 imm = fetch_long_imm(); 1438 DECODE_PRINTF2("%x\n", imm); 1439 TRACE_AND_STEP(); 1440 destval = (*genop_long_operation[rh]) (*destreg, imm); 1441 if (rh != 7) 1442 *destreg = destval; 1443 } else { 1444 u16 *destreg; 1445 u16 destval,imm; 1446 1447 destreg = DECODE_RM_WORD_REGISTER(rl); 1448 DECODE_PRINTF(","); 1449 imm = fetch_word_imm(); 1450 DECODE_PRINTF2("%x\n", imm); 1451 TRACE_AND_STEP(); 1452 destval = (*genop_word_operation[rh]) (*destreg, imm); 1453 if (rh != 7) 1454 *destreg = destval; 1455 } 1456 } 1457 DECODE_CLEAR_SEGOVR(); 1458 END_OF_INSTR(); 1459 } 1460 1461 /**************************************************************************** 1462 REMARKS: 1463 Handles opcode 0x82 1464 ****************************************************************************/ 1465 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 1466 { 1467 int mod, rl, rh; 1468 u8 *destreg; 1469 uint destoffset; 1470 u8 imm; 1471 u8 destval; 1472 1473 /* 1474 * Weirdo special case instruction format. Part of the opcode 1475 * held below in "RH". Doubly nested case would result, except 1476 * that the decoded instruction Similar to opcode 81, except that 1477 * the immediate byte is sign extended to a word length. 1478 */ 1479 START_OF_INSTR(); 1480 FETCH_DECODE_MODRM(mod, rh, rl); 1481 #ifdef DEBUG 1482 if (DEBUG_DECODE()) { 1483 /* XXX DECODE_PRINTF may be changed to something more 1484 general, so that it is important to leave the strings 1485 in the same format, even though the result is that the 1486 above test is done twice. */ 1487 switch (rh) { 1488 case 0: 1489 DECODE_PRINTF("ADD\t"); 1490 break; 1491 case 1: 1492 DECODE_PRINTF("OR\t"); 1493 break; 1494 case 2: 1495 DECODE_PRINTF("ADC\t"); 1496 break; 1497 case 3: 1498 DECODE_PRINTF("SBB\t"); 1499 break; 1500 case 4: 1501 DECODE_PRINTF("AND\t"); 1502 break; 1503 case 5: 1504 DECODE_PRINTF("SUB\t"); 1505 break; 1506 case 6: 1507 DECODE_PRINTF("XOR\t"); 1508 break; 1509 case 7: 1510 DECODE_PRINTF("CMP\t"); 1511 break; 1512 } 1513 } 1514 #endif 1515 /* know operation, decode the mod byte to find the addressing 1516 mode. */ 1517 if (mod < 3) { 1518 DECODE_PRINTF("BYTE PTR "); 1519 destoffset = decode_rmXX_address(mod, rl); 1520 destval = fetch_data_byte(destoffset); 1521 imm = fetch_byte_imm(); 1522 DECODE_PRINTF2(",%x\n", imm); 1523 TRACE_AND_STEP(); 1524 destval = (*genop_byte_operation[rh]) (destval, imm); 1525 if (rh != 7) 1526 store_data_byte(destoffset, destval); 1527 } else { /* register to register */ 1528 destreg = DECODE_RM_BYTE_REGISTER(rl); 1529 imm = fetch_byte_imm(); 1530 DECODE_PRINTF2(",%x\n", imm); 1531 TRACE_AND_STEP(); 1532 destval = (*genop_byte_operation[rh]) (*destreg, imm); 1533 if (rh != 7) 1534 *destreg = destval; 1535 } 1536 DECODE_CLEAR_SEGOVR(); 1537 END_OF_INSTR(); 1538 } 1539 1540 /**************************************************************************** 1541 REMARKS: 1542 Handles opcode 0x83 1543 ****************************************************************************/ 1544 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 1545 { 1546 int mod, rl, rh; 1547 uint destoffset; 1548 1549 /* 1550 * Weirdo special case instruction format. Part of the opcode 1551 * held below in "RH". Doubly nested case would result, except 1552 * that the decoded instruction Similar to opcode 81, except that 1553 * the immediate byte is sign extended to a word length. 1554 */ 1555 START_OF_INSTR(); 1556 FETCH_DECODE_MODRM(mod, rh, rl); 1557 #ifdef DEBUG 1558 if (DEBUG_DECODE()) { 1559 /* XXX DECODE_PRINTF may be changed to something more 1560 general, so that it is important to leave the strings 1561 in the same format, even though the result is that the 1562 above test is done twice. */ 1563 switch (rh) { 1564 case 0: 1565 DECODE_PRINTF("ADD\t"); 1566 break; 1567 case 1: 1568 DECODE_PRINTF("OR\t"); 1569 break; 1570 case 2: 1571 DECODE_PRINTF("ADC\t"); 1572 break; 1573 case 3: 1574 DECODE_PRINTF("SBB\t"); 1575 break; 1576 case 4: 1577 DECODE_PRINTF("AND\t"); 1578 break; 1579 case 5: 1580 DECODE_PRINTF("SUB\t"); 1581 break; 1582 case 6: 1583 DECODE_PRINTF("XOR\t"); 1584 break; 1585 case 7: 1586 DECODE_PRINTF("CMP\t"); 1587 break; 1588 } 1589 } 1590 #endif 1591 /* know operation, decode the mod byte to find the addressing 1592 mode. */ 1593 if (mod < 3) { 1594 DECODE_PRINTF("DWORD PTR "); 1595 destoffset = decode_rmXX_address(mod,rl); 1596 1597 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1598 u32 destval,imm; 1599 1600 destval = fetch_data_long(destoffset); 1601 imm = (s8) fetch_byte_imm(); 1602 DECODE_PRINTF2(",%x\n", imm); 1603 TRACE_AND_STEP(); 1604 destval = (*genop_long_operation[rh]) (destval, imm); 1605 if (rh != 7) 1606 store_data_long(destoffset, destval); 1607 } else { 1608 u16 destval,imm; 1609 1610 destval = fetch_data_word(destoffset); 1611 imm = (s8) fetch_byte_imm(); 1612 DECODE_PRINTF2(",%x\n", imm); 1613 TRACE_AND_STEP(); 1614 destval = (*genop_word_operation[rh]) (destval, imm); 1615 if (rh != 7) 1616 store_data_word(destoffset, destval); 1617 } 1618 } else { /* register to register */ 1619 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1620 u32 *destreg; 1621 u32 destval,imm; 1622 1623 destreg = DECODE_RM_LONG_REGISTER(rl); 1624 imm = (s8) fetch_byte_imm(); 1625 DECODE_PRINTF2(",%x\n", imm); 1626 TRACE_AND_STEP(); 1627 destval = (*genop_long_operation[rh]) (*destreg, imm); 1628 if (rh != 7) 1629 *destreg = destval; 1630 } else { 1631 u16 *destreg; 1632 u16 destval,imm; 1633 1634 destreg = DECODE_RM_WORD_REGISTER(rl); 1635 imm = (s8) fetch_byte_imm(); 1636 DECODE_PRINTF2(",%x\n", imm); 1637 TRACE_AND_STEP(); 1638 destval = (*genop_word_operation[rh]) (*destreg, imm); 1639 if (rh != 7) 1640 *destreg = destval; 1641 } 1642 } 1643 DECODE_CLEAR_SEGOVR(); 1644 END_OF_INSTR(); 1645 } 1646 1647 /**************************************************************************** 1648 REMARKS: 1649 Handles opcode 0x84 1650 ****************************************************************************/ 1651 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1652 { 1653 int mod, rl, rh; 1654 u8 *destreg, *srcreg; 1655 uint destoffset; 1656 u8 destval; 1657 1658 START_OF_INSTR(); 1659 DECODE_PRINTF("TEST\t"); 1660 FETCH_DECODE_MODRM(mod, rh, rl); 1661 if (mod < 3) { 1662 destoffset = decode_rmXX_address(mod, rl); 1663 DECODE_PRINTF(","); 1664 destval = fetch_data_byte(destoffset); 1665 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1666 DECODE_PRINTF("\n"); 1667 TRACE_AND_STEP(); 1668 test_byte(destval, *srcreg); 1669 } else { /* register to register */ 1670 destreg = DECODE_RM_BYTE_REGISTER(rl); 1671 DECODE_PRINTF(","); 1672 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1673 DECODE_PRINTF("\n"); 1674 TRACE_AND_STEP(); 1675 test_byte(*destreg, *srcreg); 1676 } 1677 DECODE_CLEAR_SEGOVR(); 1678 END_OF_INSTR(); 1679 } 1680 1681 /**************************************************************************** 1682 REMARKS: 1683 Handles opcode 0x85 1684 ****************************************************************************/ 1685 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 1686 { 1687 int mod, rl, rh; 1688 uint destoffset; 1689 1690 START_OF_INSTR(); 1691 DECODE_PRINTF("TEST\t"); 1692 FETCH_DECODE_MODRM(mod, rh, rl); 1693 if (mod < 3) { 1694 destoffset = decode_rmXX_address(mod, rl); 1695 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1696 u32 destval; 1697 u32 *srcreg; 1698 1699 DECODE_PRINTF(","); 1700 destval = fetch_data_long(destoffset); 1701 srcreg = DECODE_RM_LONG_REGISTER(rh); 1702 DECODE_PRINTF("\n"); 1703 TRACE_AND_STEP(); 1704 test_long(destval, *srcreg); 1705 } else { 1706 u16 destval; 1707 u16 *srcreg; 1708 1709 DECODE_PRINTF(","); 1710 destval = fetch_data_word(destoffset); 1711 srcreg = DECODE_RM_WORD_REGISTER(rh); 1712 DECODE_PRINTF("\n"); 1713 TRACE_AND_STEP(); 1714 test_word(destval, *srcreg); 1715 } 1716 } else { /* register to register */ 1717 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1718 u32 *destreg,*srcreg; 1719 1720 destreg = DECODE_RM_LONG_REGISTER(rl); 1721 DECODE_PRINTF(","); 1722 srcreg = DECODE_RM_LONG_REGISTER(rh); 1723 DECODE_PRINTF("\n"); 1724 TRACE_AND_STEP(); 1725 test_long(*destreg, *srcreg); 1726 } else { 1727 u16 *destreg,*srcreg; 1728 1729 destreg = DECODE_RM_WORD_REGISTER(rl); 1730 DECODE_PRINTF(","); 1731 srcreg = DECODE_RM_WORD_REGISTER(rh); 1732 DECODE_PRINTF("\n"); 1733 TRACE_AND_STEP(); 1734 test_word(*destreg, *srcreg); 1735 } 1736 } 1737 DECODE_CLEAR_SEGOVR(); 1738 END_OF_INSTR(); 1739 } 1740 1741 /**************************************************************************** 1742 REMARKS: 1743 Handles opcode 0x86 1744 ****************************************************************************/ 1745 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1746 { 1747 int mod, rl, rh; 1748 u8 *destreg, *srcreg; 1749 uint destoffset; 1750 u8 destval; 1751 u8 tmp; 1752 1753 START_OF_INSTR(); 1754 DECODE_PRINTF("XCHG\t"); 1755 FETCH_DECODE_MODRM(mod, rh, rl); 1756 if (mod < 3) { 1757 destoffset = decode_rmXX_address(mod, rl); 1758 DECODE_PRINTF(","); 1759 destval = fetch_data_byte(destoffset); 1760 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1761 DECODE_PRINTF("\n"); 1762 TRACE_AND_STEP(); 1763 tmp = *srcreg; 1764 *srcreg = destval; 1765 destval = tmp; 1766 store_data_byte(destoffset, destval); 1767 } else { /* register to register */ 1768 destreg = DECODE_RM_BYTE_REGISTER(rl); 1769 DECODE_PRINTF(","); 1770 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1771 DECODE_PRINTF("\n"); 1772 TRACE_AND_STEP(); 1773 tmp = *srcreg; 1774 *srcreg = *destreg; 1775 *destreg = tmp; 1776 } 1777 DECODE_CLEAR_SEGOVR(); 1778 END_OF_INSTR(); 1779 } 1780 1781 /**************************************************************************** 1782 REMARKS: 1783 Handles opcode 0x87 1784 ****************************************************************************/ 1785 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 1786 { 1787 int mod, rl, rh; 1788 uint destoffset; 1789 1790 START_OF_INSTR(); 1791 DECODE_PRINTF("XCHG\t"); 1792 FETCH_DECODE_MODRM(mod, rh, rl); 1793 if (mod < 3) { 1794 destoffset = decode_rmXX_address(mod, rl); 1795 DECODE_PRINTF(","); 1796 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1797 u32 *srcreg; 1798 u32 destval,tmp; 1799 1800 destval = fetch_data_long(destoffset); 1801 srcreg = DECODE_RM_LONG_REGISTER(rh); 1802 DECODE_PRINTF("\n"); 1803 TRACE_AND_STEP(); 1804 tmp = *srcreg; 1805 *srcreg = destval; 1806 destval = tmp; 1807 store_data_long(destoffset, destval); 1808 } else { 1809 u16 *srcreg; 1810 u16 destval,tmp; 1811 1812 destval = fetch_data_word(destoffset); 1813 srcreg = DECODE_RM_WORD_REGISTER(rh); 1814 DECODE_PRINTF("\n"); 1815 TRACE_AND_STEP(); 1816 tmp = *srcreg; 1817 *srcreg = destval; 1818 destval = tmp; 1819 store_data_word(destoffset, destval); 1820 } 1821 } else { /* register to register */ 1822 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1823 u32 *destreg,*srcreg; 1824 u32 tmp; 1825 1826 destreg = DECODE_RM_LONG_REGISTER(rl); 1827 DECODE_PRINTF(","); 1828 srcreg = DECODE_RM_LONG_REGISTER(rh); 1829 DECODE_PRINTF("\n"); 1830 TRACE_AND_STEP(); 1831 tmp = *srcreg; 1832 *srcreg = *destreg; 1833 *destreg = tmp; 1834 } else { 1835 u16 *destreg,*srcreg; 1836 u16 tmp; 1837 1838 destreg = DECODE_RM_WORD_REGISTER(rl); 1839 DECODE_PRINTF(","); 1840 srcreg = DECODE_RM_WORD_REGISTER(rh); 1841 DECODE_PRINTF("\n"); 1842 TRACE_AND_STEP(); 1843 tmp = *srcreg; 1844 *srcreg = *destreg; 1845 *destreg = tmp; 1846 } 1847 } 1848 DECODE_CLEAR_SEGOVR(); 1849 END_OF_INSTR(); 1850 } 1851 1852 /**************************************************************************** 1853 REMARKS: 1854 Handles opcode 0x88 1855 ****************************************************************************/ 1856 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1857 { 1858 int mod, rl, rh; 1859 u8 *destreg, *srcreg; 1860 uint destoffset; 1861 1862 START_OF_INSTR(); 1863 DECODE_PRINTF("MOV\t"); 1864 FETCH_DECODE_MODRM(mod, rh, rl); 1865 if (mod < 3) { 1866 destoffset = decode_rmXX_address(mod, rl); 1867 DECODE_PRINTF(","); 1868 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1869 DECODE_PRINTF("\n"); 1870 TRACE_AND_STEP(); 1871 store_data_byte(destoffset, *srcreg); 1872 } else { /* register to register */ 1873 destreg = DECODE_RM_BYTE_REGISTER(rl); 1874 DECODE_PRINTF(","); 1875 srcreg = DECODE_RM_BYTE_REGISTER(rh); 1876 DECODE_PRINTF("\n"); 1877 TRACE_AND_STEP(); 1878 *destreg = *srcreg; 1879 } 1880 DECODE_CLEAR_SEGOVR(); 1881 END_OF_INSTR(); 1882 } 1883 1884 /**************************************************************************** 1885 REMARKS: 1886 Handles opcode 0x89 1887 ****************************************************************************/ 1888 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 1889 { 1890 int mod, rl, rh; 1891 uint destoffset; 1892 1893 START_OF_INSTR(); 1894 DECODE_PRINTF("MOV\t"); 1895 FETCH_DECODE_MODRM(mod, rh, rl); 1896 if (mod < 3) { 1897 destoffset = decode_rmXX_address(mod, rl); 1898 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1899 u32 *srcreg; 1900 1901 DECODE_PRINTF(","); 1902 srcreg = DECODE_RM_LONG_REGISTER(rh); 1903 DECODE_PRINTF("\n"); 1904 TRACE_AND_STEP(); 1905 store_data_long(destoffset, *srcreg); 1906 } else { 1907 u16 *srcreg; 1908 1909 DECODE_PRINTF(","); 1910 srcreg = DECODE_RM_WORD_REGISTER(rh); 1911 DECODE_PRINTF("\n"); 1912 TRACE_AND_STEP(); 1913 store_data_word(destoffset, *srcreg); 1914 } 1915 } else { /* register to register */ 1916 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1917 u32 *destreg,*srcreg; 1918 1919 destreg = DECODE_RM_LONG_REGISTER(rl); 1920 DECODE_PRINTF(","); 1921 srcreg = DECODE_RM_LONG_REGISTER(rh); 1922 DECODE_PRINTF("\n"); 1923 TRACE_AND_STEP(); 1924 *destreg = *srcreg; 1925 } else { 1926 u16 *destreg,*srcreg; 1927 1928 destreg = DECODE_RM_WORD_REGISTER(rl); 1929 DECODE_PRINTF(","); 1930 srcreg = DECODE_RM_WORD_REGISTER(rh); 1931 DECODE_PRINTF("\n"); 1932 TRACE_AND_STEP(); 1933 *destreg = *srcreg; 1934 } 1935 } 1936 DECODE_CLEAR_SEGOVR(); 1937 END_OF_INSTR(); 1938 } 1939 1940 /**************************************************************************** 1941 REMARKS: 1942 Handles opcode 0x8a 1943 ****************************************************************************/ 1944 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1945 { 1946 int mod, rl, rh; 1947 u8 *destreg, *srcreg; 1948 uint srcoffset; 1949 u8 srcval; 1950 1951 START_OF_INSTR(); 1952 DECODE_PRINTF("MOV\t"); 1953 FETCH_DECODE_MODRM(mod, rh, rl); 1954 if (mod < 3) { 1955 destreg = DECODE_RM_BYTE_REGISTER(rh); 1956 DECODE_PRINTF(","); 1957 srcoffset = decode_rmXX_address(mod, rl); 1958 srcval = fetch_data_byte(srcoffset); 1959 DECODE_PRINTF("\n"); 1960 TRACE_AND_STEP(); 1961 *destreg = srcval; 1962 } else { /* register to register */ 1963 destreg = DECODE_RM_BYTE_REGISTER(rh); 1964 DECODE_PRINTF(","); 1965 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1966 DECODE_PRINTF("\n"); 1967 TRACE_AND_STEP(); 1968 *destreg = *srcreg; 1969 } 1970 DECODE_CLEAR_SEGOVR(); 1971 END_OF_INSTR(); 1972 } 1973 1974 /**************************************************************************** 1975 REMARKS: 1976 Handles opcode 0x8b 1977 ****************************************************************************/ 1978 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 1979 { 1980 int mod, rl, rh; 1981 uint srcoffset; 1982 1983 START_OF_INSTR(); 1984 DECODE_PRINTF("MOV\t"); 1985 FETCH_DECODE_MODRM(mod, rh, rl); 1986 if (mod < 3) { 1987 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1988 u32 *destreg; 1989 u32 srcval; 1990 1991 destreg = DECODE_RM_LONG_REGISTER(rh); 1992 DECODE_PRINTF(","); 1993 srcoffset = decode_rmXX_address(mod, rl); 1994 srcval = fetch_data_long(srcoffset); 1995 DECODE_PRINTF("\n"); 1996 TRACE_AND_STEP(); 1997 *destreg = srcval; 1998 } else { 1999 u16 *destreg; 2000 u16 srcval; 2001 2002 destreg = DECODE_RM_WORD_REGISTER(rh); 2003 DECODE_PRINTF(","); 2004 srcoffset = decode_rmXX_address(mod, rl); 2005 srcval = fetch_data_word(srcoffset); 2006 DECODE_PRINTF("\n"); 2007 TRACE_AND_STEP(); 2008 *destreg = srcval; 2009 } 2010 } else { /* register to register */ 2011 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2012 u32 *destreg, *srcreg; 2013 2014 destreg = DECODE_RM_LONG_REGISTER(rh); 2015 DECODE_PRINTF(","); 2016 srcreg = DECODE_RM_LONG_REGISTER(rl); 2017 DECODE_PRINTF("\n"); 2018 TRACE_AND_STEP(); 2019 *destreg = *srcreg; 2020 } else { 2021 u16 *destreg, *srcreg; 2022 2023 destreg = DECODE_RM_WORD_REGISTER(rh); 2024 DECODE_PRINTF(","); 2025 srcreg = DECODE_RM_WORD_REGISTER(rl); 2026 DECODE_PRINTF("\n"); 2027 TRACE_AND_STEP(); 2028 *destreg = *srcreg; 2029 } 2030 } 2031 DECODE_CLEAR_SEGOVR(); 2032 END_OF_INSTR(); 2033 } 2034 2035 /**************************************************************************** 2036 REMARKS: 2037 Handles opcode 0x8c 2038 ****************************************************************************/ 2039 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 2040 { 2041 int mod, rl, rh; 2042 u16 *destreg, *srcreg; 2043 uint destoffset; 2044 u16 destval; 2045 2046 START_OF_INSTR(); 2047 DECODE_PRINTF("MOV\t"); 2048 FETCH_DECODE_MODRM(mod, rh, rl); 2049 if (mod < 3) { 2050 destoffset = decode_rmXX_address(mod, rl); 2051 DECODE_PRINTF(","); 2052 srcreg = decode_rm_seg_register(rh); 2053 DECODE_PRINTF("\n"); 2054 TRACE_AND_STEP(); 2055 destval = *srcreg; 2056 store_data_word(destoffset, destval); 2057 } else { /* register to register */ 2058 destreg = DECODE_RM_WORD_REGISTER(rl); 2059 DECODE_PRINTF(","); 2060 srcreg = decode_rm_seg_register(rh); 2061 DECODE_PRINTF("\n"); 2062 TRACE_AND_STEP(); 2063 *destreg = *srcreg; 2064 } 2065 DECODE_CLEAR_SEGOVR(); 2066 END_OF_INSTR(); 2067 } 2068 2069 /**************************************************************************** 2070 REMARKS: 2071 Handles opcode 0x8d 2072 ****************************************************************************/ 2073 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 2074 { 2075 int mod, rl, rh; 2076 u16 *srcreg; 2077 uint destoffset; 2078 2079 /* 2080 * TODO: Need to handle address size prefix! 2081 * 2082 * lea eax,[eax+ebx*2] ?? 2083 */ 2084 2085 START_OF_INSTR(); 2086 DECODE_PRINTF("LEA\t"); 2087 FETCH_DECODE_MODRM(mod, rh, rl); 2088 if (mod < 3) { 2089 srcreg = DECODE_RM_WORD_REGISTER(rh); 2090 DECODE_PRINTF(","); 2091 destoffset = decode_rmXX_address(mod, rl); 2092 DECODE_PRINTF("\n"); 2093 TRACE_AND_STEP(); 2094 *srcreg = (u16)destoffset; 2095 } 2096 /* } else { undefined. Do nothing. } */ 2097 DECODE_CLEAR_SEGOVR(); 2098 END_OF_INSTR(); 2099 } 2100 2101 /**************************************************************************** 2102 REMARKS: 2103 Handles opcode 0x8e 2104 ****************************************************************************/ 2105 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 2106 { 2107 int mod, rl, rh; 2108 u16 *destreg, *srcreg; 2109 uint srcoffset; 2110 u16 srcval; 2111 2112 START_OF_INSTR(); 2113 DECODE_PRINTF("MOV\t"); 2114 FETCH_DECODE_MODRM(mod, rh, rl); 2115 if (mod < 3) { 2116 destreg = decode_rm_seg_register(rh); 2117 DECODE_PRINTF(","); 2118 srcoffset = decode_rmXX_address(mod, rl); 2119 srcval = fetch_data_word(srcoffset); 2120 DECODE_PRINTF("\n"); 2121 TRACE_AND_STEP(); 2122 *destreg = srcval; 2123 } else { /* register to register */ 2124 destreg = decode_rm_seg_register(rh); 2125 DECODE_PRINTF(","); 2126 srcreg = DECODE_RM_WORD_REGISTER(rl); 2127 DECODE_PRINTF("\n"); 2128 TRACE_AND_STEP(); 2129 *destreg = *srcreg; 2130 } 2131 /* 2132 * Clean up, and reset all the R_xSP pointers to the correct 2133 * locations. This is about 3x too much overhead (doing all the 2134 * segreg ptrs when only one is needed, but this instruction 2135 * *cannot* be that common, and this isn't too much work anyway. 2136 */ 2137 DECODE_CLEAR_SEGOVR(); 2138 END_OF_INSTR(); 2139 } 2140 2141 /**************************************************************************** 2142 REMARKS: 2143 Handles opcode 0x8f 2144 ****************************************************************************/ 2145 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 2146 { 2147 int mod, rl, rh; 2148 uint destoffset; 2149 2150 START_OF_INSTR(); 2151 DECODE_PRINTF("POP\t"); 2152 FETCH_DECODE_MODRM(mod, rh, rl); 2153 if (rh != 0) { 2154 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 2155 HALT_SYS(); 2156 } 2157 if (mod < 3) { 2158 destoffset = decode_rmXX_address(mod, rl); 2159 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2160 u32 destval; 2161 2162 DECODE_PRINTF("\n"); 2163 TRACE_AND_STEP(); 2164 destval = pop_long(); 2165 store_data_long(destoffset, destval); 2166 } else { 2167 u16 destval; 2168 2169 DECODE_PRINTF("\n"); 2170 TRACE_AND_STEP(); 2171 destval = pop_word(); 2172 store_data_word(destoffset, destval); 2173 } 2174 } else { /* register to register */ 2175 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2176 u32 *destreg; 2177 2178 destreg = DECODE_RM_LONG_REGISTER(rl); 2179 DECODE_PRINTF("\n"); 2180 TRACE_AND_STEP(); 2181 *destreg = pop_long(); 2182 } else { 2183 u16 *destreg; 2184 2185 destreg = DECODE_RM_WORD_REGISTER(rl); 2186 DECODE_PRINTF("\n"); 2187 TRACE_AND_STEP(); 2188 *destreg = pop_word(); 2189 } 2190 } 2191 DECODE_CLEAR_SEGOVR(); 2192 END_OF_INSTR(); 2193 } 2194 2195 /**************************************************************************** 2196 REMARKS: 2197 Handles opcode 0x90 2198 ****************************************************************************/ 2199 void x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 2200 { 2201 START_OF_INSTR(); 2202 DECODE_PRINTF("NOP\n"); 2203 TRACE_AND_STEP(); 2204 DECODE_CLEAR_SEGOVR(); 2205 END_OF_INSTR(); 2206 } 2207 2208 /**************************************************************************** 2209 REMARKS: 2210 Handles opcode 0x91-0x97 2211 ****************************************************************************/ 2212 void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1)) 2213 { 2214 u32 tmp; 2215 2216 op1 &= 0x7; 2217 2218 START_OF_INSTR(); 2219 2220 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2221 u32 *reg32; 2222 DECODE_PRINTF("XCHG\tEAX,"); 2223 reg32 = DECODE_RM_LONG_REGISTER(op1); 2224 DECODE_PRINTF("\n"); 2225 TRACE_AND_STEP(); 2226 tmp = M.x86.R_EAX; 2227 M.x86.R_EAX = *reg32; 2228 *reg32 = tmp; 2229 } else { 2230 u16 *reg16; 2231 DECODE_PRINTF("XCHG\tAX,"); 2232 reg16 = DECODE_RM_WORD_REGISTER(op1); 2233 DECODE_PRINTF("\n"); 2234 TRACE_AND_STEP(); 2235 tmp = M.x86.R_AX; 2236 M.x86.R_EAX = *reg16; 2237 *reg16 = (u16)tmp; 2238 } 2239 DECODE_CLEAR_SEGOVR(); 2240 END_OF_INSTR(); 2241 } 2242 2243 /**************************************************************************** 2244 REMARKS: 2245 Handles opcode 0x98 2246 ****************************************************************************/ 2247 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 2248 { 2249 START_OF_INSTR(); 2250 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2251 DECODE_PRINTF("CWDE\n"); 2252 } else { 2253 DECODE_PRINTF("CBW\n"); 2254 } 2255 TRACE_AND_STEP(); 2256 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2257 if (M.x86.R_AX & 0x8000) { 2258 M.x86.R_EAX |= 0xffff0000; 2259 } else { 2260 M.x86.R_EAX &= 0x0000ffff; 2261 } 2262 } else { 2263 if (M.x86.R_AL & 0x80) { 2264 M.x86.R_AH = 0xff; 2265 } else { 2266 M.x86.R_AH = 0x0; 2267 } 2268 } 2269 DECODE_CLEAR_SEGOVR(); 2270 END_OF_INSTR(); 2271 } 2272 2273 /**************************************************************************** 2274 REMARKS: 2275 Handles opcode 0x99 2276 ****************************************************************************/ 2277 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 2278 { 2279 START_OF_INSTR(); 2280 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2281 DECODE_PRINTF("CDQ\n"); 2282 } else { 2283 DECODE_PRINTF("CWD\n"); 2284 } 2285 DECODE_PRINTF("CWD\n"); 2286 TRACE_AND_STEP(); 2287 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2288 if (M.x86.R_EAX & 0x80000000) { 2289 M.x86.R_EDX = 0xffffffff; 2290 } else { 2291 M.x86.R_EDX = 0x0; 2292 } 2293 } else { 2294 if (M.x86.R_AX & 0x8000) { 2295 M.x86.R_DX = 0xffff; 2296 } else { 2297 M.x86.R_DX = 0x0; 2298 } 2299 } 2300 DECODE_CLEAR_SEGOVR(); 2301 END_OF_INSTR(); 2302 } 2303 2304 /**************************************************************************** 2305 REMARKS: 2306 Handles opcode 0x9a 2307 ****************************************************************************/ 2308 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 2309 { 2310 u16 farseg, faroff; 2311 2312 START_OF_INSTR(); 2313 DECODE_PRINTF("CALL\t"); 2314 faroff = fetch_word_imm(); 2315 farseg = fetch_word_imm(); 2316 DECODE_PRINTF2("%04x:", farseg); 2317 DECODE_PRINTF2("%04x\n", faroff); 2318 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 2319 2320 /* XXX 2321 * 2322 * Hooked interrupt vectors calling into our "BIOS" will cause 2323 * problems unless all intersegment stuff is checked for BIOS 2324 * access. Check needed here. For moment, let it alone. 2325 */ 2326 TRACE_AND_STEP(); 2327 push_word(M.x86.R_CS); 2328 M.x86.R_CS = farseg; 2329 push_word(M.x86.R_IP); 2330 M.x86.R_IP = faroff; 2331 DECODE_CLEAR_SEGOVR(); 2332 END_OF_INSTR(); 2333 } 2334 2335 /**************************************************************************** 2336 REMARKS: 2337 Handles opcode 0x9b 2338 ****************************************************************************/ 2339 void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 2340 { 2341 START_OF_INSTR(); 2342 DECODE_PRINTF("WAIT"); 2343 TRACE_AND_STEP(); 2344 /* NADA. */ 2345 DECODE_CLEAR_SEGOVR(); 2346 END_OF_INSTR(); 2347 } 2348 2349 /**************************************************************************** 2350 REMARKS: 2351 Handles opcode 0x9c 2352 ****************************************************************************/ 2353 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 2354 { 2355 u32 flags; 2356 2357 START_OF_INSTR(); 2358 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2359 DECODE_PRINTF("PUSHFD\n"); 2360 } else { 2361 DECODE_PRINTF("PUSHF\n"); 2362 } 2363 TRACE_AND_STEP(); 2364 2365 /* clear out *all* bits not representing flags, and turn on real bits */ 2366 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 2367 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2368 push_long(flags); 2369 } else { 2370 push_word((u16)flags); 2371 } 2372 DECODE_CLEAR_SEGOVR(); 2373 END_OF_INSTR(); 2374 } 2375 2376 /**************************************************************************** 2377 REMARKS: 2378 Handles opcode 0x9d 2379 ****************************************************************************/ 2380 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 2381 { 2382 START_OF_INSTR(); 2383 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2384 DECODE_PRINTF("POPFD\n"); 2385 } else { 2386 DECODE_PRINTF("POPF\n"); 2387 } 2388 TRACE_AND_STEP(); 2389 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2390 M.x86.R_EFLG = pop_long(); 2391 } else { 2392 M.x86.R_FLG = pop_word(); 2393 } 2394 DECODE_CLEAR_SEGOVR(); 2395 END_OF_INSTR(); 2396 } 2397 2398 /**************************************************************************** 2399 REMARKS: 2400 Handles opcode 0x9e 2401 ****************************************************************************/ 2402 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 2403 { 2404 START_OF_INSTR(); 2405 DECODE_PRINTF("SAHF\n"); 2406 TRACE_AND_STEP(); 2407 /* clear the lower bits of the flag register */ 2408 M.x86.R_FLG &= 0xffffff00; 2409 /* or in the AH register into the flags register */ 2410 M.x86.R_FLG |= M.x86.R_AH; 2411 DECODE_CLEAR_SEGOVR(); 2412 END_OF_INSTR(); 2413 } 2414 2415 /**************************************************************************** 2416 REMARKS: 2417 Handles opcode 0x9f 2418 ****************************************************************************/ 2419 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 2420 { 2421 START_OF_INSTR(); 2422 DECODE_PRINTF("LAHF\n"); 2423 TRACE_AND_STEP(); 2424 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 2425 /*undocumented TC++ behavior??? Nope. It's documented, but 2426 you have too look real hard to notice it. */ 2427 M.x86.R_AH |= 0x2; 2428 DECODE_CLEAR_SEGOVR(); 2429 END_OF_INSTR(); 2430 } 2431 2432 /**************************************************************************** 2433 REMARKS: 2434 Handles opcode 0xa0 2435 ****************************************************************************/ 2436 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 2437 { 2438 u16 offset; 2439 2440 START_OF_INSTR(); 2441 DECODE_PRINTF("MOV\tAL,"); 2442 offset = fetch_word_imm(); 2443 DECODE_PRINTF2("[%04x]\n", offset); 2444 TRACE_AND_STEP(); 2445 M.x86.R_AL = fetch_data_byte(offset); 2446 DECODE_CLEAR_SEGOVR(); 2447 END_OF_INSTR(); 2448 } 2449 2450 /**************************************************************************** 2451 REMARKS: 2452 Handles opcode 0xa1 2453 ****************************************************************************/ 2454 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 2455 { 2456 u16 offset; 2457 2458 START_OF_INSTR(); 2459 offset = fetch_word_imm(); 2460 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2461 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 2462 } else { 2463 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 2464 } 2465 TRACE_AND_STEP(); 2466 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2467 M.x86.R_EAX = fetch_data_long(offset); 2468 } else { 2469 M.x86.R_AX = fetch_data_word(offset); 2470 } 2471 DECODE_CLEAR_SEGOVR(); 2472 END_OF_INSTR(); 2473 } 2474 2475 /**************************************************************************** 2476 REMARKS: 2477 Handles opcode 0xa2 2478 ****************************************************************************/ 2479 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 2480 { 2481 u16 offset; 2482 2483 START_OF_INSTR(); 2484 DECODE_PRINTF("MOV\t"); 2485 offset = fetch_word_imm(); 2486 DECODE_PRINTF2("[%04x],AL\n", offset); 2487 TRACE_AND_STEP(); 2488 store_data_byte(offset, M.x86.R_AL); 2489 DECODE_CLEAR_SEGOVR(); 2490 END_OF_INSTR(); 2491 } 2492 2493 /**************************************************************************** 2494 REMARKS: 2495 Handles opcode 0xa3 2496 ****************************************************************************/ 2497 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 2498 { 2499 u16 offset; 2500 2501 START_OF_INSTR(); 2502 offset = fetch_word_imm(); 2503 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2504 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 2505 } else { 2506 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 2507 } 2508 TRACE_AND_STEP(); 2509 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2510 store_data_long(offset, M.x86.R_EAX); 2511 } else { 2512 store_data_word(offset, M.x86.R_AX); 2513 } 2514 DECODE_CLEAR_SEGOVR(); 2515 END_OF_INSTR(); 2516 } 2517 2518 /**************************************************************************** 2519 REMARKS: 2520 Handles opcode 0xa4 2521 ****************************************************************************/ 2522 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 2523 { 2524 u8 val; 2525 u32 count; 2526 int inc; 2527 2528 START_OF_INSTR(); 2529 DECODE_PRINTF("MOVS\tBYTE\n"); 2530 if (ACCESS_FLAG(F_DF)) /* down */ 2531 inc = -1; 2532 else 2533 inc = 1; 2534 TRACE_AND_STEP(); 2535 count = 1; 2536 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2537 /* dont care whether REPE or REPNE */ 2538 /* move them until CX is ZERO. */ 2539 count = M.x86.R_CX; 2540 M.x86.R_CX = 0; 2541 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2542 } 2543 while (count--) { 2544 val = fetch_data_byte(M.x86.R_SI); 2545 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 2546 M.x86.R_SI += inc; 2547 M.x86.R_DI += inc; 2548 } 2549 DECODE_CLEAR_SEGOVR(); 2550 END_OF_INSTR(); 2551 } 2552 2553 /**************************************************************************** 2554 REMARKS: 2555 Handles opcode 0xa5 2556 ****************************************************************************/ 2557 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 2558 { 2559 u32 val; 2560 int inc; 2561 u32 count; 2562 2563 START_OF_INSTR(); 2564 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2565 DECODE_PRINTF("MOVS\tDWORD\n"); 2566 if (ACCESS_FLAG(F_DF)) /* down */ 2567 inc = -4; 2568 else 2569 inc = 4; 2570 } else { 2571 DECODE_PRINTF("MOVS\tWORD\n"); 2572 if (ACCESS_FLAG(F_DF)) /* down */ 2573 inc = -2; 2574 else 2575 inc = 2; 2576 } 2577 TRACE_AND_STEP(); 2578 count = 1; 2579 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2580 /* dont care whether REPE or REPNE */ 2581 /* move them until CX is ZERO. */ 2582 count = M.x86.R_CX; 2583 M.x86.R_CX = 0; 2584 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2585 } 2586 while (count--) { 2587 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2588 val = fetch_data_long(M.x86.R_SI); 2589 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 2590 } else { 2591 val = fetch_data_word(M.x86.R_SI); 2592 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 2593 } 2594 M.x86.R_SI += inc; 2595 M.x86.R_DI += inc; 2596 } 2597 DECODE_CLEAR_SEGOVR(); 2598 END_OF_INSTR(); 2599 } 2600 2601 /**************************************************************************** 2602 REMARKS: 2603 Handles opcode 0xa6 2604 ****************************************************************************/ 2605 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 2606 { 2607 s8 val1, val2; 2608 int inc; 2609 2610 START_OF_INSTR(); 2611 DECODE_PRINTF("CMPS\tBYTE\n"); 2612 TRACE_AND_STEP(); 2613 if (ACCESS_FLAG(F_DF)) /* down */ 2614 inc = -1; 2615 else 2616 inc = 1; 2617 2618 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2619 /* REPE */ 2620 /* move them until CX is ZERO. */ 2621 while (M.x86.R_CX != 0) { 2622 val1 = fetch_data_byte(M.x86.R_SI); 2623 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2624 cmp_byte(val1, val2); 2625 M.x86.R_CX -= 1; 2626 M.x86.R_SI += inc; 2627 M.x86.R_DI += inc; 2628 if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break; 2629 if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; 2630 } 2631 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2632 } else { 2633 val1 = fetch_data_byte(M.x86.R_SI); 2634 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2635 cmp_byte(val1, val2); 2636 M.x86.R_SI += inc; 2637 M.x86.R_DI += inc; 2638 } 2639 DECODE_CLEAR_SEGOVR(); 2640 END_OF_INSTR(); 2641 } 2642 2643 /**************************************************************************** 2644 REMARKS: 2645 Handles opcode 0xa7 2646 ****************************************************************************/ 2647 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 2648 { 2649 u32 val1,val2; 2650 int inc; 2651 2652 START_OF_INSTR(); 2653 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2654 DECODE_PRINTF("CMPS\tDWORD\n"); 2655 inc = 4; 2656 } else { 2657 DECODE_PRINTF("CMPS\tWORD\n"); 2658 inc = 2; 2659 } 2660 if (ACCESS_FLAG(F_DF)) /* down */ 2661 inc = -inc; 2662 2663 TRACE_AND_STEP(); 2664 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2665 /* REPE */ 2666 /* move them until CX is ZERO. */ 2667 while (M.x86.R_CX != 0) { 2668 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2669 val1 = fetch_data_long(M.x86.R_SI); 2670 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2671 cmp_long(val1, val2); 2672 } else { 2673 val1 = fetch_data_word(M.x86.R_SI); 2674 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2675 cmp_word((u16)val1, (u16)val2); 2676 } 2677 M.x86.R_CX -= 1; 2678 M.x86.R_SI += inc; 2679 M.x86.R_DI += inc; 2680 if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break; 2681 if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; 2682 } 2683 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2684 } else { 2685 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2686 val1 = fetch_data_long(M.x86.R_SI); 2687 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2688 cmp_long(val1, val2); 2689 } else { 2690 val1 = fetch_data_word(M.x86.R_SI); 2691 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2692 cmp_word((u16)val1, (u16)val2); 2693 } 2694 M.x86.R_SI += inc; 2695 M.x86.R_DI += inc; 2696 } 2697 DECODE_CLEAR_SEGOVR(); 2698 END_OF_INSTR(); 2699 } 2700 2701 /**************************************************************************** 2702 REMARKS: 2703 Handles opcode 0xa8 2704 ****************************************************************************/ 2705 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 2706 { 2707 int imm; 2708 2709 START_OF_INSTR(); 2710 DECODE_PRINTF("TEST\tAL,"); 2711 imm = fetch_byte_imm(); 2712 DECODE_PRINTF2("%04x\n", imm); 2713 TRACE_AND_STEP(); 2714 test_byte(M.x86.R_AL, (u8)imm); 2715 DECODE_CLEAR_SEGOVR(); 2716 END_OF_INSTR(); 2717 } 2718 2719 /**************************************************************************** 2720 REMARKS: 2721 Handles opcode 0xa9 2722 ****************************************************************************/ 2723 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 2724 { 2725 u32 srcval; 2726 2727 START_OF_INSTR(); 2728 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2729 DECODE_PRINTF("TEST\tEAX,"); 2730 srcval = fetch_long_imm(); 2731 } else { 2732 DECODE_PRINTF("TEST\tAX,"); 2733 srcval = fetch_word_imm(); 2734 } 2735 DECODE_PRINTF2("%x\n", srcval); 2736 TRACE_AND_STEP(); 2737 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2738 test_long(M.x86.R_EAX, srcval); 2739 } else { 2740 test_word(M.x86.R_AX, (u16)srcval); 2741 } 2742 DECODE_CLEAR_SEGOVR(); 2743 END_OF_INSTR(); 2744 } 2745 2746 /**************************************************************************** 2747 REMARKS: 2748 Handles opcode 0xaa 2749 ****************************************************************************/ 2750 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 2751 { 2752 int inc; 2753 2754 START_OF_INSTR(); 2755 DECODE_PRINTF("STOS\tBYTE\n"); 2756 if (ACCESS_FLAG(F_DF)) /* down */ 2757 inc = -1; 2758 else 2759 inc = 1; 2760 TRACE_AND_STEP(); 2761 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2762 /* dont care whether REPE or REPNE */ 2763 /* move them until CX is ZERO. */ 2764 while (M.x86.R_CX != 0) { 2765 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 2766 M.x86.R_CX -= 1; 2767 M.x86.R_DI += inc; 2768 } 2769 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2770 } else { 2771 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 2772 M.x86.R_DI += inc; 2773 } 2774 DECODE_CLEAR_SEGOVR(); 2775 END_OF_INSTR(); 2776 } 2777 2778 /**************************************************************************** 2779 REMARKS: 2780 Handles opcode 0xab 2781 ****************************************************************************/ 2782 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 2783 { 2784 int inc; 2785 u32 count; 2786 2787 START_OF_INSTR(); 2788 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2789 DECODE_PRINTF("STOS\tDWORD\n"); 2790 if (ACCESS_FLAG(F_DF)) /* down */ 2791 inc = -4; 2792 else 2793 inc = 4; 2794 } else { 2795 DECODE_PRINTF("STOS\tWORD\n"); 2796 if (ACCESS_FLAG(F_DF)) /* down */ 2797 inc = -2; 2798 else 2799 inc = 2; 2800 } 2801 TRACE_AND_STEP(); 2802 count = 1; 2803 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2804 /* dont care whether REPE or REPNE */ 2805 /* move them until CX is ZERO. */ 2806 count = M.x86.R_CX; 2807 M.x86.R_CX = 0; 2808 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2809 } 2810 while (count--) { 2811 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2812 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 2813 } else { 2814 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 2815 } 2816 M.x86.R_DI += inc; 2817 } 2818 DECODE_CLEAR_SEGOVR(); 2819 END_OF_INSTR(); 2820 } 2821 2822 /**************************************************************************** 2823 REMARKS: 2824 Handles opcode 0xac 2825 ****************************************************************************/ 2826 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 2827 { 2828 int inc; 2829 2830 START_OF_INSTR(); 2831 DECODE_PRINTF("LODS\tBYTE\n"); 2832 TRACE_AND_STEP(); 2833 if (ACCESS_FLAG(F_DF)) /* down */ 2834 inc = -1; 2835 else 2836 inc = 1; 2837 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2838 /* dont care whether REPE or REPNE */ 2839 /* move them until CX is ZERO. */ 2840 while (M.x86.R_CX != 0) { 2841 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 2842 M.x86.R_CX -= 1; 2843 M.x86.R_SI += inc; 2844 } 2845 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2846 } else { 2847 M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 2848 M.x86.R_SI += inc; 2849 } 2850 DECODE_CLEAR_SEGOVR(); 2851 END_OF_INSTR(); 2852 } 2853 2854 /**************************************************************************** 2855 REMARKS: 2856 Handles opcode 0xad 2857 ****************************************************************************/ 2858 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 2859 { 2860 int inc; 2861 u32 count; 2862 2863 START_OF_INSTR(); 2864 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2865 DECODE_PRINTF("LODS\tDWORD\n"); 2866 if (ACCESS_FLAG(F_DF)) /* down */ 2867 inc = -4; 2868 else 2869 inc = 4; 2870 } else { 2871 DECODE_PRINTF("LODS\tWORD\n"); 2872 if (ACCESS_FLAG(F_DF)) /* down */ 2873 inc = -2; 2874 else 2875 inc = 2; 2876 } 2877 TRACE_AND_STEP(); 2878 count = 1; 2879 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2880 /* dont care whether REPE or REPNE */ 2881 /* move them until CX is ZERO. */ 2882 count = M.x86.R_CX; 2883 M.x86.R_CX = 0; 2884 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2885 } 2886 while (count--) { 2887 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2888 M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 2889 } else { 2890 M.x86.R_AX = fetch_data_word(M.x86.R_SI); 2891 } 2892 M.x86.R_SI += inc; 2893 } 2894 DECODE_CLEAR_SEGOVR(); 2895 END_OF_INSTR(); 2896 } 2897 2898 /**************************************************************************** 2899 REMARKS: 2900 Handles opcode 0xae 2901 ****************************************************************************/ 2902 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 2903 { 2904 s8 val2; 2905 int inc; 2906 2907 START_OF_INSTR(); 2908 DECODE_PRINTF("SCAS\tBYTE\n"); 2909 TRACE_AND_STEP(); 2910 if (ACCESS_FLAG(F_DF)) /* down */ 2911 inc = -1; 2912 else 2913 inc = 1; 2914 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 2915 /* REPE */ 2916 /* move them until CX is ZERO. */ 2917 while (M.x86.R_CX != 0) { 2918 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2919 cmp_byte(M.x86.R_AL, val2); 2920 M.x86.R_CX -= 1; 2921 M.x86.R_DI += inc; 2922 if (ACCESS_FLAG(F_ZF) == 0) 2923 break; 2924 } 2925 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 2926 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 2927 /* REPNE */ 2928 /* move them until CX is ZERO. */ 2929 while (M.x86.R_CX != 0) { 2930 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2931 cmp_byte(M.x86.R_AL, val2); 2932 M.x86.R_CX -= 1; 2933 M.x86.R_DI += inc; 2934 if (ACCESS_FLAG(F_ZF)) 2935 break; /* zero flag set means equal */ 2936 } 2937 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 2938 } else { 2939 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2940 cmp_byte(M.x86.R_AL, val2); 2941 M.x86.R_DI += inc; 2942 } 2943 DECODE_CLEAR_SEGOVR(); 2944 END_OF_INSTR(); 2945 } 2946 2947 /**************************************************************************** 2948 REMARKS: 2949 Handles opcode 0xaf 2950 ****************************************************************************/ 2951 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 2952 { 2953 int inc; 2954 u32 val; 2955 2956 START_OF_INSTR(); 2957 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2958 DECODE_PRINTF("SCAS\tDWORD\n"); 2959 if (ACCESS_FLAG(F_DF)) /* down */ 2960 inc = -4; 2961 else 2962 inc = 4; 2963 } else { 2964 DECODE_PRINTF("SCAS\tWORD\n"); 2965 if (ACCESS_FLAG(F_DF)) /* down */ 2966 inc = -2; 2967 else 2968 inc = 2; 2969 } 2970 TRACE_AND_STEP(); 2971 if (M.x86.mode & SYSMODE_PREFIX_REPE) { 2972 /* REPE */ 2973 /* move them until CX is ZERO. */ 2974 while (M.x86.R_CX != 0) { 2975 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2976 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2977 cmp_long(M.x86.R_EAX, val); 2978 } else { 2979 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2980 cmp_word(M.x86.R_AX, (u16)val); 2981 } 2982 M.x86.R_CX -= 1; 2983 M.x86.R_DI += inc; 2984 if (ACCESS_FLAG(F_ZF) == 0) 2985 break; 2986 } 2987 M.x86.mode &= ~SYSMODE_PREFIX_REPE; 2988 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 2989 /* REPNE */ 2990 /* move them until CX is ZERO. */ 2991 while (M.x86.R_CX != 0) { 2992 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2993 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2994 cmp_long(M.x86.R_EAX, val); 2995 } else { 2996 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2997 cmp_word(M.x86.R_AX, (u16)val); 2998 } 2999 M.x86.R_CX -= 1; 3000 M.x86.R_DI += inc; 3001 if (ACCESS_FLAG(F_ZF)) 3002 break; /* zero flag set means equal */ 3003 } 3004 M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 3005 } else { 3006 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3007 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 3008 cmp_long(M.x86.R_EAX, val); 3009 } else { 3010 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 3011 cmp_word(M.x86.R_AX, (u16)val); 3012 } 3013 M.x86.R_DI += inc; 3014 } 3015 DECODE_CLEAR_SEGOVR(); 3016 END_OF_INSTR(); 3017 } 3018 3019 /**************************************************************************** 3020 REMARKS: 3021 Handles opcode 0xb0 - 0xb7 3022 ****************************************************************************/ 3023 void x86emuOp_mov_byte_register_IMM(u8 op1) 3024 { 3025 u8 imm, *ptr; 3026 3027 START_OF_INSTR(); 3028 DECODE_PRINTF("MOV\t"); 3029 ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7); 3030 DECODE_PRINTF(","); 3031 imm = fetch_byte_imm(); 3032 DECODE_PRINTF2("%x\n", imm); 3033 TRACE_AND_STEP(); 3034 *ptr = imm; 3035 DECODE_CLEAR_SEGOVR(); 3036 END_OF_INSTR(); 3037 } 3038 3039 /**************************************************************************** 3040 REMARKS: 3041 Handles opcode 0xb8 - 0xbf 3042 ****************************************************************************/ 3043 void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1)) 3044 { 3045 u32 srcval; 3046 3047 op1 &= 0x7; 3048 3049 START_OF_INSTR(); 3050 DECODE_PRINTF("MOV\t"); 3051 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3052 u32 *reg32; 3053 reg32 = DECODE_RM_LONG_REGISTER(op1); 3054 srcval = fetch_long_imm(); 3055 DECODE_PRINTF2(",%x\n", srcval); 3056 TRACE_AND_STEP(); 3057 *reg32 = srcval; 3058 } else { 3059 u16 *reg16; 3060 reg16 = DECODE_RM_WORD_REGISTER(op1); 3061 srcval = fetch_word_imm(); 3062 DECODE_PRINTF2(",%x\n", srcval); 3063 TRACE_AND_STEP(); 3064 *reg16 = (u16)srcval; 3065 } 3066 DECODE_CLEAR_SEGOVR(); 3067 END_OF_INSTR(); 3068 } 3069 3070 /**************************************************************************** 3071 REMARKS: 3072 Handles opcode 0xc0 3073 ****************************************************************************/ 3074 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 3075 { 3076 int mod, rl, rh; 3077 u8 *destreg; 3078 uint destoffset; 3079 u8 destval; 3080 u8 amt; 3081 3082 /* 3083 * Yet another weirdo special case instruction format. Part of 3084 * the opcode held below in "RH". Doubly nested case would 3085 * result, except that the decoded instruction 3086 */ 3087 START_OF_INSTR(); 3088 FETCH_DECODE_MODRM(mod, rh, rl); 3089 #ifdef DEBUG 3090 if (DEBUG_DECODE()) { 3091 /* XXX DECODE_PRINTF may be changed to something more 3092 general, so that it is important to leave the strings 3093 in the same format, even though the result is that the 3094 above test is done twice. */ 3095 3096 switch (rh) { 3097 case 0: 3098 DECODE_PRINTF("ROL\t"); 3099 break; 3100 case 1: 3101 DECODE_PRINTF("ROR\t"); 3102 break; 3103 case 2: 3104 DECODE_PRINTF("RCL\t"); 3105 break; 3106 case 3: 3107 DECODE_PRINTF("RCR\t"); 3108 break; 3109 case 4: 3110 DECODE_PRINTF("SHL\t"); 3111 break; 3112 case 5: 3113 DECODE_PRINTF("SHR\t"); 3114 break; 3115 case 6: 3116 DECODE_PRINTF("SAL\t"); 3117 break; 3118 case 7: 3119 DECODE_PRINTF("SAR\t"); 3120 break; 3121 } 3122 } 3123 #endif 3124 /* know operation, decode the mod byte to find the addressing 3125 mode. */ 3126 if (mod < 3) { 3127 DECODE_PRINTF("BYTE PTR "); 3128 destoffset = decode_rmXX_address(mod, rl); 3129 amt = fetch_byte_imm(); 3130 DECODE_PRINTF2(",%x\n", amt); 3131 destval = fetch_data_byte(destoffset); 3132 TRACE_AND_STEP(); 3133 destval = (*opcD0_byte_operation[rh]) (destval, amt); 3134 store_data_byte(destoffset, destval); 3135 } else { /* register to register */ 3136 destreg = DECODE_RM_BYTE_REGISTER(rl); 3137 amt = fetch_byte_imm(); 3138 DECODE_PRINTF2(",%x\n", amt); 3139 TRACE_AND_STEP(); 3140 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 3141 *destreg = destval; 3142 } 3143 DECODE_CLEAR_SEGOVR(); 3144 END_OF_INSTR(); 3145 } 3146 3147 /**************************************************************************** 3148 REMARKS: 3149 Handles opcode 0xc1 3150 ****************************************************************************/ 3151 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 3152 { 3153 int mod, rl, rh; 3154 uint destoffset; 3155 u8 amt; 3156 3157 /* 3158 * Yet another weirdo special case instruction format. Part of 3159 * the opcode held below in "RH". Doubly nested case would 3160 * result, except that the decoded instruction 3161 */ 3162 START_OF_INSTR(); 3163 FETCH_DECODE_MODRM(mod, rh, rl); 3164 #ifdef DEBUG 3165 if (DEBUG_DECODE()) { 3166 /* XXX DECODE_PRINTF may be changed to something more 3167 general, so that it is important to leave the strings 3168 in the same format, even though the result is that the 3169 above test is done twice. */ 3170 3171 switch (rh) { 3172 case 0: 3173 DECODE_PRINTF("ROL\t"); 3174 break; 3175 case 1: 3176 DECODE_PRINTF("ROR\t"); 3177 break; 3178 case 2: 3179 DECODE_PRINTF("RCL\t"); 3180 break; 3181 case 3: 3182 DECODE_PRINTF("RCR\t"); 3183 break; 3184 case 4: 3185 DECODE_PRINTF("SHL\t"); 3186 break; 3187 case 5: 3188 DECODE_PRINTF("SHR\t"); 3189 break; 3190 case 6: 3191 DECODE_PRINTF("SAL\t"); 3192 break; 3193 case 7: 3194 DECODE_PRINTF("SAR\t"); 3195 break; 3196 } 3197 } 3198 #endif 3199 /* know operation, decode the mod byte to find the addressing 3200 mode. */ 3201 if (mod < 3) { 3202 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3203 u32 destval; 3204 3205 DECODE_PRINTF("DWORD PTR "); 3206 destoffset = decode_rmXX_address(mod, rl); 3207 amt = fetch_byte_imm(); 3208 DECODE_PRINTF2(",%x\n", amt); 3209 destval = fetch_data_long(destoffset); 3210 TRACE_AND_STEP(); 3211 destval = (*opcD1_long_operation[rh]) (destval, amt); 3212 store_data_long(destoffset, destval); 3213 } else { 3214 u16 destval; 3215 3216 DECODE_PRINTF("WORD PTR "); 3217 destoffset = decode_rmXX_address(mod, rl); 3218 amt = fetch_byte_imm(); 3219 DECODE_PRINTF2(",%x\n", amt); 3220 destval = fetch_data_word(destoffset); 3221 TRACE_AND_STEP(); 3222 destval = (*opcD1_word_operation[rh]) (destval, amt); 3223 store_data_word(destoffset, destval); 3224 } 3225 } else { /* register to register */ 3226 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3227 u32 *destreg; 3228 3229 destreg = DECODE_RM_LONG_REGISTER(rl); 3230 amt = fetch_byte_imm(); 3231 DECODE_PRINTF2(",%x\n", amt); 3232 TRACE_AND_STEP(); 3233 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 3234 } else { 3235 u16 *destreg; 3236 3237 destreg = DECODE_RM_WORD_REGISTER(rl); 3238 amt = fetch_byte_imm(); 3239 DECODE_PRINTF2(",%x\n", amt); 3240 TRACE_AND_STEP(); 3241 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 3242 } 3243 } 3244 DECODE_CLEAR_SEGOVR(); 3245 END_OF_INSTR(); 3246 } 3247 3248 /**************************************************************************** 3249 REMARKS: 3250 Handles opcode 0xc2 3251 ****************************************************************************/ 3252 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 3253 { 3254 u16 imm; 3255 3256 START_OF_INSTR(); 3257 DECODE_PRINTF("RET\t"); 3258 imm = fetch_word_imm(); 3259 DECODE_PRINTF2("%x\n", imm); 3260 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 3261 TRACE_AND_STEP(); 3262 M.x86.R_IP = pop_word(); 3263 M.x86.R_SP += imm; 3264 DECODE_CLEAR_SEGOVR(); 3265 END_OF_INSTR(); 3266 } 3267 3268 /**************************************************************************** 3269 REMARKS: 3270 Handles opcode 0xc3 3271 ****************************************************************************/ 3272 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 3273 { 3274 START_OF_INSTR(); 3275 DECODE_PRINTF("RET\n"); 3276 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 3277 TRACE_AND_STEP(); 3278 M.x86.R_IP = pop_word(); 3279 DECODE_CLEAR_SEGOVR(); 3280 END_OF_INSTR(); 3281 } 3282 3283 /**************************************************************************** 3284 REMARKS: 3285 Handles opcode 0xc4 3286 ****************************************************************************/ 3287 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 3288 { 3289 int mod, rh, rl; 3290 u16 *dstreg; 3291 uint srcoffset; 3292 3293 START_OF_INSTR(); 3294 DECODE_PRINTF("LES\t"); 3295 FETCH_DECODE_MODRM(mod, rh, rl); 3296 if (mod < 3) { 3297 dstreg = DECODE_RM_WORD_REGISTER(rh); 3298 DECODE_PRINTF(","); 3299 srcoffset = decode_rmXX_address(mod, rl); 3300 DECODE_PRINTF("\n"); 3301 TRACE_AND_STEP(); 3302 *dstreg = fetch_data_word(srcoffset); 3303 M.x86.R_ES = fetch_data_word(srcoffset + 2); 3304 } 3305 /* else UNDEFINED! register to register */ 3306 3307 DECODE_CLEAR_SEGOVR(); 3308 END_OF_INSTR(); 3309 } 3310 3311 /**************************************************************************** 3312 REMARKS: 3313 Handles opcode 0xc5 3314 ****************************************************************************/ 3315 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 3316 { 3317 int mod, rh, rl; 3318 u16 *dstreg; 3319 uint srcoffset; 3320 3321 START_OF_INSTR(); 3322 DECODE_PRINTF("LDS\t"); 3323 FETCH_DECODE_MODRM(mod, rh, rl); 3324 if (mod < 3) { 3325 dstreg = DECODE_RM_WORD_REGISTER(rh); 3326 DECODE_PRINTF(","); 3327 srcoffset = decode_rmXX_address(mod, rl); 3328 DECODE_PRINTF("\n"); 3329 TRACE_AND_STEP(); 3330 *dstreg = fetch_data_word(srcoffset); 3331 M.x86.R_DS = fetch_data_word(srcoffset + 2); 3332 } 3333 /* else UNDEFINED! */ 3334 DECODE_CLEAR_SEGOVR(); 3335 END_OF_INSTR(); 3336 } 3337 3338 /**************************************************************************** 3339 REMARKS: 3340 Handles opcode 0xc6 3341 ****************************************************************************/ 3342 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 3343 { 3344 int mod, rl, rh; 3345 u8 *destreg; 3346 uint destoffset; 3347 u8 imm; 3348 3349 START_OF_INSTR(); 3350 DECODE_PRINTF("MOV\t"); 3351 FETCH_DECODE_MODRM(mod, rh, rl); 3352 if (rh != 0) { 3353 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 3354 HALT_SYS(); 3355 } 3356 if (mod < 3) { 3357 DECODE_PRINTF("BYTE PTR "); 3358 destoffset = decode_rmXX_address(mod, rl); 3359 imm = fetch_byte_imm(); 3360 DECODE_PRINTF2(",%2x\n", imm); 3361 TRACE_AND_STEP(); 3362 store_data_byte(destoffset, imm); 3363 } else { /* register to register */ 3364 destreg = DECODE_RM_BYTE_REGISTER(rl); 3365 imm = fetch_byte_imm(); 3366 DECODE_PRINTF2(",%2x\n", imm); 3367 TRACE_AND_STEP(); 3368 *destreg = imm; 3369 } 3370 DECODE_CLEAR_SEGOVR(); 3371 END_OF_INSTR(); 3372 } 3373 3374 /**************************************************************************** 3375 REMARKS: 3376 Handles opcode 0xc7 3377 ****************************************************************************/ 3378 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 3379 { 3380 int mod, rl, rh; 3381 uint destoffset; 3382 3383 START_OF_INSTR(); 3384 DECODE_PRINTF("MOV\t"); 3385 FETCH_DECODE_MODRM(mod, rh, rl); 3386 if (rh != 0) { 3387 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 3388 HALT_SYS(); 3389 } 3390 if (mod < 3) { 3391 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3392 u32 imm; 3393 3394 DECODE_PRINTF("DWORD PTR "); 3395 destoffset = decode_rmXX_address(mod, rl); 3396 imm = fetch_long_imm(); 3397 DECODE_PRINTF2(",%x\n", imm); 3398 TRACE_AND_STEP(); 3399 store_data_long(destoffset, imm); 3400 } else { 3401 u16 imm; 3402 3403 DECODE_PRINTF("WORD PTR "); 3404 destoffset = decode_rmXX_address(mod, rl); 3405 imm = fetch_word_imm(); 3406 DECODE_PRINTF2(",%x\n", imm); 3407 TRACE_AND_STEP(); 3408 store_data_word(destoffset, imm); 3409 } 3410 } else { /* register to register */ 3411 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3412 u32 *destreg; 3413 u32 imm; 3414 3415 destreg = DECODE_RM_LONG_REGISTER(rl); 3416 imm = fetch_long_imm(); 3417 DECODE_PRINTF2(",%x\n", imm); 3418 TRACE_AND_STEP(); 3419 *destreg = imm; 3420 } else { 3421 u16 *destreg; 3422 u16 imm; 3423 3424 destreg = DECODE_RM_WORD_REGISTER(rl); 3425 imm = fetch_word_imm(); 3426 DECODE_PRINTF2(",%x\n", imm); 3427 TRACE_AND_STEP(); 3428 *destreg = imm; 3429 } 3430 } 3431 DECODE_CLEAR_SEGOVR(); 3432 END_OF_INSTR(); 3433 } 3434 3435 /**************************************************************************** 3436 REMARKS: 3437 Handles opcode 0xc8 3438 ****************************************************************************/ 3439 void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 3440 { 3441 u16 local,frame_pointer; 3442 u8 nesting; 3443 int i; 3444 3445 START_OF_INSTR(); 3446 local = fetch_word_imm(); 3447 nesting = fetch_byte_imm(); 3448 DECODE_PRINTF2("ENTER %x\n", local); 3449 DECODE_PRINTF2(",%x\n", nesting); 3450 TRACE_AND_STEP(); 3451 push_word(M.x86.R_BP); 3452 frame_pointer = M.x86.R_SP; 3453 if (nesting > 0) { 3454 for (i = 1; i < nesting; i++) { 3455 M.x86.R_BP -= 2; 3456 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 3457 } 3458 push_word(frame_pointer); 3459 } 3460 M.x86.R_BP = frame_pointer; 3461 M.x86.R_SP = (u16)(M.x86.R_SP - local); 3462 DECODE_CLEAR_SEGOVR(); 3463 END_OF_INSTR(); 3464 } 3465 3466 /**************************************************************************** 3467 REMARKS: 3468 Handles opcode 0xc9 3469 ****************************************************************************/ 3470 void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 3471 { 3472 START_OF_INSTR(); 3473 DECODE_PRINTF("LEAVE\n"); 3474 TRACE_AND_STEP(); 3475 M.x86.R_SP = M.x86.R_BP; 3476 M.x86.R_BP = pop_word(); 3477 DECODE_CLEAR_SEGOVR(); 3478 END_OF_INSTR(); 3479 } 3480 3481 /**************************************************************************** 3482 REMARKS: 3483 Handles opcode 0xca 3484 ****************************************************************************/ 3485 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 3486 { 3487 u16 imm; 3488 3489 START_OF_INSTR(); 3490 DECODE_PRINTF("RETF\t"); 3491 imm = fetch_word_imm(); 3492 DECODE_PRINTF2("%x\n", imm); 3493 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 3494 TRACE_AND_STEP(); 3495 M.x86.R_IP = pop_word(); 3496 M.x86.R_CS = pop_word(); 3497 M.x86.R_SP += imm; 3498 DECODE_CLEAR_SEGOVR(); 3499 END_OF_INSTR(); 3500 } 3501 3502 /**************************************************************************** 3503 REMARKS: 3504 Handles opcode 0xcb 3505 ****************************************************************************/ 3506 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 3507 { 3508 START_OF_INSTR(); 3509 DECODE_PRINTF("RETF\n"); 3510 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 3511 TRACE_AND_STEP(); 3512 M.x86.R_IP = pop_word(); 3513 M.x86.R_CS = pop_word(); 3514 DECODE_CLEAR_SEGOVR(); 3515 END_OF_INSTR(); 3516 } 3517 3518 /**************************************************************************** 3519 REMARKS: 3520 Handles opcode 0xcc 3521 ****************************************************************************/ 3522 void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 3523 { 3524 u16 tmp; 3525 3526 START_OF_INSTR(); 3527 DECODE_PRINTF("INT 3\n"); 3528 tmp = (u16) mem_access_word(3 * 4 + 2); 3529 /* access the segment register */ 3530 TRACE_AND_STEP(); 3531 if (_X86EMU_intrTab[3]) { 3532 (*_X86EMU_intrTab[3])(3); 3533 } else { 3534 push_word((u16)M.x86.R_FLG); 3535 CLEAR_FLAG(F_IF); 3536 CLEAR_FLAG(F_TF); 3537 push_word(M.x86.R_CS); 3538 M.x86.R_CS = mem_access_word(3 * 4 + 2); 3539 push_word(M.x86.R_IP); 3540 M.x86.R_IP = mem_access_word(3 * 4); 3541 } 3542 DECODE_CLEAR_SEGOVR(); 3543 END_OF_INSTR(); 3544 } 3545 3546 /**************************************************************************** 3547 REMARKS: 3548 Handles opcode 0xcd 3549 ****************************************************************************/ 3550 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 3551 { 3552 u16 tmp; 3553 u8 intnum; 3554 3555 START_OF_INSTR(); 3556 DECODE_PRINTF("INT\t"); 3557 intnum = fetch_byte_imm(); 3558 DECODE_PRINTF2("%x\n", intnum); 3559 tmp = mem_access_word(intnum * 4 + 2); 3560 TRACE_AND_STEP(); 3561 if (_X86EMU_intrTab[intnum]) { 3562 (*_X86EMU_intrTab[intnum])(intnum); 3563 } else { 3564 push_word((u16)M.x86.R_FLG); 3565 CLEAR_FLAG(F_IF); 3566 CLEAR_FLAG(F_TF); 3567 push_word(M.x86.R_CS); 3568 M.x86.R_CS = mem_access_word(intnum * 4 + 2); 3569 push_word(M.x86.R_IP); 3570 M.x86.R_IP = mem_access_word(intnum * 4); 3571 } 3572 DECODE_CLEAR_SEGOVR(); 3573 END_OF_INSTR(); 3574 } 3575 3576 /**************************************************************************** 3577 REMARKS: 3578 Handles opcode 0xce 3579 ****************************************************************************/ 3580 void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 3581 { 3582 u16 tmp; 3583 3584 START_OF_INSTR(); 3585 DECODE_PRINTF("INTO\n"); 3586 TRACE_AND_STEP(); 3587 if (ACCESS_FLAG(F_OF)) { 3588 tmp = mem_access_word(4 * 4 + 2); 3589 if (_X86EMU_intrTab[4]) { 3590 (*_X86EMU_intrTab[4])(4); 3591 } else { 3592 push_word((u16)M.x86.R_FLG); 3593 CLEAR_FLAG(F_IF); 3594 CLEAR_FLAG(F_TF); 3595 push_word(M.x86.R_CS); 3596 M.x86.R_CS = mem_access_word(4 * 4 + 2); 3597 push_word(M.x86.R_IP); 3598 M.x86.R_IP = mem_access_word(4 * 4); 3599 } 3600 } 3601 DECODE_CLEAR_SEGOVR(); 3602 END_OF_INSTR(); 3603 } 3604 3605 /**************************************************************************** 3606 REMARKS: 3607 Handles opcode 0xcf 3608 ****************************************************************************/ 3609 void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 3610 { 3611 START_OF_INSTR(); 3612 DECODE_PRINTF("IRET\n"); 3613 3614 TRACE_AND_STEP(); 3615 3616 M.x86.R_IP = pop_word(); 3617 M.x86.R_CS = pop_word(); 3618 M.x86.R_FLG = pop_word(); 3619 DECODE_CLEAR_SEGOVR(); 3620 END_OF_INSTR(); 3621 } 3622 3623 /**************************************************************************** 3624 REMARKS: 3625 Handles opcode 0xd0 3626 ****************************************************************************/ 3627 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 3628 { 3629 int mod, rl, rh; 3630 u8 *destreg; 3631 uint destoffset; 3632 u8 destval; 3633 3634 /* 3635 * Yet another weirdo special case instruction format. Part of 3636 * the opcode held below in "RH". Doubly nested case would 3637 * result, except that the decoded instruction 3638 */ 3639 START_OF_INSTR(); 3640 FETCH_DECODE_MODRM(mod, rh, rl); 3641 #ifdef DEBUG 3642 if (DEBUG_DECODE()) { 3643 /* XXX DECODE_PRINTF may be changed to something more 3644 general, so that it is important to leave the strings 3645 in the same format, even though the result is that the 3646 above test is done twice. */ 3647 switch (rh) { 3648 case 0: 3649 DECODE_PRINTF("ROL\t"); 3650 break; 3651 case 1: 3652 DECODE_PRINTF("ROR\t"); 3653 break; 3654 case 2: 3655 DECODE_PRINTF("RCL\t"); 3656 break; 3657 case 3: 3658 DECODE_PRINTF("RCR\t"); 3659 break; 3660 case 4: 3661 DECODE_PRINTF("SHL\t"); 3662 break; 3663 case 5: 3664 DECODE_PRINTF("SHR\t"); 3665 break; 3666 case 6: 3667 DECODE_PRINTF("SAL\t"); 3668 break; 3669 case 7: 3670 DECODE_PRINTF("SAR\t"); 3671 break; 3672 } 3673 } 3674 #endif 3675 /* know operation, decode the mod byte to find the addressing 3676 mode. */ 3677 if (mod < 3) { 3678 DECODE_PRINTF("BYTE PTR "); 3679 destoffset = decode_rmXX_address(mod, rl); 3680 DECODE_PRINTF(",1\n"); 3681 destval = fetch_data_byte(destoffset); 3682 TRACE_AND_STEP(); 3683 destval = (*opcD0_byte_operation[rh]) (destval, 1); 3684 store_data_byte(destoffset, destval); 3685 } else { /* register to register */ 3686 destreg = DECODE_RM_BYTE_REGISTER(rl); 3687 DECODE_PRINTF(",1\n"); 3688 TRACE_AND_STEP(); 3689 destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 3690 *destreg = destval; 3691 } 3692 DECODE_CLEAR_SEGOVR(); 3693 END_OF_INSTR(); 3694 } 3695 3696 /**************************************************************************** 3697 REMARKS: 3698 Handles opcode 0xd1 3699 ****************************************************************************/ 3700 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 3701 { 3702 int mod, rl, rh; 3703 uint destoffset; 3704 3705 /* 3706 * Yet another weirdo special case instruction format. Part of 3707 * the opcode held below in "RH". Doubly nested case would 3708 * result, except that the decoded instruction 3709 */ 3710 START_OF_INSTR(); 3711 FETCH_DECODE_MODRM(mod, rh, rl); 3712 #ifdef DEBUG 3713 if (DEBUG_DECODE()) { 3714 /* XXX DECODE_PRINTF may be changed to something more 3715 general, so that it is important to leave the strings 3716 in the same format, even though the result is that the 3717 above test is done twice. */ 3718 switch (rh) { 3719 case 0: 3720 DECODE_PRINTF("ROL\t"); 3721 break; 3722 case 1: 3723 DECODE_PRINTF("ROR\t"); 3724 break; 3725 case 2: 3726 DECODE_PRINTF("RCL\t"); 3727 break; 3728 case 3: 3729 DECODE_PRINTF("RCR\t"); 3730 break; 3731 case 4: 3732 DECODE_PRINTF("SHL\t"); 3733 break; 3734 case 5: 3735 DECODE_PRINTF("SHR\t"); 3736 break; 3737 case 6: 3738 DECODE_PRINTF("SAL\t"); 3739 break; 3740 case 7: 3741 DECODE_PRINTF("SAR\t"); 3742 break; 3743 } 3744 } 3745 #endif 3746 /* know operation, decode the mod byte to find the addressing 3747 mode. */ 3748 if (mod < 3) { 3749 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3750 u32 destval; 3751 3752 DECODE_PRINTF("DWORD PTR "); 3753 destoffset = decode_rmXX_address(mod, rl); 3754 DECODE_PRINTF(",1\n"); 3755 destval = fetch_data_long(destoffset); 3756 TRACE_AND_STEP(); 3757 destval = (*opcD1_long_operation[rh]) (destval, 1); 3758 store_data_long(destoffset, destval); 3759 } else { 3760 u16 destval; 3761 3762 DECODE_PRINTF("WORD PTR "); 3763 destoffset = decode_rmXX_address(mod, rl); 3764 DECODE_PRINTF(",1\n"); 3765 destval = fetch_data_word(destoffset); 3766 TRACE_AND_STEP(); 3767 destval = (*opcD1_word_operation[rh]) (destval, 1); 3768 store_data_word(destoffset, destval); 3769 } 3770 } else { /* register to register */ 3771 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3772 u32 destval; 3773 u32 *destreg; 3774 3775 destreg = DECODE_RM_LONG_REGISTER(rl); 3776 DECODE_PRINTF(",1\n"); 3777 TRACE_AND_STEP(); 3778 destval = (*opcD1_long_operation[rh]) (*destreg, 1); 3779 *destreg = destval; 3780 } else { 3781 u16 destval; 3782 u16 *destreg; 3783 3784 destreg = DECODE_RM_WORD_REGISTER(rl); 3785 DECODE_PRINTF(",1\n"); 3786 TRACE_AND_STEP(); 3787 destval = (*opcD1_word_operation[rh]) (*destreg, 1); 3788 *destreg = destval; 3789 } 3790 } 3791 DECODE_CLEAR_SEGOVR(); 3792 END_OF_INSTR(); 3793 } 3794 3795 /**************************************************************************** 3796 REMARKS: 3797 Handles opcode 0xd2 3798 ****************************************************************************/ 3799 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 3800 { 3801 int mod, rl, rh; 3802 u8 *destreg; 3803 uint destoffset; 3804 u8 destval; 3805 u8 amt; 3806 3807 /* 3808 * Yet another weirdo special case instruction format. Part of 3809 * the opcode held below in "RH". Doubly nested case would 3810 * result, except that the decoded instruction 3811 */ 3812 START_OF_INSTR(); 3813 FETCH_DECODE_MODRM(mod, rh, rl); 3814 #ifdef DEBUG 3815 if (DEBUG_DECODE()) { 3816 /* XXX DECODE_PRINTF may be changed to something more 3817 general, so that it is important to leave the strings 3818 in the same format, even though the result is that the 3819 above test is done twice. */ 3820 switch (rh) { 3821 case 0: 3822 DECODE_PRINTF("ROL\t"); 3823 break; 3824 case 1: 3825 DECODE_PRINTF("ROR\t"); 3826 break; 3827 case 2: 3828 DECODE_PRINTF("RCL\t"); 3829 break; 3830 case 3: 3831 DECODE_PRINTF("RCR\t"); 3832 break; 3833 case 4: 3834 DECODE_PRINTF("SHL\t"); 3835 break; 3836 case 5: 3837 DECODE_PRINTF("SHR\t"); 3838 break; 3839 case 6: 3840 DECODE_PRINTF("SAL\t"); 3841 break; 3842 case 7: 3843 DECODE_PRINTF("SAR\t"); 3844 break; 3845 } 3846 } 3847 #endif 3848 /* know operation, decode the mod byte to find the addressing 3849 mode. */ 3850 amt = M.x86.R_CL; 3851 if (mod < 3) { 3852 DECODE_PRINTF("BYTE PTR "); 3853 destoffset = decode_rmXX_address(mod, rl); 3854 DECODE_PRINTF(",CL\n"); 3855 destval = fetch_data_byte(destoffset); 3856 TRACE_AND_STEP(); 3857 destval = (*opcD0_byte_operation[rh]) (destval, amt); 3858 store_data_byte(destoffset, destval); 3859 } else { /* register to register */ 3860 destreg = DECODE_RM_BYTE_REGISTER(rl); 3861 DECODE_PRINTF(",CL\n"); 3862 TRACE_AND_STEP(); 3863 destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 3864 *destreg = destval; 3865 } 3866 DECODE_CLEAR_SEGOVR(); 3867 END_OF_INSTR(); 3868 } 3869 3870 /**************************************************************************** 3871 REMARKS: 3872 Handles opcode 0xd3 3873 ****************************************************************************/ 3874 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 3875 { 3876 int mod, rl, rh; 3877 uint destoffset; 3878 u8 amt; 3879 3880 /* 3881 * Yet another weirdo special case instruction format. Part of 3882 * the opcode held below in "RH". Doubly nested case would 3883 * result, except that the decoded instruction 3884 */ 3885 START_OF_INSTR(); 3886 FETCH_DECODE_MODRM(mod, rh, rl); 3887 #ifdef DEBUG 3888 if (DEBUG_DECODE()) { 3889 /* XXX DECODE_PRINTF may be changed to something more 3890 general, so that it is important to leave the strings 3891 in the same format, even though the result is that the 3892 above test is done twice. */ 3893 switch (rh) { 3894 case 0: 3895 DECODE_PRINTF("ROL\t"); 3896 break; 3897 case 1: 3898 DECODE_PRINTF("ROR\t"); 3899 break; 3900 case 2: 3901 DECODE_PRINTF("RCL\t"); 3902 break; 3903 case 3: 3904 DECODE_PRINTF("RCR\t"); 3905 break; 3906 case 4: 3907 DECODE_PRINTF("SHL\t"); 3908 break; 3909 case 5: 3910 DECODE_PRINTF("SHR\t"); 3911 break; 3912 case 6: 3913 DECODE_PRINTF("SAL\t"); 3914 break; 3915 case 7: 3916 DECODE_PRINTF("SAR\t"); 3917 break; 3918 } 3919 } 3920 #endif 3921 /* know operation, decode the mod byte to find the addressing 3922 mode. */ 3923 amt = M.x86.R_CL; 3924 if (mod < 3) { 3925 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3926 u32 destval; 3927 3928 DECODE_PRINTF("DWORD PTR "); 3929 destoffset = decode_rmXX_address(mod, rl); 3930 DECODE_PRINTF(",CL\n"); 3931 destval = fetch_data_long(destoffset); 3932 TRACE_AND_STEP(); 3933 destval = (*opcD1_long_operation[rh]) (destval, amt); 3934 store_data_long(destoffset, destval); 3935 } else { 3936 u16 destval; 3937 3938 DECODE_PRINTF("WORD PTR "); 3939 destoffset = decode_rmXX_address(mod, rl); 3940 DECODE_PRINTF(",CL\n"); 3941 destval = fetch_data_word(destoffset); 3942 TRACE_AND_STEP(); 3943 destval = (*opcD1_word_operation[rh]) (destval, amt); 3944 store_data_word(destoffset, destval); 3945 } 3946 } else { /* register to register */ 3947 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3948 u32 *destreg; 3949 3950 destreg = DECODE_RM_LONG_REGISTER(rl); 3951 DECODE_PRINTF(",CL\n"); 3952 TRACE_AND_STEP(); 3953 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 3954 } else { 3955 u16 *destreg; 3956 3957 destreg = DECODE_RM_WORD_REGISTER(rl); 3958 DECODE_PRINTF(",CL\n"); 3959 TRACE_AND_STEP(); 3960 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 3961 } 3962 } 3963 DECODE_CLEAR_SEGOVR(); 3964 END_OF_INSTR(); 3965 } 3966 3967 /**************************************************************************** 3968 REMARKS: 3969 Handles opcode 0xd4 3970 ****************************************************************************/ 3971 void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 3972 { 3973 u8 a; 3974 3975 START_OF_INSTR(); 3976 DECODE_PRINTF("AAM\n"); 3977 a = fetch_byte_imm(); /* this is a stupid encoding. */ 3978 if (a != 10) { 3979 DECODE_PRINTF("ERROR DECODING AAM\n"); 3980 TRACE_REGS(); 3981 HALT_SYS(); 3982 } 3983 TRACE_AND_STEP(); 3984 /* note the type change here --- returning AL and AH in AX. */ 3985 M.x86.R_AX = aam_word(M.x86.R_AL); 3986 DECODE_CLEAR_SEGOVR(); 3987 END_OF_INSTR(); 3988 } 3989 3990 /**************************************************************************** 3991 REMARKS: 3992 Handles opcode 0xd5 3993 ****************************************************************************/ 3994 void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 3995 { 3996 u8 a; 3997 3998 START_OF_INSTR(); 3999 DECODE_PRINTF("AAD\n"); 4000 a = fetch_byte_imm(); 4001 TRACE_AND_STEP(); 4002 M.x86.R_AX = aad_word(M.x86.R_AX); 4003 DECODE_CLEAR_SEGOVR(); 4004 END_OF_INSTR(); 4005 } 4006 4007 /* opcode 0xd6 ILLEGAL OPCODE */ 4008 4009 /**************************************************************************** 4010 REMARKS: 4011 Handles opcode 0xd7 4012 ****************************************************************************/ 4013 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 4014 { 4015 u16 addr; 4016 4017 START_OF_INSTR(); 4018 DECODE_PRINTF("XLAT\n"); 4019 TRACE_AND_STEP(); 4020 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 4021 M.x86.R_AL = fetch_data_byte(addr); 4022 DECODE_CLEAR_SEGOVR(); 4023 END_OF_INSTR(); 4024 } 4025 4026 /* instuctions D8 .. DF are in i87_ops.c */ 4027 4028 /**************************************************************************** 4029 REMARKS: 4030 Handles opcode 0xe0 4031 ****************************************************************************/ 4032 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 4033 { 4034 s16 ip; 4035 4036 START_OF_INSTR(); 4037 DECODE_PRINTF("LOOPNE\t"); 4038 ip = (s8) fetch_byte_imm(); 4039 ip += (s16) M.x86.R_IP; 4040 DECODE_PRINTF2("%04x\n", ip); 4041 TRACE_AND_STEP(); 4042 M.x86.R_CX -= 1; 4043 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 4044 M.x86.R_IP = ip; 4045 DECODE_CLEAR_SEGOVR(); 4046 END_OF_INSTR(); 4047 } 4048 4049 /**************************************************************************** 4050 REMARKS: 4051 Handles opcode 0xe1 4052 ****************************************************************************/ 4053 void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 4054 { 4055 s16 ip; 4056 4057 START_OF_INSTR(); 4058 DECODE_PRINTF("LOOPE\t"); 4059 ip = (s8) fetch_byte_imm(); 4060 ip += (s16) M.x86.R_IP; 4061 DECODE_PRINTF2("%04x\n", ip); 4062 TRACE_AND_STEP(); 4063 M.x86.R_CX -= 1; 4064 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 4065 M.x86.R_IP = ip; 4066 DECODE_CLEAR_SEGOVR(); 4067 END_OF_INSTR(); 4068 } 4069 4070 /**************************************************************************** 4071 REMARKS: 4072 Handles opcode 0xe2 4073 ****************************************************************************/ 4074 void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 4075 { 4076 s16 ip; 4077 4078 START_OF_INSTR(); 4079 DECODE_PRINTF("LOOP\t"); 4080 ip = (s8) fetch_byte_imm(); 4081 ip += (s16) M.x86.R_IP; 4082 DECODE_PRINTF2("%04x\n", ip); 4083 TRACE_AND_STEP(); 4084 M.x86.R_CX -= 1; 4085 if (M.x86.R_CX != 0) 4086 M.x86.R_IP = ip; 4087 DECODE_CLEAR_SEGOVR(); 4088 END_OF_INSTR(); 4089 } 4090 4091 /**************************************************************************** 4092 REMARKS: 4093 Handles opcode 0xe3 4094 ****************************************************************************/ 4095 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 4096 { 4097 u16 target; 4098 s8 offset; 4099 4100 /* jump to byte offset if overflow flag is set */ 4101 START_OF_INSTR(); 4102 DECODE_PRINTF("JCXZ\t"); 4103 offset = (s8)fetch_byte_imm(); 4104 target = (u16)(M.x86.R_IP + offset); 4105 DECODE_PRINTF2("%x\n", target); 4106 TRACE_AND_STEP(); 4107 if (M.x86.R_CX == 0) 4108 M.x86.R_IP = target; 4109 DECODE_CLEAR_SEGOVR(); 4110 END_OF_INSTR(); 4111 } 4112 4113 /**************************************************************************** 4114 REMARKS: 4115 Handles opcode 0xe4 4116 ****************************************************************************/ 4117 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 4118 { 4119 u8 port; 4120 4121 START_OF_INSTR(); 4122 DECODE_PRINTF("IN\t"); 4123 port = (u8) fetch_byte_imm(); 4124 DECODE_PRINTF2("%x,AL\n", port); 4125 TRACE_AND_STEP(); 4126 M.x86.R_AL = (*sys_inb)(port); 4127 DECODE_CLEAR_SEGOVR(); 4128 END_OF_INSTR(); 4129 } 4130 4131 /**************************************************************************** 4132 REMARKS: 4133 Handles opcode 0xe5 4134 ****************************************************************************/ 4135 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 4136 { 4137 u8 port; 4138 4139 START_OF_INSTR(); 4140 DECODE_PRINTF("IN\t"); 4141 port = (u8) fetch_byte_imm(); 4142 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4143 DECODE_PRINTF2("EAX,%x\n", port); 4144 } else { 4145 DECODE_PRINTF2("AX,%x\n", port); 4146 } 4147 TRACE_AND_STEP(); 4148 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4149 M.x86.R_EAX = (*sys_inl)(port); 4150 } else { 4151 M.x86.R_AX = (*sys_inw)(port); 4152 } 4153 DECODE_CLEAR_SEGOVR(); 4154 END_OF_INSTR(); 4155 } 4156 4157 /**************************************************************************** 4158 REMARKS: 4159 Handles opcode 0xe6 4160 ****************************************************************************/ 4161 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 4162 { 4163 u8 port; 4164 4165 START_OF_INSTR(); 4166 DECODE_PRINTF("OUT\t"); 4167 port = (u8) fetch_byte_imm(); 4168 DECODE_PRINTF2("%x,AL\n", port); 4169 TRACE_AND_STEP(); 4170 (*sys_outb)(port, M.x86.R_AL); 4171 DECODE_CLEAR_SEGOVR(); 4172 END_OF_INSTR(); 4173 } 4174 4175 /**************************************************************************** 4176 REMARKS: 4177 Handles opcode 0xe7 4178 ****************************************************************************/ 4179 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 4180 { 4181 u8 port; 4182 4183 START_OF_INSTR(); 4184 DECODE_PRINTF("OUT\t"); 4185 port = (u8) fetch_byte_imm(); 4186 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4187 DECODE_PRINTF2("%x,EAX\n", port); 4188 } else { 4189 DECODE_PRINTF2("%x,AX\n", port); 4190 } 4191 TRACE_AND_STEP(); 4192 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4193 (*sys_outl)(port, M.x86.R_EAX); 4194 } else { 4195 (*sys_outw)(port, M.x86.R_AX); 4196 } 4197 DECODE_CLEAR_SEGOVR(); 4198 END_OF_INSTR(); 4199 } 4200 4201 /**************************************************************************** 4202 REMARKS: 4203 Handles opcode 0xe8 4204 ****************************************************************************/ 4205 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 4206 { 4207 s16 ip; 4208 4209 START_OF_INSTR(); 4210 DECODE_PRINTF("CALL\t"); 4211 ip = (s16) fetch_word_imm(); 4212 ip += (s16) M.x86.R_IP; /* CHECK SIGN */ 4213 DECODE_PRINTF2("%04x\n", ip); 4214 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, ""); 4215 TRACE_AND_STEP(); 4216 push_word(M.x86.R_IP); 4217 M.x86.R_IP = ip; 4218 DECODE_CLEAR_SEGOVR(); 4219 END_OF_INSTR(); 4220 } 4221 4222 /**************************************************************************** 4223 REMARKS: 4224 Handles opcode 0xe9 4225 ****************************************************************************/ 4226 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 4227 { 4228 int ip; 4229 4230 START_OF_INSTR(); 4231 DECODE_PRINTF("JMP\t"); 4232 ip = (s16)fetch_word_imm(); 4233 ip += (s16)M.x86.R_IP; 4234 DECODE_PRINTF2("%04x\n", ip); 4235 TRACE_AND_STEP(); 4236 M.x86.R_IP = (u16)ip; 4237 DECODE_CLEAR_SEGOVR(); 4238 END_OF_INSTR(); 4239 } 4240 4241 /**************************************************************************** 4242 REMARKS: 4243 Handles opcode 0xea 4244 ****************************************************************************/ 4245 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 4246 { 4247 u16 cs, ip; 4248 4249 START_OF_INSTR(); 4250 DECODE_PRINTF("JMP\tFAR "); 4251 ip = fetch_word_imm(); 4252 cs = fetch_word_imm(); 4253 DECODE_PRINTF2("%04x:", cs); 4254 DECODE_PRINTF2("%04x\n", ip); 4255 TRACE_AND_STEP(); 4256 M.x86.R_IP = ip; 4257 M.x86.R_CS = cs; 4258 DECODE_CLEAR_SEGOVR(); 4259 END_OF_INSTR(); 4260 } 4261 4262 /**************************************************************************** 4263 REMARKS: 4264 Handles opcode 0xeb 4265 ****************************************************************************/ 4266 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 4267 { 4268 u16 target; 4269 s8 offset; 4270 4271 START_OF_INSTR(); 4272 DECODE_PRINTF("JMP\t"); 4273 offset = (s8)fetch_byte_imm(); 4274 target = (u16)(M.x86.R_IP + offset); 4275 DECODE_PRINTF2("%x\n", target); 4276 TRACE_AND_STEP(); 4277 M.x86.R_IP = target; 4278 DECODE_CLEAR_SEGOVR(); 4279 END_OF_INSTR(); 4280 } 4281 4282 /**************************************************************************** 4283 REMARKS: 4284 Handles opcode 0xec 4285 ****************************************************************************/ 4286 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 4287 { 4288 START_OF_INSTR(); 4289 DECODE_PRINTF("IN\tAL,DX\n"); 4290 TRACE_AND_STEP(); 4291 M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 4292 DECODE_CLEAR_SEGOVR(); 4293 END_OF_INSTR(); 4294 } 4295 4296 /**************************************************************************** 4297 REMARKS: 4298 Handles opcode 0xed 4299 ****************************************************************************/ 4300 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 4301 { 4302 START_OF_INSTR(); 4303 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4304 DECODE_PRINTF("IN\tEAX,DX\n"); 4305 } else { 4306 DECODE_PRINTF("IN\tAX,DX\n"); 4307 } 4308 TRACE_AND_STEP(); 4309 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4310 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 4311 } else { 4312 M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 4313 } 4314 DECODE_CLEAR_SEGOVR(); 4315 END_OF_INSTR(); 4316 } 4317 4318 /**************************************************************************** 4319 REMARKS: 4320 Handles opcode 0xee 4321 ****************************************************************************/ 4322 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 4323 { 4324 START_OF_INSTR(); 4325 DECODE_PRINTF("OUT\tDX,AL\n"); 4326 TRACE_AND_STEP(); 4327 (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 4328 DECODE_CLEAR_SEGOVR(); 4329 END_OF_INSTR(); 4330 } 4331 4332 /**************************************************************************** 4333 REMARKS: 4334 Handles opcode 0xef 4335 ****************************************************************************/ 4336 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 4337 { 4338 START_OF_INSTR(); 4339 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4340 DECODE_PRINTF("OUT\tDX,EAX\n"); 4341 } else { 4342 DECODE_PRINTF("OUT\tDX,AX\n"); 4343 } 4344 TRACE_AND_STEP(); 4345 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4346 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 4347 } else { 4348 (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 4349 } 4350 DECODE_CLEAR_SEGOVR(); 4351 END_OF_INSTR(); 4352 } 4353 4354 /**************************************************************************** 4355 REMARKS: 4356 Handles opcode 0xf0 4357 ****************************************************************************/ 4358 void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 4359 { 4360 START_OF_INSTR(); 4361 DECODE_PRINTF("LOCK:\n"); 4362 TRACE_AND_STEP(); 4363 DECODE_CLEAR_SEGOVR(); 4364 END_OF_INSTR(); 4365 } 4366 4367 /*opcode 0xf1 ILLEGAL OPERATION */ 4368 4369 /**************************************************************************** 4370 REMARKS: 4371 Handles opcode 0xf2 4372 ****************************************************************************/ 4373 void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 4374 { 4375 START_OF_INSTR(); 4376 DECODE_PRINTF("REPNE\n"); 4377 TRACE_AND_STEP(); 4378 M.x86.mode |= SYSMODE_PREFIX_REPNE; 4379 DECODE_CLEAR_SEGOVR(); 4380 END_OF_INSTR(); 4381 } 4382 4383 /**************************************************************************** 4384 REMARKS: 4385 Handles opcode 0xf3 4386 ****************************************************************************/ 4387 void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 4388 { 4389 START_OF_INSTR(); 4390 DECODE_PRINTF("REPE\n"); 4391 TRACE_AND_STEP(); 4392 M.x86.mode |= SYSMODE_PREFIX_REPE; 4393 DECODE_CLEAR_SEGOVR(); 4394 END_OF_INSTR(); 4395 } 4396 4397 /**************************************************************************** 4398 REMARKS: 4399 Handles opcode 0xf4 4400 ****************************************************************************/ 4401 void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 4402 { 4403 START_OF_INSTR(); 4404 DECODE_PRINTF("HALT\n"); 4405 TRACE_AND_STEP(); 4406 HALT_SYS(); 4407 DECODE_CLEAR_SEGOVR(); 4408 END_OF_INSTR(); 4409 } 4410 4411 /**************************************************************************** 4412 REMARKS: 4413 Handles opcode 0xf5 4414 ****************************************************************************/ 4415 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 4416 { 4417 /* complement the carry flag. */ 4418 START_OF_INSTR(); 4419 DECODE_PRINTF("CMC\n"); 4420 TRACE_AND_STEP(); 4421 TOGGLE_FLAG(F_CF); 4422 DECODE_CLEAR_SEGOVR(); 4423 END_OF_INSTR(); 4424 } 4425 4426 /**************************************************************************** 4427 REMARKS: 4428 Handles opcode 0xf6 4429 ****************************************************************************/ 4430 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 4431 { 4432 int mod, rl, rh; 4433 u8 *destreg; 4434 uint destoffset; 4435 u8 destval, srcval; 4436 4437 /* long, drawn out code follows. Double switch for a total 4438 of 32 cases. */ 4439 START_OF_INSTR(); 4440 FETCH_DECODE_MODRM(mod, rh, rl); 4441 DECODE_PRINTF(opF6_names[rh]); 4442 if (mod < 3) { 4443 DECODE_PRINTF("BYTE PTR "); 4444 destoffset = decode_rmXX_address(mod, rl); 4445 destval = fetch_data_byte(destoffset); 4446 4447 switch (rh) { 4448 case 0: /* test byte imm */ 4449 DECODE_PRINTF(","); 4450 srcval = fetch_byte_imm(); 4451 DECODE_PRINTF2("%02x\n", srcval); 4452 TRACE_AND_STEP(); 4453 test_byte(destval, srcval); 4454 break; 4455 case 1: 4456 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4457 HALT_SYS(); 4458 break; 4459 case 2: 4460 DECODE_PRINTF("\n"); 4461 TRACE_AND_STEP(); 4462 destval = not_byte(destval); 4463 store_data_byte(destoffset, destval); 4464 break; 4465 case 3: 4466 DECODE_PRINTF("\n"); 4467 TRACE_AND_STEP(); 4468 destval = neg_byte(destval); 4469 store_data_byte(destoffset, destval); 4470 break; 4471 case 4: 4472 DECODE_PRINTF("\n"); 4473 TRACE_AND_STEP(); 4474 mul_byte(destval); 4475 break; 4476 case 5: 4477 DECODE_PRINTF("\n"); 4478 TRACE_AND_STEP(); 4479 imul_byte(destval); 4480 break; 4481 case 6: 4482 DECODE_PRINTF("\n"); 4483 TRACE_AND_STEP(); 4484 div_byte(destval); 4485 break; 4486 default: 4487 DECODE_PRINTF("\n"); 4488 TRACE_AND_STEP(); 4489 idiv_byte(destval); 4490 break; 4491 } 4492 } else { /* mod=11 */ 4493 destreg = DECODE_RM_BYTE_REGISTER(rl); 4494 switch (rh) { 4495 case 0: /* test byte imm */ 4496 DECODE_PRINTF(","); 4497 srcval = fetch_byte_imm(); 4498 DECODE_PRINTF2("%02x\n", srcval); 4499 TRACE_AND_STEP(); 4500 test_byte(*destreg, srcval); 4501 break; 4502 case 1: 4503 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4504 HALT_SYS(); 4505 break; 4506 case 2: 4507 DECODE_PRINTF("\n"); 4508 TRACE_AND_STEP(); 4509 *destreg = not_byte(*destreg); 4510 break; 4511 case 3: 4512 DECODE_PRINTF("\n"); 4513 TRACE_AND_STEP(); 4514 *destreg = neg_byte(*destreg); 4515 break; 4516 case 4: 4517 DECODE_PRINTF("\n"); 4518 TRACE_AND_STEP(); 4519 mul_byte(*destreg); /*!!! */ 4520 break; 4521 case 5: 4522 DECODE_PRINTF("\n"); 4523 TRACE_AND_STEP(); 4524 imul_byte(*destreg); 4525 break; 4526 case 6: 4527 DECODE_PRINTF("\n"); 4528 TRACE_AND_STEP(); 4529 div_byte(*destreg); 4530 break; 4531 default: 4532 DECODE_PRINTF("\n"); 4533 TRACE_AND_STEP(); 4534 idiv_byte(*destreg); 4535 break; 4536 } 4537 } 4538 DECODE_CLEAR_SEGOVR(); 4539 END_OF_INSTR(); 4540 } 4541 4542 /**************************************************************************** 4543 REMARKS: 4544 Handles opcode 0xf7 4545 ****************************************************************************/ 4546 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 4547 { 4548 int mod, rl, rh; 4549 uint destoffset; 4550 4551 START_OF_INSTR(); 4552 FETCH_DECODE_MODRM(mod, rh, rl); 4553 DECODE_PRINTF(opF6_names[rh]); 4554 if (mod < 3) { 4555 4556 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4557 u32 destval, srcval; 4558 4559 DECODE_PRINTF("DWORD PTR "); 4560 destoffset = decode_rmXX_address(mod, rl); 4561 destval = fetch_data_long(destoffset); 4562 4563 switch (rh) { 4564 case 0: 4565 DECODE_PRINTF(","); 4566 srcval = fetch_long_imm(); 4567 DECODE_PRINTF2("%x\n", srcval); 4568 TRACE_AND_STEP(); 4569 test_long(destval, srcval); 4570 break; 4571 case 1: 4572 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 4573 HALT_SYS(); 4574 break; 4575 case 2: 4576 DECODE_PRINTF("\n"); 4577 TRACE_AND_STEP(); 4578 destval = not_long(destval); 4579 store_data_long(destoffset, destval); 4580 break; 4581 case 3: 4582 DECODE_PRINTF("\n"); 4583 TRACE_AND_STEP(); 4584 destval = neg_long(destval); 4585 store_data_long(destoffset, destval); 4586 break; 4587 case 4: 4588 DECODE_PRINTF("\n"); 4589 TRACE_AND_STEP(); 4590 mul_long(destval); 4591 break; 4592 case 5: 4593 DECODE_PRINTF("\n"); 4594 TRACE_AND_STEP(); 4595 imul_long(destval); 4596 break; 4597 case 6: 4598 DECODE_PRINTF("\n"); 4599 TRACE_AND_STEP(); 4600 div_long(destval); 4601 break; 4602 case 7: 4603 DECODE_PRINTF("\n"); 4604 TRACE_AND_STEP(); 4605 idiv_long(destval); 4606 break; 4607 } 4608 } else { 4609 u16 destval, srcval; 4610 4611 DECODE_PRINTF("WORD PTR "); 4612 destoffset = decode_rmXX_address(mod, rl); 4613 destval = fetch_data_word(destoffset); 4614 4615 switch (rh) { 4616 case 0: /* test word imm */ 4617 DECODE_PRINTF(","); 4618 srcval = fetch_word_imm(); 4619 DECODE_PRINTF2("%x\n", srcval); 4620 TRACE_AND_STEP(); 4621 test_word(destval, srcval); 4622 break; 4623 case 1: 4624 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 4625 HALT_SYS(); 4626 break; 4627 case 2: 4628 DECODE_PRINTF("\n"); 4629 TRACE_AND_STEP(); 4630 destval = not_word(destval); 4631 store_data_word(destoffset, destval); 4632 break; 4633 case 3: 4634 DECODE_PRINTF("\n"); 4635 TRACE_AND_STEP(); 4636 destval = neg_word(destval); 4637 store_data_word(destoffset, destval); 4638 break; 4639 case 4: 4640 DECODE_PRINTF("\n"); 4641 TRACE_AND_STEP(); 4642 mul_word(destval); 4643 break; 4644 case 5: 4645 DECODE_PRINTF("\n"); 4646 TRACE_AND_STEP(); 4647 imul_word(destval); 4648 break; 4649 case 6: 4650 DECODE_PRINTF("\n"); 4651 TRACE_AND_STEP(); 4652 div_word(destval); 4653 break; 4654 case 7: 4655 DECODE_PRINTF("\n"); 4656 TRACE_AND_STEP(); 4657 idiv_word(destval); 4658 break; 4659 } 4660 } 4661 4662 } else { /* mod=11 */ 4663 4664 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4665 u32 *destreg; 4666 u32 srcval; 4667 4668 destreg = DECODE_RM_LONG_REGISTER(rl); 4669 4670 switch (rh) { 4671 case 0: /* test word imm */ 4672 DECODE_PRINTF(","); 4673 srcval = fetch_long_imm(); 4674 DECODE_PRINTF2("%x\n", srcval); 4675 TRACE_AND_STEP(); 4676 test_long(*destreg, srcval); 4677 break; 4678 case 1: 4679 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4680 HALT_SYS(); 4681 break; 4682 case 2: 4683 DECODE_PRINTF("\n"); 4684 TRACE_AND_STEP(); 4685 *destreg = not_long(*destreg); 4686 break; 4687 case 3: 4688 DECODE_PRINTF("\n"); 4689 TRACE_AND_STEP(); 4690 *destreg = neg_long(*destreg); 4691 break; 4692 case 4: 4693 DECODE_PRINTF("\n"); 4694 TRACE_AND_STEP(); 4695 mul_long(*destreg); /*!!! */ 4696 break; 4697 case 5: 4698 DECODE_PRINTF("\n"); 4699 TRACE_AND_STEP(); 4700 imul_long(*destreg); 4701 break; 4702 case 6: 4703 DECODE_PRINTF("\n"); 4704 TRACE_AND_STEP(); 4705 div_long(*destreg); 4706 break; 4707 case 7: 4708 DECODE_PRINTF("\n"); 4709 TRACE_AND_STEP(); 4710 idiv_long(*destreg); 4711 break; 4712 } 4713 } else { 4714 u16 *destreg; 4715 u16 srcval; 4716 4717 destreg = DECODE_RM_WORD_REGISTER(rl); 4718 4719 switch (rh) { 4720 case 0: /* test word imm */ 4721 DECODE_PRINTF(","); 4722 srcval = fetch_word_imm(); 4723 DECODE_PRINTF2("%x\n", srcval); 4724 TRACE_AND_STEP(); 4725 test_word(*destreg, srcval); 4726 break; 4727 case 1: 4728 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4729 HALT_SYS(); 4730 break; 4731 case 2: 4732 DECODE_PRINTF("\n"); 4733 TRACE_AND_STEP(); 4734 *destreg = not_word(*destreg); 4735 break; 4736 case 3: 4737 DECODE_PRINTF("\n"); 4738 TRACE_AND_STEP(); 4739 *destreg = neg_word(*destreg); 4740 break; 4741 case 4: 4742 DECODE_PRINTF("\n"); 4743 TRACE_AND_STEP(); 4744 mul_word(*destreg); /*!!! */ 4745 break; 4746 case 5: 4747 DECODE_PRINTF("\n"); 4748 TRACE_AND_STEP(); 4749 imul_word(*destreg); 4750 break; 4751 case 6: 4752 DECODE_PRINTF("\n"); 4753 TRACE_AND_STEP(); 4754 div_word(*destreg); 4755 break; 4756 case 7: 4757 DECODE_PRINTF("\n"); 4758 TRACE_AND_STEP(); 4759 idiv_word(*destreg); 4760 break; 4761 } 4762 } 4763 } 4764 DECODE_CLEAR_SEGOVR(); 4765 END_OF_INSTR(); 4766 } 4767 4768 /**************************************************************************** 4769 REMARKS: 4770 Handles opcode 0xf8 4771 ****************************************************************************/ 4772 void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 4773 { 4774 /* clear the carry flag. */ 4775 START_OF_INSTR(); 4776 DECODE_PRINTF("CLC\n"); 4777 TRACE_AND_STEP(); 4778 CLEAR_FLAG(F_CF); 4779 DECODE_CLEAR_SEGOVR(); 4780 END_OF_INSTR(); 4781 } 4782 4783 /**************************************************************************** 4784 REMARKS: 4785 Handles opcode 0xf9 4786 ****************************************************************************/ 4787 void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 4788 { 4789 /* set the carry flag. */ 4790 START_OF_INSTR(); 4791 DECODE_PRINTF("STC\n"); 4792 TRACE_AND_STEP(); 4793 SET_FLAG(F_CF); 4794 DECODE_CLEAR_SEGOVR(); 4795 END_OF_INSTR(); 4796 } 4797 4798 /**************************************************************************** 4799 REMARKS: 4800 Handles opcode 0xfa 4801 ****************************************************************************/ 4802 void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 4803 { 4804 /* clear interrupts. */ 4805 START_OF_INSTR(); 4806 DECODE_PRINTF("CLI\n"); 4807 TRACE_AND_STEP(); 4808 CLEAR_FLAG(F_IF); 4809 DECODE_CLEAR_SEGOVR(); 4810 END_OF_INSTR(); 4811 } 4812 4813 /**************************************************************************** 4814 REMARKS: 4815 Handles opcode 0xfb 4816 ****************************************************************************/ 4817 void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 4818 { 4819 /* enable interrupts. */ 4820 START_OF_INSTR(); 4821 DECODE_PRINTF("STI\n"); 4822 TRACE_AND_STEP(); 4823 SET_FLAG(F_IF); 4824 DECODE_CLEAR_SEGOVR(); 4825 END_OF_INSTR(); 4826 } 4827 4828 /**************************************************************************** 4829 REMARKS: 4830 Handles opcode 0xfc 4831 ****************************************************************************/ 4832 void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 4833 { 4834 /* clear interrupts. */ 4835 START_OF_INSTR(); 4836 DECODE_PRINTF("CLD\n"); 4837 TRACE_AND_STEP(); 4838 CLEAR_FLAG(F_DF); 4839 DECODE_CLEAR_SEGOVR(); 4840 END_OF_INSTR(); 4841 } 4842 4843 /**************************************************************************** 4844 REMARKS: 4845 Handles opcode 0xfd 4846 ****************************************************************************/ 4847 void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 4848 { 4849 /* clear interrupts. */ 4850 START_OF_INSTR(); 4851 DECODE_PRINTF("STD\n"); 4852 TRACE_AND_STEP(); 4853 SET_FLAG(F_DF); 4854 DECODE_CLEAR_SEGOVR(); 4855 END_OF_INSTR(); 4856 } 4857 4858 /**************************************************************************** 4859 REMARKS: 4860 Handles opcode 0xfe 4861 ****************************************************************************/ 4862 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 4863 { 4864 int mod, rh, rl; 4865 u8 destval; 4866 uint destoffset; 4867 u8 *destreg; 4868 4869 /* Yet another special case instruction. */ 4870 START_OF_INSTR(); 4871 FETCH_DECODE_MODRM(mod, rh, rl); 4872 #ifdef DEBUG 4873 if (DEBUG_DECODE()) { 4874 /* XXX DECODE_PRINTF may be changed to something more 4875 general, so that it is important to leave the strings 4876 in the same format, even though the result is that the 4877 above test is done twice. */ 4878 4879 switch (rh) { 4880 case 0: 4881 DECODE_PRINTF("INC\t"); 4882 break; 4883 case 1: 4884 DECODE_PRINTF("DEC\t"); 4885 break; 4886 case 2: 4887 case 3: 4888 case 4: 4889 case 5: 4890 case 6: 4891 case 7: 4892 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 4893 HALT_SYS(); 4894 break; 4895 } 4896 } 4897 #endif 4898 if (mod < 3) { 4899 DECODE_PRINTF("BYTE PTR "); 4900 destoffset = decode_rmXX_address(mod, rl); 4901 DECODE_PRINTF("\n"); 4902 destval = fetch_data_byte(destoffset); 4903 TRACE_AND_STEP(); 4904 if (rh == 0) 4905 destval = inc_byte(destval); 4906 else 4907 destval = dec_byte(destval); 4908 store_data_byte(destoffset, destval); 4909 } else { 4910 destreg = DECODE_RM_BYTE_REGISTER(rl); 4911 DECODE_PRINTF("\n"); 4912 TRACE_AND_STEP(); 4913 if (rh == 0) 4914 *destreg = inc_byte(*destreg); 4915 else 4916 *destreg = dec_byte(*destreg); 4917 } 4918 DECODE_CLEAR_SEGOVR(); 4919 END_OF_INSTR(); 4920 } 4921 4922 /**************************************************************************** 4923 REMARKS: 4924 Handles opcode 0xff 4925 ****************************************************************************/ 4926 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 4927 { 4928 int mod, rh, rl; 4929 uint destoffset = 0; 4930 u16 *destreg; 4931 u16 destval,destval2; 4932 4933 /* Yet another special case instruction. */ 4934 START_OF_INSTR(); 4935 FETCH_DECODE_MODRM(mod, rh, rl); 4936 #ifdef DEBUG 4937 if (DEBUG_DECODE()) { 4938 /* XXX DECODE_PRINTF may be changed to something more 4939 general, so that it is important to leave the strings 4940 in the same format, even though the result is that the 4941 above test is done twice. */ 4942 4943 switch (rh) { 4944 case 0: 4945 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4946 DECODE_PRINTF("INC\tDWORD PTR "); 4947 } else { 4948 DECODE_PRINTF("INC\tWORD PTR "); 4949 } 4950 break; 4951 case 1: 4952 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4953 DECODE_PRINTF("DEC\tDWORD PTR "); 4954 } else { 4955 DECODE_PRINTF("DEC\tWORD PTR "); 4956 } 4957 break; 4958 case 2: 4959 DECODE_PRINTF("CALL\t "); 4960 break; 4961 case 3: 4962 DECODE_PRINTF("CALL\tFAR "); 4963 break; 4964 case 4: 4965 DECODE_PRINTF("JMP\t"); 4966 break; 4967 case 5: 4968 DECODE_PRINTF("JMP\tFAR "); 4969 break; 4970 case 6: 4971 DECODE_PRINTF("PUSH\t"); 4972 break; 4973 case 7: 4974 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 4975 HALT_SYS(); 4976 break; 4977 } 4978 } 4979 #endif 4980 if (mod < 3) { 4981 destoffset = decode_rmXX_address(mod, rl); 4982 DECODE_PRINTF("\n"); 4983 switch (rh) { 4984 case 0: /* inc word ptr ... */ 4985 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4986 u32 destval; 4987 4988 destval = fetch_data_long(destoffset); 4989 TRACE_AND_STEP(); 4990 destval = inc_long(destval); 4991 store_data_long(destoffset, destval); 4992 } else { 4993 u16 destval; 4994 4995 destval = fetch_data_word(destoffset); 4996 TRACE_AND_STEP(); 4997 destval = inc_word(destval); 4998 store_data_word(destoffset, destval); 4999 } 5000 break; 5001 case 1: /* dec word ptr ... */ 5002 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5003 u32 destval; 5004 5005 destval = fetch_data_long(destoffset); 5006 TRACE_AND_STEP(); 5007 destval = dec_long(destval); 5008 store_data_long(destoffset, destval); 5009 } else { 5010 u16 destval; 5011 5012 destval = fetch_data_word(destoffset); 5013 TRACE_AND_STEP(); 5014 destval = dec_word(destval); 5015 store_data_word(destoffset, destval); 5016 } 5017 break; 5018 case 2: /* call word ptr ... */ 5019 destval = fetch_data_word(destoffset); 5020 TRACE_AND_STEP(); 5021 push_word(M.x86.R_IP); 5022 M.x86.R_IP = destval; 5023 break; 5024 case 3: /* call far ptr ... */ 5025 destval = fetch_data_word(destoffset); 5026 destval2 = fetch_data_word(destoffset + 2); 5027 TRACE_AND_STEP(); 5028 push_word(M.x86.R_CS); 5029 M.x86.R_CS = destval2; 5030 push_word(M.x86.R_IP); 5031 M.x86.R_IP = destval; 5032 break; 5033 case 4: /* jmp word ptr ... */ 5034 destval = fetch_data_word(destoffset); 5035 TRACE_AND_STEP(); 5036 M.x86.R_IP = destval; 5037 break; 5038 case 5: /* jmp far ptr ... */ 5039 destval = fetch_data_word(destoffset); 5040 destval2 = fetch_data_word(destoffset + 2); 5041 TRACE_AND_STEP(); 5042 M.x86.R_IP = destval; 5043 M.x86.R_CS = destval2; 5044 break; 5045 case 6: /* push word ptr ... */ 5046 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5047 u32 destval; 5048 5049 destval = fetch_data_long(destoffset); 5050 TRACE_AND_STEP(); 5051 push_long(destval); 5052 } else { 5053 u16 destval; 5054 5055 destval = fetch_data_word(destoffset); 5056 TRACE_AND_STEP(); 5057 push_word(destval); 5058 } 5059 break; 5060 } 5061 } else { 5062 switch (rh) { 5063 case 0: 5064 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5065 u32 *destreg; 5066 5067 destreg = DECODE_RM_LONG_REGISTER(rl); 5068 DECODE_PRINTF("\n"); 5069 TRACE_AND_STEP(); 5070 *destreg = inc_long(*destreg); 5071 } else { 5072 u16 *destreg; 5073 5074 destreg = DECODE_RM_WORD_REGISTER(rl); 5075 DECODE_PRINTF("\n"); 5076 TRACE_AND_STEP(); 5077 *destreg = inc_word(*destreg); 5078 } 5079 break; 5080 case 1: 5081 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5082 u32 *destreg; 5083 5084 destreg = DECODE_RM_LONG_REGISTER(rl); 5085 DECODE_PRINTF("\n"); 5086 TRACE_AND_STEP(); 5087 *destreg = dec_long(*destreg); 5088 } else { 5089 u16 *destreg; 5090 5091 destreg = DECODE_RM_WORD_REGISTER(rl); 5092 DECODE_PRINTF("\n"); 5093 TRACE_AND_STEP(); 5094 *destreg = dec_word(*destreg); 5095 } 5096 break; 5097 case 2: /* call word ptr ... */ 5098 destreg = DECODE_RM_WORD_REGISTER(rl); 5099 DECODE_PRINTF("\n"); 5100 TRACE_AND_STEP(); 5101 push_word(M.x86.R_IP); 5102 M.x86.R_IP = *destreg; 5103 break; 5104 case 3: /* jmp far ptr ... */ 5105 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 5106 TRACE_AND_STEP(); 5107 HALT_SYS(); 5108 break; 5109 5110 case 4: /* jmp ... */ 5111 destreg = DECODE_RM_WORD_REGISTER(rl); 5112 DECODE_PRINTF("\n"); 5113 TRACE_AND_STEP(); 5114 M.x86.R_IP = (u16) (*destreg); 5115 break; 5116 case 5: /* jmp far ptr ... */ 5117 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 5118 TRACE_AND_STEP(); 5119 HALT_SYS(); 5120 break; 5121 case 6: 5122 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5123 u32 *destreg; 5124 5125 destreg = DECODE_RM_LONG_REGISTER(rl); 5126 DECODE_PRINTF("\n"); 5127 TRACE_AND_STEP(); 5128 push_long(*destreg); 5129 } else { 5130 u16 *destreg; 5131 5132 destreg = DECODE_RM_WORD_REGISTER(rl); 5133 DECODE_PRINTF("\n"); 5134 TRACE_AND_STEP(); 5135 push_word(*destreg); 5136 } 5137 break; 5138 } 5139 } 5140 DECODE_CLEAR_SEGOVR(); 5141 END_OF_INSTR(); 5142 } 5143 5144 /*************************************************************************** 5145 * Single byte operation code table: 5146 **************************************************************************/ 5147 void (*x86emu_optab[256])(u8) __attribute__ ((section(GOT2_TYPE))) = 5148 { 5149 /* 0x00 */ x86emuOp_genop_byte_RM_R, 5150 /* 0x01 */ x86emuOp_genop_word_RM_R, 5151 /* 0x02 */ x86emuOp_genop_byte_R_RM, 5152 /* 0x03 */ x86emuOp_genop_word_R_RM, 5153 /* 0x04 */ x86emuOp_genop_byte_AL_IMM, 5154 /* 0x05 */ x86emuOp_genop_word_AX_IMM, 5155 /* 0x06 */ x86emuOp_push_ES, 5156 /* 0x07 */ x86emuOp_pop_ES, 5157 5158 /* 0x08 */ x86emuOp_genop_byte_RM_R, 5159 /* 0x09 */ x86emuOp_genop_word_RM_R, 5160 /* 0x0a */ x86emuOp_genop_byte_R_RM, 5161 /* 0x0b */ x86emuOp_genop_word_R_RM, 5162 /* 0x0c */ x86emuOp_genop_byte_AL_IMM, 5163 /* 0x0d */ x86emuOp_genop_word_AX_IMM, 5164 /* 0x0e */ x86emuOp_push_CS, 5165 /* 0x0f */ x86emuOp_two_byte, 5166 5167 /* 0x10 */ x86emuOp_genop_byte_RM_R, 5168 /* 0x11 */ x86emuOp_genop_word_RM_R, 5169 /* 0x12 */ x86emuOp_genop_byte_R_RM, 5170 /* 0x13 */ x86emuOp_genop_word_R_RM, 5171 /* 0x14 */ x86emuOp_genop_byte_AL_IMM, 5172 /* 0x15 */ x86emuOp_genop_word_AX_IMM, 5173 /* 0x16 */ x86emuOp_push_SS, 5174 /* 0x17 */ x86emuOp_pop_SS, 5175 5176 /* 0x18 */ x86emuOp_genop_byte_RM_R, 5177 /* 0x19 */ x86emuOp_genop_word_RM_R, 5178 /* 0x1a */ x86emuOp_genop_byte_R_RM, 5179 /* 0x1b */ x86emuOp_genop_word_R_RM, 5180 /* 0x1c */ x86emuOp_genop_byte_AL_IMM, 5181 /* 0x1d */ x86emuOp_genop_word_AX_IMM, 5182 /* 0x1e */ x86emuOp_push_DS, 5183 /* 0x1f */ x86emuOp_pop_DS, 5184 5185 /* 0x20 */ x86emuOp_genop_byte_RM_R, 5186 /* 0x21 */ x86emuOp_genop_word_RM_R, 5187 /* 0x22 */ x86emuOp_genop_byte_R_RM, 5188 /* 0x23 */ x86emuOp_genop_word_R_RM, 5189 /* 0x24 */ x86emuOp_genop_byte_AL_IMM, 5190 /* 0x25 */ x86emuOp_genop_word_AX_IMM, 5191 /* 0x26 */ x86emuOp_segovr_ES, 5192 /* 0x27 */ x86emuOp_daa, 5193 5194 /* 0x28 */ x86emuOp_genop_byte_RM_R, 5195 /* 0x29 */ x86emuOp_genop_word_RM_R, 5196 /* 0x2a */ x86emuOp_genop_byte_R_RM, 5197 /* 0x2b */ x86emuOp_genop_word_R_RM, 5198 /* 0x2c */ x86emuOp_genop_byte_AL_IMM, 5199 /* 0x2d */ x86emuOp_genop_word_AX_IMM, 5200 /* 0x2e */ x86emuOp_segovr_CS, 5201 /* 0x2f */ x86emuOp_das, 5202 5203 /* 0x30 */ x86emuOp_genop_byte_RM_R, 5204 /* 0x31 */ x86emuOp_genop_word_RM_R, 5205 /* 0x32 */ x86emuOp_genop_byte_R_RM, 5206 /* 0x33 */ x86emuOp_genop_word_R_RM, 5207 /* 0x34 */ x86emuOp_genop_byte_AL_IMM, 5208 /* 0x35 */ x86emuOp_genop_word_AX_IMM, 5209 /* 0x36 */ x86emuOp_segovr_SS, 5210 /* 0x37 */ x86emuOp_aaa, 5211 5212 /* 0x38 */ x86emuOp_genop_byte_RM_R, 5213 /* 0x39 */ x86emuOp_genop_word_RM_R, 5214 /* 0x3a */ x86emuOp_genop_byte_R_RM, 5215 /* 0x3b */ x86emuOp_genop_word_R_RM, 5216 /* 0x3c */ x86emuOp_genop_byte_AL_IMM, 5217 /* 0x3d */ x86emuOp_genop_word_AX_IMM, 5218 /* 0x3e */ x86emuOp_segovr_DS, 5219 /* 0x3f */ x86emuOp_aas, 5220 5221 /* 0x40 */ x86emuOp_inc_register, 5222 /* 0x41 */ x86emuOp_inc_register, 5223 /* 0x42 */ x86emuOp_inc_register, 5224 /* 0x43 */ x86emuOp_inc_register, 5225 /* 0x44 */ x86emuOp_inc_register, 5226 /* 0x45 */ x86emuOp_inc_register, 5227 /* 0x46 */ x86emuOp_inc_register, 5228 /* 0x47 */ x86emuOp_inc_register, 5229 5230 /* 0x48 */ x86emuOp_dec_register, 5231 /* 0x49 */ x86emuOp_dec_register, 5232 /* 0x4a */ x86emuOp_dec_register, 5233 /* 0x4b */ x86emuOp_dec_register, 5234 /* 0x4c */ x86emuOp_dec_register, 5235 /* 0x4d */ x86emuOp_dec_register, 5236 /* 0x4e */ x86emuOp_dec_register, 5237 /* 0x4f */ x86emuOp_dec_register, 5238 5239 /* 0x50 */ x86emuOp_push_register, 5240 /* 0x51 */ x86emuOp_push_register, 5241 /* 0x52 */ x86emuOp_push_register, 5242 /* 0x53 */ x86emuOp_push_register, 5243 /* 0x54 */ x86emuOp_push_register, 5244 /* 0x55 */ x86emuOp_push_register, 5245 /* 0x56 */ x86emuOp_push_register, 5246 /* 0x57 */ x86emuOp_push_register, 5247 5248 /* 0x58 */ x86emuOp_pop_register, 5249 /* 0x59 */ x86emuOp_pop_register, 5250 /* 0x5a */ x86emuOp_pop_register, 5251 /* 0x5b */ x86emuOp_pop_register, 5252 /* 0x5c */ x86emuOp_pop_register, 5253 /* 0x5d */ x86emuOp_pop_register, 5254 /* 0x5e */ x86emuOp_pop_register, 5255 /* 0x5f */ x86emuOp_pop_register, 5256 5257 /* 0x60 */ x86emuOp_push_all, 5258 /* 0x61 */ x86emuOp_pop_all, 5259 /* 0x62 */ x86emuOp_illegal_op, /* bound */ 5260 /* 0x63 */ x86emuOp_illegal_op, /* arpl */ 5261 /* 0x64 */ x86emuOp_segovr_FS, 5262 /* 0x65 */ x86emuOp_segovr_GS, 5263 /* 0x66 */ x86emuOp_prefix_data, 5264 /* 0x67 */ x86emuOp_prefix_addr, 5265 5266 /* 0x68 */ x86emuOp_push_word_IMM, 5267 /* 0x69 */ x86emuOp_imul_word_IMM, 5268 /* 0x6a */ x86emuOp_push_byte_IMM, 5269 /* 0x6b */ x86emuOp_imul_byte_IMM, 5270 /* 0x6c */ x86emuOp_ins_byte, 5271 /* 0x6d */ x86emuOp_ins_word, 5272 /* 0x6e */ x86emuOp_outs_byte, 5273 /* 0x6f */ x86emuOp_outs_word, 5274 5275 /* 0x70 */ x86emuOp_jump_near_cond, 5276 /* 0x71 */ x86emuOp_jump_near_cond, 5277 /* 0x72 */ x86emuOp_jump_near_cond, 5278 /* 0x73 */ x86emuOp_jump_near_cond, 5279 /* 0x74 */ x86emuOp_jump_near_cond, 5280 /* 0x75 */ x86emuOp_jump_near_cond, 5281 /* 0x76 */ x86emuOp_jump_near_cond, 5282 /* 0x77 */ x86emuOp_jump_near_cond, 5283 5284 /* 0x78 */ x86emuOp_jump_near_cond, 5285 /* 0x79 */ x86emuOp_jump_near_cond, 5286 /* 0x7a */ x86emuOp_jump_near_cond, 5287 /* 0x7b */ x86emuOp_jump_near_cond, 5288 /* 0x7c */ x86emuOp_jump_near_cond, 5289 /* 0x7d */ x86emuOp_jump_near_cond, 5290 /* 0x7e */ x86emuOp_jump_near_cond, 5291 /* 0x7f */ x86emuOp_jump_near_cond, 5292 5293 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 5294 /* 0x81 */ x86emuOp_opc81_word_RM_IMM, 5295 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 5296 /* 0x83 */ x86emuOp_opc83_word_RM_IMM, 5297 /* 0x84 */ x86emuOp_test_byte_RM_R, 5298 /* 0x85 */ x86emuOp_test_word_RM_R, 5299 /* 0x86 */ x86emuOp_xchg_byte_RM_R, 5300 /* 0x87 */ x86emuOp_xchg_word_RM_R, 5301 5302 /* 0x88 */ x86emuOp_mov_byte_RM_R, 5303 /* 0x89 */ x86emuOp_mov_word_RM_R, 5304 /* 0x8a */ x86emuOp_mov_byte_R_RM, 5305 /* 0x8b */ x86emuOp_mov_word_R_RM, 5306 /* 0x8c */ x86emuOp_mov_word_RM_SR, 5307 /* 0x8d */ x86emuOp_lea_word_R_M, 5308 /* 0x8e */ x86emuOp_mov_word_SR_RM, 5309 /* 0x8f */ x86emuOp_pop_RM, 5310 5311 /* 0x90 */ x86emuOp_nop, 5312 /* 0x91 */ x86emuOp_xchg_word_AX_register, 5313 /* 0x92 */ x86emuOp_xchg_word_AX_register, 5314 /* 0x93 */ x86emuOp_xchg_word_AX_register, 5315 /* 0x94 */ x86emuOp_xchg_word_AX_register, 5316 /* 0x95 */ x86emuOp_xchg_word_AX_register, 5317 /* 0x96 */ x86emuOp_xchg_word_AX_register, 5318 /* 0x97 */ x86emuOp_xchg_word_AX_register, 5319 5320 /* 0x98 */ x86emuOp_cbw, 5321 /* 0x99 */ x86emuOp_cwd, 5322 /* 0x9a */ x86emuOp_call_far_IMM, 5323 /* 0x9b */ x86emuOp_wait, 5324 /* 0x9c */ x86emuOp_pushf_word, 5325 /* 0x9d */ x86emuOp_popf_word, 5326 /* 0x9e */ x86emuOp_sahf, 5327 /* 0x9f */ x86emuOp_lahf, 5328 5329 /* 0xa0 */ x86emuOp_mov_AL_M_IMM, 5330 /* 0xa1 */ x86emuOp_mov_AX_M_IMM, 5331 /* 0xa2 */ x86emuOp_mov_M_AL_IMM, 5332 /* 0xa3 */ x86emuOp_mov_M_AX_IMM, 5333 /* 0xa4 */ x86emuOp_movs_byte, 5334 /* 0xa5 */ x86emuOp_movs_word, 5335 /* 0xa6 */ x86emuOp_cmps_byte, 5336 /* 0xa7 */ x86emuOp_cmps_word, 5337 /* 0xa8 */ x86emuOp_test_AL_IMM, 5338 /* 0xa9 */ x86emuOp_test_AX_IMM, 5339 /* 0xaa */ x86emuOp_stos_byte, 5340 /* 0xab */ x86emuOp_stos_word, 5341 /* 0xac */ x86emuOp_lods_byte, 5342 /* 0xad */ x86emuOp_lods_word, 5343 /* 0xac */ x86emuOp_scas_byte, 5344 /* 0xad */ x86emuOp_scas_word, 5345 5346 /* 0xb0 */ x86emuOp_mov_byte_register_IMM, 5347 /* 0xb1 */ x86emuOp_mov_byte_register_IMM, 5348 /* 0xb2 */ x86emuOp_mov_byte_register_IMM, 5349 /* 0xb3 */ x86emuOp_mov_byte_register_IMM, 5350 /* 0xb4 */ x86emuOp_mov_byte_register_IMM, 5351 /* 0xb5 */ x86emuOp_mov_byte_register_IMM, 5352 /* 0xb6 */ x86emuOp_mov_byte_register_IMM, 5353 /* 0xb7 */ x86emuOp_mov_byte_register_IMM, 5354 5355 /* 0xb8 */ x86emuOp_mov_word_register_IMM, 5356 /* 0xb9 */ x86emuOp_mov_word_register_IMM, 5357 /* 0xba */ x86emuOp_mov_word_register_IMM, 5358 /* 0xbb */ x86emuOp_mov_word_register_IMM, 5359 /* 0xbc */ x86emuOp_mov_word_register_IMM, 5360 /* 0xbd */ x86emuOp_mov_word_register_IMM, 5361 /* 0xbe */ x86emuOp_mov_word_register_IMM, 5362 /* 0xbf */ x86emuOp_mov_word_register_IMM, 5363 5364 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 5365 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 5366 /* 0xc2 */ x86emuOp_ret_near_IMM, 5367 /* 0xc3 */ x86emuOp_ret_near, 5368 /* 0xc4 */ x86emuOp_les_R_IMM, 5369 /* 0xc5 */ x86emuOp_lds_R_IMM, 5370 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 5371 /* 0xc7 */ x86emuOp_mov_word_RM_IMM, 5372 /* 0xc8 */ x86emuOp_enter, 5373 /* 0xc9 */ x86emuOp_leave, 5374 /* 0xca */ x86emuOp_ret_far_IMM, 5375 /* 0xcb */ x86emuOp_ret_far, 5376 /* 0xcc */ x86emuOp_int3, 5377 /* 0xcd */ x86emuOp_int_IMM, 5378 /* 0xce */ x86emuOp_into, 5379 /* 0xcf */ x86emuOp_iret, 5380 5381 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 5382 /* 0xd1 */ x86emuOp_opcD1_word_RM_1, 5383 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 5384 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 5385 /* 0xd4 */ x86emuOp_aam, 5386 /* 0xd5 */ x86emuOp_aad, 5387 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 5388 /* 0xd7 */ x86emuOp_xlat, 5389 /* 0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/ 5390 /* 0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/ 5391 /* 0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/ 5392 /* 0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/ 5393 /* 0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/ 5394 /* 0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/ 5395 /* 0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/ 5396 /* 0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/ 5397 5398 /* 0xe0 */ x86emuOp_loopne, 5399 /* 0xe1 */ x86emuOp_loope, 5400 /* 0xe2 */ x86emuOp_loop, 5401 /* 0xe3 */ x86emuOp_jcxz, 5402 /* 0xe4 */ x86emuOp_in_byte_AL_IMM, 5403 /* 0xe5 */ x86emuOp_in_word_AX_IMM, 5404 /* 0xe6 */ x86emuOp_out_byte_IMM_AL, 5405 /* 0xe7 */ x86emuOp_out_word_IMM_AX, 5406 5407 /* 0xe8 */ x86emuOp_call_near_IMM, 5408 /* 0xe9 */ x86emuOp_jump_near_IMM, 5409 /* 0xea */ x86emuOp_jump_far_IMM, 5410 /* 0xeb */ x86emuOp_jump_byte_IMM, 5411 /* 0xec */ x86emuOp_in_byte_AL_DX, 5412 /* 0xed */ x86emuOp_in_word_AX_DX, 5413 /* 0xee */ x86emuOp_out_byte_DX_AL, 5414 /* 0xef */ x86emuOp_out_word_DX_AX, 5415 5416 /* 0xf0 */ x86emuOp_lock, 5417 /* 0xf1 */ x86emuOp_illegal_op, 5418 /* 0xf2 */ x86emuOp_repne, 5419 /* 0xf3 */ x86emuOp_repe, 5420 /* 0xf4 */ x86emuOp_halt, 5421 /* 0xf5 */ x86emuOp_cmc, 5422 /* 0xf6 */ x86emuOp_opcF6_byte_RM, 5423 /* 0xf7 */ x86emuOp_opcF7_word_RM, 5424 5425 /* 0xf8 */ x86emuOp_clc, 5426 /* 0xf9 */ x86emuOp_stc, 5427 /* 0xfa */ x86emuOp_cli, 5428 /* 0xfb */ x86emuOp_sti, 5429 /* 0xfc */ x86emuOp_cld, 5430 /* 0xfd */ x86emuOp_std, 5431 /* 0xfe */ x86emuOp_opcFE_byte_RM, 5432 /* 0xff */ x86emuOp_opcFF_word_RM, 5433 }; 5434