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