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