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