1 /**************************************************************************** 2 * 3 * Realmode X86 Emulator Library 4 * 5 * Copyright (C) 2007 Freescale Semiconductor, Inc. 6 * Jason Jin <Jason.jin@freescale.com> 7 * 8 * Copyright (C) 1991-2004 SciTech Software, Inc. 9 * Copyright (C) David Mosberger-Tang 10 * Copyright (C) 1999 Egbert Eich 11 * 12 * ======================================================================== 13 * 14 * Permission to use, copy, modify, distribute, and sell this software and 15 * its documentation for any purpose is hereby granted without fee, 16 * provided that the above copyright notice appear in all copies and that 17 * both that copyright notice and this permission notice appear in 18 * supporting documentation, and that the name of the authors not be used 19 * in advertising or publicity pertaining to distribution of the software 20 * without specific, written prior permission. The authors makes no 21 * representations about the suitability of this software for any purpose. 22 * It is provided "as is" without express or implied warranty. 23 * 24 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 25 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 26 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 27 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 28 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 29 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 30 * PERFORMANCE OF THIS SOFTWARE. 31 * 32 * ======================================================================== 33 * 34 * Language: ANSI C 35 * Environment: Any 36 * Developer: Kendall Bennett 37 * 38 * Description: This file includes subroutines to implement the decoding 39 * and emulation of all the x86 extended two-byte processor 40 * instructions. 41 * 42 ****************************************************************************/ 43 44 #include <common.h> 45 #include "x86emu/x86emui.h" 46 47 /*----------------------------- Implementation ----------------------------*/ 48 49 /**************************************************************************** 50 PARAMETERS: 51 op1 - Instruction op code 52 53 REMARKS: 54 Handles illegal opcodes. 55 ****************************************************************************/ 56 void x86emuOp2_illegal_op( 57 u8 op2) 58 { 59 START_OF_INSTR(); 60 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 61 TRACE_REGS(); 62 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", 63 M.x86.R_CS, M.x86.R_IP-2,op2); 64 HALT_SYS(); 65 END_OF_INSTR(); 66 } 67 68 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) 69 70 /**************************************************************************** 71 REMARKS: 72 Handles opcode 0x0f,0x80-0x8F 73 ****************************************************************************/ 74 int x86emu_check_jump_condition(u8 op) 75 { 76 switch (op) { 77 case 0x0: 78 DECODE_PRINTF("JO\t"); 79 return ACCESS_FLAG(F_OF); 80 case 0x1: 81 DECODE_PRINTF("JNO\t"); 82 return !ACCESS_FLAG(F_OF); 83 break; 84 case 0x2: 85 DECODE_PRINTF("JB\t"); 86 return ACCESS_FLAG(F_CF); 87 break; 88 case 0x3: 89 DECODE_PRINTF("JNB\t"); 90 return !ACCESS_FLAG(F_CF); 91 break; 92 case 0x4: 93 DECODE_PRINTF("JZ\t"); 94 return ACCESS_FLAG(F_ZF); 95 break; 96 case 0x5: 97 DECODE_PRINTF("JNZ\t"); 98 return !ACCESS_FLAG(F_ZF); 99 break; 100 case 0x6: 101 DECODE_PRINTF("JBE\t"); 102 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 103 break; 104 case 0x7: 105 DECODE_PRINTF("JNBE\t"); 106 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 107 break; 108 case 0x8: 109 DECODE_PRINTF("JS\t"); 110 return ACCESS_FLAG(F_SF); 111 break; 112 case 0x9: 113 DECODE_PRINTF("JNS\t"); 114 return !ACCESS_FLAG(F_SF); 115 break; 116 case 0xa: 117 DECODE_PRINTF("JP\t"); 118 return ACCESS_FLAG(F_PF); 119 break; 120 case 0xb: 121 DECODE_PRINTF("JNP\t"); 122 return !ACCESS_FLAG(F_PF); 123 break; 124 case 0xc: 125 DECODE_PRINTF("JL\t"); 126 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 127 break; 128 case 0xd: 129 DECODE_PRINTF("JNL\t"); 130 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 131 break; 132 case 0xe: 133 DECODE_PRINTF("JLE\t"); 134 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 135 ACCESS_FLAG(F_ZF)); 136 break; 137 default: 138 DECODE_PRINTF("JNLE\t"); 139 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 140 ACCESS_FLAG(F_ZF)); 141 } 142 } 143 144 void x86emuOp2_long_jump(u8 op2) 145 { 146 s32 target; 147 int cond; 148 149 /* conditional jump to word offset. */ 150 START_OF_INSTR(); 151 cond = x86emu_check_jump_condition(op2 & 0xF); 152 target = (s16) fetch_word_imm(); 153 target += (s16) M.x86.R_IP; 154 DECODE_PRINTF2("%04x\n", target); 155 TRACE_AND_STEP(); 156 if (cond) 157 M.x86.R_IP = (u16)target; 158 DECODE_CLEAR_SEGOVR(); 159 END_OF_INSTR(); 160 } 161 162 /**************************************************************************** 163 REMARKS: 164 Handles opcode 0x0f,0x90-0x9F 165 ****************************************************************************/ 166 void x86emuOp2_set_byte(u8 op2) 167 { 168 int mod, rl, rh; 169 uint destoffset; 170 u8 *destreg; 171 char *name = 0; 172 int cond = 0; 173 174 START_OF_INSTR(); 175 switch (op2) { 176 case 0x90: 177 name = "SETO\t"; 178 cond = ACCESS_FLAG(F_OF); 179 break; 180 case 0x91: 181 name = "SETNO\t"; 182 cond = !ACCESS_FLAG(F_OF); 183 break; 184 case 0x92: 185 name = "SETB\t"; 186 cond = ACCESS_FLAG(F_CF); 187 break; 188 case 0x93: 189 name = "SETNB\t"; 190 cond = !ACCESS_FLAG(F_CF); 191 break; 192 case 0x94: 193 name = "SETZ\t"; 194 cond = ACCESS_FLAG(F_ZF); 195 break; 196 case 0x95: 197 name = "SETNZ\t"; 198 cond = !ACCESS_FLAG(F_ZF); 199 break; 200 case 0x96: 201 name = "SETBE\t"; 202 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 203 break; 204 case 0x97: 205 name = "SETNBE\t"; 206 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 207 break; 208 case 0x98: 209 name = "SETS\t"; 210 cond = ACCESS_FLAG(F_SF); 211 break; 212 case 0x99: 213 name = "SETNS\t"; 214 cond = !ACCESS_FLAG(F_SF); 215 break; 216 case 0x9a: 217 name = "SETP\t"; 218 cond = ACCESS_FLAG(F_PF); 219 break; 220 case 0x9b: 221 name = "SETNP\t"; 222 cond = !ACCESS_FLAG(F_PF); 223 break; 224 case 0x9c: 225 name = "SETL\t"; 226 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 227 break; 228 case 0x9d: 229 name = "SETNL\t"; 230 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 231 break; 232 case 0x9e: 233 name = "SETLE\t"; 234 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 235 ACCESS_FLAG(F_ZF)); 236 break; 237 case 0x9f: 238 name = "SETNLE\t"; 239 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 240 ACCESS_FLAG(F_ZF)); 241 break; 242 } 243 DECODE_PRINTF(name); 244 FETCH_DECODE_MODRM(mod, rh, rl); 245 if (mod < 3) { 246 destoffset = decode_rmXX_address(mod, rl); 247 TRACE_AND_STEP(); 248 store_data_byte(destoffset, cond ? 0x01 : 0x00); 249 } else { /* register to register */ 250 destreg = DECODE_RM_BYTE_REGISTER(rl); 251 TRACE_AND_STEP(); 252 *destreg = cond ? 0x01 : 0x00; 253 } 254 DECODE_CLEAR_SEGOVR(); 255 END_OF_INSTR(); 256 } 257 258 /**************************************************************************** 259 REMARKS: 260 Handles opcode 0x0f,0xa0 261 ****************************************************************************/ 262 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)) 263 { 264 START_OF_INSTR(); 265 DECODE_PRINTF("PUSH\tFS\n"); 266 TRACE_AND_STEP(); 267 push_word(M.x86.R_FS); 268 DECODE_CLEAR_SEGOVR(); 269 END_OF_INSTR(); 270 } 271 272 /**************************************************************************** 273 REMARKS: 274 Handles opcode 0x0f,0xa1 275 ****************************************************************************/ 276 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) 277 { 278 START_OF_INSTR(); 279 DECODE_PRINTF("POP\tFS\n"); 280 TRACE_AND_STEP(); 281 M.x86.R_FS = pop_word(); 282 DECODE_CLEAR_SEGOVR(); 283 END_OF_INSTR(); 284 } 285 286 /**************************************************************************** 287 REMARKS: 288 Handles opcode 0x0f,0xa3 289 ****************************************************************************/ 290 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)) 291 { 292 int mod, rl, rh; 293 uint srcoffset; 294 int bit,disp; 295 296 START_OF_INSTR(); 297 DECODE_PRINTF("BT\t"); 298 FETCH_DECODE_MODRM(mod, rh, rl); 299 if (mod < 3) { 300 srcoffset = decode_rmXX_address(mod, rl); 301 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 302 u32 srcval; 303 u32 *shiftreg; 304 305 DECODE_PRINTF(","); 306 shiftreg = DECODE_RM_LONG_REGISTER(rh); 307 TRACE_AND_STEP(); 308 bit = *shiftreg & 0x1F; 309 disp = (s16)*shiftreg >> 5; 310 srcval = fetch_data_long(srcoffset+disp); 311 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); 312 } else { 313 u16 srcval; 314 u16 *shiftreg; 315 316 DECODE_PRINTF(","); 317 shiftreg = DECODE_RM_WORD_REGISTER(rh); 318 TRACE_AND_STEP(); 319 bit = *shiftreg & 0xF; 320 disp = (s16)*shiftreg >> 4; 321 srcval = fetch_data_word(srcoffset+disp); 322 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); 323 } 324 } else { /* register to register */ 325 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 326 u32 *srcreg,*shiftreg; 327 328 srcreg = DECODE_RM_LONG_REGISTER(rl); 329 DECODE_PRINTF(","); 330 shiftreg = DECODE_RM_LONG_REGISTER(rh); 331 TRACE_AND_STEP(); 332 bit = *shiftreg & 0x1F; 333 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); 334 } else { 335 u16 *srcreg,*shiftreg; 336 337 srcreg = DECODE_RM_WORD_REGISTER(rl); 338 DECODE_PRINTF(","); 339 shiftreg = DECODE_RM_WORD_REGISTER(rh); 340 TRACE_AND_STEP(); 341 bit = *shiftreg & 0xF; 342 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); 343 } 344 } 345 DECODE_CLEAR_SEGOVR(); 346 END_OF_INSTR(); 347 } 348 349 /**************************************************************************** 350 REMARKS: 351 Handles opcode 0x0f,0xa4 352 ****************************************************************************/ 353 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)) 354 { 355 int mod, rl, rh; 356 uint destoffset; 357 u8 shift; 358 359 START_OF_INSTR(); 360 DECODE_PRINTF("SHLD\t"); 361 FETCH_DECODE_MODRM(mod, rh, rl); 362 if (mod < 3) { 363 destoffset = decode_rmXX_address(mod, rl); 364 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 365 u32 destval; 366 u32 *shiftreg; 367 368 DECODE_PRINTF(","); 369 shiftreg = DECODE_RM_LONG_REGISTER(rh); 370 DECODE_PRINTF(","); 371 shift = fetch_byte_imm(); 372 DECODE_PRINTF2("%d\n", shift); 373 TRACE_AND_STEP(); 374 destval = fetch_data_long(destoffset); 375 destval = shld_long(destval,*shiftreg,shift); 376 store_data_long(destoffset, destval); 377 } else { 378 u16 destval; 379 u16 *shiftreg; 380 381 DECODE_PRINTF(","); 382 shiftreg = DECODE_RM_WORD_REGISTER(rh); 383 DECODE_PRINTF(","); 384 shift = fetch_byte_imm(); 385 DECODE_PRINTF2("%d\n", shift); 386 TRACE_AND_STEP(); 387 destval = fetch_data_word(destoffset); 388 destval = shld_word(destval,*shiftreg,shift); 389 store_data_word(destoffset, destval); 390 } 391 } else { /* register to register */ 392 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 393 u32 *destreg,*shiftreg; 394 395 destreg = DECODE_RM_LONG_REGISTER(rl); 396 DECODE_PRINTF(","); 397 shiftreg = DECODE_RM_LONG_REGISTER(rh); 398 DECODE_PRINTF(","); 399 shift = fetch_byte_imm(); 400 DECODE_PRINTF2("%d\n", shift); 401 TRACE_AND_STEP(); 402 *destreg = shld_long(*destreg,*shiftreg,shift); 403 } else { 404 u16 *destreg,*shiftreg; 405 406 destreg = DECODE_RM_WORD_REGISTER(rl); 407 DECODE_PRINTF(","); 408 shiftreg = DECODE_RM_WORD_REGISTER(rh); 409 DECODE_PRINTF(","); 410 shift = fetch_byte_imm(); 411 DECODE_PRINTF2("%d\n", shift); 412 TRACE_AND_STEP(); 413 *destreg = shld_word(*destreg,*shiftreg,shift); 414 } 415 } 416 DECODE_CLEAR_SEGOVR(); 417 END_OF_INSTR(); 418 } 419 420 /**************************************************************************** 421 REMARKS: 422 Handles opcode 0x0f,0xa5 423 ****************************************************************************/ 424 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)) 425 { 426 int mod, rl, rh; 427 uint destoffset; 428 429 START_OF_INSTR(); 430 DECODE_PRINTF("SHLD\t"); 431 FETCH_DECODE_MODRM(mod, rh, rl); 432 if (mod < 3) { 433 destoffset = decode_rmXX_address(mod, rl); 434 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 435 u32 destval; 436 u32 *shiftreg; 437 438 DECODE_PRINTF(","); 439 shiftreg = DECODE_RM_LONG_REGISTER(rh); 440 DECODE_PRINTF(",CL\n"); 441 TRACE_AND_STEP(); 442 destval = fetch_data_long(destoffset); 443 destval = shld_long(destval,*shiftreg,M.x86.R_CL); 444 store_data_long(destoffset, destval); 445 } else { 446 u16 destval; 447 u16 *shiftreg; 448 449 DECODE_PRINTF(","); 450 shiftreg = DECODE_RM_WORD_REGISTER(rh); 451 DECODE_PRINTF(",CL\n"); 452 TRACE_AND_STEP(); 453 destval = fetch_data_word(destoffset); 454 destval = shld_word(destval,*shiftreg,M.x86.R_CL); 455 store_data_word(destoffset, destval); 456 } 457 } else { /* register to register */ 458 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 459 u32 *destreg,*shiftreg; 460 461 destreg = DECODE_RM_LONG_REGISTER(rl); 462 DECODE_PRINTF(","); 463 shiftreg = DECODE_RM_LONG_REGISTER(rh); 464 DECODE_PRINTF(",CL\n"); 465 TRACE_AND_STEP(); 466 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL); 467 } else { 468 u16 *destreg,*shiftreg; 469 470 destreg = DECODE_RM_WORD_REGISTER(rl); 471 DECODE_PRINTF(","); 472 shiftreg = DECODE_RM_WORD_REGISTER(rh); 473 DECODE_PRINTF(",CL\n"); 474 TRACE_AND_STEP(); 475 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL); 476 } 477 } 478 DECODE_CLEAR_SEGOVR(); 479 END_OF_INSTR(); 480 } 481 482 /**************************************************************************** 483 REMARKS: 484 Handles opcode 0x0f,0xa8 485 ****************************************************************************/ 486 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2)) 487 { 488 START_OF_INSTR(); 489 DECODE_PRINTF("PUSH\tGS\n"); 490 TRACE_AND_STEP(); 491 push_word(M.x86.R_GS); 492 DECODE_CLEAR_SEGOVR(); 493 END_OF_INSTR(); 494 } 495 496 /**************************************************************************** 497 REMARKS: 498 Handles opcode 0x0f,0xa9 499 ****************************************************************************/ 500 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2)) 501 { 502 START_OF_INSTR(); 503 DECODE_PRINTF("POP\tGS\n"); 504 TRACE_AND_STEP(); 505 M.x86.R_GS = pop_word(); 506 DECODE_CLEAR_SEGOVR(); 507 END_OF_INSTR(); 508 } 509 510 /**************************************************************************** 511 REMARKS: 512 Handles opcode 0x0f,0xaa 513 ****************************************************************************/ 514 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2)) 515 { 516 int mod, rl, rh; 517 uint srcoffset; 518 int bit,disp; 519 520 START_OF_INSTR(); 521 DECODE_PRINTF("BTS\t"); 522 FETCH_DECODE_MODRM(mod, rh, rl); 523 if (mod < 3) { 524 srcoffset = decode_rmXX_address(mod, rl); 525 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 526 u32 srcval,mask; 527 u32 *shiftreg; 528 529 DECODE_PRINTF(","); 530 shiftreg = DECODE_RM_LONG_REGISTER(rh); 531 TRACE_AND_STEP(); 532 bit = *shiftreg & 0x1F; 533 disp = (s16)*shiftreg >> 5; 534 srcval = fetch_data_long(srcoffset+disp); 535 mask = (0x1 << bit); 536 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 537 store_data_long(srcoffset+disp, srcval | mask); 538 } else { 539 u16 srcval,mask; 540 u16 *shiftreg; 541 542 DECODE_PRINTF(","); 543 shiftreg = DECODE_RM_WORD_REGISTER(rh); 544 TRACE_AND_STEP(); 545 bit = *shiftreg & 0xF; 546 disp = (s16)*shiftreg >> 4; 547 srcval = fetch_data_word(srcoffset+disp); 548 mask = (u16)(0x1 << bit); 549 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 550 store_data_word(srcoffset+disp, srcval | mask); 551 } 552 } else { /* register to register */ 553 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 554 u32 *srcreg,*shiftreg; 555 u32 mask; 556 557 srcreg = DECODE_RM_LONG_REGISTER(rl); 558 DECODE_PRINTF(","); 559 shiftreg = DECODE_RM_LONG_REGISTER(rh); 560 TRACE_AND_STEP(); 561 bit = *shiftreg & 0x1F; 562 mask = (0x1 << bit); 563 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 564 *srcreg |= mask; 565 } else { 566 u16 *srcreg,*shiftreg; 567 u16 mask; 568 569 srcreg = DECODE_RM_WORD_REGISTER(rl); 570 DECODE_PRINTF(","); 571 shiftreg = DECODE_RM_WORD_REGISTER(rh); 572 TRACE_AND_STEP(); 573 bit = *shiftreg & 0xF; 574 mask = (u16)(0x1 << bit); 575 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 576 *srcreg |= mask; 577 } 578 } 579 DECODE_CLEAR_SEGOVR(); 580 END_OF_INSTR(); 581 } 582 583 /**************************************************************************** 584 REMARKS: 585 Handles opcode 0x0f,0xac 586 ****************************************************************************/ 587 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)) 588 { 589 int mod, rl, rh; 590 uint destoffset; 591 u8 shift; 592 593 START_OF_INSTR(); 594 DECODE_PRINTF("SHLD\t"); 595 FETCH_DECODE_MODRM(mod, rh, rl); 596 if (mod < 3) { 597 destoffset = decode_rmXX_address(mod, rl); 598 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 599 u32 destval; 600 u32 *shiftreg; 601 602 DECODE_PRINTF(","); 603 shiftreg = DECODE_RM_LONG_REGISTER(rh); 604 DECODE_PRINTF(","); 605 shift = fetch_byte_imm(); 606 DECODE_PRINTF2("%d\n", shift); 607 TRACE_AND_STEP(); 608 destval = fetch_data_long(destoffset); 609 destval = shrd_long(destval,*shiftreg,shift); 610 store_data_long(destoffset, destval); 611 } else { 612 u16 destval; 613 u16 *shiftreg; 614 615 DECODE_PRINTF(","); 616 shiftreg = DECODE_RM_WORD_REGISTER(rh); 617 DECODE_PRINTF(","); 618 shift = fetch_byte_imm(); 619 DECODE_PRINTF2("%d\n", shift); 620 TRACE_AND_STEP(); 621 destval = fetch_data_word(destoffset); 622 destval = shrd_word(destval,*shiftreg,shift); 623 store_data_word(destoffset, destval); 624 } 625 } else { /* register to register */ 626 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 627 u32 *destreg,*shiftreg; 628 629 destreg = DECODE_RM_LONG_REGISTER(rl); 630 DECODE_PRINTF(","); 631 shiftreg = DECODE_RM_LONG_REGISTER(rh); 632 DECODE_PRINTF(","); 633 shift = fetch_byte_imm(); 634 DECODE_PRINTF2("%d\n", shift); 635 TRACE_AND_STEP(); 636 *destreg = shrd_long(*destreg,*shiftreg,shift); 637 } else { 638 u16 *destreg,*shiftreg; 639 640 destreg = DECODE_RM_WORD_REGISTER(rl); 641 DECODE_PRINTF(","); 642 shiftreg = DECODE_RM_WORD_REGISTER(rh); 643 DECODE_PRINTF(","); 644 shift = fetch_byte_imm(); 645 DECODE_PRINTF2("%d\n", shift); 646 TRACE_AND_STEP(); 647 *destreg = shrd_word(*destreg,*shiftreg,shift); 648 } 649 } 650 DECODE_CLEAR_SEGOVR(); 651 END_OF_INSTR(); 652 } 653 654 /**************************************************************************** 655 REMARKS: 656 Handles opcode 0x0f,0xad 657 ****************************************************************************/ 658 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)) 659 { 660 int mod, rl, rh; 661 uint destoffset; 662 663 START_OF_INSTR(); 664 DECODE_PRINTF("SHLD\t"); 665 FETCH_DECODE_MODRM(mod, rh, rl); 666 if (mod < 3) { 667 destoffset = decode_rmXX_address(mod, rl); 668 DECODE_PRINTF(","); 669 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 670 u32 destval; 671 u32 *shiftreg; 672 673 shiftreg = DECODE_RM_LONG_REGISTER(rh); 674 DECODE_PRINTF(",CL\n"); 675 TRACE_AND_STEP(); 676 destval = fetch_data_long(destoffset); 677 destval = shrd_long(destval,*shiftreg,M.x86.R_CL); 678 store_data_long(destoffset, destval); 679 } else { 680 u16 destval; 681 u16 *shiftreg; 682 683 shiftreg = DECODE_RM_WORD_REGISTER(rh); 684 DECODE_PRINTF(",CL\n"); 685 TRACE_AND_STEP(); 686 destval = fetch_data_word(destoffset); 687 destval = shrd_word(destval,*shiftreg,M.x86.R_CL); 688 store_data_word(destoffset, destval); 689 } 690 } else { /* register to register */ 691 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 692 u32 *destreg,*shiftreg; 693 694 destreg = DECODE_RM_LONG_REGISTER(rl); 695 DECODE_PRINTF(","); 696 shiftreg = DECODE_RM_LONG_REGISTER(rh); 697 DECODE_PRINTF(",CL\n"); 698 TRACE_AND_STEP(); 699 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL); 700 } else { 701 u16 *destreg,*shiftreg; 702 703 destreg = DECODE_RM_WORD_REGISTER(rl); 704 DECODE_PRINTF(","); 705 shiftreg = DECODE_RM_WORD_REGISTER(rh); 706 DECODE_PRINTF(",CL\n"); 707 TRACE_AND_STEP(); 708 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL); 709 } 710 } 711 DECODE_CLEAR_SEGOVR(); 712 END_OF_INSTR(); 713 } 714 715 /**************************************************************************** 716 REMARKS: 717 Handles opcode 0x0f,0xaf 718 ****************************************************************************/ 719 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)) 720 { 721 int mod, rl, rh; 722 uint srcoffset; 723 724 START_OF_INSTR(); 725 DECODE_PRINTF("IMUL\t"); 726 FETCH_DECODE_MODRM(mod, rh, rl); 727 if (mod < 3) { 728 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 729 u32 *destreg; 730 u32 srcval; 731 u32 res_lo,res_hi; 732 733 destreg = DECODE_RM_LONG_REGISTER(rh); 734 DECODE_PRINTF(","); 735 srcoffset = decode_rmXX_address(mod, rl); 736 srcval = fetch_data_long(srcoffset); 737 TRACE_AND_STEP(); 738 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval); 739 if (res_hi != 0) { 740 SET_FLAG(F_CF); 741 SET_FLAG(F_OF); 742 } else { 743 CLEAR_FLAG(F_CF); 744 CLEAR_FLAG(F_OF); 745 } 746 *destreg = (u32)res_lo; 747 } else { 748 u16 *destreg; 749 u16 srcval; 750 u32 res; 751 752 destreg = DECODE_RM_WORD_REGISTER(rh); 753 DECODE_PRINTF(","); 754 srcoffset = decode_rmXX_address(mod, rl); 755 srcval = fetch_data_word(srcoffset); 756 TRACE_AND_STEP(); 757 res = (s16)*destreg * (s16)srcval; 758 if (res > 0xFFFF) { 759 SET_FLAG(F_CF); 760 SET_FLAG(F_OF); 761 } else { 762 CLEAR_FLAG(F_CF); 763 CLEAR_FLAG(F_OF); 764 } 765 *destreg = (u16)res; 766 } 767 } else { /* register to register */ 768 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 769 u32 *destreg,*srcreg; 770 u32 res_lo,res_hi; 771 772 destreg = DECODE_RM_LONG_REGISTER(rh); 773 DECODE_PRINTF(","); 774 srcreg = DECODE_RM_LONG_REGISTER(rl); 775 TRACE_AND_STEP(); 776 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg); 777 if (res_hi != 0) { 778 SET_FLAG(F_CF); 779 SET_FLAG(F_OF); 780 } else { 781 CLEAR_FLAG(F_CF); 782 CLEAR_FLAG(F_OF); 783 } 784 *destreg = (u32)res_lo; 785 } else { 786 u16 *destreg,*srcreg; 787 u32 res; 788 789 destreg = DECODE_RM_WORD_REGISTER(rh); 790 DECODE_PRINTF(","); 791 srcreg = DECODE_RM_WORD_REGISTER(rl); 792 res = (s16)*destreg * (s16)*srcreg; 793 if (res > 0xFFFF) { 794 SET_FLAG(F_CF); 795 SET_FLAG(F_OF); 796 } else { 797 CLEAR_FLAG(F_CF); 798 CLEAR_FLAG(F_OF); 799 } 800 *destreg = (u16)res; 801 } 802 } 803 DECODE_CLEAR_SEGOVR(); 804 END_OF_INSTR(); 805 } 806 807 /**************************************************************************** 808 REMARKS: 809 Handles opcode 0x0f,0xb2 810 ****************************************************************************/ 811 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2)) 812 { 813 int mod, rh, rl; 814 u16 *dstreg; 815 uint srcoffset; 816 817 START_OF_INSTR(); 818 DECODE_PRINTF("LSS\t"); 819 FETCH_DECODE_MODRM(mod, rh, rl); 820 if (mod < 3) { 821 dstreg = DECODE_RM_WORD_REGISTER(rh); 822 DECODE_PRINTF(","); 823 srcoffset = decode_rmXX_address(mod, rl); 824 DECODE_PRINTF("\n"); 825 TRACE_AND_STEP(); 826 *dstreg = fetch_data_word(srcoffset); 827 M.x86.R_SS = fetch_data_word(srcoffset + 2); 828 } else { /* register to register */ 829 /* UNDEFINED! */ 830 TRACE_AND_STEP(); 831 } 832 DECODE_CLEAR_SEGOVR(); 833 END_OF_INSTR(); 834 } 835 836 /**************************************************************************** 837 REMARKS: 838 Handles opcode 0x0f,0xb3 839 ****************************************************************************/ 840 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2)) 841 { 842 int mod, rl, rh; 843 uint srcoffset; 844 int bit,disp; 845 846 START_OF_INSTR(); 847 DECODE_PRINTF("BTR\t"); 848 FETCH_DECODE_MODRM(mod, rh, rl); 849 if (mod < 3) { 850 srcoffset = decode_rmXX_address(mod, rl); 851 DECODE_PRINTF(","); 852 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 853 u32 srcval,mask; 854 u32 *shiftreg; 855 856 shiftreg = DECODE_RM_LONG_REGISTER(rh); 857 TRACE_AND_STEP(); 858 bit = *shiftreg & 0x1F; 859 disp = (s16)*shiftreg >> 5; 860 srcval = fetch_data_long(srcoffset+disp); 861 mask = (0x1 << bit); 862 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 863 store_data_long(srcoffset+disp, srcval & ~mask); 864 } else { 865 u16 srcval,mask; 866 u16 *shiftreg; 867 868 shiftreg = DECODE_RM_WORD_REGISTER(rh); 869 TRACE_AND_STEP(); 870 bit = *shiftreg & 0xF; 871 disp = (s16)*shiftreg >> 4; 872 srcval = fetch_data_word(srcoffset+disp); 873 mask = (u16)(0x1 << bit); 874 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 875 store_data_word(srcoffset+disp, (u16)(srcval & ~mask)); 876 } 877 } else { /* register to register */ 878 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 879 u32 *srcreg,*shiftreg; 880 u32 mask; 881 882 srcreg = DECODE_RM_LONG_REGISTER(rl); 883 DECODE_PRINTF(","); 884 shiftreg = DECODE_RM_LONG_REGISTER(rh); 885 TRACE_AND_STEP(); 886 bit = *shiftreg & 0x1F; 887 mask = (0x1 << bit); 888 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 889 *srcreg &= ~mask; 890 } else { 891 u16 *srcreg,*shiftreg; 892 u16 mask; 893 894 srcreg = DECODE_RM_WORD_REGISTER(rl); 895 DECODE_PRINTF(","); 896 shiftreg = DECODE_RM_WORD_REGISTER(rh); 897 TRACE_AND_STEP(); 898 bit = *shiftreg & 0xF; 899 mask = (u16)(0x1 << bit); 900 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 901 *srcreg &= ~mask; 902 } 903 } 904 DECODE_CLEAR_SEGOVR(); 905 END_OF_INSTR(); 906 } 907 908 /**************************************************************************** 909 REMARKS: 910 Handles opcode 0x0f,0xb4 911 ****************************************************************************/ 912 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2)) 913 { 914 int mod, rh, rl; 915 u16 *dstreg; 916 uint srcoffset; 917 918 START_OF_INSTR(); 919 DECODE_PRINTF("LFS\t"); 920 FETCH_DECODE_MODRM(mod, rh, rl); 921 if (mod < 3) { 922 dstreg = DECODE_RM_WORD_REGISTER(rh); 923 DECODE_PRINTF(","); 924 srcoffset = decode_rmXX_address(mod, rl); 925 DECODE_PRINTF("\n"); 926 TRACE_AND_STEP(); 927 *dstreg = fetch_data_word(srcoffset); 928 M.x86.R_FS = fetch_data_word(srcoffset + 2); 929 } else { /* register to register */ 930 /* UNDEFINED! */ 931 TRACE_AND_STEP(); 932 } 933 DECODE_CLEAR_SEGOVR(); 934 END_OF_INSTR(); 935 } 936 937 /**************************************************************************** 938 REMARKS: 939 Handles opcode 0x0f,0xb5 940 ****************************************************************************/ 941 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2)) 942 { 943 int mod, rh, rl; 944 u16 *dstreg; 945 uint srcoffset; 946 947 START_OF_INSTR(); 948 DECODE_PRINTF("LGS\t"); 949 FETCH_DECODE_MODRM(mod, rh, rl); 950 if (mod < 3) { 951 dstreg = DECODE_RM_WORD_REGISTER(rh); 952 DECODE_PRINTF(","); 953 srcoffset = decode_rmXX_address(mod, rl); 954 DECODE_PRINTF("\n"); 955 TRACE_AND_STEP(); 956 *dstreg = fetch_data_word(srcoffset); 957 M.x86.R_GS = fetch_data_word(srcoffset + 2); 958 } else { /* register to register */ 959 /* UNDEFINED! */ 960 TRACE_AND_STEP(); 961 } 962 DECODE_CLEAR_SEGOVR(); 963 END_OF_INSTR(); 964 } 965 966 /**************************************************************************** 967 REMARKS: 968 Handles opcode 0x0f,0xb6 969 ****************************************************************************/ 970 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 971 { 972 int mod, rl, rh; 973 uint srcoffset; 974 975 START_OF_INSTR(); 976 DECODE_PRINTF("MOVZX\t"); 977 FETCH_DECODE_MODRM(mod, rh, rl); 978 if (mod < 3) { 979 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 980 u32 *destreg; 981 u32 srcval; 982 983 destreg = DECODE_RM_LONG_REGISTER(rh); 984 DECODE_PRINTF(","); 985 srcoffset = decode_rmXX_address(mod, rl); 986 srcval = fetch_data_byte(srcoffset); 987 DECODE_PRINTF("\n"); 988 TRACE_AND_STEP(); 989 *destreg = srcval; 990 } else { 991 u16 *destreg; 992 u16 srcval; 993 994 destreg = DECODE_RM_WORD_REGISTER(rh); 995 DECODE_PRINTF(","); 996 srcoffset = decode_rmXX_address(mod, rl); 997 srcval = fetch_data_byte(srcoffset); 998 DECODE_PRINTF("\n"); 999 TRACE_AND_STEP(); 1000 *destreg = srcval; 1001 } 1002 } else { /* register to register */ 1003 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1004 u32 *destreg; 1005 u8 *srcreg; 1006 1007 destreg = DECODE_RM_LONG_REGISTER(rh); 1008 DECODE_PRINTF(","); 1009 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1010 DECODE_PRINTF("\n"); 1011 TRACE_AND_STEP(); 1012 *destreg = *srcreg; 1013 } else { 1014 u16 *destreg; 1015 u8 *srcreg; 1016 1017 destreg = DECODE_RM_WORD_REGISTER(rh); 1018 DECODE_PRINTF(","); 1019 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1020 DECODE_PRINTF("\n"); 1021 TRACE_AND_STEP(); 1022 *destreg = *srcreg; 1023 } 1024 } 1025 DECODE_CLEAR_SEGOVR(); 1026 END_OF_INSTR(); 1027 } 1028 1029 /**************************************************************************** 1030 REMARKS: 1031 Handles opcode 0x0f,0xb7 1032 ****************************************************************************/ 1033 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2)) 1034 { 1035 int mod, rl, rh; 1036 uint srcoffset; 1037 u32 *destreg; 1038 u32 srcval; 1039 u16 *srcreg; 1040 1041 START_OF_INSTR(); 1042 DECODE_PRINTF("MOVZX\t"); 1043 FETCH_DECODE_MODRM(mod, rh, rl); 1044 if (mod < 3) { 1045 destreg = DECODE_RM_LONG_REGISTER(rh); 1046 DECODE_PRINTF(","); 1047 srcoffset = decode_rmXX_address(mod, rl); 1048 srcval = fetch_data_word(srcoffset); 1049 DECODE_PRINTF("\n"); 1050 TRACE_AND_STEP(); 1051 *destreg = srcval; 1052 } else { /* register to register */ 1053 destreg = DECODE_RM_LONG_REGISTER(rh); 1054 DECODE_PRINTF(","); 1055 srcreg = DECODE_RM_WORD_REGISTER(rl); 1056 DECODE_PRINTF("\n"); 1057 TRACE_AND_STEP(); 1058 *destreg = *srcreg; 1059 } 1060 DECODE_CLEAR_SEGOVR(); 1061 END_OF_INSTR(); 1062 } 1063 1064 /**************************************************************************** 1065 REMARKS: 1066 Handles opcode 0x0f,0xba 1067 ****************************************************************************/ 1068 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) 1069 { 1070 int mod, rl, rh; 1071 uint srcoffset; 1072 u8 shift; 1073 int bit; 1074 1075 START_OF_INSTR(); 1076 FETCH_DECODE_MODRM(mod, rh, rl); 1077 switch (rh) { 1078 case 4: 1079 DECODE_PRINTF("BT\t"); 1080 break; 1081 case 5: 1082 DECODE_PRINTF("BTS\t"); 1083 break; 1084 case 6: 1085 DECODE_PRINTF("BTR\t"); 1086 break; 1087 case 7: 1088 DECODE_PRINTF("BTC\t"); 1089 break; 1090 default: 1091 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 1092 TRACE_REGS(); 1093 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", 1094 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl); 1095 HALT_SYS(); 1096 } 1097 if (mod < 3) { 1098 1099 srcoffset = decode_rmXX_address(mod, rl); 1100 shift = fetch_byte_imm(); 1101 DECODE_PRINTF2(",%d\n", shift); 1102 TRACE_AND_STEP(); 1103 1104 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1105 u32 srcval, mask; 1106 1107 bit = shift & 0x1F; 1108 srcval = fetch_data_long(srcoffset); 1109 mask = (0x1 << bit); 1110 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1111 switch (rh) { 1112 case 5: 1113 store_data_long(srcoffset, srcval | mask); 1114 break; 1115 case 6: 1116 store_data_long(srcoffset, srcval & ~mask); 1117 break; 1118 case 7: 1119 store_data_long(srcoffset, srcval ^ mask); 1120 break; 1121 default: 1122 break; 1123 } 1124 } else { 1125 u16 srcval, mask; 1126 1127 bit = shift & 0xF; 1128 srcval = fetch_data_word(srcoffset); 1129 mask = (0x1 << bit); 1130 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1131 switch (rh) { 1132 case 5: 1133 store_data_word(srcoffset, srcval | mask); 1134 break; 1135 case 6: 1136 store_data_word(srcoffset, srcval & ~mask); 1137 break; 1138 case 7: 1139 store_data_word(srcoffset, srcval ^ mask); 1140 break; 1141 default: 1142 break; 1143 } 1144 } 1145 } else { /* register to register */ 1146 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1147 u32 *srcreg; 1148 u32 mask; 1149 1150 srcreg = DECODE_RM_LONG_REGISTER(rl); 1151 shift = fetch_byte_imm(); 1152 DECODE_PRINTF2(",%d\n", shift); 1153 TRACE_AND_STEP(); 1154 bit = shift & 0x1F; 1155 mask = (0x1 << bit); 1156 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1157 switch (rh) { 1158 case 5: 1159 *srcreg |= mask; 1160 break; 1161 case 6: 1162 *srcreg &= ~mask; 1163 break; 1164 case 7: 1165 *srcreg ^= mask; 1166 break; 1167 default: 1168 break; 1169 } 1170 } else { 1171 u16 *srcreg; 1172 u16 mask; 1173 1174 srcreg = DECODE_RM_WORD_REGISTER(rl); 1175 shift = fetch_byte_imm(); 1176 DECODE_PRINTF2(",%d\n", shift); 1177 TRACE_AND_STEP(); 1178 bit = shift & 0xF; 1179 mask = (0x1 << bit); 1180 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1181 switch (rh) { 1182 case 5: 1183 *srcreg |= mask; 1184 break; 1185 case 6: 1186 *srcreg &= ~mask; 1187 break; 1188 case 7: 1189 *srcreg ^= mask; 1190 break; 1191 default: 1192 break; 1193 } 1194 } 1195 } 1196 DECODE_CLEAR_SEGOVR(); 1197 END_OF_INSTR(); 1198 } 1199 1200 /**************************************************************************** 1201 REMARKS: 1202 Handles opcode 0x0f,0xbb 1203 ****************************************************************************/ 1204 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2)) 1205 { 1206 int mod, rl, rh; 1207 uint srcoffset; 1208 int bit,disp; 1209 1210 START_OF_INSTR(); 1211 DECODE_PRINTF("BTC\t"); 1212 FETCH_DECODE_MODRM(mod, rh, rl); 1213 if (mod < 3) { 1214 srcoffset = decode_rmXX_address(mod, rl); 1215 DECODE_PRINTF(","); 1216 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1217 u32 srcval,mask; 1218 u32 *shiftreg; 1219 1220 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1221 TRACE_AND_STEP(); 1222 bit = *shiftreg & 0x1F; 1223 disp = (s16)*shiftreg >> 5; 1224 srcval = fetch_data_long(srcoffset+disp); 1225 mask = (0x1 << bit); 1226 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1227 store_data_long(srcoffset+disp, srcval ^ mask); 1228 } else { 1229 u16 srcval,mask; 1230 u16 *shiftreg; 1231 1232 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1233 TRACE_AND_STEP(); 1234 bit = *shiftreg & 0xF; 1235 disp = (s16)*shiftreg >> 4; 1236 srcval = fetch_data_word(srcoffset+disp); 1237 mask = (u16)(0x1 << bit); 1238 CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1239 store_data_word(srcoffset+disp, (u16)(srcval ^ mask)); 1240 } 1241 } else { /* register to register */ 1242 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1243 u32 *srcreg,*shiftreg; 1244 u32 mask; 1245 1246 srcreg = DECODE_RM_LONG_REGISTER(rl); 1247 DECODE_PRINTF(","); 1248 shiftreg = DECODE_RM_LONG_REGISTER(rh); 1249 TRACE_AND_STEP(); 1250 bit = *shiftreg & 0x1F; 1251 mask = (0x1 << bit); 1252 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1253 *srcreg ^= mask; 1254 } else { 1255 u16 *srcreg,*shiftreg; 1256 u16 mask; 1257 1258 srcreg = DECODE_RM_WORD_REGISTER(rl); 1259 DECODE_PRINTF(","); 1260 shiftreg = DECODE_RM_WORD_REGISTER(rh); 1261 TRACE_AND_STEP(); 1262 bit = *shiftreg & 0xF; 1263 mask = (u16)(0x1 << bit); 1264 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1265 *srcreg ^= mask; 1266 } 1267 } 1268 DECODE_CLEAR_SEGOVR(); 1269 END_OF_INSTR(); 1270 } 1271 1272 /**************************************************************************** 1273 REMARKS: 1274 Handles opcode 0x0f,0xbc 1275 ****************************************************************************/ 1276 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) 1277 { 1278 int mod, rl, rh; 1279 uint srcoffset; 1280 1281 START_OF_INSTR(); 1282 DECODE_PRINTF("BSF\n"); 1283 FETCH_DECODE_MODRM(mod, rh, rl); 1284 if (mod < 3) { 1285 srcoffset = decode_rmXX_address(mod, rl); 1286 DECODE_PRINTF(","); 1287 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1288 u32 srcval, *dstreg; 1289 1290 dstreg = DECODE_RM_LONG_REGISTER(rh); 1291 TRACE_AND_STEP(); 1292 srcval = fetch_data_long(srcoffset); 1293 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1294 for(*dstreg = 0; *dstreg < 32; (*dstreg)++) 1295 if ((srcval >> *dstreg) & 1) break; 1296 } else { 1297 u16 srcval, *dstreg; 1298 1299 dstreg = DECODE_RM_WORD_REGISTER(rh); 1300 TRACE_AND_STEP(); 1301 srcval = fetch_data_word(srcoffset); 1302 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1303 for(*dstreg = 0; *dstreg < 16; (*dstreg)++) 1304 if ((srcval >> *dstreg) & 1) break; 1305 } 1306 } else { /* register to register */ 1307 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1308 u32 *srcreg, *dstreg; 1309 1310 srcreg = DECODE_RM_LONG_REGISTER(rl); 1311 DECODE_PRINTF(","); 1312 dstreg = DECODE_RM_LONG_REGISTER(rh); 1313 TRACE_AND_STEP(); 1314 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1315 for(*dstreg = 0; *dstreg < 32; (*dstreg)++) 1316 if ((*srcreg >> *dstreg) & 1) break; 1317 } else { 1318 u16 *srcreg, *dstreg; 1319 1320 srcreg = DECODE_RM_WORD_REGISTER(rl); 1321 DECODE_PRINTF(","); 1322 dstreg = DECODE_RM_WORD_REGISTER(rh); 1323 TRACE_AND_STEP(); 1324 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1325 for(*dstreg = 0; *dstreg < 16; (*dstreg)++) 1326 if ((*srcreg >> *dstreg) & 1) break; 1327 } 1328 } 1329 DECODE_CLEAR_SEGOVR(); 1330 END_OF_INSTR(); 1331 } 1332 1333 /**************************************************************************** 1334 REMARKS: 1335 Handles opcode 0x0f,0xbd 1336 ****************************************************************************/ 1337 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) 1338 { 1339 int mod, rl, rh; 1340 uint srcoffset; 1341 1342 START_OF_INSTR(); 1343 DECODE_PRINTF("BSF\n"); 1344 FETCH_DECODE_MODRM(mod, rh, rl); 1345 if (mod < 3) { 1346 srcoffset = decode_rmXX_address(mod, rl); 1347 DECODE_PRINTF(","); 1348 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1349 u32 srcval, *dstreg; 1350 1351 dstreg = DECODE_RM_LONG_REGISTER(rh); 1352 TRACE_AND_STEP(); 1353 srcval = fetch_data_long(srcoffset); 1354 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1355 for(*dstreg = 31; *dstreg > 0; (*dstreg)--) 1356 if ((srcval >> *dstreg) & 1) break; 1357 } else { 1358 u16 srcval, *dstreg; 1359 1360 dstreg = DECODE_RM_WORD_REGISTER(rh); 1361 TRACE_AND_STEP(); 1362 srcval = fetch_data_word(srcoffset); 1363 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1364 for(*dstreg = 15; *dstreg > 0; (*dstreg)--) 1365 if ((srcval >> *dstreg) & 1) break; 1366 } 1367 } else { /* register to register */ 1368 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1369 u32 *srcreg, *dstreg; 1370 1371 srcreg = DECODE_RM_LONG_REGISTER(rl); 1372 DECODE_PRINTF(","); 1373 dstreg = DECODE_RM_LONG_REGISTER(rh); 1374 TRACE_AND_STEP(); 1375 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1376 for(*dstreg = 31; *dstreg > 0; (*dstreg)--) 1377 if ((*srcreg >> *dstreg) & 1) break; 1378 } else { 1379 u16 *srcreg, *dstreg; 1380 1381 srcreg = DECODE_RM_WORD_REGISTER(rl); 1382 DECODE_PRINTF(","); 1383 dstreg = DECODE_RM_WORD_REGISTER(rh); 1384 TRACE_AND_STEP(); 1385 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1386 for(*dstreg = 15; *dstreg > 0; (*dstreg)--) 1387 if ((*srcreg >> *dstreg) & 1) break; 1388 } 1389 } 1390 DECODE_CLEAR_SEGOVR(); 1391 END_OF_INSTR(); 1392 } 1393 1394 /**************************************************************************** 1395 REMARKS: 1396 Handles opcode 0x0f,0xbe 1397 ****************************************************************************/ 1398 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 1399 { 1400 int mod, rl, rh; 1401 uint srcoffset; 1402 1403 START_OF_INSTR(); 1404 DECODE_PRINTF("MOVSX\t"); 1405 FETCH_DECODE_MODRM(mod, rh, rl); 1406 if (mod < 3) { 1407 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1408 u32 *destreg; 1409 u32 srcval; 1410 1411 destreg = DECODE_RM_LONG_REGISTER(rh); 1412 DECODE_PRINTF(","); 1413 srcoffset = decode_rmXX_address(mod, rl); 1414 srcval = (s32)((s8)fetch_data_byte(srcoffset)); 1415 DECODE_PRINTF("\n"); 1416 TRACE_AND_STEP(); 1417 *destreg = srcval; 1418 } else { 1419 u16 *destreg; 1420 u16 srcval; 1421 1422 destreg = DECODE_RM_WORD_REGISTER(rh); 1423 DECODE_PRINTF(","); 1424 srcoffset = decode_rmXX_address(mod, rl); 1425 srcval = (s16)((s8)fetch_data_byte(srcoffset)); 1426 DECODE_PRINTF("\n"); 1427 TRACE_AND_STEP(); 1428 *destreg = srcval; 1429 } 1430 } else { /* register to register */ 1431 if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1432 u32 *destreg; 1433 u8 *srcreg; 1434 1435 destreg = DECODE_RM_LONG_REGISTER(rh); 1436 DECODE_PRINTF(","); 1437 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1438 DECODE_PRINTF("\n"); 1439 TRACE_AND_STEP(); 1440 *destreg = (s32)((s8)*srcreg); 1441 } else { 1442 u16 *destreg; 1443 u8 *srcreg; 1444 1445 destreg = DECODE_RM_WORD_REGISTER(rh); 1446 DECODE_PRINTF(","); 1447 srcreg = DECODE_RM_BYTE_REGISTER(rl); 1448 DECODE_PRINTF("\n"); 1449 TRACE_AND_STEP(); 1450 *destreg = (s16)((s8)*srcreg); 1451 } 1452 } 1453 DECODE_CLEAR_SEGOVR(); 1454 END_OF_INSTR(); 1455 } 1456 1457 /**************************************************************************** 1458 REMARKS: 1459 Handles opcode 0x0f,0xbf 1460 ****************************************************************************/ 1461 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2)) 1462 { 1463 int mod, rl, rh; 1464 uint srcoffset; 1465 u32 *destreg; 1466 u32 srcval; 1467 u16 *srcreg; 1468 1469 START_OF_INSTR(); 1470 DECODE_PRINTF("MOVSX\t"); 1471 FETCH_DECODE_MODRM(mod, rh, rl); 1472 if (mod < 3) { 1473 destreg = DECODE_RM_LONG_REGISTER(rh); 1474 DECODE_PRINTF(","); 1475 srcoffset = decode_rmXX_address(mod, rl); 1476 srcval = (s32)((s16)fetch_data_word(srcoffset)); 1477 DECODE_PRINTF("\n"); 1478 TRACE_AND_STEP(); 1479 *destreg = srcval; 1480 } else { /* register to register */ 1481 destreg = DECODE_RM_LONG_REGISTER(rh); 1482 DECODE_PRINTF(","); 1483 srcreg = DECODE_RM_WORD_REGISTER(rl); 1484 DECODE_PRINTF("\n"); 1485 TRACE_AND_STEP(); 1486 *destreg = (s32)((s16)*srcreg); 1487 } 1488 DECODE_CLEAR_SEGOVR(); 1489 END_OF_INSTR(); 1490 } 1491 1492 /*************************************************************************** 1493 * Double byte operation code table: 1494 **************************************************************************/ 1495 void (*x86emu_optab2[256])(u8) = 1496 { 1497 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */ 1498 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */ 1499 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */ 1500 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */ 1501 /* 0x04 */ x86emuOp2_illegal_op, 1502 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */ 1503 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */ 1504 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */ 1505 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */ 1506 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */ 1507 /* 0x0a */ x86emuOp2_illegal_op, 1508 /* 0x0b */ x86emuOp2_illegal_op, 1509 /* 0x0c */ x86emuOp2_illegal_op, 1510 /* 0x0d */ x86emuOp2_illegal_op, 1511 /* 0x0e */ x86emuOp2_illegal_op, 1512 /* 0x0f */ x86emuOp2_illegal_op, 1513 1514 /* 0x10 */ x86emuOp2_illegal_op, 1515 /* 0x11 */ x86emuOp2_illegal_op, 1516 /* 0x12 */ x86emuOp2_illegal_op, 1517 /* 0x13 */ x86emuOp2_illegal_op, 1518 /* 0x14 */ x86emuOp2_illegal_op, 1519 /* 0x15 */ x86emuOp2_illegal_op, 1520 /* 0x16 */ x86emuOp2_illegal_op, 1521 /* 0x17 */ x86emuOp2_illegal_op, 1522 /* 0x18 */ x86emuOp2_illegal_op, 1523 /* 0x19 */ x86emuOp2_illegal_op, 1524 /* 0x1a */ x86emuOp2_illegal_op, 1525 /* 0x1b */ x86emuOp2_illegal_op, 1526 /* 0x1c */ x86emuOp2_illegal_op, 1527 /* 0x1d */ x86emuOp2_illegal_op, 1528 /* 0x1e */ x86emuOp2_illegal_op, 1529 /* 0x1f */ x86emuOp2_illegal_op, 1530 1531 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */ 1532 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */ 1533 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */ 1534 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */ 1535 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */ 1536 /* 0x25 */ x86emuOp2_illegal_op, 1537 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */ 1538 /* 0x27 */ x86emuOp2_illegal_op, 1539 /* 0x28 */ x86emuOp2_illegal_op, 1540 /* 0x29 */ x86emuOp2_illegal_op, 1541 /* 0x2a */ x86emuOp2_illegal_op, 1542 /* 0x2b */ x86emuOp2_illegal_op, 1543 /* 0x2c */ x86emuOp2_illegal_op, 1544 /* 0x2d */ x86emuOp2_illegal_op, 1545 /* 0x2e */ x86emuOp2_illegal_op, 1546 /* 0x2f */ x86emuOp2_illegal_op, 1547 1548 /* 0x30 */ x86emuOp2_illegal_op, 1549 /* 0x31 */ x86emuOp2_illegal_op, 1550 /* 0x32 */ x86emuOp2_illegal_op, 1551 /* 0x33 */ x86emuOp2_illegal_op, 1552 /* 0x34 */ x86emuOp2_illegal_op, 1553 /* 0x35 */ x86emuOp2_illegal_op, 1554 /* 0x36 */ x86emuOp2_illegal_op, 1555 /* 0x37 */ x86emuOp2_illegal_op, 1556 /* 0x38 */ x86emuOp2_illegal_op, 1557 /* 0x39 */ x86emuOp2_illegal_op, 1558 /* 0x3a */ x86emuOp2_illegal_op, 1559 /* 0x3b */ x86emuOp2_illegal_op, 1560 /* 0x3c */ x86emuOp2_illegal_op, 1561 /* 0x3d */ x86emuOp2_illegal_op, 1562 /* 0x3e */ x86emuOp2_illegal_op, 1563 /* 0x3f */ x86emuOp2_illegal_op, 1564 1565 /* 0x40 */ x86emuOp2_illegal_op, 1566 /* 0x41 */ x86emuOp2_illegal_op, 1567 /* 0x42 */ x86emuOp2_illegal_op, 1568 /* 0x43 */ x86emuOp2_illegal_op, 1569 /* 0x44 */ x86emuOp2_illegal_op, 1570 /* 0x45 */ x86emuOp2_illegal_op, 1571 /* 0x46 */ x86emuOp2_illegal_op, 1572 /* 0x47 */ x86emuOp2_illegal_op, 1573 /* 0x48 */ x86emuOp2_illegal_op, 1574 /* 0x49 */ x86emuOp2_illegal_op, 1575 /* 0x4a */ x86emuOp2_illegal_op, 1576 /* 0x4b */ x86emuOp2_illegal_op, 1577 /* 0x4c */ x86emuOp2_illegal_op, 1578 /* 0x4d */ x86emuOp2_illegal_op, 1579 /* 0x4e */ x86emuOp2_illegal_op, 1580 /* 0x4f */ x86emuOp2_illegal_op, 1581 1582 /* 0x50 */ x86emuOp2_illegal_op, 1583 /* 0x51 */ x86emuOp2_illegal_op, 1584 /* 0x52 */ x86emuOp2_illegal_op, 1585 /* 0x53 */ x86emuOp2_illegal_op, 1586 /* 0x54 */ x86emuOp2_illegal_op, 1587 /* 0x55 */ x86emuOp2_illegal_op, 1588 /* 0x56 */ x86emuOp2_illegal_op, 1589 /* 0x57 */ x86emuOp2_illegal_op, 1590 /* 0x58 */ x86emuOp2_illegal_op, 1591 /* 0x59 */ x86emuOp2_illegal_op, 1592 /* 0x5a */ x86emuOp2_illegal_op, 1593 /* 0x5b */ x86emuOp2_illegal_op, 1594 /* 0x5c */ x86emuOp2_illegal_op, 1595 /* 0x5d */ x86emuOp2_illegal_op, 1596 /* 0x5e */ x86emuOp2_illegal_op, 1597 /* 0x5f */ x86emuOp2_illegal_op, 1598 1599 /* 0x60 */ x86emuOp2_illegal_op, 1600 /* 0x61 */ x86emuOp2_illegal_op, 1601 /* 0x62 */ x86emuOp2_illegal_op, 1602 /* 0x63 */ x86emuOp2_illegal_op, 1603 /* 0x64 */ x86emuOp2_illegal_op, 1604 /* 0x65 */ x86emuOp2_illegal_op, 1605 /* 0x66 */ x86emuOp2_illegal_op, 1606 /* 0x67 */ x86emuOp2_illegal_op, 1607 /* 0x68 */ x86emuOp2_illegal_op, 1608 /* 0x69 */ x86emuOp2_illegal_op, 1609 /* 0x6a */ x86emuOp2_illegal_op, 1610 /* 0x6b */ x86emuOp2_illegal_op, 1611 /* 0x6c */ x86emuOp2_illegal_op, 1612 /* 0x6d */ x86emuOp2_illegal_op, 1613 /* 0x6e */ x86emuOp2_illegal_op, 1614 /* 0x6f */ x86emuOp2_illegal_op, 1615 1616 /* 0x70 */ x86emuOp2_illegal_op, 1617 /* 0x71 */ x86emuOp2_illegal_op, 1618 /* 0x72 */ x86emuOp2_illegal_op, 1619 /* 0x73 */ x86emuOp2_illegal_op, 1620 /* 0x74 */ x86emuOp2_illegal_op, 1621 /* 0x75 */ x86emuOp2_illegal_op, 1622 /* 0x76 */ x86emuOp2_illegal_op, 1623 /* 0x77 */ x86emuOp2_illegal_op, 1624 /* 0x78 */ x86emuOp2_illegal_op, 1625 /* 0x79 */ x86emuOp2_illegal_op, 1626 /* 0x7a */ x86emuOp2_illegal_op, 1627 /* 0x7b */ x86emuOp2_illegal_op, 1628 /* 0x7c */ x86emuOp2_illegal_op, 1629 /* 0x7d */ x86emuOp2_illegal_op, 1630 /* 0x7e */ x86emuOp2_illegal_op, 1631 /* 0x7f */ x86emuOp2_illegal_op, 1632 1633 /* 0x80 */ x86emuOp2_long_jump, 1634 /* 0x81 */ x86emuOp2_long_jump, 1635 /* 0x82 */ x86emuOp2_long_jump, 1636 /* 0x83 */ x86emuOp2_long_jump, 1637 /* 0x84 */ x86emuOp2_long_jump, 1638 /* 0x85 */ x86emuOp2_long_jump, 1639 /* 0x86 */ x86emuOp2_long_jump, 1640 /* 0x87 */ x86emuOp2_long_jump, 1641 /* 0x88 */ x86emuOp2_long_jump, 1642 /* 0x89 */ x86emuOp2_long_jump, 1643 /* 0x8a */ x86emuOp2_long_jump, 1644 /* 0x8b */ x86emuOp2_long_jump, 1645 /* 0x8c */ x86emuOp2_long_jump, 1646 /* 0x8d */ x86emuOp2_long_jump, 1647 /* 0x8e */ x86emuOp2_long_jump, 1648 /* 0x8f */ x86emuOp2_long_jump, 1649 1650 /* 0x90 */ x86emuOp2_set_byte, 1651 /* 0x91 */ x86emuOp2_set_byte, 1652 /* 0x92 */ x86emuOp2_set_byte, 1653 /* 0x93 */ x86emuOp2_set_byte, 1654 /* 0x94 */ x86emuOp2_set_byte, 1655 /* 0x95 */ x86emuOp2_set_byte, 1656 /* 0x96 */ x86emuOp2_set_byte, 1657 /* 0x97 */ x86emuOp2_set_byte, 1658 /* 0x98 */ x86emuOp2_set_byte, 1659 /* 0x99 */ x86emuOp2_set_byte, 1660 /* 0x9a */ x86emuOp2_set_byte, 1661 /* 0x9b */ x86emuOp2_set_byte, 1662 /* 0x9c */ x86emuOp2_set_byte, 1663 /* 0x9d */ x86emuOp2_set_byte, 1664 /* 0x9e */ x86emuOp2_set_byte, 1665 /* 0x9f */ x86emuOp2_set_byte, 1666 1667 /* 0xa0 */ x86emuOp2_push_FS, 1668 /* 0xa1 */ x86emuOp2_pop_FS, 1669 /* 0xa2 */ x86emuOp2_illegal_op, 1670 /* 0xa3 */ x86emuOp2_bt_R, 1671 /* 0xa4 */ x86emuOp2_shld_IMM, 1672 /* 0xa5 */ x86emuOp2_shld_CL, 1673 /* 0xa6 */ x86emuOp2_illegal_op, 1674 /* 0xa7 */ x86emuOp2_illegal_op, 1675 /* 0xa8 */ x86emuOp2_push_GS, 1676 /* 0xa9 */ x86emuOp2_pop_GS, 1677 /* 0xaa */ x86emuOp2_illegal_op, 1678 /* 0xab */ x86emuOp2_bt_R, 1679 /* 0xac */ x86emuOp2_shrd_IMM, 1680 /* 0xad */ x86emuOp2_shrd_CL, 1681 /* 0xae */ x86emuOp2_illegal_op, 1682 /* 0xaf */ x86emuOp2_imul_R_RM, 1683 1684 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */ 1685 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */ 1686 /* 0xb2 */ x86emuOp2_lss_R_IMM, 1687 /* 0xb3 */ x86emuOp2_btr_R, 1688 /* 0xb4 */ x86emuOp2_lfs_R_IMM, 1689 /* 0xb5 */ x86emuOp2_lgs_R_IMM, 1690 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM, 1691 /* 0xb7 */ x86emuOp2_movzx_word_R_RM, 1692 /* 0xb8 */ x86emuOp2_illegal_op, 1693 /* 0xb9 */ x86emuOp2_illegal_op, 1694 /* 0xba */ x86emuOp2_btX_I, 1695 /* 0xbb */ x86emuOp2_btc_R, 1696 /* 0xbc */ x86emuOp2_bsf, 1697 /* 0xbd */ x86emuOp2_bsr, 1698 /* 0xbe */ x86emuOp2_movsx_byte_R_RM, 1699 /* 0xbf */ x86emuOp2_movsx_word_R_RM, 1700 1701 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */ 1702 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */ 1703 /* 0xc2 */ x86emuOp2_illegal_op, 1704 /* 0xc3 */ x86emuOp2_illegal_op, 1705 /* 0xc4 */ x86emuOp2_illegal_op, 1706 /* 0xc5 */ x86emuOp2_illegal_op, 1707 /* 0xc6 */ x86emuOp2_illegal_op, 1708 /* 0xc7 */ x86emuOp2_illegal_op, 1709 /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */ 1710 /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */ 1711 /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */ 1712 /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */ 1713 /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */ 1714 /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */ 1715 /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */ 1716 /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */ 1717 1718 /* 0xd0 */ x86emuOp2_illegal_op, 1719 /* 0xd1 */ x86emuOp2_illegal_op, 1720 /* 0xd2 */ x86emuOp2_illegal_op, 1721 /* 0xd3 */ x86emuOp2_illegal_op, 1722 /* 0xd4 */ x86emuOp2_illegal_op, 1723 /* 0xd5 */ x86emuOp2_illegal_op, 1724 /* 0xd6 */ x86emuOp2_illegal_op, 1725 /* 0xd7 */ x86emuOp2_illegal_op, 1726 /* 0xd8 */ x86emuOp2_illegal_op, 1727 /* 0xd9 */ x86emuOp2_illegal_op, 1728 /* 0xda */ x86emuOp2_illegal_op, 1729 /* 0xdb */ x86emuOp2_illegal_op, 1730 /* 0xdc */ x86emuOp2_illegal_op, 1731 /* 0xdd */ x86emuOp2_illegal_op, 1732 /* 0xde */ x86emuOp2_illegal_op, 1733 /* 0xdf */ x86emuOp2_illegal_op, 1734 1735 /* 0xe0 */ x86emuOp2_illegal_op, 1736 /* 0xe1 */ x86emuOp2_illegal_op, 1737 /* 0xe2 */ x86emuOp2_illegal_op, 1738 /* 0xe3 */ x86emuOp2_illegal_op, 1739 /* 0xe4 */ x86emuOp2_illegal_op, 1740 /* 0xe5 */ x86emuOp2_illegal_op, 1741 /* 0xe6 */ x86emuOp2_illegal_op, 1742 /* 0xe7 */ x86emuOp2_illegal_op, 1743 /* 0xe8 */ x86emuOp2_illegal_op, 1744 /* 0xe9 */ x86emuOp2_illegal_op, 1745 /* 0xea */ x86emuOp2_illegal_op, 1746 /* 0xeb */ x86emuOp2_illegal_op, 1747 /* 0xec */ x86emuOp2_illegal_op, 1748 /* 0xed */ x86emuOp2_illegal_op, 1749 /* 0xee */ x86emuOp2_illegal_op, 1750 /* 0xef */ x86emuOp2_illegal_op, 1751 1752 /* 0xf0 */ x86emuOp2_illegal_op, 1753 /* 0xf1 */ x86emuOp2_illegal_op, 1754 /* 0xf2 */ x86emuOp2_illegal_op, 1755 /* 0xf3 */ x86emuOp2_illegal_op, 1756 /* 0xf4 */ x86emuOp2_illegal_op, 1757 /* 0xf5 */ x86emuOp2_illegal_op, 1758 /* 0xf6 */ x86emuOp2_illegal_op, 1759 /* 0xf7 */ x86emuOp2_illegal_op, 1760 /* 0xf8 */ x86emuOp2_illegal_op, 1761 /* 0xf9 */ x86emuOp2_illegal_op, 1762 /* 0xfa */ x86emuOp2_illegal_op, 1763 /* 0xfb */ x86emuOp2_illegal_op, 1764 /* 0xfc */ x86emuOp2_illegal_op, 1765 /* 0xfd */ x86emuOp2_illegal_op, 1766 /* 0xfe */ x86emuOp2_illegal_op, 1767 /* 0xff */ x86emuOp2_illegal_op, 1768 }; 1769