xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

ops2.c (94753B)


      1 /****************************************************************************
      2 *
      3 *						Realmode X86 Emulator Library
      4 *
      5 *            	Copyright (C) 1996-1999 SciTech Software, Inc.
      6 * 				     Copyright (C) David Mosberger-Tang
      7 * 					   Copyright (C) 1999 Egbert Eich
      8 *
      9 *  ========================================================================
     10 *
     11 *  Permission to use, copy, modify, distribute, and sell this software and
     12 *  its documentation for any purpose is hereby granted without fee,
     13 *  provided that the above copyright notice appear in all copies and that
     14 *  both that copyright notice and this permission notice appear in
     15 *  supporting documentation, and that the name of the authors not be used
     16 *  in advertising or publicity pertaining to distribution of the software
     17 *  without specific, written prior permission.  The authors makes no
     18 *  representations about the suitability of this software for any purpose.
     19 *  It is provided "as is" without express or implied warranty.
     20 *
     21 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     22 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     23 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     24 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     25 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     26 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     27 *  PERFORMANCE OF THIS SOFTWARE.
     28 *
     29 *  ========================================================================
     30 *
     31 * Language:		ANSI C
     32 * Environment:	Any
     33 * Developer:    Kendall Bennett
     34 *
     35 * Description:  This file includes subroutines to implement the decoding
     36 *               and emulation of all the x86 extended two-byte processor
     37 *               instructions.
     38 *
     39 ****************************************************************************/
     40 
     41 #include "x86emu/x86emui.h"
     42 
     43 #undef bswap_32
     44 #define bswap_32(x) (((x & 0xff000000) >> 24) | \
     45 		     ((x & 0x00ff0000) >> 8) | \
     46 		     ((x & 0x0000ff00) << 8) | \
     47 		     ((x & 0x000000ff) << 24))
     48 
     49 /*----------------------------- Implementation ----------------------------*/
     50 
     51 /****************************************************************************
     52 PARAMETERS:
     53 op1 - Instruction op code
     54 
     55 REMARKS:
     56 Handles illegal opcodes.
     57 ****************************************************************************/
     58 static void
     59 x86emuOp2_illegal_op(u8 op2)
     60 {
     61     START_OF_INSTR();
     62     DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
     63     TRACE_REGS();
     64     printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
     65            M.x86.R_CS, M.x86.R_IP - 2, op2);
     66     HALT_SYS();
     67     END_OF_INSTR();
     68 }
     69 
     70 #define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
     71 
     72 /****************************************************************************
     73 REMARKS:
     74 Handles opcode 0x0f,0x31
     75 ****************************************************************************/
     76 static void
     77 x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
     78 {
     79 #ifdef __HAS_LONG_LONG__
     80     static u64 counter = 0;
     81 #else
     82     static u32 counter = 0;
     83 #endif
     84 
     85     counter += 0x10000;
     86 
     87     /* read timestamp counter */
     88     /*
     89      * Note that instead of actually trying to accurately measure this, we just
     90      * increase the counter by a fixed amount every time we hit one of these
     91      * instructions.  Feel free to come up with a better method.
     92      */
     93     START_OF_INSTR();
     94     DECODE_PRINTF("RDTSC\n");
     95     TRACE_AND_STEP();
     96 #ifdef __HAS_LONG_LONG__
     97     M.x86.R_EAX = counter & 0xffffffff;
     98     M.x86.R_EDX = counter >> 32;
     99 #else
    100     M.x86.R_EAX = counter;
    101     M.x86.R_EDX = 0;
    102 #endif
    103     DECODE_CLEAR_SEGOVR();
    104     END_OF_INSTR();
    105 }
    106 
    107 /****************************************************************************
    108 REMARKS:
    109 Handles opcode 0x0f,0x80-0x8F
    110 ****************************************************************************/
    111 static void
    112 x86emuOp2_long_jump(u8 op2)
    113 {
    114     s32 target;
    115     const char *name = NULL;
    116     int cond = 0;
    117 
    118     /* conditional jump to word offset. */
    119     START_OF_INSTR();
    120     switch (op2) {
    121     case 0x80:
    122         name = "JO\t";
    123         cond = ACCESS_FLAG(F_OF);
    124         break;
    125     case 0x81:
    126         name = "JNO\t";
    127         cond = !ACCESS_FLAG(F_OF);
    128         break;
    129     case 0x82:
    130         name = "JB\t";
    131         cond = ACCESS_FLAG(F_CF);
    132         break;
    133     case 0x83:
    134         name = "JNB\t";
    135         cond = !ACCESS_FLAG(F_CF);
    136         break;
    137     case 0x84:
    138         name = "JZ\t";
    139         cond = ACCESS_FLAG(F_ZF);
    140         break;
    141     case 0x85:
    142         name = "JNZ\t";
    143         cond = !ACCESS_FLAG(F_ZF);
    144         break;
    145     case 0x86:
    146         name = "JBE\t";
    147         cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
    148         break;
    149     case 0x87:
    150         name = "JNBE\t";
    151         cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
    152         break;
    153     case 0x88:
    154         name = "JS\t";
    155         cond = ACCESS_FLAG(F_SF);
    156         break;
    157     case 0x89:
    158         name = "JNS\t";
    159         cond = !ACCESS_FLAG(F_SF);
    160         break;
    161     case 0x8a:
    162         name = "JP\t";
    163         cond = ACCESS_FLAG(F_PF);
    164         break;
    165     case 0x8b:
    166         name = "JNP\t";
    167         cond = !ACCESS_FLAG(F_PF);
    168         break;
    169     case 0x8c:
    170         name = "JL\t";
    171         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
    172         break;
    173     case 0x8d:
    174         name = "JNL\t";
    175         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
    176         break;
    177     case 0x8e:
    178         name = "JLE\t";
    179         cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
    180                 ACCESS_FLAG(F_ZF));
    181         break;
    182     case 0x8f:
    183         name = "JNLE\t";
    184         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
    185                  ACCESS_FLAG(F_ZF));
    186         break;
    187     }
    188     DECODE_PRINTF(name);
    189     (void) name;
    190     target = (s16) fetch_word_imm();
    191     target += (s16) M.x86.R_IP;
    192     DECODE_PRINTF2("%04x\n", target);
    193     TRACE_AND_STEP();
    194     if (cond)
    195         M.x86.R_IP = (u16) target;
    196     DECODE_CLEAR_SEGOVR();
    197     END_OF_INSTR();
    198 }
    199 
    200 /****************************************************************************
    201 REMARKS:
    202 Handles opcode 0x0f,0x90-0x9F
    203 ****************************************************************************/
    204 static void
    205 x86emuOp2_set_byte(u8 op2)
    206 {
    207     int mod, rl, rh;
    208     uint destoffset;
    209     u8 *destreg;
    210     const char *name = NULL;
    211     int cond = 0;
    212 
    213     START_OF_INSTR();
    214     switch (op2) {
    215     case 0x90:
    216         name = "SETO\t";
    217         cond = ACCESS_FLAG(F_OF);
    218         break;
    219     case 0x91:
    220         name = "SETNO\t";
    221         cond = !ACCESS_FLAG(F_OF);
    222         break;
    223     case 0x92:
    224         name = "SETB\t";
    225         cond = ACCESS_FLAG(F_CF);
    226         break;
    227     case 0x93:
    228         name = "SETNB\t";
    229         cond = !ACCESS_FLAG(F_CF);
    230         break;
    231     case 0x94:
    232         name = "SETZ\t";
    233         cond = ACCESS_FLAG(F_ZF);
    234         break;
    235     case 0x95:
    236         name = "SETNZ\t";
    237         cond = !ACCESS_FLAG(F_ZF);
    238         break;
    239     case 0x96:
    240         name = "SETBE\t";
    241         cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
    242         break;
    243     case 0x97:
    244         name = "SETNBE\t";
    245         cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
    246         break;
    247     case 0x98:
    248         name = "SETS\t";
    249         cond = ACCESS_FLAG(F_SF);
    250         break;
    251     case 0x99:
    252         name = "SETNS\t";
    253         cond = !ACCESS_FLAG(F_SF);
    254         break;
    255     case 0x9a:
    256         name = "SETP\t";
    257         cond = ACCESS_FLAG(F_PF);
    258         break;
    259     case 0x9b:
    260         name = "SETNP\t";
    261         cond = !ACCESS_FLAG(F_PF);
    262         break;
    263     case 0x9c:
    264         name = "SETL\t";
    265         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
    266         break;
    267     case 0x9d:
    268         name = "SETNL\t";
    269         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
    270         break;
    271     case 0x9e:
    272         name = "SETLE\t";
    273         cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
    274                 ACCESS_FLAG(F_ZF));
    275         break;
    276     case 0x9f:
    277         name = "SETNLE\t";
    278         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
    279                  ACCESS_FLAG(F_ZF));
    280         break;
    281     }
    282     DECODE_PRINTF(name);
    283     (void) name;
    284     FETCH_DECODE_MODRM(mod, rh, rl);
    285     switch (mod) {
    286     case 0:
    287         destoffset = decode_rm00_address(rl);
    288         TRACE_AND_STEP();
    289         store_data_byte(destoffset, cond ? 0x01 : 0x00);
    290         break;
    291     case 1:
    292         destoffset = decode_rm01_address(rl);
    293         TRACE_AND_STEP();
    294         store_data_byte(destoffset, cond ? 0x01 : 0x00);
    295         break;
    296     case 2:
    297         destoffset = decode_rm10_address(rl);
    298         TRACE_AND_STEP();
    299         store_data_byte(destoffset, cond ? 0x01 : 0x00);
    300         break;
    301     case 3:                    /* register to register */
    302         destreg = DECODE_RM_BYTE_REGISTER(rl);
    303         TRACE_AND_STEP();
    304         *destreg = cond ? 0x01 : 0x00;
    305         break;
    306     }
    307     DECODE_CLEAR_SEGOVR();
    308     END_OF_INSTR();
    309 }
    310 
    311 /****************************************************************************
    312 REMARKS:
    313 Handles opcode 0x0f,0xa0
    314 ****************************************************************************/
    315 static void
    316 x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
    317 {
    318     START_OF_INSTR();
    319     DECODE_PRINTF("PUSH\tFS\n");
    320     TRACE_AND_STEP();
    321     push_word(M.x86.R_FS);
    322     DECODE_CLEAR_SEGOVR();
    323     END_OF_INSTR();
    324 }
    325 
    326 /****************************************************************************
    327 REMARKS:
    328 Handles opcode 0x0f,0xa1
    329 ****************************************************************************/
    330 static void
    331 x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
    332 {
    333     START_OF_INSTR();
    334     DECODE_PRINTF("POP\tFS\n");
    335     TRACE_AND_STEP();
    336     M.x86.R_FS = pop_word();
    337     DECODE_CLEAR_SEGOVR();
    338     END_OF_INSTR();
    339 }
    340 
    341 /****************************************************************************
    342 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
    343 Handles opcode 0x0f,0xa2
    344 ****************************************************************************/
    345 static void
    346 x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
    347 {
    348     START_OF_INSTR();
    349     DECODE_PRINTF("CPUID\n");
    350     TRACE_AND_STEP();
    351     cpuid();
    352     DECODE_CLEAR_SEGOVR();
    353     END_OF_INSTR();
    354 }
    355 
    356 /****************************************************************************
    357 REMARKS:
    358 Handles opcode 0x0f,0xa3
    359 ****************************************************************************/
    360 static void
    361 x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
    362 {
    363     int mod, rl, rh;
    364     uint srcoffset;
    365     int bit, disp;
    366 
    367     START_OF_INSTR();
    368     DECODE_PRINTF("BT\t");
    369     FETCH_DECODE_MODRM(mod, rh, rl);
    370     switch (mod) {
    371     case 0:
    372         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    373             u32 srcval;
    374             u32 *shiftreg;
    375 
    376             srcoffset = decode_rm00_address(rl);
    377             DECODE_PRINTF(",");
    378             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    379             TRACE_AND_STEP();
    380             bit = *shiftreg & 0x1F;
    381             disp = (s16) * shiftreg >> 5;
    382             srcval = fetch_data_long(srcoffset + disp);
    383             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    384         }
    385         else {
    386             u16 srcval;
    387             u16 *shiftreg;
    388 
    389             srcoffset = decode_rm00_address(rl);
    390             DECODE_PRINTF(",");
    391             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    392             TRACE_AND_STEP();
    393             bit = *shiftreg & 0xF;
    394             disp = (s16) * shiftreg >> 4;
    395             srcval = fetch_data_word(srcoffset + disp);
    396             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    397         }
    398         break;
    399     case 1:
    400         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    401             u32 srcval;
    402             u32 *shiftreg;
    403 
    404             srcoffset = decode_rm01_address(rl);
    405             DECODE_PRINTF(",");
    406             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    407             TRACE_AND_STEP();
    408             bit = *shiftreg & 0x1F;
    409             disp = (s16) * shiftreg >> 5;
    410             srcval = fetch_data_long(srcoffset + disp);
    411             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    412         }
    413         else {
    414             u16 srcval;
    415             u16 *shiftreg;
    416 
    417             srcoffset = decode_rm01_address(rl);
    418             DECODE_PRINTF(",");
    419             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    420             TRACE_AND_STEP();
    421             bit = *shiftreg & 0xF;
    422             disp = (s16) * shiftreg >> 4;
    423             srcval = fetch_data_word(srcoffset + disp);
    424             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    425         }
    426         break;
    427     case 2:
    428         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    429             u32 srcval;
    430             u32 *shiftreg;
    431 
    432             srcoffset = decode_rm10_address(rl);
    433             DECODE_PRINTF(",");
    434             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    435             TRACE_AND_STEP();
    436             bit = *shiftreg & 0x1F;
    437             disp = (s16) * shiftreg >> 5;
    438             srcval = fetch_data_long(srcoffset + disp);
    439             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    440         }
    441         else {
    442             u16 srcval;
    443             u16 *shiftreg;
    444 
    445             srcoffset = decode_rm10_address(rl);
    446             DECODE_PRINTF(",");
    447             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    448             TRACE_AND_STEP();
    449             bit = *shiftreg & 0xF;
    450             disp = (s16) * shiftreg >> 4;
    451             srcval = fetch_data_word(srcoffset + disp);
    452             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
    453         }
    454         break;
    455     case 3:                    /* register to register */
    456         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    457             u32 *srcreg, *shiftreg;
    458 
    459             srcreg = DECODE_RM_LONG_REGISTER(rl);
    460             DECODE_PRINTF(",");
    461             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    462             TRACE_AND_STEP();
    463             bit = *shiftreg & 0x1F;
    464             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
    465         }
    466         else {
    467             u16 *srcreg, *shiftreg;
    468 
    469             srcreg = DECODE_RM_WORD_REGISTER(rl);
    470             DECODE_PRINTF(",");
    471             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    472             TRACE_AND_STEP();
    473             bit = *shiftreg & 0xF;
    474             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
    475         }
    476         break;
    477     }
    478     DECODE_CLEAR_SEGOVR();
    479     END_OF_INSTR();
    480 }
    481 
    482 /****************************************************************************
    483 REMARKS:
    484 Handles opcode 0x0f,0xa4
    485 ****************************************************************************/
    486 static void
    487 x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
    488 {
    489     int mod, rl, rh;
    490     uint destoffset;
    491     u8 shift;
    492 
    493     START_OF_INSTR();
    494     DECODE_PRINTF("SHLD\t");
    495     FETCH_DECODE_MODRM(mod, rh, rl);
    496     switch (mod) {
    497     case 0:
    498         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    499             u32 destval;
    500             u32 *shiftreg;
    501 
    502             destoffset = decode_rm00_address(rl);
    503             DECODE_PRINTF(",");
    504             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    505             DECODE_PRINTF(",");
    506             shift = fetch_byte_imm();
    507             DECODE_PRINTF2("%d\n", shift);
    508             TRACE_AND_STEP();
    509             destval = fetch_data_long(destoffset);
    510             destval = shld_long(destval, *shiftreg, shift);
    511             store_data_long(destoffset, destval);
    512         }
    513         else {
    514             u16 destval;
    515             u16 *shiftreg;
    516 
    517             destoffset = decode_rm00_address(rl);
    518             DECODE_PRINTF(",");
    519             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    520             DECODE_PRINTF(",");
    521             shift = fetch_byte_imm();
    522             DECODE_PRINTF2("%d\n", shift);
    523             TRACE_AND_STEP();
    524             destval = fetch_data_word(destoffset);
    525             destval = shld_word(destval, *shiftreg, shift);
    526             store_data_word(destoffset, destval);
    527         }
    528         break;
    529     case 1:
    530         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    531             u32 destval;
    532             u32 *shiftreg;
    533 
    534             destoffset = decode_rm01_address(rl);
    535             DECODE_PRINTF(",");
    536             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    537             DECODE_PRINTF(",");
    538             shift = fetch_byte_imm();
    539             DECODE_PRINTF2("%d\n", shift);
    540             TRACE_AND_STEP();
    541             destval = fetch_data_long(destoffset);
    542             destval = shld_long(destval, *shiftreg, shift);
    543             store_data_long(destoffset, destval);
    544         }
    545         else {
    546             u16 destval;
    547             u16 *shiftreg;
    548 
    549             destoffset = decode_rm01_address(rl);
    550             DECODE_PRINTF(",");
    551             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    552             DECODE_PRINTF(",");
    553             shift = fetch_byte_imm();
    554             DECODE_PRINTF2("%d\n", shift);
    555             TRACE_AND_STEP();
    556             destval = fetch_data_word(destoffset);
    557             destval = shld_word(destval, *shiftreg, shift);
    558             store_data_word(destoffset, destval);
    559         }
    560         break;
    561     case 2:
    562         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    563             u32 destval;
    564             u32 *shiftreg;
    565 
    566             destoffset = decode_rm10_address(rl);
    567             DECODE_PRINTF(",");
    568             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    569             DECODE_PRINTF(",");
    570             shift = fetch_byte_imm();
    571             DECODE_PRINTF2("%d\n", shift);
    572             TRACE_AND_STEP();
    573             destval = fetch_data_long(destoffset);
    574             destval = shld_long(destval, *shiftreg, shift);
    575             store_data_long(destoffset, destval);
    576         }
    577         else {
    578             u16 destval;
    579             u16 *shiftreg;
    580 
    581             destoffset = decode_rm10_address(rl);
    582             DECODE_PRINTF(",");
    583             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    584             DECODE_PRINTF(",");
    585             shift = fetch_byte_imm();
    586             DECODE_PRINTF2("%d\n", shift);
    587             TRACE_AND_STEP();
    588             destval = fetch_data_word(destoffset);
    589             destval = shld_word(destval, *shiftreg, shift);
    590             store_data_word(destoffset, destval);
    591         }
    592         break;
    593     case 3:                    /* register to register */
    594         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    595             u32 *destreg, *shiftreg;
    596 
    597             destreg = DECODE_RM_LONG_REGISTER(rl);
    598             DECODE_PRINTF(",");
    599             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    600             DECODE_PRINTF(",");
    601             shift = fetch_byte_imm();
    602             DECODE_PRINTF2("%d\n", shift);
    603             TRACE_AND_STEP();
    604             *destreg = shld_long(*destreg, *shiftreg, shift);
    605         }
    606         else {
    607             u16 *destreg, *shiftreg;
    608 
    609             destreg = DECODE_RM_WORD_REGISTER(rl);
    610             DECODE_PRINTF(",");
    611             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    612             DECODE_PRINTF(",");
    613             shift = fetch_byte_imm();
    614             DECODE_PRINTF2("%d\n", shift);
    615             TRACE_AND_STEP();
    616             *destreg = shld_word(*destreg, *shiftreg, shift);
    617         }
    618         break;
    619     }
    620     DECODE_CLEAR_SEGOVR();
    621     END_OF_INSTR();
    622 }
    623 
    624 /****************************************************************************
    625 REMARKS:
    626 Handles opcode 0x0f,0xa5
    627 ****************************************************************************/
    628 static void
    629 x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
    630 {
    631     int mod, rl, rh;
    632     uint destoffset;
    633 
    634     START_OF_INSTR();
    635     DECODE_PRINTF("SHLD\t");
    636     FETCH_DECODE_MODRM(mod, rh, rl);
    637     switch (mod) {
    638     case 0:
    639         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    640             u32 destval;
    641             u32 *shiftreg;
    642 
    643             destoffset = decode_rm00_address(rl);
    644             DECODE_PRINTF(",");
    645             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    646             DECODE_PRINTF(",CL\n");
    647             TRACE_AND_STEP();
    648             destval = fetch_data_long(destoffset);
    649             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
    650             store_data_long(destoffset, destval);
    651         }
    652         else {
    653             u16 destval;
    654             u16 *shiftreg;
    655 
    656             destoffset = decode_rm00_address(rl);
    657             DECODE_PRINTF(",");
    658             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    659             DECODE_PRINTF(",CL\n");
    660             TRACE_AND_STEP();
    661             destval = fetch_data_word(destoffset);
    662             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
    663             store_data_word(destoffset, destval);
    664         }
    665         break;
    666     case 1:
    667         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    668             u32 destval;
    669             u32 *shiftreg;
    670 
    671             destoffset = decode_rm01_address(rl);
    672             DECODE_PRINTF(",");
    673             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    674             DECODE_PRINTF(",CL\n");
    675             TRACE_AND_STEP();
    676             destval = fetch_data_long(destoffset);
    677             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
    678             store_data_long(destoffset, destval);
    679         }
    680         else {
    681             u16 destval;
    682             u16 *shiftreg;
    683 
    684             destoffset = decode_rm01_address(rl);
    685             DECODE_PRINTF(",");
    686             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    687             DECODE_PRINTF(",CL\n");
    688             TRACE_AND_STEP();
    689             destval = fetch_data_word(destoffset);
    690             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
    691             store_data_word(destoffset, destval);
    692         }
    693         break;
    694     case 2:
    695         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    696             u32 destval;
    697             u32 *shiftreg;
    698 
    699             destoffset = decode_rm10_address(rl);
    700             DECODE_PRINTF(",");
    701             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    702             DECODE_PRINTF(",CL\n");
    703             TRACE_AND_STEP();
    704             destval = fetch_data_long(destoffset);
    705             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
    706             store_data_long(destoffset, destval);
    707         }
    708         else {
    709             u16 destval;
    710             u16 *shiftreg;
    711 
    712             destoffset = decode_rm10_address(rl);
    713             DECODE_PRINTF(",");
    714             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    715             DECODE_PRINTF(",CL\n");
    716             TRACE_AND_STEP();
    717             destval = fetch_data_word(destoffset);
    718             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
    719             store_data_word(destoffset, destval);
    720         }
    721         break;
    722     case 3:                    /* register to register */
    723         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    724             u32 *destreg, *shiftreg;
    725 
    726             destreg = DECODE_RM_LONG_REGISTER(rl);
    727             DECODE_PRINTF(",");
    728             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    729             DECODE_PRINTF(",CL\n");
    730             TRACE_AND_STEP();
    731             *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL);
    732         }
    733         else {
    734             u16 *destreg, *shiftreg;
    735 
    736             destreg = DECODE_RM_WORD_REGISTER(rl);
    737             DECODE_PRINTF(",");
    738             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    739             DECODE_PRINTF(",CL\n");
    740             TRACE_AND_STEP();
    741             *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL);
    742         }
    743         break;
    744     }
    745     DECODE_CLEAR_SEGOVR();
    746     END_OF_INSTR();
    747 }
    748 
    749 /****************************************************************************
    750 REMARKS:
    751 Handles opcode 0x0f,0xa8
    752 ****************************************************************************/
    753 static void
    754 x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
    755 {
    756     START_OF_INSTR();
    757     DECODE_PRINTF("PUSH\tGS\n");
    758     TRACE_AND_STEP();
    759     push_word(M.x86.R_GS);
    760     DECODE_CLEAR_SEGOVR();
    761     END_OF_INSTR();
    762 }
    763 
    764 /****************************************************************************
    765 REMARKS:
    766 Handles opcode 0x0f,0xa9
    767 ****************************************************************************/
    768 static void
    769 x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
    770 {
    771     START_OF_INSTR();
    772     DECODE_PRINTF("POP\tGS\n");
    773     TRACE_AND_STEP();
    774     M.x86.R_GS = pop_word();
    775     DECODE_CLEAR_SEGOVR();
    776     END_OF_INSTR();
    777 }
    778 
    779 /****************************************************************************
    780 REMARKS:
    781 Handles opcode 0x0f,0xab
    782 ****************************************************************************/
    783 static void
    784 x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
    785 {
    786     int mod, rl, rh;
    787     uint srcoffset;
    788     int bit, disp;
    789 
    790     START_OF_INSTR();
    791     DECODE_PRINTF("BTS\t");
    792     FETCH_DECODE_MODRM(mod, rh, rl);
    793     switch (mod) {
    794     case 0:
    795         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    796             u32 srcval, mask;
    797             u32 *shiftreg;
    798 
    799             srcoffset = decode_rm00_address(rl);
    800             DECODE_PRINTF(",");
    801             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    802             TRACE_AND_STEP();
    803             bit = *shiftreg & 0x1F;
    804             disp = (s16) * shiftreg >> 5;
    805             srcval = fetch_data_long(srcoffset + disp);
    806             mask = (0x1 << bit);
    807             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    808             store_data_long(srcoffset + disp, srcval | mask);
    809         }
    810         else {
    811             u16 srcval, mask;
    812             u16 *shiftreg;
    813 
    814             srcoffset = decode_rm00_address(rl);
    815             DECODE_PRINTF(",");
    816             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    817             TRACE_AND_STEP();
    818             bit = *shiftreg & 0xF;
    819             disp = (s16) * shiftreg >> 4;
    820             srcval = fetch_data_word(srcoffset + disp);
    821             mask = (u16) (0x1 << bit);
    822             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    823             store_data_word(srcoffset + disp, srcval | mask);
    824         }
    825         break;
    826     case 1:
    827         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    828             u32 srcval, mask;
    829             u32 *shiftreg;
    830 
    831             srcoffset = decode_rm01_address(rl);
    832             DECODE_PRINTF(",");
    833             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    834             TRACE_AND_STEP();
    835             bit = *shiftreg & 0x1F;
    836             disp = (s16) * shiftreg >> 5;
    837             srcval = fetch_data_long(srcoffset + disp);
    838             mask = (0x1 << bit);
    839             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    840             store_data_long(srcoffset + disp, srcval | mask);
    841         }
    842         else {
    843             u16 srcval, mask;
    844             u16 *shiftreg;
    845 
    846             srcoffset = decode_rm01_address(rl);
    847             DECODE_PRINTF(",");
    848             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    849             TRACE_AND_STEP();
    850             bit = *shiftreg & 0xF;
    851             disp = (s16) * shiftreg >> 4;
    852             srcval = fetch_data_word(srcoffset + disp);
    853             mask = (u16) (0x1 << bit);
    854             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    855             store_data_word(srcoffset + disp, srcval | mask);
    856         }
    857         break;
    858     case 2:
    859         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    860             u32 srcval, mask;
    861             u32 *shiftreg;
    862 
    863             srcoffset = decode_rm10_address(rl);
    864             DECODE_PRINTF(",");
    865             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    866             TRACE_AND_STEP();
    867             bit = *shiftreg & 0x1F;
    868             disp = (s16) * shiftreg >> 5;
    869             srcval = fetch_data_long(srcoffset + disp);
    870             mask = (0x1 << bit);
    871             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    872             store_data_long(srcoffset + disp, srcval | mask);
    873         }
    874         else {
    875             u16 srcval, mask;
    876             u16 *shiftreg;
    877 
    878             srcoffset = decode_rm10_address(rl);
    879             DECODE_PRINTF(",");
    880             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    881             TRACE_AND_STEP();
    882             bit = *shiftreg & 0xF;
    883             disp = (s16) * shiftreg >> 4;
    884             srcval = fetch_data_word(srcoffset + disp);
    885             mask = (u16) (0x1 << bit);
    886             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
    887             store_data_word(srcoffset + disp, srcval | mask);
    888         }
    889         break;
    890     case 3:                    /* register to register */
    891         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    892             u32 *srcreg, *shiftreg;
    893             u32 mask;
    894 
    895             srcreg = DECODE_RM_LONG_REGISTER(rl);
    896             DECODE_PRINTF(",");
    897             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    898             TRACE_AND_STEP();
    899             bit = *shiftreg & 0x1F;
    900             mask = (0x1 << bit);
    901             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
    902             *srcreg |= mask;
    903         }
    904         else {
    905             u16 *srcreg, *shiftreg;
    906             u16 mask;
    907 
    908             srcreg = DECODE_RM_WORD_REGISTER(rl);
    909             DECODE_PRINTF(",");
    910             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    911             TRACE_AND_STEP();
    912             bit = *shiftreg & 0xF;
    913             mask = (u16) (0x1 << bit);
    914             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
    915             *srcreg |= mask;
    916         }
    917         break;
    918     }
    919     DECODE_CLEAR_SEGOVR();
    920     END_OF_INSTR();
    921 }
    922 
    923 /****************************************************************************
    924 REMARKS:
    925 Handles opcode 0x0f,0xac
    926 ****************************************************************************/
    927 static void
    928 x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
    929 {
    930     int mod, rl, rh;
    931     uint destoffset;
    932     u8 shift;
    933 
    934     START_OF_INSTR();
    935     DECODE_PRINTF("SHLD\t");
    936     FETCH_DECODE_MODRM(mod, rh, rl);
    937     switch (mod) {
    938     case 0:
    939         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    940             u32 destval;
    941             u32 *shiftreg;
    942 
    943             destoffset = decode_rm00_address(rl);
    944             DECODE_PRINTF(",");
    945             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    946             DECODE_PRINTF(",");
    947             shift = fetch_byte_imm();
    948             DECODE_PRINTF2("%d\n", shift);
    949             TRACE_AND_STEP();
    950             destval = fetch_data_long(destoffset);
    951             destval = shrd_long(destval, *shiftreg, shift);
    952             store_data_long(destoffset, destval);
    953         }
    954         else {
    955             u16 destval;
    956             u16 *shiftreg;
    957 
    958             destoffset = decode_rm00_address(rl);
    959             DECODE_PRINTF(",");
    960             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    961             DECODE_PRINTF(",");
    962             shift = fetch_byte_imm();
    963             DECODE_PRINTF2("%d\n", shift);
    964             TRACE_AND_STEP();
    965             destval = fetch_data_word(destoffset);
    966             destval = shrd_word(destval, *shiftreg, shift);
    967             store_data_word(destoffset, destval);
    968         }
    969         break;
    970     case 1:
    971         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
    972             u32 destval;
    973             u32 *shiftreg;
    974 
    975             destoffset = decode_rm01_address(rl);
    976             DECODE_PRINTF(",");
    977             shiftreg = DECODE_RM_LONG_REGISTER(rh);
    978             DECODE_PRINTF(",");
    979             shift = fetch_byte_imm();
    980             DECODE_PRINTF2("%d\n", shift);
    981             TRACE_AND_STEP();
    982             destval = fetch_data_long(destoffset);
    983             destval = shrd_long(destval, *shiftreg, shift);
    984             store_data_long(destoffset, destval);
    985         }
    986         else {
    987             u16 destval;
    988             u16 *shiftreg;
    989 
    990             destoffset = decode_rm01_address(rl);
    991             DECODE_PRINTF(",");
    992             shiftreg = DECODE_RM_WORD_REGISTER(rh);
    993             DECODE_PRINTF(",");
    994             shift = fetch_byte_imm();
    995             DECODE_PRINTF2("%d\n", shift);
    996             TRACE_AND_STEP();
    997             destval = fetch_data_word(destoffset);
    998             destval = shrd_word(destval, *shiftreg, shift);
    999             store_data_word(destoffset, destval);
   1000         }
   1001         break;
   1002     case 2:
   1003         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1004             u32 destval;
   1005             u32 *shiftreg;
   1006 
   1007             destoffset = decode_rm10_address(rl);
   1008             DECODE_PRINTF(",");
   1009             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1010             DECODE_PRINTF(",");
   1011             shift = fetch_byte_imm();
   1012             DECODE_PRINTF2("%d\n", shift);
   1013             TRACE_AND_STEP();
   1014             destval = fetch_data_long(destoffset);
   1015             destval = shrd_long(destval, *shiftreg, shift);
   1016             store_data_long(destoffset, destval);
   1017         }
   1018         else {
   1019             u16 destval;
   1020             u16 *shiftreg;
   1021 
   1022             destoffset = decode_rm10_address(rl);
   1023             DECODE_PRINTF(",");
   1024             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1025             DECODE_PRINTF(",");
   1026             shift = fetch_byte_imm();
   1027             DECODE_PRINTF2("%d\n", shift);
   1028             TRACE_AND_STEP();
   1029             destval = fetch_data_word(destoffset);
   1030             destval = shrd_word(destval, *shiftreg, shift);
   1031             store_data_word(destoffset, destval);
   1032         }
   1033         break;
   1034     case 3:                    /* register to register */
   1035         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1036             u32 *destreg, *shiftreg;
   1037 
   1038             destreg = DECODE_RM_LONG_REGISTER(rl);
   1039             DECODE_PRINTF(",");
   1040             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1041             DECODE_PRINTF(",");
   1042             shift = fetch_byte_imm();
   1043             DECODE_PRINTF2("%d\n", shift);
   1044             TRACE_AND_STEP();
   1045             *destreg = shrd_long(*destreg, *shiftreg, shift);
   1046         }
   1047         else {
   1048             u16 *destreg, *shiftreg;
   1049 
   1050             destreg = DECODE_RM_WORD_REGISTER(rl);
   1051             DECODE_PRINTF(",");
   1052             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1053             DECODE_PRINTF(",");
   1054             shift = fetch_byte_imm();
   1055             DECODE_PRINTF2("%d\n", shift);
   1056             TRACE_AND_STEP();
   1057             *destreg = shrd_word(*destreg, *shiftreg, shift);
   1058         }
   1059         break;
   1060     }
   1061     DECODE_CLEAR_SEGOVR();
   1062     END_OF_INSTR();
   1063 }
   1064 
   1065 /****************************************************************************
   1066 REMARKS:
   1067 Handles opcode 0x0f,0xad
   1068 ****************************************************************************/
   1069 static void
   1070 x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
   1071 {
   1072     int mod, rl, rh;
   1073     uint destoffset;
   1074 
   1075     START_OF_INSTR();
   1076     DECODE_PRINTF("SHLD\t");
   1077     FETCH_DECODE_MODRM(mod, rh, rl);
   1078     switch (mod) {
   1079     case 0:
   1080         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1081             u32 destval;
   1082             u32 *shiftreg;
   1083 
   1084             destoffset = decode_rm00_address(rl);
   1085             DECODE_PRINTF(",");
   1086             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1087             DECODE_PRINTF(",CL\n");
   1088             TRACE_AND_STEP();
   1089             destval = fetch_data_long(destoffset);
   1090             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
   1091             store_data_long(destoffset, destval);
   1092         }
   1093         else {
   1094             u16 destval;
   1095             u16 *shiftreg;
   1096 
   1097             destoffset = decode_rm00_address(rl);
   1098             DECODE_PRINTF(",");
   1099             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1100             DECODE_PRINTF(",CL\n");
   1101             TRACE_AND_STEP();
   1102             destval = fetch_data_word(destoffset);
   1103             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
   1104             store_data_word(destoffset, destval);
   1105         }
   1106         break;
   1107     case 1:
   1108         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1109             u32 destval;
   1110             u32 *shiftreg;
   1111 
   1112             destoffset = decode_rm01_address(rl);
   1113             DECODE_PRINTF(",");
   1114             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1115             DECODE_PRINTF(",CL\n");
   1116             TRACE_AND_STEP();
   1117             destval = fetch_data_long(destoffset);
   1118             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
   1119             store_data_long(destoffset, destval);
   1120         }
   1121         else {
   1122             u16 destval;
   1123             u16 *shiftreg;
   1124 
   1125             destoffset = decode_rm01_address(rl);
   1126             DECODE_PRINTF(",");
   1127             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1128             DECODE_PRINTF(",CL\n");
   1129             TRACE_AND_STEP();
   1130             destval = fetch_data_word(destoffset);
   1131             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
   1132             store_data_word(destoffset, destval);
   1133         }
   1134         break;
   1135     case 2:
   1136         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1137             u32 destval;
   1138             u32 *shiftreg;
   1139 
   1140             destoffset = decode_rm10_address(rl);
   1141             DECODE_PRINTF(",");
   1142             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1143             DECODE_PRINTF(",CL\n");
   1144             TRACE_AND_STEP();
   1145             destval = fetch_data_long(destoffset);
   1146             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
   1147             store_data_long(destoffset, destval);
   1148         }
   1149         else {
   1150             u16 destval;
   1151             u16 *shiftreg;
   1152 
   1153             destoffset = decode_rm10_address(rl);
   1154             DECODE_PRINTF(",");
   1155             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1156             DECODE_PRINTF(",CL\n");
   1157             TRACE_AND_STEP();
   1158             destval = fetch_data_word(destoffset);
   1159             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
   1160             store_data_word(destoffset, destval);
   1161         }
   1162         break;
   1163     case 3:                    /* register to register */
   1164         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1165             u32 *destreg, *shiftreg;
   1166 
   1167             destreg = DECODE_RM_LONG_REGISTER(rl);
   1168             DECODE_PRINTF(",");
   1169             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1170             DECODE_PRINTF(",CL\n");
   1171             TRACE_AND_STEP();
   1172             *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL);
   1173         }
   1174         else {
   1175             u16 *destreg, *shiftreg;
   1176 
   1177             destreg = DECODE_RM_WORD_REGISTER(rl);
   1178             DECODE_PRINTF(",");
   1179             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1180             DECODE_PRINTF(",CL\n");
   1181             TRACE_AND_STEP();
   1182             *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL);
   1183         }
   1184         break;
   1185     }
   1186     DECODE_CLEAR_SEGOVR();
   1187     END_OF_INSTR();
   1188 }
   1189 
   1190 /****************************************************************************
   1191 REMARKS:
   1192 Handles opcode 0x0f,0xaf
   1193 ****************************************************************************/
   1194 static void
   1195 x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
   1196 {
   1197     int mod, rl, rh;
   1198     uint srcoffset;
   1199 
   1200     START_OF_INSTR();
   1201     DECODE_PRINTF("IMUL\t");
   1202     FETCH_DECODE_MODRM(mod, rh, rl);
   1203     switch (mod) {
   1204     case 0:
   1205         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1206             u32 *destreg;
   1207             u32 srcval;
   1208             u32 res_lo, res_hi;
   1209 
   1210             destreg = DECODE_RM_LONG_REGISTER(rh);
   1211             DECODE_PRINTF(",");
   1212             srcoffset = decode_rm00_address(rl);
   1213             srcval = fetch_data_long(srcoffset);
   1214             TRACE_AND_STEP();
   1215             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
   1216             if (res_hi != 0) {
   1217                 SET_FLAG(F_CF);
   1218                 SET_FLAG(F_OF);
   1219             }
   1220             else {
   1221                 CLEAR_FLAG(F_CF);
   1222                 CLEAR_FLAG(F_OF);
   1223             }
   1224             *destreg = (u32) res_lo;
   1225         }
   1226         else {
   1227             u16 *destreg;
   1228             u16 srcval;
   1229             u32 res;
   1230 
   1231             destreg = DECODE_RM_WORD_REGISTER(rh);
   1232             DECODE_PRINTF(",");
   1233             srcoffset = decode_rm00_address(rl);
   1234             srcval = fetch_data_word(srcoffset);
   1235             TRACE_AND_STEP();
   1236             res = (s16) * destreg * (s16) srcval;
   1237             if (res > 0xFFFF) {
   1238                 SET_FLAG(F_CF);
   1239                 SET_FLAG(F_OF);
   1240             }
   1241             else {
   1242                 CLEAR_FLAG(F_CF);
   1243                 CLEAR_FLAG(F_OF);
   1244             }
   1245             *destreg = (u16) res;
   1246         }
   1247         break;
   1248     case 1:
   1249         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1250             u32 *destreg;
   1251             u32 srcval;
   1252             u32 res_lo, res_hi;
   1253 
   1254             destreg = DECODE_RM_LONG_REGISTER(rh);
   1255             DECODE_PRINTF(",");
   1256             srcoffset = decode_rm01_address(rl);
   1257             srcval = fetch_data_long(srcoffset);
   1258             TRACE_AND_STEP();
   1259             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
   1260             if (res_hi != 0) {
   1261                 SET_FLAG(F_CF);
   1262                 SET_FLAG(F_OF);
   1263             }
   1264             else {
   1265                 CLEAR_FLAG(F_CF);
   1266                 CLEAR_FLAG(F_OF);
   1267             }
   1268             *destreg = (u32) res_lo;
   1269         }
   1270         else {
   1271             u16 *destreg;
   1272             u16 srcval;
   1273             u32 res;
   1274 
   1275             destreg = DECODE_RM_WORD_REGISTER(rh);
   1276             DECODE_PRINTF(",");
   1277             srcoffset = decode_rm01_address(rl);
   1278             srcval = fetch_data_word(srcoffset);
   1279             TRACE_AND_STEP();
   1280             res = (s16) * destreg * (s16) srcval;
   1281             if (res > 0xFFFF) {
   1282                 SET_FLAG(F_CF);
   1283                 SET_FLAG(F_OF);
   1284             }
   1285             else {
   1286                 CLEAR_FLAG(F_CF);
   1287                 CLEAR_FLAG(F_OF);
   1288             }
   1289             *destreg = (u16) res;
   1290         }
   1291         break;
   1292     case 2:
   1293         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1294             u32 *destreg;
   1295             u32 srcval;
   1296             u32 res_lo, res_hi;
   1297 
   1298             destreg = DECODE_RM_LONG_REGISTER(rh);
   1299             DECODE_PRINTF(",");
   1300             srcoffset = decode_rm10_address(rl);
   1301             srcval = fetch_data_long(srcoffset);
   1302             TRACE_AND_STEP();
   1303             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
   1304             if (res_hi != 0) {
   1305                 SET_FLAG(F_CF);
   1306                 SET_FLAG(F_OF);
   1307             }
   1308             else {
   1309                 CLEAR_FLAG(F_CF);
   1310                 CLEAR_FLAG(F_OF);
   1311             }
   1312             *destreg = (u32) res_lo;
   1313         }
   1314         else {
   1315             u16 *destreg;
   1316             u16 srcval;
   1317             u32 res;
   1318 
   1319             destreg = DECODE_RM_WORD_REGISTER(rh);
   1320             DECODE_PRINTF(",");
   1321             srcoffset = decode_rm10_address(rl);
   1322             srcval = fetch_data_word(srcoffset);
   1323             TRACE_AND_STEP();
   1324             res = (s16) * destreg * (s16) srcval;
   1325             if (res > 0xFFFF) {
   1326                 SET_FLAG(F_CF);
   1327                 SET_FLAG(F_OF);
   1328             }
   1329             else {
   1330                 CLEAR_FLAG(F_CF);
   1331                 CLEAR_FLAG(F_OF);
   1332             }
   1333             *destreg = (u16) res;
   1334         }
   1335         break;
   1336     case 3:                    /* register to register */
   1337         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1338             u32 *destreg, *srcreg;
   1339             u32 res_lo, res_hi;
   1340 
   1341             destreg = DECODE_RM_LONG_REGISTER(rh);
   1342             DECODE_PRINTF(",");
   1343             srcreg = DECODE_RM_LONG_REGISTER(rl);
   1344             TRACE_AND_STEP();
   1345             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg);
   1346             if (res_hi != 0) {
   1347                 SET_FLAG(F_CF);
   1348                 SET_FLAG(F_OF);
   1349             }
   1350             else {
   1351                 CLEAR_FLAG(F_CF);
   1352                 CLEAR_FLAG(F_OF);
   1353             }
   1354             *destreg = (u32) res_lo;
   1355         }
   1356         else {
   1357             u16 *destreg, *srcreg;
   1358             u32 res;
   1359 
   1360             destreg = DECODE_RM_WORD_REGISTER(rh);
   1361             DECODE_PRINTF(",");
   1362             srcreg = DECODE_RM_WORD_REGISTER(rl);
   1363             res = (s16) * destreg * (s16) * srcreg;
   1364             if (res > 0xFFFF) {
   1365                 SET_FLAG(F_CF);
   1366                 SET_FLAG(F_OF);
   1367             }
   1368             else {
   1369                 CLEAR_FLAG(F_CF);
   1370                 CLEAR_FLAG(F_OF);
   1371             }
   1372             *destreg = (u16) res;
   1373         }
   1374         break;
   1375     }
   1376     DECODE_CLEAR_SEGOVR();
   1377     END_OF_INSTR();
   1378 }
   1379 
   1380 /****************************************************************************
   1381 REMARKS:
   1382 Handles opcode 0x0f,0xb2
   1383 ****************************************************************************/
   1384 static void
   1385 x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
   1386 {
   1387     int mod, rh, rl;
   1388     u16 *dstreg;
   1389     uint srcoffset;
   1390 
   1391     START_OF_INSTR();
   1392     DECODE_PRINTF("LSS\t");
   1393     FETCH_DECODE_MODRM(mod, rh, rl);
   1394     switch (mod) {
   1395     case 0:
   1396         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1397         DECODE_PRINTF(",");
   1398         srcoffset = decode_rm00_address(rl);
   1399         DECODE_PRINTF("\n");
   1400         TRACE_AND_STEP();
   1401         *dstreg = fetch_data_word(srcoffset);
   1402         M.x86.R_SS = fetch_data_word(srcoffset + 2);
   1403         break;
   1404     case 1:
   1405         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1406         DECODE_PRINTF(",");
   1407         srcoffset = decode_rm01_address(rl);
   1408         DECODE_PRINTF("\n");
   1409         TRACE_AND_STEP();
   1410         *dstreg = fetch_data_word(srcoffset);
   1411         M.x86.R_SS = fetch_data_word(srcoffset + 2);
   1412         break;
   1413     case 2:
   1414         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1415         DECODE_PRINTF(",");
   1416         srcoffset = decode_rm10_address(rl);
   1417         DECODE_PRINTF("\n");
   1418         TRACE_AND_STEP();
   1419         *dstreg = fetch_data_word(srcoffset);
   1420         M.x86.R_SS = fetch_data_word(srcoffset + 2);
   1421         break;
   1422     case 3:                    /* register to register */
   1423         /* UNDEFINED! */
   1424         TRACE_AND_STEP();
   1425     }
   1426     DECODE_CLEAR_SEGOVR();
   1427     END_OF_INSTR();
   1428 }
   1429 
   1430 /****************************************************************************
   1431 REMARKS:
   1432 Handles opcode 0x0f,0xb3
   1433 ****************************************************************************/
   1434 static void
   1435 x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
   1436 {
   1437     int mod, rl, rh;
   1438     uint srcoffset;
   1439     int bit, disp;
   1440 
   1441     START_OF_INSTR();
   1442     DECODE_PRINTF("BTR\t");
   1443     FETCH_DECODE_MODRM(mod, rh, rl);
   1444     switch (mod) {
   1445     case 0:
   1446         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1447             u32 srcval, mask;
   1448             u32 *shiftreg;
   1449 
   1450             srcoffset = decode_rm00_address(rl);
   1451             DECODE_PRINTF(",");
   1452             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1453             TRACE_AND_STEP();
   1454             bit = *shiftreg & 0x1F;
   1455             disp = (s16) * shiftreg >> 5;
   1456             srcval = fetch_data_long(srcoffset + disp);
   1457             mask = (0x1 << bit);
   1458             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1459             store_data_long(srcoffset + disp, srcval & ~mask);
   1460         }
   1461         else {
   1462             u16 srcval, mask;
   1463             u16 *shiftreg;
   1464 
   1465             srcoffset = decode_rm00_address(rl);
   1466             DECODE_PRINTF(",");
   1467             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1468             TRACE_AND_STEP();
   1469             bit = *shiftreg & 0xF;
   1470             disp = (s16) * shiftreg >> 4;
   1471             srcval = fetch_data_word(srcoffset + disp);
   1472             mask = (u16) (0x1 << bit);
   1473             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1474             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
   1475         }
   1476         break;
   1477     case 1:
   1478         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1479             u32 srcval, mask;
   1480             u32 *shiftreg;
   1481 
   1482             srcoffset = decode_rm01_address(rl);
   1483             DECODE_PRINTF(",");
   1484             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1485             TRACE_AND_STEP();
   1486             bit = *shiftreg & 0x1F;
   1487             disp = (s16) * shiftreg >> 5;
   1488             srcval = fetch_data_long(srcoffset + disp);
   1489             mask = (0x1 << bit);
   1490             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1491             store_data_long(srcoffset + disp, srcval & ~mask);
   1492         }
   1493         else {
   1494             u16 srcval, mask;
   1495             u16 *shiftreg;
   1496 
   1497             srcoffset = decode_rm01_address(rl);
   1498             DECODE_PRINTF(",");
   1499             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1500             TRACE_AND_STEP();
   1501             bit = *shiftreg & 0xF;
   1502             disp = (s16) * shiftreg >> 4;
   1503             srcval = fetch_data_word(srcoffset + disp);
   1504             mask = (u16) (0x1 << bit);
   1505             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1506             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
   1507         }
   1508         break;
   1509     case 2:
   1510         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1511             u32 srcval, mask;
   1512             u32 *shiftreg;
   1513 
   1514             srcoffset = decode_rm10_address(rl);
   1515             DECODE_PRINTF(",");
   1516             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1517             TRACE_AND_STEP();
   1518             bit = *shiftreg & 0x1F;
   1519             disp = (s16) * shiftreg >> 5;
   1520             srcval = fetch_data_long(srcoffset + disp);
   1521             mask = (0x1 << bit);
   1522             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1523             store_data_long(srcoffset + disp, srcval & ~mask);
   1524         }
   1525         else {
   1526             u16 srcval, mask;
   1527             u16 *shiftreg;
   1528 
   1529             srcoffset = decode_rm10_address(rl);
   1530             DECODE_PRINTF(",");
   1531             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1532             TRACE_AND_STEP();
   1533             bit = *shiftreg & 0xF;
   1534             disp = (s16) * shiftreg >> 4;
   1535             srcval = fetch_data_word(srcoffset + disp);
   1536             mask = (u16) (0x1 << bit);
   1537             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1538             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
   1539         }
   1540         break;
   1541     case 3:                    /* register to register */
   1542         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1543             u32 *srcreg, *shiftreg;
   1544             u32 mask;
   1545 
   1546             srcreg = DECODE_RM_LONG_REGISTER(rl);
   1547             DECODE_PRINTF(",");
   1548             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   1549             TRACE_AND_STEP();
   1550             bit = *shiftreg & 0x1F;
   1551             mask = (0x1 << bit);
   1552             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   1553             *srcreg &= ~mask;
   1554         }
   1555         else {
   1556             u16 *srcreg, *shiftreg;
   1557             u16 mask;
   1558 
   1559             srcreg = DECODE_RM_WORD_REGISTER(rl);
   1560             DECODE_PRINTF(",");
   1561             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   1562             TRACE_AND_STEP();
   1563             bit = *shiftreg & 0xF;
   1564             mask = (u16) (0x1 << bit);
   1565             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   1566             *srcreg &= ~mask;
   1567         }
   1568         break;
   1569     }
   1570     DECODE_CLEAR_SEGOVR();
   1571     END_OF_INSTR();
   1572 }
   1573 
   1574 /****************************************************************************
   1575 REMARKS:
   1576 Handles opcode 0x0f,0xb4
   1577 ****************************************************************************/
   1578 static void
   1579 x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
   1580 {
   1581     int mod, rh, rl;
   1582     u16 *dstreg;
   1583     uint srcoffset;
   1584 
   1585     START_OF_INSTR();
   1586     DECODE_PRINTF("LFS\t");
   1587     FETCH_DECODE_MODRM(mod, rh, rl);
   1588     switch (mod) {
   1589     case 0:
   1590         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1591         DECODE_PRINTF(",");
   1592         srcoffset = decode_rm00_address(rl);
   1593         DECODE_PRINTF("\n");
   1594         TRACE_AND_STEP();
   1595         *dstreg = fetch_data_word(srcoffset);
   1596         M.x86.R_FS = fetch_data_word(srcoffset + 2);
   1597         break;
   1598     case 1:
   1599         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1600         DECODE_PRINTF(",");
   1601         srcoffset = decode_rm01_address(rl);
   1602         DECODE_PRINTF("\n");
   1603         TRACE_AND_STEP();
   1604         *dstreg = fetch_data_word(srcoffset);
   1605         M.x86.R_FS = fetch_data_word(srcoffset + 2);
   1606         break;
   1607     case 2:
   1608         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1609         DECODE_PRINTF(",");
   1610         srcoffset = decode_rm10_address(rl);
   1611         DECODE_PRINTF("\n");
   1612         TRACE_AND_STEP();
   1613         *dstreg = fetch_data_word(srcoffset);
   1614         M.x86.R_FS = fetch_data_word(srcoffset + 2);
   1615         break;
   1616     case 3:                    /* register to register */
   1617         /* UNDEFINED! */
   1618         TRACE_AND_STEP();
   1619     }
   1620     DECODE_CLEAR_SEGOVR();
   1621     END_OF_INSTR();
   1622 }
   1623 
   1624 /****************************************************************************
   1625 REMARKS:
   1626 Handles opcode 0x0f,0xb5
   1627 ****************************************************************************/
   1628 static void
   1629 x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
   1630 {
   1631     int mod, rh, rl;
   1632     u16 *dstreg;
   1633     uint srcoffset;
   1634 
   1635     START_OF_INSTR();
   1636     DECODE_PRINTF("LGS\t");
   1637     FETCH_DECODE_MODRM(mod, rh, rl);
   1638     switch (mod) {
   1639     case 0:
   1640         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1641         DECODE_PRINTF(",");
   1642         srcoffset = decode_rm00_address(rl);
   1643         DECODE_PRINTF("\n");
   1644         TRACE_AND_STEP();
   1645         *dstreg = fetch_data_word(srcoffset);
   1646         M.x86.R_GS = fetch_data_word(srcoffset + 2);
   1647         break;
   1648     case 1:
   1649         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1650         DECODE_PRINTF(",");
   1651         srcoffset = decode_rm01_address(rl);
   1652         DECODE_PRINTF("\n");
   1653         TRACE_AND_STEP();
   1654         *dstreg = fetch_data_word(srcoffset);
   1655         M.x86.R_GS = fetch_data_word(srcoffset + 2);
   1656         break;
   1657     case 2:
   1658         dstreg = DECODE_RM_WORD_REGISTER(rh);
   1659         DECODE_PRINTF(",");
   1660         srcoffset = decode_rm10_address(rl);
   1661         DECODE_PRINTF("\n");
   1662         TRACE_AND_STEP();
   1663         *dstreg = fetch_data_word(srcoffset);
   1664         M.x86.R_GS = fetch_data_word(srcoffset + 2);
   1665         break;
   1666     case 3:                    /* register to register */
   1667         /* UNDEFINED! */
   1668         TRACE_AND_STEP();
   1669     }
   1670     DECODE_CLEAR_SEGOVR();
   1671     END_OF_INSTR();
   1672 }
   1673 
   1674 /****************************************************************************
   1675 REMARKS:
   1676 Handles opcode 0x0f,0xb6
   1677 ****************************************************************************/
   1678 static void
   1679 x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
   1680 {
   1681     int mod, rl, rh;
   1682     uint srcoffset;
   1683 
   1684     START_OF_INSTR();
   1685     DECODE_PRINTF("MOVZX\t");
   1686     FETCH_DECODE_MODRM(mod, rh, rl);
   1687     switch (mod) {
   1688     case 0:
   1689         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1690             u32 *destreg;
   1691             u32 srcval;
   1692 
   1693             destreg = DECODE_RM_LONG_REGISTER(rh);
   1694             DECODE_PRINTF(",");
   1695             srcoffset = decode_rm00_address(rl);
   1696             srcval = fetch_data_byte(srcoffset);
   1697             DECODE_PRINTF("\n");
   1698             TRACE_AND_STEP();
   1699             *destreg = srcval;
   1700         }
   1701         else {
   1702             u16 *destreg;
   1703             u16 srcval;
   1704 
   1705             destreg = DECODE_RM_WORD_REGISTER(rh);
   1706             DECODE_PRINTF(",");
   1707             srcoffset = decode_rm00_address(rl);
   1708             srcval = fetch_data_byte(srcoffset);
   1709             DECODE_PRINTF("\n");
   1710             TRACE_AND_STEP();
   1711             *destreg = srcval;
   1712         }
   1713         break;
   1714     case 1:
   1715         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1716             u32 *destreg;
   1717             u32 srcval;
   1718 
   1719             destreg = DECODE_RM_LONG_REGISTER(rh);
   1720             DECODE_PRINTF(",");
   1721             srcoffset = decode_rm01_address(rl);
   1722             srcval = fetch_data_byte(srcoffset);
   1723             DECODE_PRINTF("\n");
   1724             TRACE_AND_STEP();
   1725             *destreg = srcval;
   1726         }
   1727         else {
   1728             u16 *destreg;
   1729             u16 srcval;
   1730 
   1731             destreg = DECODE_RM_WORD_REGISTER(rh);
   1732             DECODE_PRINTF(",");
   1733             srcoffset = decode_rm01_address(rl);
   1734             srcval = fetch_data_byte(srcoffset);
   1735             DECODE_PRINTF("\n");
   1736             TRACE_AND_STEP();
   1737             *destreg = srcval;
   1738         }
   1739         break;
   1740     case 2:
   1741         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1742             u32 *destreg;
   1743             u32 srcval;
   1744 
   1745             destreg = DECODE_RM_LONG_REGISTER(rh);
   1746             DECODE_PRINTF(",");
   1747             srcoffset = decode_rm10_address(rl);
   1748             srcval = fetch_data_byte(srcoffset);
   1749             DECODE_PRINTF("\n");
   1750             TRACE_AND_STEP();
   1751             *destreg = srcval;
   1752         }
   1753         else {
   1754             u16 *destreg;
   1755             u16 srcval;
   1756 
   1757             destreg = DECODE_RM_WORD_REGISTER(rh);
   1758             DECODE_PRINTF(",");
   1759             srcoffset = decode_rm10_address(rl);
   1760             srcval = fetch_data_byte(srcoffset);
   1761             DECODE_PRINTF("\n");
   1762             TRACE_AND_STEP();
   1763             *destreg = srcval;
   1764         }
   1765         break;
   1766     case 3:                    /* register to register */
   1767         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1768             u32 *destreg;
   1769             u8 *srcreg;
   1770 
   1771             destreg = DECODE_RM_LONG_REGISTER(rh);
   1772             DECODE_PRINTF(",");
   1773             srcreg = DECODE_RM_BYTE_REGISTER(rl);
   1774             DECODE_PRINTF("\n");
   1775             TRACE_AND_STEP();
   1776             *destreg = *srcreg;
   1777         }
   1778         else {
   1779             u16 *destreg;
   1780             u8 *srcreg;
   1781 
   1782             destreg = DECODE_RM_WORD_REGISTER(rh);
   1783             DECODE_PRINTF(",");
   1784             srcreg = DECODE_RM_BYTE_REGISTER(rl);
   1785             DECODE_PRINTF("\n");
   1786             TRACE_AND_STEP();
   1787             *destreg = *srcreg;
   1788         }
   1789         break;
   1790     }
   1791     DECODE_CLEAR_SEGOVR();
   1792     END_OF_INSTR();
   1793 }
   1794 
   1795 /****************************************************************************
   1796 REMARKS:
   1797 Handles opcode 0x0f,0xb7
   1798 ****************************************************************************/
   1799 static void
   1800 x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
   1801 {
   1802     int mod, rl, rh;
   1803     uint srcoffset;
   1804     u32 *destreg;
   1805     u32 srcval;
   1806     u16 *srcreg;
   1807 
   1808     START_OF_INSTR();
   1809     DECODE_PRINTF("MOVZX\t");
   1810     FETCH_DECODE_MODRM(mod, rh, rl);
   1811     switch (mod) {
   1812     case 0:
   1813         destreg = DECODE_RM_LONG_REGISTER(rh);
   1814         DECODE_PRINTF(",");
   1815         srcoffset = decode_rm00_address(rl);
   1816         srcval = fetch_data_word(srcoffset);
   1817         DECODE_PRINTF("\n");
   1818         TRACE_AND_STEP();
   1819         *destreg = srcval;
   1820         break;
   1821     case 1:
   1822         destreg = DECODE_RM_LONG_REGISTER(rh);
   1823         DECODE_PRINTF(",");
   1824         srcoffset = decode_rm01_address(rl);
   1825         srcval = fetch_data_word(srcoffset);
   1826         DECODE_PRINTF("\n");
   1827         TRACE_AND_STEP();
   1828         *destreg = srcval;
   1829         break;
   1830     case 2:
   1831         destreg = DECODE_RM_LONG_REGISTER(rh);
   1832         DECODE_PRINTF(",");
   1833         srcoffset = decode_rm10_address(rl);
   1834         srcval = fetch_data_word(srcoffset);
   1835         DECODE_PRINTF("\n");
   1836         TRACE_AND_STEP();
   1837         *destreg = srcval;
   1838         break;
   1839     case 3:                    /* register to register */
   1840         destreg = DECODE_RM_LONG_REGISTER(rh);
   1841         DECODE_PRINTF(",");
   1842         srcreg = DECODE_RM_WORD_REGISTER(rl);
   1843         DECODE_PRINTF("\n");
   1844         TRACE_AND_STEP();
   1845         *destreg = *srcreg;
   1846         break;
   1847     }
   1848     DECODE_CLEAR_SEGOVR();
   1849     END_OF_INSTR();
   1850 }
   1851 
   1852 /****************************************************************************
   1853 REMARKS:
   1854 Handles opcode 0x0f,0xba
   1855 ****************************************************************************/
   1856 static void
   1857 x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
   1858 {
   1859     int mod, rl, rh;
   1860     uint srcoffset;
   1861     int bit;
   1862 
   1863     START_OF_INSTR();
   1864     FETCH_DECODE_MODRM(mod, rh, rl);
   1865     switch (rh) {
   1866     case 4:
   1867         DECODE_PRINTF("BT\t");
   1868         break;
   1869     case 5:
   1870         DECODE_PRINTF("BTS\t");
   1871         break;
   1872     case 6:
   1873         DECODE_PRINTF("BTR\t");
   1874         break;
   1875     case 7:
   1876         DECODE_PRINTF("BTC\t");
   1877         break;
   1878     default:
   1879         DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
   1880         TRACE_REGS();
   1881         printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
   1882                M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl);
   1883         HALT_SYS();
   1884     }
   1885     switch (mod) {
   1886     case 0:
   1887         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1888             u32 srcval, mask;
   1889             u8 shift;
   1890 
   1891             srcoffset = decode_rm00_address(rl);
   1892             DECODE_PRINTF(",");
   1893             shift = fetch_byte_imm();
   1894             TRACE_AND_STEP();
   1895             bit = shift & 0x1F;
   1896             srcval = fetch_data_long(srcoffset);
   1897             mask = (0x1 << bit);
   1898             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1899             switch (rh) {
   1900             case 5:
   1901                 store_data_long(srcoffset, srcval | mask);
   1902                 break;
   1903             case 6:
   1904                 store_data_long(srcoffset, srcval & ~mask);
   1905                 break;
   1906             case 7:
   1907                 store_data_long(srcoffset, srcval ^ mask);
   1908                 break;
   1909             default:
   1910                 break;
   1911             }
   1912         }
   1913         else {
   1914             u16 srcval, mask;
   1915             u8 shift;
   1916 
   1917             srcoffset = decode_rm00_address(rl);
   1918             DECODE_PRINTF(",");
   1919             shift = fetch_byte_imm();
   1920             TRACE_AND_STEP();
   1921             bit = shift & 0xF;
   1922             srcval = fetch_data_word(srcoffset);
   1923             mask = (0x1 << bit);
   1924             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1925             switch (rh) {
   1926             case 5:
   1927                 store_data_word(srcoffset, srcval | mask);
   1928                 break;
   1929             case 6:
   1930                 store_data_word(srcoffset, srcval & ~mask);
   1931                 break;
   1932             case 7:
   1933                 store_data_word(srcoffset, srcval ^ mask);
   1934                 break;
   1935             default:
   1936                 break;
   1937             }
   1938         }
   1939         break;
   1940     case 1:
   1941         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1942             u32 srcval, mask;
   1943             u8 shift;
   1944 
   1945             srcoffset = decode_rm01_address(rl);
   1946             DECODE_PRINTF(",");
   1947             shift = fetch_byte_imm();
   1948             TRACE_AND_STEP();
   1949             bit = shift & 0x1F;
   1950             srcval = fetch_data_long(srcoffset);
   1951             mask = (0x1 << bit);
   1952             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1953             switch (rh) {
   1954             case 5:
   1955                 store_data_long(srcoffset, srcval | mask);
   1956                 break;
   1957             case 6:
   1958                 store_data_long(srcoffset, srcval & ~mask);
   1959                 break;
   1960             case 7:
   1961                 store_data_long(srcoffset, srcval ^ mask);
   1962                 break;
   1963             default:
   1964                 break;
   1965             }
   1966         }
   1967         else {
   1968             u16 srcval, mask;
   1969             u8 shift;
   1970 
   1971             srcoffset = decode_rm01_address(rl);
   1972             DECODE_PRINTF(",");
   1973             shift = fetch_byte_imm();
   1974             TRACE_AND_STEP();
   1975             bit = shift & 0xF;
   1976             srcval = fetch_data_word(srcoffset);
   1977             mask = (0x1 << bit);
   1978             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   1979             switch (rh) {
   1980             case 5:
   1981                 store_data_word(srcoffset, srcval | mask);
   1982                 break;
   1983             case 6:
   1984                 store_data_word(srcoffset, srcval & ~mask);
   1985                 break;
   1986             case 7:
   1987                 store_data_word(srcoffset, srcval ^ mask);
   1988                 break;
   1989             default:
   1990                 break;
   1991             }
   1992         }
   1993         break;
   1994     case 2:
   1995         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   1996             u32 srcval, mask;
   1997             u8 shift;
   1998 
   1999             srcoffset = decode_rm10_address(rl);
   2000             DECODE_PRINTF(",");
   2001             shift = fetch_byte_imm();
   2002             TRACE_AND_STEP();
   2003             bit = shift & 0x1F;
   2004             srcval = fetch_data_long(srcoffset);
   2005             mask = (0x1 << bit);
   2006             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2007             switch (rh) {
   2008             case 5:
   2009                 store_data_long(srcoffset, srcval | mask);
   2010                 break;
   2011             case 6:
   2012                 store_data_long(srcoffset, srcval & ~mask);
   2013                 break;
   2014             case 7:
   2015                 store_data_long(srcoffset, srcval ^ mask);
   2016                 break;
   2017             default:
   2018                 break;
   2019             }
   2020         }
   2021         else {
   2022             u16 srcval, mask;
   2023             u8 shift;
   2024 
   2025             srcoffset = decode_rm10_address(rl);
   2026             DECODE_PRINTF(",");
   2027             shift = fetch_byte_imm();
   2028             TRACE_AND_STEP();
   2029             bit = shift & 0xF;
   2030             srcval = fetch_data_word(srcoffset);
   2031             mask = (0x1 << bit);
   2032             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2033             switch (rh) {
   2034             case 5:
   2035                 store_data_word(srcoffset, srcval | mask);
   2036                 break;
   2037             case 6:
   2038                 store_data_word(srcoffset, srcval & ~mask);
   2039                 break;
   2040             case 7:
   2041                 store_data_word(srcoffset, srcval ^ mask);
   2042                 break;
   2043             default:
   2044                 break;
   2045             }
   2046         }
   2047         break;
   2048     case 3:                    /* register to register */
   2049         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2050             u32 *srcreg;
   2051             u32 mask;
   2052             u8 shift;
   2053 
   2054             srcreg = DECODE_RM_LONG_REGISTER(rl);
   2055             DECODE_PRINTF(",");
   2056             shift = fetch_byte_imm();
   2057             TRACE_AND_STEP();
   2058             bit = shift & 0x1F;
   2059             mask = (0x1 << bit);
   2060             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   2061             switch (rh) {
   2062             case 5:
   2063                 *srcreg |= mask;
   2064                 break;
   2065             case 6:
   2066                 *srcreg &= ~mask;
   2067                 break;
   2068             case 7:
   2069                 *srcreg ^= mask;
   2070                 break;
   2071             default:
   2072                 break;
   2073             }
   2074         }
   2075         else {
   2076             u16 *srcreg;
   2077             u16 mask;
   2078             u8 shift;
   2079 
   2080             srcreg = DECODE_RM_WORD_REGISTER(rl);
   2081             DECODE_PRINTF(",");
   2082             shift = fetch_byte_imm();
   2083             TRACE_AND_STEP();
   2084             bit = shift & 0xF;
   2085             mask = (0x1 << bit);
   2086             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   2087             switch (rh) {
   2088             case 5:
   2089                 *srcreg |= mask;
   2090                 break;
   2091             case 6:
   2092                 *srcreg &= ~mask;
   2093                 break;
   2094             case 7:
   2095                 *srcreg ^= mask;
   2096                 break;
   2097             default:
   2098                 break;
   2099             }
   2100         }
   2101         break;
   2102     }
   2103     DECODE_CLEAR_SEGOVR();
   2104     END_OF_INSTR();
   2105 }
   2106 
   2107 /****************************************************************************
   2108 REMARKS:
   2109 Handles opcode 0x0f,0xbb
   2110 ****************************************************************************/
   2111 static void
   2112 x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
   2113 {
   2114     int mod, rl, rh;
   2115     uint srcoffset;
   2116     int bit, disp;
   2117 
   2118     START_OF_INSTR();
   2119     DECODE_PRINTF("BTC\t");
   2120     FETCH_DECODE_MODRM(mod, rh, rl);
   2121     switch (mod) {
   2122     case 0:
   2123         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2124             u32 srcval, mask;
   2125             u32 *shiftreg;
   2126 
   2127             srcoffset = decode_rm00_address(rl);
   2128             DECODE_PRINTF(",");
   2129             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   2130             TRACE_AND_STEP();
   2131             bit = *shiftreg & 0x1F;
   2132             disp = (s16) * shiftreg >> 5;
   2133             srcval = fetch_data_long(srcoffset + disp);
   2134             mask = (0x1 << bit);
   2135             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2136             store_data_long(srcoffset + disp, srcval ^ mask);
   2137         }
   2138         else {
   2139             u16 srcval, mask;
   2140             u16 *shiftreg;
   2141 
   2142             srcoffset = decode_rm00_address(rl);
   2143             DECODE_PRINTF(",");
   2144             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   2145             TRACE_AND_STEP();
   2146             bit = *shiftreg & 0xF;
   2147             disp = (s16) * shiftreg >> 4;
   2148             srcval = fetch_data_word(srcoffset + disp);
   2149             mask = (u16) (0x1 << bit);
   2150             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2151             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
   2152         }
   2153         break;
   2154     case 1:
   2155         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2156             u32 srcval, mask;
   2157             u32 *shiftreg;
   2158 
   2159             srcoffset = decode_rm01_address(rl);
   2160             DECODE_PRINTF(",");
   2161             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   2162             TRACE_AND_STEP();
   2163             bit = *shiftreg & 0x1F;
   2164             disp = (s16) * shiftreg >> 5;
   2165             srcval = fetch_data_long(srcoffset + disp);
   2166             mask = (0x1 << bit);
   2167             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2168             store_data_long(srcoffset + disp, srcval ^ mask);
   2169         }
   2170         else {
   2171             u16 srcval, mask;
   2172             u16 *shiftreg;
   2173 
   2174             srcoffset = decode_rm01_address(rl);
   2175             DECODE_PRINTF(",");
   2176             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   2177             TRACE_AND_STEP();
   2178             bit = *shiftreg & 0xF;
   2179             disp = (s16) * shiftreg >> 4;
   2180             srcval = fetch_data_word(srcoffset + disp);
   2181             mask = (u16) (0x1 << bit);
   2182             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2183             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
   2184         }
   2185         break;
   2186     case 2:
   2187         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2188             u32 srcval, mask;
   2189             u32 *shiftreg;
   2190 
   2191             srcoffset = decode_rm10_address(rl);
   2192             DECODE_PRINTF(",");
   2193             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   2194             TRACE_AND_STEP();
   2195             bit = *shiftreg & 0x1F;
   2196             disp = (s16) * shiftreg >> 5;
   2197             srcval = fetch_data_long(srcoffset + disp);
   2198             mask = (0x1 << bit);
   2199             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2200             store_data_long(srcoffset + disp, srcval ^ mask);
   2201         }
   2202         else {
   2203             u16 srcval, mask;
   2204             u16 *shiftreg;
   2205 
   2206             srcoffset = decode_rm10_address(rl);
   2207             DECODE_PRINTF(",");
   2208             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   2209             TRACE_AND_STEP();
   2210             bit = *shiftreg & 0xF;
   2211             disp = (s16) * shiftreg >> 4;
   2212             srcval = fetch_data_word(srcoffset + disp);
   2213             mask = (u16) (0x1 << bit);
   2214             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   2215             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
   2216         }
   2217         break;
   2218     case 3:                    /* register to register */
   2219         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2220             u32 *srcreg, *shiftreg;
   2221             u32 mask;
   2222 
   2223             srcreg = DECODE_RM_LONG_REGISTER(rl);
   2224             DECODE_PRINTF(",");
   2225             shiftreg = DECODE_RM_LONG_REGISTER(rh);
   2226             TRACE_AND_STEP();
   2227             bit = *shiftreg & 0x1F;
   2228             mask = (0x1 << bit);
   2229             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   2230             *srcreg ^= mask;
   2231         }
   2232         else {
   2233             u16 *srcreg, *shiftreg;
   2234             u16 mask;
   2235 
   2236             srcreg = DECODE_RM_WORD_REGISTER(rl);
   2237             DECODE_PRINTF(",");
   2238             shiftreg = DECODE_RM_WORD_REGISTER(rh);
   2239             TRACE_AND_STEP();
   2240             bit = *shiftreg & 0xF;
   2241             mask = (u16) (0x1 << bit);
   2242             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
   2243             *srcreg ^= mask;
   2244         }
   2245         break;
   2246     }
   2247     DECODE_CLEAR_SEGOVR();
   2248     END_OF_INSTR();
   2249 }
   2250 
   2251 /****************************************************************************
   2252 REMARKS:
   2253 Handles opcode 0x0f,0xbc
   2254 ****************************************************************************/
   2255 static void
   2256 x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
   2257 {
   2258     int mod, rl, rh;
   2259     uint srcoffset;
   2260 
   2261     START_OF_INSTR();
   2262     DECODE_PRINTF("BSF\t");
   2263     FETCH_DECODE_MODRM(mod, rh, rl);
   2264     switch (mod) {
   2265     case 0:
   2266         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2267             u32 srcval, *dstreg;
   2268 
   2269             srcoffset = decode_rm00_address(rl);
   2270             DECODE_PRINTF(",");
   2271             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2272             TRACE_AND_STEP();
   2273             srcval = fetch_data_long(srcoffset);
   2274             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2275             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
   2276                 if ((srcval >> *dstreg) & 1)
   2277                     break;
   2278         }
   2279         else {
   2280             u16 srcval, *dstreg;
   2281 
   2282             srcoffset = decode_rm00_address(rl);
   2283             DECODE_PRINTF(",");
   2284             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2285             TRACE_AND_STEP();
   2286             srcval = fetch_data_word(srcoffset);
   2287             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2288             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
   2289                 if ((srcval >> *dstreg) & 1)
   2290                     break;
   2291         }
   2292         break;
   2293     case 1:
   2294         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2295             u32 srcval, *dstreg;
   2296 
   2297             srcoffset = decode_rm01_address(rl);
   2298             DECODE_PRINTF(",");
   2299             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2300             TRACE_AND_STEP();
   2301             srcval = fetch_data_long(srcoffset);
   2302             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2303             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
   2304                 if ((srcval >> *dstreg) & 1)
   2305                     break;
   2306         }
   2307         else {
   2308             u16 srcval, *dstreg;
   2309 
   2310             srcoffset = decode_rm01_address(rl);
   2311             DECODE_PRINTF(",");
   2312             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2313             TRACE_AND_STEP();
   2314             srcval = fetch_data_word(srcoffset);
   2315             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2316             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
   2317                 if ((srcval >> *dstreg) & 1)
   2318                     break;
   2319         }
   2320         break;
   2321     case 2:
   2322         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2323             u32 srcval, *dstreg;
   2324 
   2325             srcoffset = decode_rm10_address(rl);
   2326             DECODE_PRINTF(",");
   2327             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2328             TRACE_AND_STEP();
   2329             srcval = fetch_data_long(srcoffset);
   2330             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2331             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
   2332                 if ((srcval >> *dstreg) & 1)
   2333                     break;
   2334         }
   2335         else {
   2336             u16 srcval, *dstreg;
   2337 
   2338             srcoffset = decode_rm10_address(rl);
   2339             DECODE_PRINTF(",");
   2340             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2341             TRACE_AND_STEP();
   2342             srcval = fetch_data_word(srcoffset);
   2343             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2344             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
   2345                 if ((srcval >> *dstreg) & 1)
   2346                     break;
   2347         }
   2348         break;
   2349     case 3:                    /* register to register */
   2350         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2351             u32 srcval, *dstreg;
   2352 
   2353             srcval = *DECODE_RM_LONG_REGISTER(rl);
   2354             DECODE_PRINTF(",");
   2355             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2356             TRACE_AND_STEP();
   2357             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2358             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
   2359                 if ((srcval >> *dstreg) & 1)
   2360                     break;
   2361         }
   2362         else {
   2363             u16 srcval, *dstreg;
   2364 
   2365             srcval = *DECODE_RM_WORD_REGISTER(rl);
   2366             DECODE_PRINTF(",");
   2367             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2368             TRACE_AND_STEP();
   2369             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2370             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
   2371                 if ((srcval >> *dstreg) & 1)
   2372                     break;
   2373         }
   2374         break;
   2375     }
   2376     DECODE_CLEAR_SEGOVR();
   2377     END_OF_INSTR();
   2378 }
   2379 
   2380 /****************************************************************************
   2381 REMARKS:
   2382 Handles opcode 0x0f,0xbd
   2383 ****************************************************************************/
   2384 static void
   2385 x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
   2386 {
   2387     int mod, rl, rh;
   2388     uint srcoffset;
   2389 
   2390     START_OF_INSTR();
   2391     DECODE_PRINTF("BSR\t");
   2392     FETCH_DECODE_MODRM(mod, rh, rl);
   2393     switch (mod) {
   2394     case 0:
   2395         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2396             u32 srcval, *dstreg;
   2397 
   2398             srcoffset = decode_rm00_address(rl);
   2399             DECODE_PRINTF(",");
   2400             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2401             TRACE_AND_STEP();
   2402             srcval = fetch_data_long(srcoffset);
   2403             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2404             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
   2405                 if ((srcval >> *dstreg) & 1)
   2406                     break;
   2407         }
   2408         else {
   2409             u16 srcval, *dstreg;
   2410 
   2411             srcoffset = decode_rm00_address(rl);
   2412             DECODE_PRINTF(",");
   2413             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2414             TRACE_AND_STEP();
   2415             srcval = fetch_data_word(srcoffset);
   2416             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2417             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
   2418                 if ((srcval >> *dstreg) & 1)
   2419                     break;
   2420         }
   2421         break;
   2422     case 1:
   2423         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2424             u32 srcval, *dstreg;
   2425 
   2426             srcoffset = decode_rm01_address(rl);
   2427             DECODE_PRINTF(",");
   2428             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2429             TRACE_AND_STEP();
   2430             srcval = fetch_data_long(srcoffset);
   2431             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2432             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
   2433                 if ((srcval >> *dstreg) & 1)
   2434                     break;
   2435         }
   2436         else {
   2437             u16 srcval, *dstreg;
   2438 
   2439             srcoffset = decode_rm01_address(rl);
   2440             DECODE_PRINTF(",");
   2441             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2442             TRACE_AND_STEP();
   2443             srcval = fetch_data_word(srcoffset);
   2444             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2445             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
   2446                 if ((srcval >> *dstreg) & 1)
   2447                     break;
   2448         }
   2449         break;
   2450     case 2:
   2451         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2452             u32 srcval, *dstreg;
   2453 
   2454             srcoffset = decode_rm10_address(rl);
   2455             DECODE_PRINTF(",");
   2456             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2457             TRACE_AND_STEP();
   2458             srcval = fetch_data_long(srcoffset);
   2459             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2460             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
   2461                 if ((srcval >> *dstreg) & 1)
   2462                     break;
   2463         }
   2464         else {
   2465             u16 srcval, *dstreg;
   2466 
   2467             srcoffset = decode_rm10_address(rl);
   2468             DECODE_PRINTF(",");
   2469             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2470             TRACE_AND_STEP();
   2471             srcval = fetch_data_word(srcoffset);
   2472             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2473             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
   2474                 if ((srcval >> *dstreg) & 1)
   2475                     break;
   2476         }
   2477         break;
   2478     case 3:                    /* register to register */
   2479         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2480             u32 srcval, *dstreg;
   2481 
   2482             srcval = *DECODE_RM_LONG_REGISTER(rl);
   2483             DECODE_PRINTF(",");
   2484             dstreg = DECODE_RM_LONG_REGISTER(rh);
   2485             TRACE_AND_STEP();
   2486             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2487             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
   2488                 if ((srcval >> *dstreg) & 1)
   2489                     break;
   2490         }
   2491         else {
   2492             u16 srcval, *dstreg;
   2493 
   2494             srcval = *DECODE_RM_WORD_REGISTER(rl);
   2495             DECODE_PRINTF(",");
   2496             dstreg = DECODE_RM_WORD_REGISTER(rh);
   2497             TRACE_AND_STEP();
   2498             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   2499             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
   2500                 if ((srcval >> *dstreg) & 1)
   2501                     break;
   2502         }
   2503         break;
   2504     }
   2505     DECODE_CLEAR_SEGOVR();
   2506     END_OF_INSTR();
   2507 }
   2508 
   2509 /****************************************************************************
   2510 REMARKS:
   2511 Handles opcode 0x0f,0xbe
   2512 ****************************************************************************/
   2513 static void
   2514 x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
   2515 {
   2516     int mod, rl, rh;
   2517     uint srcoffset;
   2518 
   2519     START_OF_INSTR();
   2520     DECODE_PRINTF("MOVSX\t");
   2521     FETCH_DECODE_MODRM(mod, rh, rl);
   2522     switch (mod) {
   2523     case 0:
   2524         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2525             u32 *destreg;
   2526             u32 srcval;
   2527 
   2528             destreg = DECODE_RM_LONG_REGISTER(rh);
   2529             DECODE_PRINTF(",");
   2530             srcoffset = decode_rm00_address(rl);
   2531             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
   2532             DECODE_PRINTF("\n");
   2533             TRACE_AND_STEP();
   2534             *destreg = srcval;
   2535         }
   2536         else {
   2537             u16 *destreg;
   2538             u16 srcval;
   2539 
   2540             destreg = DECODE_RM_WORD_REGISTER(rh);
   2541             DECODE_PRINTF(",");
   2542             srcoffset = decode_rm00_address(rl);
   2543             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
   2544             DECODE_PRINTF("\n");
   2545             TRACE_AND_STEP();
   2546             *destreg = srcval;
   2547         }
   2548         break;
   2549     case 1:
   2550         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2551             u32 *destreg;
   2552             u32 srcval;
   2553 
   2554             destreg = DECODE_RM_LONG_REGISTER(rh);
   2555             DECODE_PRINTF(",");
   2556             srcoffset = decode_rm01_address(rl);
   2557             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
   2558             DECODE_PRINTF("\n");
   2559             TRACE_AND_STEP();
   2560             *destreg = srcval;
   2561         }
   2562         else {
   2563             u16 *destreg;
   2564             u16 srcval;
   2565 
   2566             destreg = DECODE_RM_WORD_REGISTER(rh);
   2567             DECODE_PRINTF(",");
   2568             srcoffset = decode_rm01_address(rl);
   2569             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
   2570             DECODE_PRINTF("\n");
   2571             TRACE_AND_STEP();
   2572             *destreg = srcval;
   2573         }
   2574         break;
   2575     case 2:
   2576         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2577             u32 *destreg;
   2578             u32 srcval;
   2579 
   2580             destreg = DECODE_RM_LONG_REGISTER(rh);
   2581             DECODE_PRINTF(",");
   2582             srcoffset = decode_rm10_address(rl);
   2583             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
   2584             DECODE_PRINTF("\n");
   2585             TRACE_AND_STEP();
   2586             *destreg = srcval;
   2587         }
   2588         else {
   2589             u16 *destreg;
   2590             u16 srcval;
   2591 
   2592             destreg = DECODE_RM_WORD_REGISTER(rh);
   2593             DECODE_PRINTF(",");
   2594             srcoffset = decode_rm10_address(rl);
   2595             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
   2596             DECODE_PRINTF("\n");
   2597             TRACE_AND_STEP();
   2598             *destreg = srcval;
   2599         }
   2600         break;
   2601     case 3:                    /* register to register */
   2602         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
   2603             u32 *destreg;
   2604             u8 *srcreg;
   2605 
   2606             destreg = DECODE_RM_LONG_REGISTER(rh);
   2607             DECODE_PRINTF(",");
   2608             srcreg = DECODE_RM_BYTE_REGISTER(rl);
   2609             DECODE_PRINTF("\n");
   2610             TRACE_AND_STEP();
   2611             *destreg = (s32) ((s8) * srcreg);
   2612         }
   2613         else {
   2614             u16 *destreg;
   2615             u8 *srcreg;
   2616 
   2617             destreg = DECODE_RM_WORD_REGISTER(rh);
   2618             DECODE_PRINTF(",");
   2619             srcreg = DECODE_RM_BYTE_REGISTER(rl);
   2620             DECODE_PRINTF("\n");
   2621             TRACE_AND_STEP();
   2622             *destreg = (s16) ((s8) * srcreg);
   2623         }
   2624         break;
   2625     }
   2626     DECODE_CLEAR_SEGOVR();
   2627     END_OF_INSTR();
   2628 }
   2629 
   2630 /****************************************************************************
   2631 REMARKS:
   2632 Handles opcode 0x0f,0xbf
   2633 ****************************************************************************/
   2634 static void
   2635 x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
   2636 {
   2637     int mod, rl, rh;
   2638     uint srcoffset;
   2639     u32 *destreg;
   2640     u32 srcval;
   2641     u16 *srcreg;
   2642 
   2643     START_OF_INSTR();
   2644     DECODE_PRINTF("MOVSX\t");
   2645     FETCH_DECODE_MODRM(mod, rh, rl);
   2646     switch (mod) {
   2647     case 0:
   2648         destreg = DECODE_RM_LONG_REGISTER(rh);
   2649         DECODE_PRINTF(",");
   2650         srcoffset = decode_rm00_address(rl);
   2651         srcval = (s32) ((s16) fetch_data_word(srcoffset));
   2652         DECODE_PRINTF("\n");
   2653         TRACE_AND_STEP();
   2654         *destreg = srcval;
   2655         break;
   2656     case 1:
   2657         destreg = DECODE_RM_LONG_REGISTER(rh);
   2658         DECODE_PRINTF(",");
   2659         srcoffset = decode_rm01_address(rl);
   2660         srcval = (s32) ((s16) fetch_data_word(srcoffset));
   2661         DECODE_PRINTF("\n");
   2662         TRACE_AND_STEP();
   2663         *destreg = srcval;
   2664         break;
   2665     case 2:
   2666         destreg = DECODE_RM_LONG_REGISTER(rh);
   2667         DECODE_PRINTF(",");
   2668         srcoffset = decode_rm10_address(rl);
   2669         srcval = (s32) ((s16) fetch_data_word(srcoffset));
   2670         DECODE_PRINTF("\n");
   2671         TRACE_AND_STEP();
   2672         *destreg = srcval;
   2673         break;
   2674     case 3:                    /* register to register */
   2675         destreg = DECODE_RM_LONG_REGISTER(rh);
   2676         DECODE_PRINTF(",");
   2677         srcreg = DECODE_RM_WORD_REGISTER(rl);
   2678         DECODE_PRINTF("\n");
   2679         TRACE_AND_STEP();
   2680         *destreg = (s32) ((s16) * srcreg);
   2681         break;
   2682     }
   2683     DECODE_CLEAR_SEGOVR();
   2684     END_OF_INSTR();
   2685 }
   2686 
   2687 /* Handles opcodes 0xc8-0xcf */
   2688 static void
   2689 x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
   2690 {
   2691     START_OF_INSTR();
   2692     DECODE_PRINTF("BSWAP\n");
   2693     TRACE_AND_STEP();
   2694 
   2695     switch (op2) {
   2696     case 0xc8:
   2697         M.x86.R_EAX = bswap_32(M.x86.R_EAX);
   2698         break;
   2699     case 0xc9:
   2700         M.x86.R_ECX = bswap_32(M.x86.R_ECX);
   2701         break;
   2702     case 0xca:
   2703         M.x86.R_EDX = bswap_32(M.x86.R_EDX);
   2704         break;
   2705     case 0xcb:
   2706         M.x86.R_EBX = bswap_32(M.x86.R_EBX);
   2707         break;
   2708     case 0xcc:
   2709         M.x86.R_ESP = bswap_32(M.x86.R_ESP);
   2710         break;
   2711     case 0xcd:
   2712         M.x86.R_EBP = bswap_32(M.x86.R_EBP);
   2713         break;
   2714     case 0xce:
   2715         M.x86.R_ESI = bswap_32(M.x86.R_ESI);
   2716         break;
   2717     case 0xcf:
   2718         M.x86.R_EDI = bswap_32(M.x86.R_EDI);
   2719         break;
   2720     default:
   2721         /* can't happen */
   2722         break;
   2723     }
   2724 
   2725     DECODE_CLEAR_SEGOVR();
   2726     END_OF_INSTR();
   2727 }
   2728 
   2729 /***************************************************************************
   2730  * Double byte operation code table:
   2731  **************************************************************************/
   2732 void (*x86emu_optab2[256]) (u8) = {
   2733                                         /*  0x00 */ x86emuOp2_illegal_op,
   2734                                         /* Group F (ring 0 PM)      */
   2735                                                 /*  0x01 */ x86emuOp2_illegal_op,
   2736                                                 /* Group G (ring 0 PM)      */
   2737                                                 /*  0x02 */ x86emuOp2_illegal_op,
   2738                                                 /* lar (ring 0 PM)          */
   2739                                                 /*  0x03 */ x86emuOp2_illegal_op,
   2740                                                 /* lsl (ring 0 PM)          */
   2741 /*  0x04 */ x86emuOp2_illegal_op,
   2742                                                 /*  0x05 */ x86emuOp2_illegal_op,
   2743                                                 /* loadall (undocumented)   */
   2744                                                 /*  0x06 */ x86emuOp2_illegal_op,
   2745                                                 /* clts (ring 0 PM)         */
   2746                                                 /*  0x07 */ x86emuOp2_illegal_op,
   2747                                                 /* loadall (undocumented)   */
   2748                                                 /*  0x08 */ x86emuOp2_illegal_op,
   2749                                                 /* invd (ring 0 PM)         */
   2750                                                 /*  0x09 */ x86emuOp2_illegal_op,
   2751                                                 /* wbinvd (ring 0 PM)       */
   2752 /*  0x0a */ x86emuOp2_illegal_op,
   2753 /*  0x0b */ x86emuOp2_illegal_op,
   2754 /*  0x0c */ x86emuOp2_illegal_op,
   2755 /*  0x0d */ x86emuOp2_illegal_op,
   2756 /*  0x0e */ x86emuOp2_illegal_op,
   2757 /*  0x0f */ x86emuOp2_illegal_op,
   2758 /*  0x10 */ x86emuOp2_illegal_op,
   2759 /*  0x11 */ x86emuOp2_illegal_op,
   2760 /*  0x12 */ x86emuOp2_illegal_op,
   2761 /*  0x13 */ x86emuOp2_illegal_op,
   2762 /*  0x14 */ x86emuOp2_illegal_op,
   2763 /*  0x15 */ x86emuOp2_illegal_op,
   2764 /*  0x16 */ x86emuOp2_illegal_op,
   2765 /*  0x17 */ x86emuOp2_illegal_op,
   2766 /*  0x18 */ x86emuOp2_illegal_op,
   2767 /*  0x19 */ x86emuOp2_illegal_op,
   2768 /*  0x1a */ x86emuOp2_illegal_op,
   2769 /*  0x1b */ x86emuOp2_illegal_op,
   2770 /*  0x1c */ x86emuOp2_illegal_op,
   2771 /*  0x1d */ x86emuOp2_illegal_op,
   2772 /*  0x1e */ x86emuOp2_illegal_op,
   2773 /*  0x1f */ x86emuOp2_illegal_op,
   2774                                                 /*  0x20 */ x86emuOp2_illegal_op,
   2775                                                 /* mov reg32,creg (ring 0 PM) */
   2776                                                 /*  0x21 */ x86emuOp2_illegal_op,
   2777                                                 /* mov reg32,dreg (ring 0 PM) */
   2778                                                 /*  0x22 */ x86emuOp2_illegal_op,
   2779                                                 /* mov creg,reg32 (ring 0 PM) */
   2780                                                 /*  0x23 */ x86emuOp2_illegal_op,
   2781                                                 /* mov dreg,reg32 (ring 0 PM) */
   2782                                                 /*  0x24 */ x86emuOp2_illegal_op,
   2783                                                 /* mov reg32,treg (ring 0 PM) */
   2784 /*  0x25 */ x86emuOp2_illegal_op,
   2785                                                 /*  0x26 */ x86emuOp2_illegal_op,
   2786                                                 /* mov treg,reg32 (ring 0 PM) */
   2787 /*  0x27 */ x86emuOp2_illegal_op,
   2788 /*  0x28 */ x86emuOp2_illegal_op,
   2789 /*  0x29 */ x86emuOp2_illegal_op,
   2790 /*  0x2a */ x86emuOp2_illegal_op,
   2791 /*  0x2b */ x86emuOp2_illegal_op,
   2792 /*  0x2c */ x86emuOp2_illegal_op,
   2793 /*  0x2d */ x86emuOp2_illegal_op,
   2794 /*  0x2e */ x86emuOp2_illegal_op,
   2795 /*  0x2f */ x86emuOp2_illegal_op,
   2796 /*  0x30 */ x86emuOp2_illegal_op,
   2797 /*  0x31 */ x86emuOp2_rdtsc,
   2798 /*  0x32 */ x86emuOp2_illegal_op,
   2799 /*  0x33 */ x86emuOp2_illegal_op,
   2800 /*  0x34 */ x86emuOp2_illegal_op,
   2801 /*  0x35 */ x86emuOp2_illegal_op,
   2802 /*  0x36 */ x86emuOp2_illegal_op,
   2803 /*  0x37 */ x86emuOp2_illegal_op,
   2804 /*  0x38 */ x86emuOp2_illegal_op,
   2805 /*  0x39 */ x86emuOp2_illegal_op,
   2806 /*  0x3a */ x86emuOp2_illegal_op,
   2807 /*  0x3b */ x86emuOp2_illegal_op,
   2808 /*  0x3c */ x86emuOp2_illegal_op,
   2809 /*  0x3d */ x86emuOp2_illegal_op,
   2810 /*  0x3e */ x86emuOp2_illegal_op,
   2811 /*  0x3f */ x86emuOp2_illegal_op,
   2812 /*  0x40 */ x86emuOp2_illegal_op,
   2813 /*  0x41 */ x86emuOp2_illegal_op,
   2814 /*  0x42 */ x86emuOp2_illegal_op,
   2815 /*  0x43 */ x86emuOp2_illegal_op,
   2816 /*  0x44 */ x86emuOp2_illegal_op,
   2817 /*  0x45 */ x86emuOp2_illegal_op,
   2818 /*  0x46 */ x86emuOp2_illegal_op,
   2819 /*  0x47 */ x86emuOp2_illegal_op,
   2820 /*  0x48 */ x86emuOp2_illegal_op,
   2821 /*  0x49 */ x86emuOp2_illegal_op,
   2822 /*  0x4a */ x86emuOp2_illegal_op,
   2823 /*  0x4b */ x86emuOp2_illegal_op,
   2824 /*  0x4c */ x86emuOp2_illegal_op,
   2825 /*  0x4d */ x86emuOp2_illegal_op,
   2826 /*  0x4e */ x86emuOp2_illegal_op,
   2827 /*  0x4f */ x86emuOp2_illegal_op,
   2828 /*  0x50 */ x86emuOp2_illegal_op,
   2829 /*  0x51 */ x86emuOp2_illegal_op,
   2830 /*  0x52 */ x86emuOp2_illegal_op,
   2831 /*  0x53 */ x86emuOp2_illegal_op,
   2832 /*  0x54 */ x86emuOp2_illegal_op,
   2833 /*  0x55 */ x86emuOp2_illegal_op,
   2834 /*  0x56 */ x86emuOp2_illegal_op,
   2835 /*  0x57 */ x86emuOp2_illegal_op,
   2836 /*  0x58 */ x86emuOp2_illegal_op,
   2837 /*  0x59 */ x86emuOp2_illegal_op,
   2838 /*  0x5a */ x86emuOp2_illegal_op,
   2839 /*  0x5b */ x86emuOp2_illegal_op,
   2840 /*  0x5c */ x86emuOp2_illegal_op,
   2841 /*  0x5d */ x86emuOp2_illegal_op,
   2842 /*  0x5e */ x86emuOp2_illegal_op,
   2843 /*  0x5f */ x86emuOp2_illegal_op,
   2844 /*  0x60 */ x86emuOp2_illegal_op,
   2845 /*  0x61 */ x86emuOp2_illegal_op,
   2846 /*  0x62 */ x86emuOp2_illegal_op,
   2847 /*  0x63 */ x86emuOp2_illegal_op,
   2848 /*  0x64 */ x86emuOp2_illegal_op,
   2849 /*  0x65 */ x86emuOp2_illegal_op,
   2850 /*  0x66 */ x86emuOp2_illegal_op,
   2851 /*  0x67 */ x86emuOp2_illegal_op,
   2852 /*  0x68 */ x86emuOp2_illegal_op,
   2853 /*  0x69 */ x86emuOp2_illegal_op,
   2854 /*  0x6a */ x86emuOp2_illegal_op,
   2855 /*  0x6b */ x86emuOp2_illegal_op,
   2856 /*  0x6c */ x86emuOp2_illegal_op,
   2857 /*  0x6d */ x86emuOp2_illegal_op,
   2858 /*  0x6e */ x86emuOp2_illegal_op,
   2859 /*  0x6f */ x86emuOp2_illegal_op,
   2860 /*  0x70 */ x86emuOp2_illegal_op,
   2861 /*  0x71 */ x86emuOp2_illegal_op,
   2862 /*  0x72 */ x86emuOp2_illegal_op,
   2863 /*  0x73 */ x86emuOp2_illegal_op,
   2864 /*  0x74 */ x86emuOp2_illegal_op,
   2865 /*  0x75 */ x86emuOp2_illegal_op,
   2866 /*  0x76 */ x86emuOp2_illegal_op,
   2867 /*  0x77 */ x86emuOp2_illegal_op,
   2868 /*  0x78 */ x86emuOp2_illegal_op,
   2869 /*  0x79 */ x86emuOp2_illegal_op,
   2870 /*  0x7a */ x86emuOp2_illegal_op,
   2871 /*  0x7b */ x86emuOp2_illegal_op,
   2872 /*  0x7c */ x86emuOp2_illegal_op,
   2873 /*  0x7d */ x86emuOp2_illegal_op,
   2874 /*  0x7e */ x86emuOp2_illegal_op,
   2875 /*  0x7f */ x86emuOp2_illegal_op,
   2876 /*  0x80 */ x86emuOp2_long_jump,
   2877 /*  0x81 */ x86emuOp2_long_jump,
   2878 /*  0x82 */ x86emuOp2_long_jump,
   2879 /*  0x83 */ x86emuOp2_long_jump,
   2880 /*  0x84 */ x86emuOp2_long_jump,
   2881 /*  0x85 */ x86emuOp2_long_jump,
   2882 /*  0x86 */ x86emuOp2_long_jump,
   2883 /*  0x87 */ x86emuOp2_long_jump,
   2884 /*  0x88 */ x86emuOp2_long_jump,
   2885 /*  0x89 */ x86emuOp2_long_jump,
   2886 /*  0x8a */ x86emuOp2_long_jump,
   2887 /*  0x8b */ x86emuOp2_long_jump,
   2888 /*  0x8c */ x86emuOp2_long_jump,
   2889 /*  0x8d */ x86emuOp2_long_jump,
   2890 /*  0x8e */ x86emuOp2_long_jump,
   2891 /*  0x8f */ x86emuOp2_long_jump,
   2892 /*  0x90 */ x86emuOp2_set_byte,
   2893 /*  0x91 */ x86emuOp2_set_byte,
   2894 /*  0x92 */ x86emuOp2_set_byte,
   2895 /*  0x93 */ x86emuOp2_set_byte,
   2896 /*  0x94 */ x86emuOp2_set_byte,
   2897 /*  0x95 */ x86emuOp2_set_byte,
   2898 /*  0x96 */ x86emuOp2_set_byte,
   2899 /*  0x97 */ x86emuOp2_set_byte,
   2900 /*  0x98 */ x86emuOp2_set_byte,
   2901 /*  0x99 */ x86emuOp2_set_byte,
   2902 /*  0x9a */ x86emuOp2_set_byte,
   2903 /*  0x9b */ x86emuOp2_set_byte,
   2904 /*  0x9c */ x86emuOp2_set_byte,
   2905 /*  0x9d */ x86emuOp2_set_byte,
   2906 /*  0x9e */ x86emuOp2_set_byte,
   2907 /*  0x9f */ x86emuOp2_set_byte,
   2908 /*  0xa0 */ x86emuOp2_push_FS,
   2909 /*  0xa1 */ x86emuOp2_pop_FS,
   2910 /*  0xa2 */ x86emuOp2_cpuid,
   2911 /*  0xa3 */ x86emuOp2_bt_R,
   2912 /*  0xa4 */ x86emuOp2_shld_IMM,
   2913 /*  0xa5 */ x86emuOp2_shld_CL,
   2914 /*  0xa6 */ x86emuOp2_illegal_op,
   2915 /*  0xa7 */ x86emuOp2_illegal_op,
   2916 /*  0xa8 */ x86emuOp2_push_GS,
   2917 /*  0xa9 */ x86emuOp2_pop_GS,
   2918 /*  0xaa */ x86emuOp2_illegal_op,
   2919 /*  0xab */ x86emuOp2_bts_R,
   2920 /*  0xac */ x86emuOp2_shrd_IMM,
   2921 /*  0xad */ x86emuOp2_shrd_CL,
   2922 /*  0xae */ x86emuOp2_illegal_op,
   2923 /*  0xaf */ x86emuOp2_imul_R_RM,
   2924                                                 /*  0xb0 */ x86emuOp2_illegal_op,
   2925                                                 /* TODO: cmpxchg */
   2926                                                 /*  0xb1 */ x86emuOp2_illegal_op,
   2927                                                 /* TODO: cmpxchg */
   2928 /*  0xb2 */ x86emuOp2_lss_R_IMM,
   2929 /*  0xb3 */ x86emuOp2_btr_R,
   2930 /*  0xb4 */ x86emuOp2_lfs_R_IMM,
   2931 /*  0xb5 */ x86emuOp2_lgs_R_IMM,
   2932 /*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
   2933 /*  0xb7 */ x86emuOp2_movzx_word_R_RM,
   2934 /*  0xb8 */ x86emuOp2_illegal_op,
   2935 /*  0xb9 */ x86emuOp2_illegal_op,
   2936 /*  0xba */ x86emuOp2_btX_I,
   2937 /*  0xbb */ x86emuOp2_btc_R,
   2938 /*  0xbc */ x86emuOp2_bsf,
   2939 /*  0xbd */ x86emuOp2_bsr,
   2940 /*  0xbe */ x86emuOp2_movsx_byte_R_RM,
   2941 /*  0xbf */ x86emuOp2_movsx_word_R_RM,
   2942                                                 /*  0xc0 */ x86emuOp2_illegal_op,
   2943                                                 /* TODO: xadd */
   2944                                                 /*  0xc1 */ x86emuOp2_illegal_op,
   2945                                                 /* TODO: xadd */
   2946 /*  0xc2 */ x86emuOp2_illegal_op,
   2947 /*  0xc3 */ x86emuOp2_illegal_op,
   2948 /*  0xc4 */ x86emuOp2_illegal_op,
   2949 /*  0xc5 */ x86emuOp2_illegal_op,
   2950 /*  0xc6 */ x86emuOp2_illegal_op,
   2951 /*  0xc7 */ x86emuOp2_illegal_op,
   2952 /*  0xc8 */ x86emuOp2_bswap,
   2953 /*  0xc9 */ x86emuOp2_bswap,
   2954 /*  0xca */ x86emuOp2_bswap,
   2955 /*  0xcb */ x86emuOp2_bswap,
   2956 /*  0xcc */ x86emuOp2_bswap,
   2957 /*  0xcd */ x86emuOp2_bswap,
   2958 /*  0xce */ x86emuOp2_bswap,
   2959 /*  0xcf */ x86emuOp2_bswap,
   2960 /*  0xd0 */ x86emuOp2_illegal_op,
   2961 /*  0xd1 */ x86emuOp2_illegal_op,
   2962 /*  0xd2 */ x86emuOp2_illegal_op,
   2963 /*  0xd3 */ x86emuOp2_illegal_op,
   2964 /*  0xd4 */ x86emuOp2_illegal_op,
   2965 /*  0xd5 */ x86emuOp2_illegal_op,
   2966 /*  0xd6 */ x86emuOp2_illegal_op,
   2967 /*  0xd7 */ x86emuOp2_illegal_op,
   2968 /*  0xd8 */ x86emuOp2_illegal_op,
   2969 /*  0xd9 */ x86emuOp2_illegal_op,
   2970 /*  0xda */ x86emuOp2_illegal_op,
   2971 /*  0xdb */ x86emuOp2_illegal_op,
   2972 /*  0xdc */ x86emuOp2_illegal_op,
   2973 /*  0xdd */ x86emuOp2_illegal_op,
   2974 /*  0xde */ x86emuOp2_illegal_op,
   2975 /*  0xdf */ x86emuOp2_illegal_op,
   2976 /*  0xe0 */ x86emuOp2_illegal_op,
   2977 /*  0xe1 */ x86emuOp2_illegal_op,
   2978 /*  0xe2 */ x86emuOp2_illegal_op,
   2979 /*  0xe3 */ x86emuOp2_illegal_op,
   2980 /*  0xe4 */ x86emuOp2_illegal_op,
   2981 /*  0xe5 */ x86emuOp2_illegal_op,
   2982 /*  0xe6 */ x86emuOp2_illegal_op,
   2983 /*  0xe7 */ x86emuOp2_illegal_op,
   2984 /*  0xe8 */ x86emuOp2_illegal_op,
   2985 /*  0xe9 */ x86emuOp2_illegal_op,
   2986 /*  0xea */ x86emuOp2_illegal_op,
   2987 /*  0xeb */ x86emuOp2_illegal_op,
   2988 /*  0xec */ x86emuOp2_illegal_op,
   2989 /*  0xed */ x86emuOp2_illegal_op,
   2990 /*  0xee */ x86emuOp2_illegal_op,
   2991 /*  0xef */ x86emuOp2_illegal_op,
   2992 /*  0xf0 */ x86emuOp2_illegal_op,
   2993 /*  0xf1 */ x86emuOp2_illegal_op,
   2994 /*  0xf2 */ x86emuOp2_illegal_op,
   2995 /*  0xf3 */ x86emuOp2_illegal_op,
   2996 /*  0xf4 */ x86emuOp2_illegal_op,
   2997 /*  0xf5 */ x86emuOp2_illegal_op,
   2998 /*  0xf6 */ x86emuOp2_illegal_op,
   2999 /*  0xf7 */ x86emuOp2_illegal_op,
   3000 /*  0xf8 */ x86emuOp2_illegal_op,
   3001 /*  0xf9 */ x86emuOp2_illegal_op,
   3002 /*  0xfa */ x86emuOp2_illegal_op,
   3003 /*  0xfb */ x86emuOp2_illegal_op,
   3004 /*  0xfc */ x86emuOp2_illegal_op,
   3005 /*  0xfd */ x86emuOp2_illegal_op,
   3006 /*  0xfe */ x86emuOp2_illegal_op,
   3007 /*  0xff */ x86emuOp2_illegal_op,
   3008 };