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