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