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