105b261ecSmrg/****************************************************************************
205b261ecSmrg*
305b261ecSmrg*						Realmode X86 Emulator Library
405b261ecSmrg*
505b261ecSmrg*            	Copyright (C) 1996-1999 SciTech Software, Inc.
605b261ecSmrg* 				     Copyright (C) David Mosberger-Tang
705b261ecSmrg* 					   Copyright (C) 1999 Egbert Eich
805b261ecSmrg*
905b261ecSmrg*  ========================================================================
1005b261ecSmrg*
1105b261ecSmrg*  Permission to use, copy, modify, distribute, and sell this software and
1205b261ecSmrg*  its documentation for any purpose is hereby granted without fee,
1305b261ecSmrg*  provided that the above copyright notice appear in all copies and that
1405b261ecSmrg*  both that copyright notice and this permission notice appear in
1505b261ecSmrg*  supporting documentation, and that the name of the authors not be used
1605b261ecSmrg*  in advertising or publicity pertaining to distribution of the software
1705b261ecSmrg*  without specific, written prior permission.  The authors makes no
1805b261ecSmrg*  representations about the suitability of this software for any purpose.
1905b261ecSmrg*  It is provided "as is" without express or implied warranty.
2005b261ecSmrg*
2105b261ecSmrg*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2205b261ecSmrg*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
2305b261ecSmrg*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
2405b261ecSmrg*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
2505b261ecSmrg*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2605b261ecSmrg*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2705b261ecSmrg*  PERFORMANCE OF THIS SOFTWARE.
2805b261ecSmrg*
2905b261ecSmrg*  ========================================================================
3005b261ecSmrg*
3105b261ecSmrg* Language:		ANSI C
3205b261ecSmrg* Environment:	Any
3305b261ecSmrg* Developer:    Kendall Bennett
3405b261ecSmrg*
3505b261ecSmrg* Description:  This file includes subroutines to implement the decoding
3605b261ecSmrg*               and emulation of all the x86 extended two-byte processor
3705b261ecSmrg*               instructions.
3805b261ecSmrg*
3905b261ecSmrg****************************************************************************/
4005b261ecSmrg
4105b261ecSmrg#include "x86emu/x86emui.h"
4205b261ecSmrg
434642e01fSmrg#undef bswap_32
444642e01fSmrg#define bswap_32(x) (((x & 0xff000000) >> 24) | \
454642e01fSmrg		     ((x & 0x00ff0000) >> 8) | \
464642e01fSmrg		     ((x & 0x0000ff00) << 8) | \
474642e01fSmrg		     ((x & 0x000000ff) << 24))
484642e01fSmrg
4905b261ecSmrg/*----------------------------- Implementation ----------------------------*/
5005b261ecSmrg
5105b261ecSmrg/****************************************************************************
5205b261ecSmrgPARAMETERS:
5305b261ecSmrgop1 - Instruction op code
5405b261ecSmrg
5505b261ecSmrgREMARKS:
5605b261ecSmrgHandles illegal opcodes.
5705b261ecSmrg****************************************************************************/
5835c4bbdfSmrgstatic void
5935c4bbdfSmrgx86emuOp2_illegal_op(u8 op2)
6005b261ecSmrg{
6135c4bbdfSmrg    START_OF_INSTR();
6235c4bbdfSmrg    DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
6335c4bbdfSmrg    TRACE_REGS();
6435c4bbdfSmrg    printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
6535c4bbdfSmrg           M.x86.R_CS, M.x86.R_IP - 2, op2);
6605b261ecSmrg    HALT_SYS();
6705b261ecSmrg    END_OF_INSTR();
6805b261ecSmrg}
6905b261ecSmrg
7005b261ecSmrg#define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
7105b261ecSmrg
7205b261ecSmrg/****************************************************************************
7305b261ecSmrgREMARKS:
7405b261ecSmrgHandles opcode 0x0f,0x31
7505b261ecSmrg****************************************************************************/
7635c4bbdfSmrgstatic void
7735c4bbdfSmrgx86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
7805b261ecSmrg{
7905b261ecSmrg#ifdef __HAS_LONG_LONG__
8005b261ecSmrg    static u64 counter = 0;
8105b261ecSmrg#else
8205b261ecSmrg    static u32 counter = 0;
8305b261ecSmrg#endif
8405b261ecSmrg
8505b261ecSmrg    counter += 0x10000;
8605b261ecSmrg
8705b261ecSmrg    /* read timestamp counter */
8805b261ecSmrg    /*
8905b261ecSmrg     * Note that instead of actually trying to accurately measure this, we just
9005b261ecSmrg     * increase the counter by a fixed amount every time we hit one of these
9105b261ecSmrg     * instructions.  Feel free to come up with a better method.
9205b261ecSmrg     */
9305b261ecSmrg    START_OF_INSTR();
9405b261ecSmrg    DECODE_PRINTF("RDTSC\n");
9505b261ecSmrg    TRACE_AND_STEP();
9605b261ecSmrg#ifdef __HAS_LONG_LONG__
9705b261ecSmrg    M.x86.R_EAX = counter & 0xffffffff;
9805b261ecSmrg    M.x86.R_EDX = counter >> 32;
9905b261ecSmrg#else
10005b261ecSmrg    M.x86.R_EAX = counter;
10105b261ecSmrg    M.x86.R_EDX = 0;
10205b261ecSmrg#endif
10305b261ecSmrg    DECODE_CLEAR_SEGOVR();
10405b261ecSmrg    END_OF_INSTR();
10505b261ecSmrg}
10605b261ecSmrg
10705b261ecSmrg/****************************************************************************
10805b261ecSmrgREMARKS:
10905b261ecSmrgHandles opcode 0x0f,0x80-0x8F
11005b261ecSmrg****************************************************************************/
11135c4bbdfSmrgstatic void
11235c4bbdfSmrgx86emuOp2_long_jump(u8 op2)
11305b261ecSmrg{
11405b261ecSmrg    s32 target;
11535c4bbdfSmrg    const char *name = NULL;
11605b261ecSmrg    int cond = 0;
11705b261ecSmrg
11805b261ecSmrg    /* conditional jump to word offset. */
11905b261ecSmrg    START_OF_INSTR();
12005b261ecSmrg    switch (op2) {
12135c4bbdfSmrg    case 0x80:
12205b261ecSmrg        name = "JO\t";
12335c4bbdfSmrg        cond = ACCESS_FLAG(F_OF);
12405b261ecSmrg        break;
12535c4bbdfSmrg    case 0x81:
12605b261ecSmrg        name = "JNO\t";
12705b261ecSmrg        cond = !ACCESS_FLAG(F_OF);
12805b261ecSmrg        break;
12935c4bbdfSmrg    case 0x82:
13005b261ecSmrg        name = "JB\t";
13105b261ecSmrg        cond = ACCESS_FLAG(F_CF);
13205b261ecSmrg        break;
13335c4bbdfSmrg    case 0x83:
13405b261ecSmrg        name = "JNB\t";
13505b261ecSmrg        cond = !ACCESS_FLAG(F_CF);
13605b261ecSmrg        break;
13735c4bbdfSmrg    case 0x84:
13805b261ecSmrg        name = "JZ\t";
13905b261ecSmrg        cond = ACCESS_FLAG(F_ZF);
14005b261ecSmrg        break;
14135c4bbdfSmrg    case 0x85:
14205b261ecSmrg        name = "JNZ\t";
14305b261ecSmrg        cond = !ACCESS_FLAG(F_ZF);
14405b261ecSmrg        break;
14535c4bbdfSmrg    case 0x86:
14605b261ecSmrg        name = "JBE\t";
14705b261ecSmrg        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
14805b261ecSmrg        break;
14935c4bbdfSmrg    case 0x87:
15005b261ecSmrg        name = "JNBE\t";
15105b261ecSmrg        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
15205b261ecSmrg        break;
15335c4bbdfSmrg    case 0x88:
15405b261ecSmrg        name = "JS\t";
15505b261ecSmrg        cond = ACCESS_FLAG(F_SF);
15605b261ecSmrg        break;
15735c4bbdfSmrg    case 0x89:
15805b261ecSmrg        name = "JNS\t";
15905b261ecSmrg        cond = !ACCESS_FLAG(F_SF);
16005b261ecSmrg        break;
16135c4bbdfSmrg    case 0x8a:
16205b261ecSmrg        name = "JP\t";
16305b261ecSmrg        cond = ACCESS_FLAG(F_PF);
16405b261ecSmrg        break;
16535c4bbdfSmrg    case 0x8b:
16605b261ecSmrg        name = "JNP\t";
16705b261ecSmrg        cond = !ACCESS_FLAG(F_PF);
16805b261ecSmrg        break;
16935c4bbdfSmrg    case 0x8c:
17005b261ecSmrg        name = "JL\t";
17105b261ecSmrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
17205b261ecSmrg        break;
17335c4bbdfSmrg    case 0x8d:
17405b261ecSmrg        name = "JNL\t";
17505b261ecSmrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
17605b261ecSmrg        break;
17735c4bbdfSmrg    case 0x8e:
17805b261ecSmrg        name = "JLE\t";
17905b261ecSmrg        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
18005b261ecSmrg                ACCESS_FLAG(F_ZF));
18105b261ecSmrg        break;
18235c4bbdfSmrg    case 0x8f:
18305b261ecSmrg        name = "JNLE\t";
18405b261ecSmrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
18505b261ecSmrg                 ACCESS_FLAG(F_ZF));
18605b261ecSmrg        break;
18705b261ecSmrg    }
18805b261ecSmrg    DECODE_PRINTF(name);
18935c4bbdfSmrg    (void) name;
19005b261ecSmrg    target = (s16) fetch_word_imm();
19105b261ecSmrg    target += (s16) M.x86.R_IP;
19205b261ecSmrg    DECODE_PRINTF2("%04x\n", target);
19305b261ecSmrg    TRACE_AND_STEP();
19405b261ecSmrg    if (cond)
19535c4bbdfSmrg        M.x86.R_IP = (u16) target;
19605b261ecSmrg    DECODE_CLEAR_SEGOVR();
19705b261ecSmrg    END_OF_INSTR();
19805b261ecSmrg}
19905b261ecSmrg
20005b261ecSmrg/****************************************************************************
20105b261ecSmrgREMARKS:
20205b261ecSmrgHandles opcode 0x0f,0x90-0x9F
20305b261ecSmrg****************************************************************************/
20435c4bbdfSmrgstatic void
20535c4bbdfSmrgx86emuOp2_set_byte(u8 op2)
20605b261ecSmrg{
20705b261ecSmrg    int mod, rl, rh;
20805b261ecSmrg    uint destoffset;
20935c4bbdfSmrg    u8 *destreg;
21035c4bbdfSmrg    const char *name = NULL;
21105b261ecSmrg    int cond = 0;
21205b261ecSmrg
21305b261ecSmrg    START_OF_INSTR();
21405b261ecSmrg    switch (op2) {
21535c4bbdfSmrg    case 0x90:
21605b261ecSmrg        name = "SETO\t";
21735c4bbdfSmrg        cond = ACCESS_FLAG(F_OF);
21805b261ecSmrg        break;
21935c4bbdfSmrg    case 0x91:
22005b261ecSmrg        name = "SETNO\t";
22105b261ecSmrg        cond = !ACCESS_FLAG(F_OF);
22205b261ecSmrg        break;
22335c4bbdfSmrg    case 0x92:
22405b261ecSmrg        name = "SETB\t";
22505b261ecSmrg        cond = ACCESS_FLAG(F_CF);
22605b261ecSmrg        break;
22735c4bbdfSmrg    case 0x93:
22805b261ecSmrg        name = "SETNB\t";
22905b261ecSmrg        cond = !ACCESS_FLAG(F_CF);
23005b261ecSmrg        break;
23135c4bbdfSmrg    case 0x94:
23205b261ecSmrg        name = "SETZ\t";
23305b261ecSmrg        cond = ACCESS_FLAG(F_ZF);
23405b261ecSmrg        break;
23535c4bbdfSmrg    case 0x95:
23605b261ecSmrg        name = "SETNZ\t";
23705b261ecSmrg        cond = !ACCESS_FLAG(F_ZF);
23805b261ecSmrg        break;
23935c4bbdfSmrg    case 0x96:
24005b261ecSmrg        name = "SETBE\t";
24105b261ecSmrg        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
24205b261ecSmrg        break;
24335c4bbdfSmrg    case 0x97:
24405b261ecSmrg        name = "SETNBE\t";
24505b261ecSmrg        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
24605b261ecSmrg        break;
24735c4bbdfSmrg    case 0x98:
24805b261ecSmrg        name = "SETS\t";
24905b261ecSmrg        cond = ACCESS_FLAG(F_SF);
25005b261ecSmrg        break;
25135c4bbdfSmrg    case 0x99:
25205b261ecSmrg        name = "SETNS\t";
25305b261ecSmrg        cond = !ACCESS_FLAG(F_SF);
25405b261ecSmrg        break;
25535c4bbdfSmrg    case 0x9a:
25605b261ecSmrg        name = "SETP\t";
25705b261ecSmrg        cond = ACCESS_FLAG(F_PF);
25805b261ecSmrg        break;
25935c4bbdfSmrg    case 0x9b:
26005b261ecSmrg        name = "SETNP\t";
26105b261ecSmrg        cond = !ACCESS_FLAG(F_PF);
26205b261ecSmrg        break;
26335c4bbdfSmrg    case 0x9c:
26405b261ecSmrg        name = "SETL\t";
26505b261ecSmrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
26605b261ecSmrg        break;
26735c4bbdfSmrg    case 0x9d:
26805b261ecSmrg        name = "SETNL\t";
26905b261ecSmrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
27005b261ecSmrg        break;
27135c4bbdfSmrg    case 0x9e:
27205b261ecSmrg        name = "SETLE\t";
27305b261ecSmrg        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
27405b261ecSmrg                ACCESS_FLAG(F_ZF));
27505b261ecSmrg        break;
27635c4bbdfSmrg    case 0x9f:
27705b261ecSmrg        name = "SETNLE\t";
27805b261ecSmrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
27905b261ecSmrg                 ACCESS_FLAG(F_ZF));
28005b261ecSmrg        break;
28105b261ecSmrg    }
28205b261ecSmrg    DECODE_PRINTF(name);
28335c4bbdfSmrg    (void) name;
28405b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
28505b261ecSmrg    switch (mod) {
28605b261ecSmrg    case 0:
28705b261ecSmrg        destoffset = decode_rm00_address(rl);
28805b261ecSmrg        TRACE_AND_STEP();
28905b261ecSmrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
29005b261ecSmrg        break;
29105b261ecSmrg    case 1:
29205b261ecSmrg        destoffset = decode_rm01_address(rl);
29305b261ecSmrg        TRACE_AND_STEP();
29405b261ecSmrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
29505b261ecSmrg        break;
29605b261ecSmrg    case 2:
29705b261ecSmrg        destoffset = decode_rm10_address(rl);
29805b261ecSmrg        TRACE_AND_STEP();
29905b261ecSmrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
30005b261ecSmrg        break;
30135c4bbdfSmrg    case 3:                    /* register to register */
30205b261ecSmrg        destreg = DECODE_RM_BYTE_REGISTER(rl);
30305b261ecSmrg        TRACE_AND_STEP();
30405b261ecSmrg        *destreg = cond ? 0x01 : 0x00;
30505b261ecSmrg        break;
30605b261ecSmrg    }
30705b261ecSmrg    DECODE_CLEAR_SEGOVR();
30805b261ecSmrg    END_OF_INSTR();
30905b261ecSmrg}
31005b261ecSmrg
31105b261ecSmrg/****************************************************************************
31205b261ecSmrgREMARKS:
31305b261ecSmrgHandles opcode 0x0f,0xa0
31405b261ecSmrg****************************************************************************/
31535c4bbdfSmrgstatic void
31635c4bbdfSmrgx86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
31705b261ecSmrg{
31805b261ecSmrg    START_OF_INSTR();
31905b261ecSmrg    DECODE_PRINTF("PUSH\tFS\n");
32005b261ecSmrg    TRACE_AND_STEP();
32105b261ecSmrg    push_word(M.x86.R_FS);
32205b261ecSmrg    DECODE_CLEAR_SEGOVR();
32305b261ecSmrg    END_OF_INSTR();
32405b261ecSmrg}
32505b261ecSmrg
32605b261ecSmrg/****************************************************************************
32705b261ecSmrgREMARKS:
32805b261ecSmrgHandles opcode 0x0f,0xa1
32905b261ecSmrg****************************************************************************/
33035c4bbdfSmrgstatic void
33135c4bbdfSmrgx86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
33205b261ecSmrg{
33305b261ecSmrg    START_OF_INSTR();
33405b261ecSmrg    DECODE_PRINTF("POP\tFS\n");
33505b261ecSmrg    TRACE_AND_STEP();
33605b261ecSmrg    M.x86.R_FS = pop_word();
33705b261ecSmrg    DECODE_CLEAR_SEGOVR();
33805b261ecSmrg    END_OF_INSTR();
33905b261ecSmrg}
34005b261ecSmrg
3414642e01fSmrg/****************************************************************************
3424642e01fSmrgREMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
3434642e01fSmrgHandles opcode 0x0f,0xa2
3444642e01fSmrg****************************************************************************/
34535c4bbdfSmrgstatic void
34635c4bbdfSmrgx86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
3474642e01fSmrg{
3484642e01fSmrg    START_OF_INSTR();
3494642e01fSmrg    DECODE_PRINTF("CPUID\n");
3504642e01fSmrg    TRACE_AND_STEP();
3514642e01fSmrg    cpuid();
3524642e01fSmrg    DECODE_CLEAR_SEGOVR();
3534642e01fSmrg    END_OF_INSTR();
3544642e01fSmrg}
3554642e01fSmrg
35605b261ecSmrg/****************************************************************************
35705b261ecSmrgREMARKS:
35805b261ecSmrgHandles opcode 0x0f,0xa3
35905b261ecSmrg****************************************************************************/
36035c4bbdfSmrgstatic void
36135c4bbdfSmrgx86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
36205b261ecSmrg{
36305b261ecSmrg    int mod, rl, rh;
36405b261ecSmrg    uint srcoffset;
36535c4bbdfSmrg    int bit, disp;
36605b261ecSmrg
36705b261ecSmrg    START_OF_INSTR();
36805b261ecSmrg    DECODE_PRINTF("BT\t");
36905b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
37005b261ecSmrg    switch (mod) {
37105b261ecSmrg    case 0:
37205b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
37305b261ecSmrg            u32 srcval;
37405b261ecSmrg            u32 *shiftreg;
37505b261ecSmrg
37605b261ecSmrg            srcoffset = decode_rm00_address(rl);
37705b261ecSmrg            DECODE_PRINTF(",");
37805b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
37905b261ecSmrg            TRACE_AND_STEP();
38005b261ecSmrg            bit = *shiftreg & 0x1F;
38135c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
38235c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
38335c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
38435c4bbdfSmrg        }
38535c4bbdfSmrg        else {
38605b261ecSmrg            u16 srcval;
38705b261ecSmrg            u16 *shiftreg;
38805b261ecSmrg
38905b261ecSmrg            srcoffset = decode_rm00_address(rl);
39005b261ecSmrg            DECODE_PRINTF(",");
39105b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
39205b261ecSmrg            TRACE_AND_STEP();
39305b261ecSmrg            bit = *shiftreg & 0xF;
39435c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
39535c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
39635c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
39705b261ecSmrg        }
39805b261ecSmrg        break;
39905b261ecSmrg    case 1:
40005b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
40105b261ecSmrg            u32 srcval;
40205b261ecSmrg            u32 *shiftreg;
40305b261ecSmrg
40405b261ecSmrg            srcoffset = decode_rm01_address(rl);
40505b261ecSmrg            DECODE_PRINTF(",");
40605b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
40705b261ecSmrg            TRACE_AND_STEP();
40805b261ecSmrg            bit = *shiftreg & 0x1F;
40935c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
41035c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
41135c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
41235c4bbdfSmrg        }
41335c4bbdfSmrg        else {
41405b261ecSmrg            u16 srcval;
41505b261ecSmrg            u16 *shiftreg;
41605b261ecSmrg
41705b261ecSmrg            srcoffset = decode_rm01_address(rl);
41805b261ecSmrg            DECODE_PRINTF(",");
41905b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
42005b261ecSmrg            TRACE_AND_STEP();
42105b261ecSmrg            bit = *shiftreg & 0xF;
42235c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
42335c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
42435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
42505b261ecSmrg        }
42605b261ecSmrg        break;
42705b261ecSmrg    case 2:
42805b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
42905b261ecSmrg            u32 srcval;
43005b261ecSmrg            u32 *shiftreg;
43105b261ecSmrg
43205b261ecSmrg            srcoffset = decode_rm10_address(rl);
43305b261ecSmrg            DECODE_PRINTF(",");
43405b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
43505b261ecSmrg            TRACE_AND_STEP();
43605b261ecSmrg            bit = *shiftreg & 0x1F;
43735c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
43835c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
43935c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
44035c4bbdfSmrg        }
44135c4bbdfSmrg        else {
44205b261ecSmrg            u16 srcval;
44305b261ecSmrg            u16 *shiftreg;
44405b261ecSmrg
44505b261ecSmrg            srcoffset = decode_rm10_address(rl);
44605b261ecSmrg            DECODE_PRINTF(",");
44705b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
44805b261ecSmrg            TRACE_AND_STEP();
44905b261ecSmrg            bit = *shiftreg & 0xF;
45035c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
45135c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
45235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
45305b261ecSmrg        }
45405b261ecSmrg        break;
45535c4bbdfSmrg    case 3:                    /* register to register */
45605b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
45735c4bbdfSmrg            u32 *srcreg, *shiftreg;
45805b261ecSmrg
45905b261ecSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
46005b261ecSmrg            DECODE_PRINTF(",");
46105b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
46205b261ecSmrg            TRACE_AND_STEP();
46305b261ecSmrg            bit = *shiftreg & 0x1F;
46435c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
46535c4bbdfSmrg        }
46635c4bbdfSmrg        else {
46735c4bbdfSmrg            u16 *srcreg, *shiftreg;
46805b261ecSmrg
46905b261ecSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
47005b261ecSmrg            DECODE_PRINTF(",");
47105b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
47205b261ecSmrg            TRACE_AND_STEP();
47305b261ecSmrg            bit = *shiftreg & 0xF;
47435c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
47505b261ecSmrg        }
47605b261ecSmrg        break;
47705b261ecSmrg    }
47805b261ecSmrg    DECODE_CLEAR_SEGOVR();
47905b261ecSmrg    END_OF_INSTR();
48005b261ecSmrg}
48105b261ecSmrg
48205b261ecSmrg/****************************************************************************
48305b261ecSmrgREMARKS:
48405b261ecSmrgHandles opcode 0x0f,0xa4
48505b261ecSmrg****************************************************************************/
48635c4bbdfSmrgstatic void
48735c4bbdfSmrgx86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
48805b261ecSmrg{
48905b261ecSmrg    int mod, rl, rh;
49005b261ecSmrg    uint destoffset;
49135c4bbdfSmrg    u8 shift;
49205b261ecSmrg
49305b261ecSmrg    START_OF_INSTR();
49405b261ecSmrg    DECODE_PRINTF("SHLD\t");
49505b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
49605b261ecSmrg    switch (mod) {
49705b261ecSmrg    case 0:
49805b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
49905b261ecSmrg            u32 destval;
50005b261ecSmrg            u32 *shiftreg;
50105b261ecSmrg
50205b261ecSmrg            destoffset = decode_rm00_address(rl);
50305b261ecSmrg            DECODE_PRINTF(",");
50405b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
50505b261ecSmrg            DECODE_PRINTF(",");
50605b261ecSmrg            shift = fetch_byte_imm();
50705b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
50805b261ecSmrg            TRACE_AND_STEP();
50905b261ecSmrg            destval = fetch_data_long(destoffset);
51035c4bbdfSmrg            destval = shld_long(destval, *shiftreg, shift);
51105b261ecSmrg            store_data_long(destoffset, destval);
51235c4bbdfSmrg        }
51335c4bbdfSmrg        else {
51405b261ecSmrg            u16 destval;
51505b261ecSmrg            u16 *shiftreg;
51605b261ecSmrg
51705b261ecSmrg            destoffset = decode_rm00_address(rl);
51805b261ecSmrg            DECODE_PRINTF(",");
51905b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
52005b261ecSmrg            DECODE_PRINTF(",");
52105b261ecSmrg            shift = fetch_byte_imm();
52205b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
52305b261ecSmrg            TRACE_AND_STEP();
52405b261ecSmrg            destval = fetch_data_word(destoffset);
52535c4bbdfSmrg            destval = shld_word(destval, *shiftreg, shift);
52605b261ecSmrg            store_data_word(destoffset, destval);
52705b261ecSmrg        }
52805b261ecSmrg        break;
52905b261ecSmrg    case 1:
53005b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
53105b261ecSmrg            u32 destval;
53205b261ecSmrg            u32 *shiftreg;
53305b261ecSmrg
53405b261ecSmrg            destoffset = decode_rm01_address(rl);
53505b261ecSmrg            DECODE_PRINTF(",");
53605b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
53705b261ecSmrg            DECODE_PRINTF(",");
53805b261ecSmrg            shift = fetch_byte_imm();
53905b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
54005b261ecSmrg            TRACE_AND_STEP();
54105b261ecSmrg            destval = fetch_data_long(destoffset);
54235c4bbdfSmrg            destval = shld_long(destval, *shiftreg, shift);
54305b261ecSmrg            store_data_long(destoffset, destval);
54435c4bbdfSmrg        }
54535c4bbdfSmrg        else {
54605b261ecSmrg            u16 destval;
54705b261ecSmrg            u16 *shiftreg;
54805b261ecSmrg
54905b261ecSmrg            destoffset = decode_rm01_address(rl);
55005b261ecSmrg            DECODE_PRINTF(",");
55105b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
55205b261ecSmrg            DECODE_PRINTF(",");
55305b261ecSmrg            shift = fetch_byte_imm();
55405b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
55505b261ecSmrg            TRACE_AND_STEP();
55605b261ecSmrg            destval = fetch_data_word(destoffset);
55735c4bbdfSmrg            destval = shld_word(destval, *shiftreg, shift);
55805b261ecSmrg            store_data_word(destoffset, destval);
55905b261ecSmrg        }
56005b261ecSmrg        break;
56105b261ecSmrg    case 2:
56205b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
56305b261ecSmrg            u32 destval;
56405b261ecSmrg            u32 *shiftreg;
56505b261ecSmrg
56605b261ecSmrg            destoffset = decode_rm10_address(rl);
56705b261ecSmrg            DECODE_PRINTF(",");
56805b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
56905b261ecSmrg            DECODE_PRINTF(",");
57005b261ecSmrg            shift = fetch_byte_imm();
57105b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
57205b261ecSmrg            TRACE_AND_STEP();
57305b261ecSmrg            destval = fetch_data_long(destoffset);
57435c4bbdfSmrg            destval = shld_long(destval, *shiftreg, shift);
57505b261ecSmrg            store_data_long(destoffset, destval);
57635c4bbdfSmrg        }
57735c4bbdfSmrg        else {
57805b261ecSmrg            u16 destval;
57905b261ecSmrg            u16 *shiftreg;
58005b261ecSmrg
58105b261ecSmrg            destoffset = decode_rm10_address(rl);
58205b261ecSmrg            DECODE_PRINTF(",");
58305b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
58405b261ecSmrg            DECODE_PRINTF(",");
58505b261ecSmrg            shift = fetch_byte_imm();
58605b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
58705b261ecSmrg            TRACE_AND_STEP();
58805b261ecSmrg            destval = fetch_data_word(destoffset);
58935c4bbdfSmrg            destval = shld_word(destval, *shiftreg, shift);
59005b261ecSmrg            store_data_word(destoffset, destval);
59105b261ecSmrg        }
59205b261ecSmrg        break;
59335c4bbdfSmrg    case 3:                    /* register to register */
59405b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
59535c4bbdfSmrg            u32 *destreg, *shiftreg;
59605b261ecSmrg
59705b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rl);
59805b261ecSmrg            DECODE_PRINTF(",");
59905b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
60005b261ecSmrg            DECODE_PRINTF(",");
60105b261ecSmrg            shift = fetch_byte_imm();
60205b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
60305b261ecSmrg            TRACE_AND_STEP();
60435c4bbdfSmrg            *destreg = shld_long(*destreg, *shiftreg, shift);
60535c4bbdfSmrg        }
60635c4bbdfSmrg        else {
60735c4bbdfSmrg            u16 *destreg, *shiftreg;
60805b261ecSmrg
60905b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rl);
61005b261ecSmrg            DECODE_PRINTF(",");
61105b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
61205b261ecSmrg            DECODE_PRINTF(",");
61305b261ecSmrg            shift = fetch_byte_imm();
61405b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
61505b261ecSmrg            TRACE_AND_STEP();
61635c4bbdfSmrg            *destreg = shld_word(*destreg, *shiftreg, shift);
61705b261ecSmrg        }
61805b261ecSmrg        break;
61905b261ecSmrg    }
62005b261ecSmrg    DECODE_CLEAR_SEGOVR();
62105b261ecSmrg    END_OF_INSTR();
62205b261ecSmrg}
62305b261ecSmrg
62405b261ecSmrg/****************************************************************************
62505b261ecSmrgREMARKS:
62605b261ecSmrgHandles opcode 0x0f,0xa5
62705b261ecSmrg****************************************************************************/
62835c4bbdfSmrgstatic void
62935c4bbdfSmrgx86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
63005b261ecSmrg{
63105b261ecSmrg    int mod, rl, rh;
63205b261ecSmrg    uint destoffset;
63305b261ecSmrg
63405b261ecSmrg    START_OF_INSTR();
63505b261ecSmrg    DECODE_PRINTF("SHLD\t");
63605b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
63705b261ecSmrg    switch (mod) {
63805b261ecSmrg    case 0:
63905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
64005b261ecSmrg            u32 destval;
64105b261ecSmrg            u32 *shiftreg;
64205b261ecSmrg
64305b261ecSmrg            destoffset = decode_rm00_address(rl);
64405b261ecSmrg            DECODE_PRINTF(",");
64505b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
64605b261ecSmrg            DECODE_PRINTF(",CL\n");
64705b261ecSmrg            TRACE_AND_STEP();
64805b261ecSmrg            destval = fetch_data_long(destoffset);
64935c4bbdfSmrg            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
65005b261ecSmrg            store_data_long(destoffset, destval);
65135c4bbdfSmrg        }
65235c4bbdfSmrg        else {
65305b261ecSmrg            u16 destval;
65405b261ecSmrg            u16 *shiftreg;
65505b261ecSmrg
65605b261ecSmrg            destoffset = decode_rm00_address(rl);
65705b261ecSmrg            DECODE_PRINTF(",");
65805b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
65905b261ecSmrg            DECODE_PRINTF(",CL\n");
66005b261ecSmrg            TRACE_AND_STEP();
66105b261ecSmrg            destval = fetch_data_word(destoffset);
66235c4bbdfSmrg            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
66305b261ecSmrg            store_data_word(destoffset, destval);
66405b261ecSmrg        }
66505b261ecSmrg        break;
66605b261ecSmrg    case 1:
66705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
66805b261ecSmrg            u32 destval;
66905b261ecSmrg            u32 *shiftreg;
67005b261ecSmrg
67105b261ecSmrg            destoffset = decode_rm01_address(rl);
67205b261ecSmrg            DECODE_PRINTF(",");
67305b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
67405b261ecSmrg            DECODE_PRINTF(",CL\n");
67505b261ecSmrg            TRACE_AND_STEP();
67605b261ecSmrg            destval = fetch_data_long(destoffset);
67735c4bbdfSmrg            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
67805b261ecSmrg            store_data_long(destoffset, destval);
67935c4bbdfSmrg        }
68035c4bbdfSmrg        else {
68105b261ecSmrg            u16 destval;
68205b261ecSmrg            u16 *shiftreg;
68305b261ecSmrg
68405b261ecSmrg            destoffset = decode_rm01_address(rl);
68505b261ecSmrg            DECODE_PRINTF(",");
68605b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
68705b261ecSmrg            DECODE_PRINTF(",CL\n");
68805b261ecSmrg            TRACE_AND_STEP();
68905b261ecSmrg            destval = fetch_data_word(destoffset);
69035c4bbdfSmrg            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
69105b261ecSmrg            store_data_word(destoffset, destval);
69205b261ecSmrg        }
69305b261ecSmrg        break;
69405b261ecSmrg    case 2:
69505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
69605b261ecSmrg            u32 destval;
69705b261ecSmrg            u32 *shiftreg;
69805b261ecSmrg
69905b261ecSmrg            destoffset = decode_rm10_address(rl);
70005b261ecSmrg            DECODE_PRINTF(",");
70105b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
70205b261ecSmrg            DECODE_PRINTF(",CL\n");
70305b261ecSmrg            TRACE_AND_STEP();
70405b261ecSmrg            destval = fetch_data_long(destoffset);
70535c4bbdfSmrg            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
70605b261ecSmrg            store_data_long(destoffset, destval);
70735c4bbdfSmrg        }
70835c4bbdfSmrg        else {
70905b261ecSmrg            u16 destval;
71005b261ecSmrg            u16 *shiftreg;
71105b261ecSmrg
71205b261ecSmrg            destoffset = decode_rm10_address(rl);
71305b261ecSmrg            DECODE_PRINTF(",");
71405b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
71505b261ecSmrg            DECODE_PRINTF(",CL\n");
71605b261ecSmrg            TRACE_AND_STEP();
71705b261ecSmrg            destval = fetch_data_word(destoffset);
71835c4bbdfSmrg            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
71905b261ecSmrg            store_data_word(destoffset, destval);
72005b261ecSmrg        }
72105b261ecSmrg        break;
72235c4bbdfSmrg    case 3:                    /* register to register */
72305b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
72435c4bbdfSmrg            u32 *destreg, *shiftreg;
72505b261ecSmrg
72605b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rl);
72705b261ecSmrg            DECODE_PRINTF(",");
72805b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
72905b261ecSmrg            DECODE_PRINTF(",CL\n");
73005b261ecSmrg            TRACE_AND_STEP();
73135c4bbdfSmrg            *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL);
73235c4bbdfSmrg        }
73335c4bbdfSmrg        else {
73435c4bbdfSmrg            u16 *destreg, *shiftreg;
73505b261ecSmrg
73605b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rl);
73705b261ecSmrg            DECODE_PRINTF(",");
73805b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
73905b261ecSmrg            DECODE_PRINTF(",CL\n");
74005b261ecSmrg            TRACE_AND_STEP();
74135c4bbdfSmrg            *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL);
74205b261ecSmrg        }
74305b261ecSmrg        break;
74405b261ecSmrg    }
74505b261ecSmrg    DECODE_CLEAR_SEGOVR();
74605b261ecSmrg    END_OF_INSTR();
74705b261ecSmrg}
74805b261ecSmrg
74905b261ecSmrg/****************************************************************************
75005b261ecSmrgREMARKS:
75105b261ecSmrgHandles opcode 0x0f,0xa8
75205b261ecSmrg****************************************************************************/
75335c4bbdfSmrgstatic void
75435c4bbdfSmrgx86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
75505b261ecSmrg{
75605b261ecSmrg    START_OF_INSTR();
75705b261ecSmrg    DECODE_PRINTF("PUSH\tGS\n");
75805b261ecSmrg    TRACE_AND_STEP();
75905b261ecSmrg    push_word(M.x86.R_GS);
76005b261ecSmrg    DECODE_CLEAR_SEGOVR();
76105b261ecSmrg    END_OF_INSTR();
76205b261ecSmrg}
76305b261ecSmrg
76405b261ecSmrg/****************************************************************************
76505b261ecSmrgREMARKS:
76605b261ecSmrgHandles opcode 0x0f,0xa9
76705b261ecSmrg****************************************************************************/
76835c4bbdfSmrgstatic void
76935c4bbdfSmrgx86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
77005b261ecSmrg{
77105b261ecSmrg    START_OF_INSTR();
77205b261ecSmrg    DECODE_PRINTF("POP\tGS\n");
77305b261ecSmrg    TRACE_AND_STEP();
77405b261ecSmrg    M.x86.R_GS = pop_word();
77505b261ecSmrg    DECODE_CLEAR_SEGOVR();
77605b261ecSmrg    END_OF_INSTR();
77705b261ecSmrg}
77805b261ecSmrg
77905b261ecSmrg/****************************************************************************
78005b261ecSmrgREMARKS:
78105b261ecSmrgHandles opcode 0x0f,0xab
78205b261ecSmrg****************************************************************************/
78335c4bbdfSmrgstatic void
78435c4bbdfSmrgx86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
78505b261ecSmrg{
78605b261ecSmrg    int mod, rl, rh;
78705b261ecSmrg    uint srcoffset;
78835c4bbdfSmrg    int bit, disp;
78905b261ecSmrg
79005b261ecSmrg    START_OF_INSTR();
79105b261ecSmrg    DECODE_PRINTF("BTS\t");
79205b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
79305b261ecSmrg    switch (mod) {
79405b261ecSmrg    case 0:
79505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
79635c4bbdfSmrg            u32 srcval, mask;
79705b261ecSmrg            u32 *shiftreg;
79805b261ecSmrg
79905b261ecSmrg            srcoffset = decode_rm00_address(rl);
80005b261ecSmrg            DECODE_PRINTF(",");
80105b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
80205b261ecSmrg            TRACE_AND_STEP();
80305b261ecSmrg            bit = *shiftreg & 0x1F;
80435c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
80535c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
80605b261ecSmrg            mask = (0x1 << bit);
80735c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
80835c4bbdfSmrg            store_data_long(srcoffset + disp, srcval | mask);
80935c4bbdfSmrg        }
81035c4bbdfSmrg        else {
81135c4bbdfSmrg            u16 srcval, mask;
81205b261ecSmrg            u16 *shiftreg;
81305b261ecSmrg
81405b261ecSmrg            srcoffset = decode_rm00_address(rl);
81505b261ecSmrg            DECODE_PRINTF(",");
81605b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
81705b261ecSmrg            TRACE_AND_STEP();
81805b261ecSmrg            bit = *shiftreg & 0xF;
81935c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
82035c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
82135c4bbdfSmrg            mask = (u16) (0x1 << bit);
82235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
82335c4bbdfSmrg            store_data_word(srcoffset + disp, srcval | mask);
82405b261ecSmrg        }
82505b261ecSmrg        break;
82605b261ecSmrg    case 1:
82705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
82835c4bbdfSmrg            u32 srcval, mask;
82905b261ecSmrg            u32 *shiftreg;
83005b261ecSmrg
83105b261ecSmrg            srcoffset = decode_rm01_address(rl);
83205b261ecSmrg            DECODE_PRINTF(",");
83305b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
83405b261ecSmrg            TRACE_AND_STEP();
83505b261ecSmrg            bit = *shiftreg & 0x1F;
83635c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
83735c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
83805b261ecSmrg            mask = (0x1 << bit);
83935c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
84035c4bbdfSmrg            store_data_long(srcoffset + disp, srcval | mask);
84135c4bbdfSmrg        }
84235c4bbdfSmrg        else {
84335c4bbdfSmrg            u16 srcval, mask;
84405b261ecSmrg            u16 *shiftreg;
84505b261ecSmrg
84605b261ecSmrg            srcoffset = decode_rm01_address(rl);
84705b261ecSmrg            DECODE_PRINTF(",");
84805b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
84905b261ecSmrg            TRACE_AND_STEP();
85005b261ecSmrg            bit = *shiftreg & 0xF;
85135c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
85235c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
85335c4bbdfSmrg            mask = (u16) (0x1 << bit);
85435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
85535c4bbdfSmrg            store_data_word(srcoffset + disp, srcval | mask);
85605b261ecSmrg        }
85705b261ecSmrg        break;
85805b261ecSmrg    case 2:
85905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
86035c4bbdfSmrg            u32 srcval, mask;
86105b261ecSmrg            u32 *shiftreg;
86205b261ecSmrg
86305b261ecSmrg            srcoffset = decode_rm10_address(rl);
86405b261ecSmrg            DECODE_PRINTF(",");
86505b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
86605b261ecSmrg            TRACE_AND_STEP();
86705b261ecSmrg            bit = *shiftreg & 0x1F;
86835c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
86935c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
87005b261ecSmrg            mask = (0x1 << bit);
87135c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
87235c4bbdfSmrg            store_data_long(srcoffset + disp, srcval | mask);
87335c4bbdfSmrg        }
87435c4bbdfSmrg        else {
87535c4bbdfSmrg            u16 srcval, mask;
87605b261ecSmrg            u16 *shiftreg;
87705b261ecSmrg
87835c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
87935c4bbdfSmrg            DECODE_PRINTF(",");
88035c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
88135c4bbdfSmrg            TRACE_AND_STEP();
88235c4bbdfSmrg            bit = *shiftreg & 0xF;
88335c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
88435c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
88535c4bbdfSmrg            mask = (u16) (0x1 << bit);
88635c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
88735c4bbdfSmrg            store_data_word(srcoffset + disp, srcval | mask);
88835c4bbdfSmrg        }
88935c4bbdfSmrg        break;
89035c4bbdfSmrg    case 3:                    /* register to register */
89135c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
89235c4bbdfSmrg            u32 *srcreg, *shiftreg;
89335c4bbdfSmrg            u32 mask;
89435c4bbdfSmrg
89535c4bbdfSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
89635c4bbdfSmrg            DECODE_PRINTF(",");
89735c4bbdfSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
89835c4bbdfSmrg            TRACE_AND_STEP();
89935c4bbdfSmrg            bit = *shiftreg & 0x1F;
90035c4bbdfSmrg            mask = (0x1 << bit);
90135c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
90235c4bbdfSmrg            *srcreg |= mask;
90335c4bbdfSmrg        }
90435c4bbdfSmrg        else {
90535c4bbdfSmrg            u16 *srcreg, *shiftreg;
90635c4bbdfSmrg            u16 mask;
90735c4bbdfSmrg
90835c4bbdfSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
90935c4bbdfSmrg            DECODE_PRINTF(",");
91035c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
91135c4bbdfSmrg            TRACE_AND_STEP();
91235c4bbdfSmrg            bit = *shiftreg & 0xF;
91335c4bbdfSmrg            mask = (u16) (0x1 << bit);
91435c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
91505b261ecSmrg            *srcreg |= mask;
91605b261ecSmrg        }
91705b261ecSmrg        break;
91805b261ecSmrg    }
91905b261ecSmrg    DECODE_CLEAR_SEGOVR();
92005b261ecSmrg    END_OF_INSTR();
92105b261ecSmrg}
92205b261ecSmrg
92305b261ecSmrg/****************************************************************************
92405b261ecSmrgREMARKS:
92505b261ecSmrgHandles opcode 0x0f,0xac
92605b261ecSmrg****************************************************************************/
92735c4bbdfSmrgstatic void
92835c4bbdfSmrgx86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
92905b261ecSmrg{
93005b261ecSmrg    int mod, rl, rh;
93105b261ecSmrg    uint destoffset;
93235c4bbdfSmrg    u8 shift;
93305b261ecSmrg
93405b261ecSmrg    START_OF_INSTR();
93505b261ecSmrg    DECODE_PRINTF("SHLD\t");
93605b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
93705b261ecSmrg    switch (mod) {
93805b261ecSmrg    case 0:
93905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
94005b261ecSmrg            u32 destval;
94105b261ecSmrg            u32 *shiftreg;
94205b261ecSmrg
94305b261ecSmrg            destoffset = decode_rm00_address(rl);
94405b261ecSmrg            DECODE_PRINTF(",");
94505b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
94605b261ecSmrg            DECODE_PRINTF(",");
94705b261ecSmrg            shift = fetch_byte_imm();
94805b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
94905b261ecSmrg            TRACE_AND_STEP();
95005b261ecSmrg            destval = fetch_data_long(destoffset);
95135c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, shift);
95205b261ecSmrg            store_data_long(destoffset, destval);
95335c4bbdfSmrg        }
95435c4bbdfSmrg        else {
95505b261ecSmrg            u16 destval;
95605b261ecSmrg            u16 *shiftreg;
95705b261ecSmrg
95805b261ecSmrg            destoffset = decode_rm00_address(rl);
95905b261ecSmrg            DECODE_PRINTF(",");
96005b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
96105b261ecSmrg            DECODE_PRINTF(",");
96205b261ecSmrg            shift = fetch_byte_imm();
96305b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
96405b261ecSmrg            TRACE_AND_STEP();
96505b261ecSmrg            destval = fetch_data_word(destoffset);
96635c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, shift);
96705b261ecSmrg            store_data_word(destoffset, destval);
96805b261ecSmrg        }
96905b261ecSmrg        break;
97005b261ecSmrg    case 1:
97105b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
97205b261ecSmrg            u32 destval;
97305b261ecSmrg            u32 *shiftreg;
97405b261ecSmrg
97505b261ecSmrg            destoffset = decode_rm01_address(rl);
97605b261ecSmrg            DECODE_PRINTF(",");
97705b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
97805b261ecSmrg            DECODE_PRINTF(",");
97905b261ecSmrg            shift = fetch_byte_imm();
98005b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
98105b261ecSmrg            TRACE_AND_STEP();
98205b261ecSmrg            destval = fetch_data_long(destoffset);
98335c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, shift);
98405b261ecSmrg            store_data_long(destoffset, destval);
98535c4bbdfSmrg        }
98635c4bbdfSmrg        else {
98705b261ecSmrg            u16 destval;
98805b261ecSmrg            u16 *shiftreg;
98905b261ecSmrg
99005b261ecSmrg            destoffset = decode_rm01_address(rl);
99105b261ecSmrg            DECODE_PRINTF(",");
99205b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
99305b261ecSmrg            DECODE_PRINTF(",");
99405b261ecSmrg            shift = fetch_byte_imm();
99505b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
99605b261ecSmrg            TRACE_AND_STEP();
99705b261ecSmrg            destval = fetch_data_word(destoffset);
99835c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, shift);
99905b261ecSmrg            store_data_word(destoffset, destval);
100005b261ecSmrg        }
100105b261ecSmrg        break;
100205b261ecSmrg    case 2:
100305b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
100405b261ecSmrg            u32 destval;
100505b261ecSmrg            u32 *shiftreg;
100605b261ecSmrg
100705b261ecSmrg            destoffset = decode_rm10_address(rl);
100805b261ecSmrg            DECODE_PRINTF(",");
100905b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
101005b261ecSmrg            DECODE_PRINTF(",");
101105b261ecSmrg            shift = fetch_byte_imm();
101205b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
101305b261ecSmrg            TRACE_AND_STEP();
101405b261ecSmrg            destval = fetch_data_long(destoffset);
101535c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, shift);
101605b261ecSmrg            store_data_long(destoffset, destval);
101735c4bbdfSmrg        }
101835c4bbdfSmrg        else {
101905b261ecSmrg            u16 destval;
102005b261ecSmrg            u16 *shiftreg;
102105b261ecSmrg
102205b261ecSmrg            destoffset = decode_rm10_address(rl);
102305b261ecSmrg            DECODE_PRINTF(",");
102405b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
102505b261ecSmrg            DECODE_PRINTF(",");
102605b261ecSmrg            shift = fetch_byte_imm();
102705b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
102805b261ecSmrg            TRACE_AND_STEP();
102905b261ecSmrg            destval = fetch_data_word(destoffset);
103035c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, shift);
103105b261ecSmrg            store_data_word(destoffset, destval);
103205b261ecSmrg        }
103305b261ecSmrg        break;
103435c4bbdfSmrg    case 3:                    /* register to register */
103505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
103635c4bbdfSmrg            u32 *destreg, *shiftreg;
103705b261ecSmrg
103805b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rl);
103905b261ecSmrg            DECODE_PRINTF(",");
104005b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
104105b261ecSmrg            DECODE_PRINTF(",");
104205b261ecSmrg            shift = fetch_byte_imm();
104305b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
104405b261ecSmrg            TRACE_AND_STEP();
104535c4bbdfSmrg            *destreg = shrd_long(*destreg, *shiftreg, shift);
104635c4bbdfSmrg        }
104735c4bbdfSmrg        else {
104835c4bbdfSmrg            u16 *destreg, *shiftreg;
104905b261ecSmrg
105005b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rl);
105105b261ecSmrg            DECODE_PRINTF(",");
105205b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
105305b261ecSmrg            DECODE_PRINTF(",");
105405b261ecSmrg            shift = fetch_byte_imm();
105505b261ecSmrg            DECODE_PRINTF2("%d\n", shift);
105605b261ecSmrg            TRACE_AND_STEP();
105735c4bbdfSmrg            *destreg = shrd_word(*destreg, *shiftreg, shift);
105805b261ecSmrg        }
105905b261ecSmrg        break;
106005b261ecSmrg    }
106105b261ecSmrg    DECODE_CLEAR_SEGOVR();
106205b261ecSmrg    END_OF_INSTR();
106305b261ecSmrg}
106405b261ecSmrg
106505b261ecSmrg/****************************************************************************
106605b261ecSmrgREMARKS:
106705b261ecSmrgHandles opcode 0x0f,0xad
106805b261ecSmrg****************************************************************************/
106935c4bbdfSmrgstatic void
107035c4bbdfSmrgx86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
107105b261ecSmrg{
107205b261ecSmrg    int mod, rl, rh;
107305b261ecSmrg    uint destoffset;
107405b261ecSmrg
107505b261ecSmrg    START_OF_INSTR();
107605b261ecSmrg    DECODE_PRINTF("SHLD\t");
107705b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
107805b261ecSmrg    switch (mod) {
107905b261ecSmrg    case 0:
108005b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
108105b261ecSmrg            u32 destval;
108205b261ecSmrg            u32 *shiftreg;
108305b261ecSmrg
108405b261ecSmrg            destoffset = decode_rm00_address(rl);
108505b261ecSmrg            DECODE_PRINTF(",");
108605b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
108705b261ecSmrg            DECODE_PRINTF(",CL\n");
108805b261ecSmrg            TRACE_AND_STEP();
108905b261ecSmrg            destval = fetch_data_long(destoffset);
109035c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
109105b261ecSmrg            store_data_long(destoffset, destval);
109235c4bbdfSmrg        }
109335c4bbdfSmrg        else {
109405b261ecSmrg            u16 destval;
109505b261ecSmrg            u16 *shiftreg;
109605b261ecSmrg
109705b261ecSmrg            destoffset = decode_rm00_address(rl);
109805b261ecSmrg            DECODE_PRINTF(",");
109905b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
110005b261ecSmrg            DECODE_PRINTF(",CL\n");
110105b261ecSmrg            TRACE_AND_STEP();
110205b261ecSmrg            destval = fetch_data_word(destoffset);
110335c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
110405b261ecSmrg            store_data_word(destoffset, destval);
110505b261ecSmrg        }
110605b261ecSmrg        break;
110705b261ecSmrg    case 1:
110805b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
110905b261ecSmrg            u32 destval;
111005b261ecSmrg            u32 *shiftreg;
111105b261ecSmrg
111205b261ecSmrg            destoffset = decode_rm01_address(rl);
111305b261ecSmrg            DECODE_PRINTF(",");
111405b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
111505b261ecSmrg            DECODE_PRINTF(",CL\n");
111605b261ecSmrg            TRACE_AND_STEP();
111705b261ecSmrg            destval = fetch_data_long(destoffset);
111835c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
111905b261ecSmrg            store_data_long(destoffset, destval);
112035c4bbdfSmrg        }
112135c4bbdfSmrg        else {
112205b261ecSmrg            u16 destval;
112305b261ecSmrg            u16 *shiftreg;
112405b261ecSmrg
112505b261ecSmrg            destoffset = decode_rm01_address(rl);
112605b261ecSmrg            DECODE_PRINTF(",");
112705b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
112805b261ecSmrg            DECODE_PRINTF(",CL\n");
112905b261ecSmrg            TRACE_AND_STEP();
113005b261ecSmrg            destval = fetch_data_word(destoffset);
113135c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
113205b261ecSmrg            store_data_word(destoffset, destval);
113305b261ecSmrg        }
113405b261ecSmrg        break;
113505b261ecSmrg    case 2:
113605b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
113705b261ecSmrg            u32 destval;
113805b261ecSmrg            u32 *shiftreg;
113905b261ecSmrg
114005b261ecSmrg            destoffset = decode_rm10_address(rl);
114105b261ecSmrg            DECODE_PRINTF(",");
114205b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
114305b261ecSmrg            DECODE_PRINTF(",CL\n");
114405b261ecSmrg            TRACE_AND_STEP();
114505b261ecSmrg            destval = fetch_data_long(destoffset);
114635c4bbdfSmrg            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
114705b261ecSmrg            store_data_long(destoffset, destval);
114835c4bbdfSmrg        }
114935c4bbdfSmrg        else {
115005b261ecSmrg            u16 destval;
115105b261ecSmrg            u16 *shiftreg;
115205b261ecSmrg
115305b261ecSmrg            destoffset = decode_rm10_address(rl);
115405b261ecSmrg            DECODE_PRINTF(",");
115505b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
115605b261ecSmrg            DECODE_PRINTF(",CL\n");
115705b261ecSmrg            TRACE_AND_STEP();
115805b261ecSmrg            destval = fetch_data_word(destoffset);
115935c4bbdfSmrg            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
116005b261ecSmrg            store_data_word(destoffset, destval);
116105b261ecSmrg        }
116205b261ecSmrg        break;
116335c4bbdfSmrg    case 3:                    /* register to register */
116405b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
116535c4bbdfSmrg            u32 *destreg, *shiftreg;
116605b261ecSmrg
116705b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rl);
116805b261ecSmrg            DECODE_PRINTF(",");
116905b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
117005b261ecSmrg            DECODE_PRINTF(",CL\n");
117105b261ecSmrg            TRACE_AND_STEP();
117235c4bbdfSmrg            *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL);
117335c4bbdfSmrg        }
117435c4bbdfSmrg        else {
117535c4bbdfSmrg            u16 *destreg, *shiftreg;
117605b261ecSmrg
117705b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rl);
117805b261ecSmrg            DECODE_PRINTF(",");
117905b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
118005b261ecSmrg            DECODE_PRINTF(",CL\n");
118105b261ecSmrg            TRACE_AND_STEP();
118235c4bbdfSmrg            *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL);
118305b261ecSmrg        }
118405b261ecSmrg        break;
118505b261ecSmrg    }
118605b261ecSmrg    DECODE_CLEAR_SEGOVR();
118705b261ecSmrg    END_OF_INSTR();
118805b261ecSmrg}
118905b261ecSmrg
119005b261ecSmrg/****************************************************************************
119105b261ecSmrgREMARKS:
119205b261ecSmrgHandles opcode 0x0f,0xaf
119305b261ecSmrg****************************************************************************/
119435c4bbdfSmrgstatic void
119535c4bbdfSmrgx86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
119605b261ecSmrg{
119705b261ecSmrg    int mod, rl, rh;
119805b261ecSmrg    uint srcoffset;
119905b261ecSmrg
120005b261ecSmrg    START_OF_INSTR();
120105b261ecSmrg    DECODE_PRINTF("IMUL\t");
120205b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
120305b261ecSmrg    switch (mod) {
120405b261ecSmrg    case 0:
120505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
120605b261ecSmrg            u32 *destreg;
120705b261ecSmrg            u32 srcval;
120835c4bbdfSmrg            u32 res_lo, res_hi;
120905b261ecSmrg
121005b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
121105b261ecSmrg            DECODE_PRINTF(",");
121205b261ecSmrg            srcoffset = decode_rm00_address(rl);
121305b261ecSmrg            srcval = fetch_data_long(srcoffset);
121405b261ecSmrg            TRACE_AND_STEP();
121535c4bbdfSmrg            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
121605b261ecSmrg            if (res_hi != 0) {
121705b261ecSmrg                SET_FLAG(F_CF);
121805b261ecSmrg                SET_FLAG(F_OF);
121935c4bbdfSmrg            }
122035c4bbdfSmrg            else {
122105b261ecSmrg                CLEAR_FLAG(F_CF);
122205b261ecSmrg                CLEAR_FLAG(F_OF);
122305b261ecSmrg            }
122435c4bbdfSmrg            *destreg = (u32) res_lo;
122535c4bbdfSmrg        }
122635c4bbdfSmrg        else {
122705b261ecSmrg            u16 *destreg;
122805b261ecSmrg            u16 srcval;
122905b261ecSmrg            u32 res;
123005b261ecSmrg
123105b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
123205b261ecSmrg            DECODE_PRINTF(",");
123305b261ecSmrg            srcoffset = decode_rm00_address(rl);
123405b261ecSmrg            srcval = fetch_data_word(srcoffset);
123505b261ecSmrg            TRACE_AND_STEP();
123635c4bbdfSmrg            res = (s16) * destreg * (s16) srcval;
123705b261ecSmrg            if (res > 0xFFFF) {
123805b261ecSmrg                SET_FLAG(F_CF);
123905b261ecSmrg                SET_FLAG(F_OF);
124035c4bbdfSmrg            }
124135c4bbdfSmrg            else {
124205b261ecSmrg                CLEAR_FLAG(F_CF);
124305b261ecSmrg                CLEAR_FLAG(F_OF);
124405b261ecSmrg            }
124535c4bbdfSmrg            *destreg = (u16) res;
124605b261ecSmrg        }
124705b261ecSmrg        break;
124805b261ecSmrg    case 1:
124905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
125005b261ecSmrg            u32 *destreg;
125105b261ecSmrg            u32 srcval;
125235c4bbdfSmrg            u32 res_lo, res_hi;
125305b261ecSmrg
125405b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
125505b261ecSmrg            DECODE_PRINTF(",");
125605b261ecSmrg            srcoffset = decode_rm01_address(rl);
125705b261ecSmrg            srcval = fetch_data_long(srcoffset);
125805b261ecSmrg            TRACE_AND_STEP();
125935c4bbdfSmrg            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
126005b261ecSmrg            if (res_hi != 0) {
126105b261ecSmrg                SET_FLAG(F_CF);
126205b261ecSmrg                SET_FLAG(F_OF);
126335c4bbdfSmrg            }
126435c4bbdfSmrg            else {
126505b261ecSmrg                CLEAR_FLAG(F_CF);
126605b261ecSmrg                CLEAR_FLAG(F_OF);
126705b261ecSmrg            }
126835c4bbdfSmrg            *destreg = (u32) res_lo;
126935c4bbdfSmrg        }
127035c4bbdfSmrg        else {
127105b261ecSmrg            u16 *destreg;
127205b261ecSmrg            u16 srcval;
127305b261ecSmrg            u32 res;
127405b261ecSmrg
127505b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
127605b261ecSmrg            DECODE_PRINTF(",");
127705b261ecSmrg            srcoffset = decode_rm01_address(rl);
127805b261ecSmrg            srcval = fetch_data_word(srcoffset);
127905b261ecSmrg            TRACE_AND_STEP();
128035c4bbdfSmrg            res = (s16) * destreg * (s16) srcval;
128105b261ecSmrg            if (res > 0xFFFF) {
128205b261ecSmrg                SET_FLAG(F_CF);
128305b261ecSmrg                SET_FLAG(F_OF);
128435c4bbdfSmrg            }
128535c4bbdfSmrg            else {
128605b261ecSmrg                CLEAR_FLAG(F_CF);
128705b261ecSmrg                CLEAR_FLAG(F_OF);
128805b261ecSmrg            }
128935c4bbdfSmrg            *destreg = (u16) res;
129005b261ecSmrg        }
129105b261ecSmrg        break;
129205b261ecSmrg    case 2:
129305b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
129405b261ecSmrg            u32 *destreg;
129505b261ecSmrg            u32 srcval;
129635c4bbdfSmrg            u32 res_lo, res_hi;
129705b261ecSmrg
129805b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
129905b261ecSmrg            DECODE_PRINTF(",");
130005b261ecSmrg            srcoffset = decode_rm10_address(rl);
130105b261ecSmrg            srcval = fetch_data_long(srcoffset);
130205b261ecSmrg            TRACE_AND_STEP();
130335c4bbdfSmrg            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
130405b261ecSmrg            if (res_hi != 0) {
130505b261ecSmrg                SET_FLAG(F_CF);
130605b261ecSmrg                SET_FLAG(F_OF);
130735c4bbdfSmrg            }
130835c4bbdfSmrg            else {
130905b261ecSmrg                CLEAR_FLAG(F_CF);
131005b261ecSmrg                CLEAR_FLAG(F_OF);
131105b261ecSmrg            }
131235c4bbdfSmrg            *destreg = (u32) res_lo;
131335c4bbdfSmrg        }
131435c4bbdfSmrg        else {
131505b261ecSmrg            u16 *destreg;
131605b261ecSmrg            u16 srcval;
131705b261ecSmrg            u32 res;
131805b261ecSmrg
131905b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
132005b261ecSmrg            DECODE_PRINTF(",");
132105b261ecSmrg            srcoffset = decode_rm10_address(rl);
132205b261ecSmrg            srcval = fetch_data_word(srcoffset);
132305b261ecSmrg            TRACE_AND_STEP();
132435c4bbdfSmrg            res = (s16) * destreg * (s16) srcval;
132505b261ecSmrg            if (res > 0xFFFF) {
132605b261ecSmrg                SET_FLAG(F_CF);
132705b261ecSmrg                SET_FLAG(F_OF);
132835c4bbdfSmrg            }
132935c4bbdfSmrg            else {
133005b261ecSmrg                CLEAR_FLAG(F_CF);
133105b261ecSmrg                CLEAR_FLAG(F_OF);
133205b261ecSmrg            }
133335c4bbdfSmrg            *destreg = (u16) res;
133405b261ecSmrg        }
133505b261ecSmrg        break;
133635c4bbdfSmrg    case 3:                    /* register to register */
133705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
133835c4bbdfSmrg            u32 *destreg, *srcreg;
133935c4bbdfSmrg            u32 res_lo, res_hi;
134005b261ecSmrg
134105b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
134205b261ecSmrg            DECODE_PRINTF(",");
134305b261ecSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
134405b261ecSmrg            TRACE_AND_STEP();
134535c4bbdfSmrg            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg);
134605b261ecSmrg            if (res_hi != 0) {
134705b261ecSmrg                SET_FLAG(F_CF);
134805b261ecSmrg                SET_FLAG(F_OF);
134935c4bbdfSmrg            }
135035c4bbdfSmrg            else {
135105b261ecSmrg                CLEAR_FLAG(F_CF);
135205b261ecSmrg                CLEAR_FLAG(F_OF);
135305b261ecSmrg            }
135435c4bbdfSmrg            *destreg = (u32) res_lo;
135535c4bbdfSmrg        }
135635c4bbdfSmrg        else {
135735c4bbdfSmrg            u16 *destreg, *srcreg;
135805b261ecSmrg            u32 res;
135905b261ecSmrg
136005b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
136105b261ecSmrg            DECODE_PRINTF(",");
136205b261ecSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
136335c4bbdfSmrg            res = (s16) * destreg * (s16) * srcreg;
136405b261ecSmrg            if (res > 0xFFFF) {
136505b261ecSmrg                SET_FLAG(F_CF);
136605b261ecSmrg                SET_FLAG(F_OF);
136735c4bbdfSmrg            }
136835c4bbdfSmrg            else {
136905b261ecSmrg                CLEAR_FLAG(F_CF);
137005b261ecSmrg                CLEAR_FLAG(F_OF);
137105b261ecSmrg            }
137235c4bbdfSmrg            *destreg = (u16) res;
137305b261ecSmrg        }
137405b261ecSmrg        break;
137505b261ecSmrg    }
137605b261ecSmrg    DECODE_CLEAR_SEGOVR();
137705b261ecSmrg    END_OF_INSTR();
137805b261ecSmrg}
137905b261ecSmrg
138005b261ecSmrg/****************************************************************************
138105b261ecSmrgREMARKS:
138205b261ecSmrgHandles opcode 0x0f,0xb2
138305b261ecSmrg****************************************************************************/
138435c4bbdfSmrgstatic void
138535c4bbdfSmrgx86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
138605b261ecSmrg{
138735c4bbdfSmrg    int mod, rh, rl;
138805b261ecSmrg    u16 *dstreg;
138905b261ecSmrg    uint srcoffset;
139005b261ecSmrg
139105b261ecSmrg    START_OF_INSTR();
139205b261ecSmrg    DECODE_PRINTF("LSS\t");
139305b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
139405b261ecSmrg    switch (mod) {
139505b261ecSmrg    case 0:
139605b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
139705b261ecSmrg        DECODE_PRINTF(",");
139805b261ecSmrg        srcoffset = decode_rm00_address(rl);
139905b261ecSmrg        DECODE_PRINTF("\n");
140005b261ecSmrg        TRACE_AND_STEP();
140105b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
140205b261ecSmrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
140305b261ecSmrg        break;
140405b261ecSmrg    case 1:
140505b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
140605b261ecSmrg        DECODE_PRINTF(",");
140705b261ecSmrg        srcoffset = decode_rm01_address(rl);
140805b261ecSmrg        DECODE_PRINTF("\n");
140905b261ecSmrg        TRACE_AND_STEP();
141005b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
141105b261ecSmrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
141205b261ecSmrg        break;
141305b261ecSmrg    case 2:
141405b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
141505b261ecSmrg        DECODE_PRINTF(",");
141605b261ecSmrg        srcoffset = decode_rm10_address(rl);
141705b261ecSmrg        DECODE_PRINTF("\n");
141805b261ecSmrg        TRACE_AND_STEP();
141905b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
142005b261ecSmrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
142105b261ecSmrg        break;
142235c4bbdfSmrg    case 3:                    /* register to register */
142305b261ecSmrg        /* UNDEFINED! */
142405b261ecSmrg        TRACE_AND_STEP();
142505b261ecSmrg    }
142605b261ecSmrg    DECODE_CLEAR_SEGOVR();
142705b261ecSmrg    END_OF_INSTR();
142805b261ecSmrg}
142905b261ecSmrg
143005b261ecSmrg/****************************************************************************
143105b261ecSmrgREMARKS:
143205b261ecSmrgHandles opcode 0x0f,0xb3
143305b261ecSmrg****************************************************************************/
143435c4bbdfSmrgstatic void
143535c4bbdfSmrgx86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
143605b261ecSmrg{
143735c4bbdfSmrg    int mod, rl, rh;
143835c4bbdfSmrg    uint srcoffset;
143935c4bbdfSmrg    int bit, disp;
144035c4bbdfSmrg
144135c4bbdfSmrg    START_OF_INSTR();
144235c4bbdfSmrg    DECODE_PRINTF("BTR\t");
144335c4bbdfSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
144435c4bbdfSmrg    switch (mod) {
144535c4bbdfSmrg    case 0:
144635c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
144735c4bbdfSmrg            u32 srcval, mask;
144835c4bbdfSmrg            u32 *shiftreg;
144935c4bbdfSmrg
145035c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
145135c4bbdfSmrg            DECODE_PRINTF(",");
145235c4bbdfSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
145335c4bbdfSmrg            TRACE_AND_STEP();
145435c4bbdfSmrg            bit = *shiftreg & 0x1F;
145535c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
145635c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
145735c4bbdfSmrg            mask = (0x1 << bit);
145835c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
145935c4bbdfSmrg            store_data_long(srcoffset + disp, srcval & ~mask);
146035c4bbdfSmrg        }
146135c4bbdfSmrg        else {
146235c4bbdfSmrg            u16 srcval, mask;
146335c4bbdfSmrg            u16 *shiftreg;
146435c4bbdfSmrg
146535c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
146635c4bbdfSmrg            DECODE_PRINTF(",");
146735c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
146835c4bbdfSmrg            TRACE_AND_STEP();
146935c4bbdfSmrg            bit = *shiftreg & 0xF;
147035c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
147135c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
147235c4bbdfSmrg            mask = (u16) (0x1 << bit);
147335c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
147435c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
147535c4bbdfSmrg        }
147635c4bbdfSmrg        break;
147735c4bbdfSmrg    case 1:
147835c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
147935c4bbdfSmrg            u32 srcval, mask;
148035c4bbdfSmrg            u32 *shiftreg;
148135c4bbdfSmrg
148235c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
148335c4bbdfSmrg            DECODE_PRINTF(",");
148435c4bbdfSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
148535c4bbdfSmrg            TRACE_AND_STEP();
148635c4bbdfSmrg            bit = *shiftreg & 0x1F;
148735c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
148835c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
148935c4bbdfSmrg            mask = (0x1 << bit);
149035c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
149135c4bbdfSmrg            store_data_long(srcoffset + disp, srcval & ~mask);
149235c4bbdfSmrg        }
149335c4bbdfSmrg        else {
149435c4bbdfSmrg            u16 srcval, mask;
149535c4bbdfSmrg            u16 *shiftreg;
149635c4bbdfSmrg
149735c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
149835c4bbdfSmrg            DECODE_PRINTF(",");
149935c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
150035c4bbdfSmrg            TRACE_AND_STEP();
150135c4bbdfSmrg            bit = *shiftreg & 0xF;
150235c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
150335c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
150435c4bbdfSmrg            mask = (u16) (0x1 << bit);
150535c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
150635c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
150735c4bbdfSmrg        }
150835c4bbdfSmrg        break;
150935c4bbdfSmrg    case 2:
151035c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
151135c4bbdfSmrg            u32 srcval, mask;
151235c4bbdfSmrg            u32 *shiftreg;
151335c4bbdfSmrg
151435c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
151535c4bbdfSmrg            DECODE_PRINTF(",");
151635c4bbdfSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
151735c4bbdfSmrg            TRACE_AND_STEP();
151835c4bbdfSmrg            bit = *shiftreg & 0x1F;
151935c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
152035c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
152135c4bbdfSmrg            mask = (0x1 << bit);
152235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
152335c4bbdfSmrg            store_data_long(srcoffset + disp, srcval & ~mask);
152435c4bbdfSmrg        }
152535c4bbdfSmrg        else {
152635c4bbdfSmrg            u16 srcval, mask;
152735c4bbdfSmrg            u16 *shiftreg;
152835c4bbdfSmrg
152935c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
153035c4bbdfSmrg            DECODE_PRINTF(",");
153135c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
153235c4bbdfSmrg            TRACE_AND_STEP();
153335c4bbdfSmrg            bit = *shiftreg & 0xF;
153435c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
153535c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
153635c4bbdfSmrg            mask = (u16) (0x1 << bit);
153735c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
153835c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
153935c4bbdfSmrg        }
154035c4bbdfSmrg        break;
154135c4bbdfSmrg    case 3:                    /* register to register */
154235c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
154335c4bbdfSmrg            u32 *srcreg, *shiftreg;
154435c4bbdfSmrg            u32 mask;
154535c4bbdfSmrg
154635c4bbdfSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
154735c4bbdfSmrg            DECODE_PRINTF(",");
154835c4bbdfSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
154935c4bbdfSmrg            TRACE_AND_STEP();
155035c4bbdfSmrg            bit = *shiftreg & 0x1F;
155135c4bbdfSmrg            mask = (0x1 << bit);
155235c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
155335c4bbdfSmrg            *srcreg &= ~mask;
155435c4bbdfSmrg        }
155535c4bbdfSmrg        else {
155635c4bbdfSmrg            u16 *srcreg, *shiftreg;
155735c4bbdfSmrg            u16 mask;
155835c4bbdfSmrg
155935c4bbdfSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
156035c4bbdfSmrg            DECODE_PRINTF(",");
156135c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
156235c4bbdfSmrg            TRACE_AND_STEP();
156335c4bbdfSmrg            bit = *shiftreg & 0xF;
156435c4bbdfSmrg            mask = (u16) (0x1 << bit);
156535c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
156635c4bbdfSmrg            *srcreg &= ~mask;
156735c4bbdfSmrg        }
156835c4bbdfSmrg        break;
156935c4bbdfSmrg    }
157035c4bbdfSmrg    DECODE_CLEAR_SEGOVR();
157135c4bbdfSmrg    END_OF_INSTR();
157205b261ecSmrg}
157305b261ecSmrg
157405b261ecSmrg/****************************************************************************
157505b261ecSmrgREMARKS:
157605b261ecSmrgHandles opcode 0x0f,0xb4
157705b261ecSmrg****************************************************************************/
157835c4bbdfSmrgstatic void
157935c4bbdfSmrgx86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
158005b261ecSmrg{
158135c4bbdfSmrg    int mod, rh, rl;
158205b261ecSmrg    u16 *dstreg;
158305b261ecSmrg    uint srcoffset;
158405b261ecSmrg
158505b261ecSmrg    START_OF_INSTR();
158605b261ecSmrg    DECODE_PRINTF("LFS\t");
158705b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
158805b261ecSmrg    switch (mod) {
158905b261ecSmrg    case 0:
159005b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
159105b261ecSmrg        DECODE_PRINTF(",");
159205b261ecSmrg        srcoffset = decode_rm00_address(rl);
159305b261ecSmrg        DECODE_PRINTF("\n");
159405b261ecSmrg        TRACE_AND_STEP();
159505b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
159605b261ecSmrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
159705b261ecSmrg        break;
159805b261ecSmrg    case 1:
159905b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
160005b261ecSmrg        DECODE_PRINTF(",");
160105b261ecSmrg        srcoffset = decode_rm01_address(rl);
160205b261ecSmrg        DECODE_PRINTF("\n");
160305b261ecSmrg        TRACE_AND_STEP();
160405b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
160505b261ecSmrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
160605b261ecSmrg        break;
160705b261ecSmrg    case 2:
160805b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
160905b261ecSmrg        DECODE_PRINTF(",");
161005b261ecSmrg        srcoffset = decode_rm10_address(rl);
161105b261ecSmrg        DECODE_PRINTF("\n");
161205b261ecSmrg        TRACE_AND_STEP();
161305b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
161405b261ecSmrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
161505b261ecSmrg        break;
161635c4bbdfSmrg    case 3:                    /* register to register */
161705b261ecSmrg        /* UNDEFINED! */
161805b261ecSmrg        TRACE_AND_STEP();
161905b261ecSmrg    }
162005b261ecSmrg    DECODE_CLEAR_SEGOVR();
162105b261ecSmrg    END_OF_INSTR();
162205b261ecSmrg}
162305b261ecSmrg
162405b261ecSmrg/****************************************************************************
162505b261ecSmrgREMARKS:
162605b261ecSmrgHandles opcode 0x0f,0xb5
162705b261ecSmrg****************************************************************************/
162835c4bbdfSmrgstatic void
162935c4bbdfSmrgx86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
163005b261ecSmrg{
163135c4bbdfSmrg    int mod, rh, rl;
163205b261ecSmrg    u16 *dstreg;
163305b261ecSmrg    uint srcoffset;
163405b261ecSmrg
163505b261ecSmrg    START_OF_INSTR();
163605b261ecSmrg    DECODE_PRINTF("LGS\t");
163705b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
163805b261ecSmrg    switch (mod) {
163905b261ecSmrg    case 0:
164005b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
164105b261ecSmrg        DECODE_PRINTF(",");
164205b261ecSmrg        srcoffset = decode_rm00_address(rl);
164305b261ecSmrg        DECODE_PRINTF("\n");
164405b261ecSmrg        TRACE_AND_STEP();
164505b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
164605b261ecSmrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
164705b261ecSmrg        break;
164805b261ecSmrg    case 1:
164905b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
165005b261ecSmrg        DECODE_PRINTF(",");
165105b261ecSmrg        srcoffset = decode_rm01_address(rl);
165205b261ecSmrg        DECODE_PRINTF("\n");
165305b261ecSmrg        TRACE_AND_STEP();
165405b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
165505b261ecSmrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
165605b261ecSmrg        break;
165705b261ecSmrg    case 2:
165805b261ecSmrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
165905b261ecSmrg        DECODE_PRINTF(",");
166005b261ecSmrg        srcoffset = decode_rm10_address(rl);
166105b261ecSmrg        DECODE_PRINTF("\n");
166205b261ecSmrg        TRACE_AND_STEP();
166305b261ecSmrg        *dstreg = fetch_data_word(srcoffset);
166405b261ecSmrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
166505b261ecSmrg        break;
166635c4bbdfSmrg    case 3:                    /* register to register */
166705b261ecSmrg        /* UNDEFINED! */
166805b261ecSmrg        TRACE_AND_STEP();
166905b261ecSmrg    }
167005b261ecSmrg    DECODE_CLEAR_SEGOVR();
167105b261ecSmrg    END_OF_INSTR();
167205b261ecSmrg}
167305b261ecSmrg
167405b261ecSmrg/****************************************************************************
167505b261ecSmrgREMARKS:
167605b261ecSmrgHandles opcode 0x0f,0xb6
167705b261ecSmrg****************************************************************************/
167835c4bbdfSmrgstatic void
167935c4bbdfSmrgx86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
168005b261ecSmrg{
168105b261ecSmrg    int mod, rl, rh;
168205b261ecSmrg    uint srcoffset;
168305b261ecSmrg
168405b261ecSmrg    START_OF_INSTR();
168505b261ecSmrg    DECODE_PRINTF("MOVZX\t");
168605b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
168705b261ecSmrg    switch (mod) {
168805b261ecSmrg    case 0:
168905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
169005b261ecSmrg            u32 *destreg;
169105b261ecSmrg            u32 srcval;
169205b261ecSmrg
169305b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
169405b261ecSmrg            DECODE_PRINTF(",");
169505b261ecSmrg            srcoffset = decode_rm00_address(rl);
169605b261ecSmrg            srcval = fetch_data_byte(srcoffset);
169705b261ecSmrg            DECODE_PRINTF("\n");
169805b261ecSmrg            TRACE_AND_STEP();
169905b261ecSmrg            *destreg = srcval;
170035c4bbdfSmrg        }
170135c4bbdfSmrg        else {
170205b261ecSmrg            u16 *destreg;
170305b261ecSmrg            u16 srcval;
170405b261ecSmrg
170505b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
170605b261ecSmrg            DECODE_PRINTF(",");
170705b261ecSmrg            srcoffset = decode_rm00_address(rl);
170805b261ecSmrg            srcval = fetch_data_byte(srcoffset);
170905b261ecSmrg            DECODE_PRINTF("\n");
171005b261ecSmrg            TRACE_AND_STEP();
171105b261ecSmrg            *destreg = srcval;
171205b261ecSmrg        }
171305b261ecSmrg        break;
171405b261ecSmrg    case 1:
171505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
171605b261ecSmrg            u32 *destreg;
171705b261ecSmrg            u32 srcval;
171805b261ecSmrg
171905b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
172005b261ecSmrg            DECODE_PRINTF(",");
172105b261ecSmrg            srcoffset = decode_rm01_address(rl);
172205b261ecSmrg            srcval = fetch_data_byte(srcoffset);
172305b261ecSmrg            DECODE_PRINTF("\n");
172405b261ecSmrg            TRACE_AND_STEP();
172505b261ecSmrg            *destreg = srcval;
172635c4bbdfSmrg        }
172735c4bbdfSmrg        else {
172805b261ecSmrg            u16 *destreg;
172905b261ecSmrg            u16 srcval;
173005b261ecSmrg
173105b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
173205b261ecSmrg            DECODE_PRINTF(",");
173305b261ecSmrg            srcoffset = decode_rm01_address(rl);
173405b261ecSmrg            srcval = fetch_data_byte(srcoffset);
173505b261ecSmrg            DECODE_PRINTF("\n");
173605b261ecSmrg            TRACE_AND_STEP();
173705b261ecSmrg            *destreg = srcval;
173805b261ecSmrg        }
173905b261ecSmrg        break;
174005b261ecSmrg    case 2:
174105b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
174205b261ecSmrg            u32 *destreg;
174305b261ecSmrg            u32 srcval;
174405b261ecSmrg
174505b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
174605b261ecSmrg            DECODE_PRINTF(",");
174705b261ecSmrg            srcoffset = decode_rm10_address(rl);
174805b261ecSmrg            srcval = fetch_data_byte(srcoffset);
174905b261ecSmrg            DECODE_PRINTF("\n");
175005b261ecSmrg            TRACE_AND_STEP();
175105b261ecSmrg            *destreg = srcval;
175235c4bbdfSmrg        }
175335c4bbdfSmrg        else {
175405b261ecSmrg            u16 *destreg;
175505b261ecSmrg            u16 srcval;
175605b261ecSmrg
175705b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
175805b261ecSmrg            DECODE_PRINTF(",");
175905b261ecSmrg            srcoffset = decode_rm10_address(rl);
176005b261ecSmrg            srcval = fetch_data_byte(srcoffset);
176105b261ecSmrg            DECODE_PRINTF("\n");
176205b261ecSmrg            TRACE_AND_STEP();
176305b261ecSmrg            *destreg = srcval;
176405b261ecSmrg        }
176505b261ecSmrg        break;
176635c4bbdfSmrg    case 3:                    /* register to register */
176705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
176805b261ecSmrg            u32 *destreg;
176935c4bbdfSmrg            u8 *srcreg;
177005b261ecSmrg
177105b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
177205b261ecSmrg            DECODE_PRINTF(",");
177305b261ecSmrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
177405b261ecSmrg            DECODE_PRINTF("\n");
177505b261ecSmrg            TRACE_AND_STEP();
177605b261ecSmrg            *destreg = *srcreg;
177735c4bbdfSmrg        }
177835c4bbdfSmrg        else {
177905b261ecSmrg            u16 *destreg;
178035c4bbdfSmrg            u8 *srcreg;
178105b261ecSmrg
178205b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
178305b261ecSmrg            DECODE_PRINTF(",");
178405b261ecSmrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
178505b261ecSmrg            DECODE_PRINTF("\n");
178605b261ecSmrg            TRACE_AND_STEP();
178705b261ecSmrg            *destreg = *srcreg;
178805b261ecSmrg        }
178905b261ecSmrg        break;
179005b261ecSmrg    }
179105b261ecSmrg    DECODE_CLEAR_SEGOVR();
179205b261ecSmrg    END_OF_INSTR();
179305b261ecSmrg}
179405b261ecSmrg
179505b261ecSmrg/****************************************************************************
179605b261ecSmrgREMARKS:
179705b261ecSmrgHandles opcode 0x0f,0xb7
179805b261ecSmrg****************************************************************************/
179935c4bbdfSmrgstatic void
180035c4bbdfSmrgx86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
180105b261ecSmrg{
180205b261ecSmrg    int mod, rl, rh;
180305b261ecSmrg    uint srcoffset;
180405b261ecSmrg    u32 *destreg;
180505b261ecSmrg    u32 srcval;
180605b261ecSmrg    u16 *srcreg;
180705b261ecSmrg
180805b261ecSmrg    START_OF_INSTR();
180905b261ecSmrg    DECODE_PRINTF("MOVZX\t");
181005b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
181105b261ecSmrg    switch (mod) {
181205b261ecSmrg    case 0:
181305b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
181405b261ecSmrg        DECODE_PRINTF(",");
181505b261ecSmrg        srcoffset = decode_rm00_address(rl);
181605b261ecSmrg        srcval = fetch_data_word(srcoffset);
181705b261ecSmrg        DECODE_PRINTF("\n");
181805b261ecSmrg        TRACE_AND_STEP();
181905b261ecSmrg        *destreg = srcval;
182005b261ecSmrg        break;
182105b261ecSmrg    case 1:
182205b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
182305b261ecSmrg        DECODE_PRINTF(",");
182405b261ecSmrg        srcoffset = decode_rm01_address(rl);
182505b261ecSmrg        srcval = fetch_data_word(srcoffset);
182605b261ecSmrg        DECODE_PRINTF("\n");
182705b261ecSmrg        TRACE_AND_STEP();
182805b261ecSmrg        *destreg = srcval;
182905b261ecSmrg        break;
183005b261ecSmrg    case 2:
183105b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
183205b261ecSmrg        DECODE_PRINTF(",");
183305b261ecSmrg        srcoffset = decode_rm10_address(rl);
183405b261ecSmrg        srcval = fetch_data_word(srcoffset);
183505b261ecSmrg        DECODE_PRINTF("\n");
183605b261ecSmrg        TRACE_AND_STEP();
183705b261ecSmrg        *destreg = srcval;
183805b261ecSmrg        break;
183935c4bbdfSmrg    case 3:                    /* register to register */
184005b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
184105b261ecSmrg        DECODE_PRINTF(",");
184205b261ecSmrg        srcreg = DECODE_RM_WORD_REGISTER(rl);
184305b261ecSmrg        DECODE_PRINTF("\n");
184405b261ecSmrg        TRACE_AND_STEP();
184505b261ecSmrg        *destreg = *srcreg;
184605b261ecSmrg        break;
184705b261ecSmrg    }
184805b261ecSmrg    DECODE_CLEAR_SEGOVR();
184905b261ecSmrg    END_OF_INSTR();
185005b261ecSmrg}
185105b261ecSmrg
185205b261ecSmrg/****************************************************************************
185305b261ecSmrgREMARKS:
185405b261ecSmrgHandles opcode 0x0f,0xba
185505b261ecSmrg****************************************************************************/
185635c4bbdfSmrgstatic void
185735c4bbdfSmrgx86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
185805b261ecSmrg{
185905b261ecSmrg    int mod, rl, rh;
186005b261ecSmrg    uint srcoffset;
186105b261ecSmrg    int bit;
186205b261ecSmrg
186305b261ecSmrg    START_OF_INSTR();
186405b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
186505b261ecSmrg    switch (rh) {
186605b261ecSmrg    case 4:
186735c4bbdfSmrg        DECODE_PRINTF("BT\t");
186835c4bbdfSmrg        break;
186905b261ecSmrg    case 5:
187035c4bbdfSmrg        DECODE_PRINTF("BTS\t");
187135c4bbdfSmrg        break;
187205b261ecSmrg    case 6:
187335c4bbdfSmrg        DECODE_PRINTF("BTR\t");
187435c4bbdfSmrg        break;
187505b261ecSmrg    case 7:
187635c4bbdfSmrg        DECODE_PRINTF("BTC\t");
187735c4bbdfSmrg        break;
187805b261ecSmrg    default:
187935c4bbdfSmrg        DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
188035c4bbdfSmrg        TRACE_REGS();
188135c4bbdfSmrg        printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
188235c4bbdfSmrg               M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl);
188335c4bbdfSmrg        HALT_SYS();
188405b261ecSmrg    }
188505b261ecSmrg    switch (mod) {
188605b261ecSmrg    case 0:
188705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
188805b261ecSmrg            u32 srcval, mask;
188905b261ecSmrg            u8 shift;
189005b261ecSmrg
189105b261ecSmrg            srcoffset = decode_rm00_address(rl);
189205b261ecSmrg            DECODE_PRINTF(",");
189305b261ecSmrg            shift = fetch_byte_imm();
189405b261ecSmrg            TRACE_AND_STEP();
189505b261ecSmrg            bit = shift & 0x1F;
189605b261ecSmrg            srcval = fetch_data_long(srcoffset);
189735c4bbdfSmrg            mask = (0x1 << bit);
189835c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
189935c4bbdfSmrg            switch (rh) {
190035c4bbdfSmrg            case 5:
190135c4bbdfSmrg                store_data_long(srcoffset, srcval | mask);
190235c4bbdfSmrg                break;
190335c4bbdfSmrg            case 6:
190435c4bbdfSmrg                store_data_long(srcoffset, srcval & ~mask);
190535c4bbdfSmrg                break;
190635c4bbdfSmrg            case 7:
190735c4bbdfSmrg                store_data_long(srcoffset, srcval ^ mask);
190835c4bbdfSmrg                break;
190935c4bbdfSmrg            default:
191035c4bbdfSmrg                break;
191135c4bbdfSmrg            }
191235c4bbdfSmrg        }
191335c4bbdfSmrg        else {
191405b261ecSmrg            u16 srcval, mask;
191505b261ecSmrg            u8 shift;
191605b261ecSmrg
191705b261ecSmrg            srcoffset = decode_rm00_address(rl);
191805b261ecSmrg            DECODE_PRINTF(",");
191905b261ecSmrg            shift = fetch_byte_imm();
192005b261ecSmrg            TRACE_AND_STEP();
192105b261ecSmrg            bit = shift & 0xF;
192205b261ecSmrg            srcval = fetch_data_word(srcoffset);
192335c4bbdfSmrg            mask = (0x1 << bit);
192435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
192535c4bbdfSmrg            switch (rh) {
192635c4bbdfSmrg            case 5:
192735c4bbdfSmrg                store_data_word(srcoffset, srcval | mask);
192835c4bbdfSmrg                break;
192935c4bbdfSmrg            case 6:
193035c4bbdfSmrg                store_data_word(srcoffset, srcval & ~mask);
193135c4bbdfSmrg                break;
193235c4bbdfSmrg            case 7:
193335c4bbdfSmrg                store_data_word(srcoffset, srcval ^ mask);
193435c4bbdfSmrg                break;
193535c4bbdfSmrg            default:
193635c4bbdfSmrg                break;
193735c4bbdfSmrg            }
193805b261ecSmrg        }
193905b261ecSmrg        break;
194005b261ecSmrg    case 1:
194105b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
194205b261ecSmrg            u32 srcval, mask;
194305b261ecSmrg            u8 shift;
194405b261ecSmrg
194505b261ecSmrg            srcoffset = decode_rm01_address(rl);
194605b261ecSmrg            DECODE_PRINTF(",");
194705b261ecSmrg            shift = fetch_byte_imm();
194805b261ecSmrg            TRACE_AND_STEP();
194905b261ecSmrg            bit = shift & 0x1F;
195005b261ecSmrg            srcval = fetch_data_long(srcoffset);
195135c4bbdfSmrg            mask = (0x1 << bit);
195235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
195335c4bbdfSmrg            switch (rh) {
195435c4bbdfSmrg            case 5:
195535c4bbdfSmrg                store_data_long(srcoffset, srcval | mask);
195635c4bbdfSmrg                break;
195735c4bbdfSmrg            case 6:
195835c4bbdfSmrg                store_data_long(srcoffset, srcval & ~mask);
195935c4bbdfSmrg                break;
196035c4bbdfSmrg            case 7:
196135c4bbdfSmrg                store_data_long(srcoffset, srcval ^ mask);
196235c4bbdfSmrg                break;
196335c4bbdfSmrg            default:
196435c4bbdfSmrg                break;
196535c4bbdfSmrg            }
196635c4bbdfSmrg        }
196735c4bbdfSmrg        else {
196805b261ecSmrg            u16 srcval, mask;
196905b261ecSmrg            u8 shift;
197005b261ecSmrg
197105b261ecSmrg            srcoffset = decode_rm01_address(rl);
197205b261ecSmrg            DECODE_PRINTF(",");
197305b261ecSmrg            shift = fetch_byte_imm();
197405b261ecSmrg            TRACE_AND_STEP();
197505b261ecSmrg            bit = shift & 0xF;
197605b261ecSmrg            srcval = fetch_data_word(srcoffset);
197735c4bbdfSmrg            mask = (0x1 << bit);
197835c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
197935c4bbdfSmrg            switch (rh) {
198035c4bbdfSmrg            case 5:
198135c4bbdfSmrg                store_data_word(srcoffset, srcval | mask);
198235c4bbdfSmrg                break;
198335c4bbdfSmrg            case 6:
198435c4bbdfSmrg                store_data_word(srcoffset, srcval & ~mask);
198535c4bbdfSmrg                break;
198635c4bbdfSmrg            case 7:
198735c4bbdfSmrg                store_data_word(srcoffset, srcval ^ mask);
198835c4bbdfSmrg                break;
198935c4bbdfSmrg            default:
199035c4bbdfSmrg                break;
199135c4bbdfSmrg            }
199205b261ecSmrg        }
199305b261ecSmrg        break;
199405b261ecSmrg    case 2:
199505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
199605b261ecSmrg            u32 srcval, mask;
199705b261ecSmrg            u8 shift;
199805b261ecSmrg
199905b261ecSmrg            srcoffset = decode_rm10_address(rl);
200005b261ecSmrg            DECODE_PRINTF(",");
200105b261ecSmrg            shift = fetch_byte_imm();
200205b261ecSmrg            TRACE_AND_STEP();
200305b261ecSmrg            bit = shift & 0x1F;
200405b261ecSmrg            srcval = fetch_data_long(srcoffset);
200535c4bbdfSmrg            mask = (0x1 << bit);
200635c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
200735c4bbdfSmrg            switch (rh) {
200835c4bbdfSmrg            case 5:
200935c4bbdfSmrg                store_data_long(srcoffset, srcval | mask);
201035c4bbdfSmrg                break;
201135c4bbdfSmrg            case 6:
201235c4bbdfSmrg                store_data_long(srcoffset, srcval & ~mask);
201335c4bbdfSmrg                break;
201435c4bbdfSmrg            case 7:
201535c4bbdfSmrg                store_data_long(srcoffset, srcval ^ mask);
201635c4bbdfSmrg                break;
201735c4bbdfSmrg            default:
201835c4bbdfSmrg                break;
201935c4bbdfSmrg            }
202035c4bbdfSmrg        }
202135c4bbdfSmrg        else {
202205b261ecSmrg            u16 srcval, mask;
202305b261ecSmrg            u8 shift;
202405b261ecSmrg
202505b261ecSmrg            srcoffset = decode_rm10_address(rl);
202605b261ecSmrg            DECODE_PRINTF(",");
202705b261ecSmrg            shift = fetch_byte_imm();
202805b261ecSmrg            TRACE_AND_STEP();
202905b261ecSmrg            bit = shift & 0xF;
203005b261ecSmrg            srcval = fetch_data_word(srcoffset);
203135c4bbdfSmrg            mask = (0x1 << bit);
203235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
203335c4bbdfSmrg            switch (rh) {
203435c4bbdfSmrg            case 5:
203535c4bbdfSmrg                store_data_word(srcoffset, srcval | mask);
203635c4bbdfSmrg                break;
203735c4bbdfSmrg            case 6:
203835c4bbdfSmrg                store_data_word(srcoffset, srcval & ~mask);
203935c4bbdfSmrg                break;
204035c4bbdfSmrg            case 7:
204135c4bbdfSmrg                store_data_word(srcoffset, srcval ^ mask);
204235c4bbdfSmrg                break;
204335c4bbdfSmrg            default:
204435c4bbdfSmrg                break;
204535c4bbdfSmrg            }
204635c4bbdfSmrg        }
204735c4bbdfSmrg        break;
204835c4bbdfSmrg    case 3:                    /* register to register */
204905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
205005b261ecSmrg            u32 *srcreg;
205135c4bbdfSmrg            u32 mask;
205235c4bbdfSmrg            u8 shift;
205305b261ecSmrg
205405b261ecSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
205505b261ecSmrg            DECODE_PRINTF(",");
205605b261ecSmrg            shift = fetch_byte_imm();
205705b261ecSmrg            TRACE_AND_STEP();
205805b261ecSmrg            bit = shift & 0x1F;
205935c4bbdfSmrg            mask = (0x1 << bit);
206035c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
206135c4bbdfSmrg            switch (rh) {
206235c4bbdfSmrg            case 5:
206335c4bbdfSmrg                *srcreg |= mask;
206435c4bbdfSmrg                break;
206535c4bbdfSmrg            case 6:
206635c4bbdfSmrg                *srcreg &= ~mask;
206735c4bbdfSmrg                break;
206835c4bbdfSmrg            case 7:
206935c4bbdfSmrg                *srcreg ^= mask;
207035c4bbdfSmrg                break;
207135c4bbdfSmrg            default:
207235c4bbdfSmrg                break;
207335c4bbdfSmrg            }
207435c4bbdfSmrg        }
207535c4bbdfSmrg        else {
207605b261ecSmrg            u16 *srcreg;
207735c4bbdfSmrg            u16 mask;
207835c4bbdfSmrg            u8 shift;
207905b261ecSmrg
208005b261ecSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
208105b261ecSmrg            DECODE_PRINTF(",");
208205b261ecSmrg            shift = fetch_byte_imm();
208305b261ecSmrg            TRACE_AND_STEP();
208405b261ecSmrg            bit = shift & 0xF;
208535c4bbdfSmrg            mask = (0x1 << bit);
208635c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
208735c4bbdfSmrg            switch (rh) {
208835c4bbdfSmrg            case 5:
208935c4bbdfSmrg                *srcreg |= mask;
209035c4bbdfSmrg                break;
209135c4bbdfSmrg            case 6:
209235c4bbdfSmrg                *srcreg &= ~mask;
209335c4bbdfSmrg                break;
209435c4bbdfSmrg            case 7:
209535c4bbdfSmrg                *srcreg ^= mask;
209635c4bbdfSmrg                break;
209735c4bbdfSmrg            default:
209835c4bbdfSmrg                break;
209935c4bbdfSmrg            }
210005b261ecSmrg        }
210105b261ecSmrg        break;
210205b261ecSmrg    }
210305b261ecSmrg    DECODE_CLEAR_SEGOVR();
210405b261ecSmrg    END_OF_INSTR();
210505b261ecSmrg}
210605b261ecSmrg
210705b261ecSmrg/****************************************************************************
210805b261ecSmrgREMARKS:
210905b261ecSmrgHandles opcode 0x0f,0xbb
211005b261ecSmrg****************************************************************************/
211135c4bbdfSmrgstatic void
211235c4bbdfSmrgx86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
211305b261ecSmrg{
211405b261ecSmrg    int mod, rl, rh;
211505b261ecSmrg    uint srcoffset;
211635c4bbdfSmrg    int bit, disp;
211705b261ecSmrg
211805b261ecSmrg    START_OF_INSTR();
211905b261ecSmrg    DECODE_PRINTF("BTC\t");
212005b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
212105b261ecSmrg    switch (mod) {
212205b261ecSmrg    case 0:
212305b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
212435c4bbdfSmrg            u32 srcval, mask;
212505b261ecSmrg            u32 *shiftreg;
212605b261ecSmrg
212705b261ecSmrg            srcoffset = decode_rm00_address(rl);
212805b261ecSmrg            DECODE_PRINTF(",");
212905b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
213005b261ecSmrg            TRACE_AND_STEP();
213105b261ecSmrg            bit = *shiftreg & 0x1F;
213235c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
213335c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
213405b261ecSmrg            mask = (0x1 << bit);
213535c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
213635c4bbdfSmrg            store_data_long(srcoffset + disp, srcval ^ mask);
213735c4bbdfSmrg        }
213835c4bbdfSmrg        else {
213935c4bbdfSmrg            u16 srcval, mask;
214005b261ecSmrg            u16 *shiftreg;
214105b261ecSmrg
214205b261ecSmrg            srcoffset = decode_rm00_address(rl);
214305b261ecSmrg            DECODE_PRINTF(",");
214405b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
214505b261ecSmrg            TRACE_AND_STEP();
214605b261ecSmrg            bit = *shiftreg & 0xF;
214735c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
214835c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
214935c4bbdfSmrg            mask = (u16) (0x1 << bit);
215035c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
215135c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
215205b261ecSmrg        }
215305b261ecSmrg        break;
215405b261ecSmrg    case 1:
215505b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
215635c4bbdfSmrg            u32 srcval, mask;
215705b261ecSmrg            u32 *shiftreg;
215805b261ecSmrg
215905b261ecSmrg            srcoffset = decode_rm01_address(rl);
216005b261ecSmrg            DECODE_PRINTF(",");
216105b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
216205b261ecSmrg            TRACE_AND_STEP();
216305b261ecSmrg            bit = *shiftreg & 0x1F;
216435c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
216535c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
216605b261ecSmrg            mask = (0x1 << bit);
216735c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
216835c4bbdfSmrg            store_data_long(srcoffset + disp, srcval ^ mask);
216935c4bbdfSmrg        }
217035c4bbdfSmrg        else {
217135c4bbdfSmrg            u16 srcval, mask;
217205b261ecSmrg            u16 *shiftreg;
217305b261ecSmrg
217405b261ecSmrg            srcoffset = decode_rm01_address(rl);
217505b261ecSmrg            DECODE_PRINTF(",");
217605b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
217705b261ecSmrg            TRACE_AND_STEP();
217805b261ecSmrg            bit = *shiftreg & 0xF;
217935c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
218035c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
218135c4bbdfSmrg            mask = (u16) (0x1 << bit);
218235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
218335c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
218405b261ecSmrg        }
218505b261ecSmrg        break;
218605b261ecSmrg    case 2:
218705b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
218835c4bbdfSmrg            u32 srcval, mask;
218905b261ecSmrg            u32 *shiftreg;
219005b261ecSmrg
219105b261ecSmrg            srcoffset = decode_rm10_address(rl);
219205b261ecSmrg            DECODE_PRINTF(",");
219305b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
219405b261ecSmrg            TRACE_AND_STEP();
219505b261ecSmrg            bit = *shiftreg & 0x1F;
219635c4bbdfSmrg            disp = (s16) * shiftreg >> 5;
219735c4bbdfSmrg            srcval = fetch_data_long(srcoffset + disp);
219805b261ecSmrg            mask = (0x1 << bit);
219935c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
220035c4bbdfSmrg            store_data_long(srcoffset + disp, srcval ^ mask);
220135c4bbdfSmrg        }
220235c4bbdfSmrg        else {
220335c4bbdfSmrg            u16 srcval, mask;
220405b261ecSmrg            u16 *shiftreg;
220505b261ecSmrg
220605b261ecSmrg            srcoffset = decode_rm10_address(rl);
220705b261ecSmrg            DECODE_PRINTF(",");
220805b261ecSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
220905b261ecSmrg            TRACE_AND_STEP();
221005b261ecSmrg            bit = *shiftreg & 0xF;
221135c4bbdfSmrg            disp = (s16) * shiftreg >> 4;
221235c4bbdfSmrg            srcval = fetch_data_word(srcoffset + disp);
221335c4bbdfSmrg            mask = (u16) (0x1 << bit);
221435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
221535c4bbdfSmrg            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
221605b261ecSmrg        }
221705b261ecSmrg        break;
221835c4bbdfSmrg    case 3:                    /* register to register */
221905b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
222035c4bbdfSmrg            u32 *srcreg, *shiftreg;
222105b261ecSmrg            u32 mask;
222205b261ecSmrg
222305b261ecSmrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
222405b261ecSmrg            DECODE_PRINTF(",");
222505b261ecSmrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
222605b261ecSmrg            TRACE_AND_STEP();
222705b261ecSmrg            bit = *shiftreg & 0x1F;
222805b261ecSmrg            mask = (0x1 << bit);
222935c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
223035c4bbdfSmrg            *srcreg ^= mask;
223135c4bbdfSmrg        }
223235c4bbdfSmrg        else {
223335c4bbdfSmrg            u16 *srcreg, *shiftreg;
223435c4bbdfSmrg            u16 mask;
223535c4bbdfSmrg
223635c4bbdfSmrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
223735c4bbdfSmrg            DECODE_PRINTF(",");
223835c4bbdfSmrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
223935c4bbdfSmrg            TRACE_AND_STEP();
224035c4bbdfSmrg            bit = *shiftreg & 0xF;
224135c4bbdfSmrg            mask = (u16) (0x1 << bit);
224235c4bbdfSmrg            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
224305b261ecSmrg            *srcreg ^= mask;
224405b261ecSmrg        }
224505b261ecSmrg        break;
224605b261ecSmrg    }
224705b261ecSmrg    DECODE_CLEAR_SEGOVR();
224805b261ecSmrg    END_OF_INSTR();
224905b261ecSmrg}
225005b261ecSmrg
225105b261ecSmrg/****************************************************************************
225205b261ecSmrgREMARKS:
225305b261ecSmrgHandles opcode 0x0f,0xbc
225405b261ecSmrg****************************************************************************/
225535c4bbdfSmrgstatic void
225635c4bbdfSmrgx86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
225705b261ecSmrg{
225805b261ecSmrg    int mod, rl, rh;
225905b261ecSmrg    uint srcoffset;
226005b261ecSmrg
226105b261ecSmrg    START_OF_INSTR();
226205b261ecSmrg    DECODE_PRINTF("BSF\t");
226305b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
226435c4bbdfSmrg    switch (mod) {
226505b261ecSmrg    case 0:
226635c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
226735c4bbdfSmrg            u32 srcval, *dstreg;
226835c4bbdfSmrg
226935c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
227035c4bbdfSmrg            DECODE_PRINTF(",");
227135c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
227235c4bbdfSmrg            TRACE_AND_STEP();
227335c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
227435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
227535c4bbdfSmrg            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
227635c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
227735c4bbdfSmrg                    break;
227835c4bbdfSmrg        }
227935c4bbdfSmrg        else {
228035c4bbdfSmrg            u16 srcval, *dstreg;
228135c4bbdfSmrg
228235c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
228335c4bbdfSmrg            DECODE_PRINTF(",");
228435c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
228535c4bbdfSmrg            TRACE_AND_STEP();
228635c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
228735c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
228835c4bbdfSmrg            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
228935c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
229035c4bbdfSmrg                    break;
229135c4bbdfSmrg        }
229235c4bbdfSmrg        break;
229305b261ecSmrg    case 1:
229435c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
229535c4bbdfSmrg            u32 srcval, *dstreg;
229635c4bbdfSmrg
229735c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
229835c4bbdfSmrg            DECODE_PRINTF(",");
229935c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
230035c4bbdfSmrg            TRACE_AND_STEP();
230135c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
230235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
230335c4bbdfSmrg            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
230435c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
230535c4bbdfSmrg                    break;
230635c4bbdfSmrg        }
230735c4bbdfSmrg        else {
230835c4bbdfSmrg            u16 srcval, *dstreg;
230935c4bbdfSmrg
231035c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
231135c4bbdfSmrg            DECODE_PRINTF(",");
231235c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
231335c4bbdfSmrg            TRACE_AND_STEP();
231435c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
231535c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
231635c4bbdfSmrg            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
231735c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
231835c4bbdfSmrg                    break;
231935c4bbdfSmrg        }
232035c4bbdfSmrg        break;
232105b261ecSmrg    case 2:
232235c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
232335c4bbdfSmrg            u32 srcval, *dstreg;
232435c4bbdfSmrg
232535c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
232635c4bbdfSmrg            DECODE_PRINTF(",");
232735c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
232835c4bbdfSmrg            TRACE_AND_STEP();
232935c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
233035c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
233135c4bbdfSmrg            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
233235c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
233335c4bbdfSmrg                    break;
233435c4bbdfSmrg        }
233535c4bbdfSmrg        else {
233635c4bbdfSmrg            u16 srcval, *dstreg;
233735c4bbdfSmrg
233835c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
233935c4bbdfSmrg            DECODE_PRINTF(",");
234035c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
234135c4bbdfSmrg            TRACE_AND_STEP();
234235c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
234335c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
234435c4bbdfSmrg            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
234535c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
234635c4bbdfSmrg                    break;
234735c4bbdfSmrg        }
234835c4bbdfSmrg        break;
234935c4bbdfSmrg    case 3:                    /* register to register */
235035c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
235135c4bbdfSmrg            u32 srcval, *dstreg;
235235c4bbdfSmrg
235335c4bbdfSmrg            srcval = *DECODE_RM_LONG_REGISTER(rl);
235435c4bbdfSmrg            DECODE_PRINTF(",");
235535c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
235635c4bbdfSmrg            TRACE_AND_STEP();
235735c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
235835c4bbdfSmrg            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
235935c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
236035c4bbdfSmrg                    break;
236135c4bbdfSmrg        }
236235c4bbdfSmrg        else {
236335c4bbdfSmrg            u16 srcval, *dstreg;
236435c4bbdfSmrg
236535c4bbdfSmrg            srcval = *DECODE_RM_WORD_REGISTER(rl);
236635c4bbdfSmrg            DECODE_PRINTF(",");
236735c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
236835c4bbdfSmrg            TRACE_AND_STEP();
236935c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
237035c4bbdfSmrg            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
237135c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
237235c4bbdfSmrg                    break;
237335c4bbdfSmrg        }
237435c4bbdfSmrg        break;
237505b261ecSmrg    }
237605b261ecSmrg    DECODE_CLEAR_SEGOVR();
237705b261ecSmrg    END_OF_INSTR();
237805b261ecSmrg}
237905b261ecSmrg
238005b261ecSmrg/****************************************************************************
238105b261ecSmrgREMARKS:
238205b261ecSmrgHandles opcode 0x0f,0xbd
238305b261ecSmrg****************************************************************************/
238435c4bbdfSmrgstatic void
238535c4bbdfSmrgx86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
238605b261ecSmrg{
238705b261ecSmrg    int mod, rl, rh;
238805b261ecSmrg    uint srcoffset;
238905b261ecSmrg
239005b261ecSmrg    START_OF_INSTR();
239105b261ecSmrg    DECODE_PRINTF("BSR\t");
239205b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
239335c4bbdfSmrg    switch (mod) {
239405b261ecSmrg    case 0:
239535c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
239635c4bbdfSmrg            u32 srcval, *dstreg;
239735c4bbdfSmrg
239835c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
239935c4bbdfSmrg            DECODE_PRINTF(",");
240035c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
240135c4bbdfSmrg            TRACE_AND_STEP();
240235c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
240335c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
240435c4bbdfSmrg            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
240535c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
240635c4bbdfSmrg                    break;
240735c4bbdfSmrg        }
240835c4bbdfSmrg        else {
240935c4bbdfSmrg            u16 srcval, *dstreg;
241035c4bbdfSmrg
241135c4bbdfSmrg            srcoffset = decode_rm00_address(rl);
241235c4bbdfSmrg            DECODE_PRINTF(",");
241335c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
241435c4bbdfSmrg            TRACE_AND_STEP();
241535c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
241635c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
241735c4bbdfSmrg            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
241835c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
241935c4bbdfSmrg                    break;
242035c4bbdfSmrg        }
242135c4bbdfSmrg        break;
242205b261ecSmrg    case 1:
242335c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
242435c4bbdfSmrg            u32 srcval, *dstreg;
242535c4bbdfSmrg
242635c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
242735c4bbdfSmrg            DECODE_PRINTF(",");
242835c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
242935c4bbdfSmrg            TRACE_AND_STEP();
243035c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
243135c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
243235c4bbdfSmrg            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
243335c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
243435c4bbdfSmrg                    break;
243535c4bbdfSmrg        }
243635c4bbdfSmrg        else {
243735c4bbdfSmrg            u16 srcval, *dstreg;
243835c4bbdfSmrg
243935c4bbdfSmrg            srcoffset = decode_rm01_address(rl);
244035c4bbdfSmrg            DECODE_PRINTF(",");
244135c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
244235c4bbdfSmrg            TRACE_AND_STEP();
244335c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
244435c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
244535c4bbdfSmrg            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
244635c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
244735c4bbdfSmrg                    break;
244835c4bbdfSmrg        }
244935c4bbdfSmrg        break;
245005b261ecSmrg    case 2:
245135c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
245235c4bbdfSmrg            u32 srcval, *dstreg;
245335c4bbdfSmrg
245435c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
245535c4bbdfSmrg            DECODE_PRINTF(",");
245635c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
245735c4bbdfSmrg            TRACE_AND_STEP();
245835c4bbdfSmrg            srcval = fetch_data_long(srcoffset);
245935c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
246035c4bbdfSmrg            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
246135c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
246235c4bbdfSmrg                    break;
246335c4bbdfSmrg        }
246435c4bbdfSmrg        else {
246535c4bbdfSmrg            u16 srcval, *dstreg;
246635c4bbdfSmrg
246735c4bbdfSmrg            srcoffset = decode_rm10_address(rl);
246835c4bbdfSmrg            DECODE_PRINTF(",");
246935c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
247035c4bbdfSmrg            TRACE_AND_STEP();
247135c4bbdfSmrg            srcval = fetch_data_word(srcoffset);
247235c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
247335c4bbdfSmrg            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
247435c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
247535c4bbdfSmrg                    break;
247635c4bbdfSmrg        }
247735c4bbdfSmrg        break;
247835c4bbdfSmrg    case 3:                    /* register to register */
247935c4bbdfSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
248035c4bbdfSmrg            u32 srcval, *dstreg;
248135c4bbdfSmrg
248235c4bbdfSmrg            srcval = *DECODE_RM_LONG_REGISTER(rl);
248335c4bbdfSmrg            DECODE_PRINTF(",");
248435c4bbdfSmrg            dstreg = DECODE_RM_LONG_REGISTER(rh);
248535c4bbdfSmrg            TRACE_AND_STEP();
248635c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
248735c4bbdfSmrg            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
248835c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
248935c4bbdfSmrg                    break;
249035c4bbdfSmrg        }
249135c4bbdfSmrg        else {
249235c4bbdfSmrg            u16 srcval, *dstreg;
249335c4bbdfSmrg
249435c4bbdfSmrg            srcval = *DECODE_RM_WORD_REGISTER(rl);
249535c4bbdfSmrg            DECODE_PRINTF(",");
249635c4bbdfSmrg            dstreg = DECODE_RM_WORD_REGISTER(rh);
249735c4bbdfSmrg            TRACE_AND_STEP();
249835c4bbdfSmrg            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
249935c4bbdfSmrg            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
250035c4bbdfSmrg                if ((srcval >> *dstreg) & 1)
250135c4bbdfSmrg                    break;
250235c4bbdfSmrg        }
250335c4bbdfSmrg        break;
250405b261ecSmrg    }
250505b261ecSmrg    DECODE_CLEAR_SEGOVR();
250605b261ecSmrg    END_OF_INSTR();
250705b261ecSmrg}
250805b261ecSmrg
250905b261ecSmrg/****************************************************************************
251005b261ecSmrgREMARKS:
251105b261ecSmrgHandles opcode 0x0f,0xbe
251205b261ecSmrg****************************************************************************/
251335c4bbdfSmrgstatic void
251435c4bbdfSmrgx86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
251505b261ecSmrg{
251605b261ecSmrg    int mod, rl, rh;
251705b261ecSmrg    uint srcoffset;
251805b261ecSmrg
251905b261ecSmrg    START_OF_INSTR();
252005b261ecSmrg    DECODE_PRINTF("MOVSX\t");
252105b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
252205b261ecSmrg    switch (mod) {
252305b261ecSmrg    case 0:
252405b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
252505b261ecSmrg            u32 *destreg;
252605b261ecSmrg            u32 srcval;
252705b261ecSmrg
252805b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
252905b261ecSmrg            DECODE_PRINTF(",");
253005b261ecSmrg            srcoffset = decode_rm00_address(rl);
253135c4bbdfSmrg            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
253205b261ecSmrg            DECODE_PRINTF("\n");
253305b261ecSmrg            TRACE_AND_STEP();
253405b261ecSmrg            *destreg = srcval;
253535c4bbdfSmrg        }
253635c4bbdfSmrg        else {
253705b261ecSmrg            u16 *destreg;
253805b261ecSmrg            u16 srcval;
253905b261ecSmrg
254005b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
254105b261ecSmrg            DECODE_PRINTF(",");
254205b261ecSmrg            srcoffset = decode_rm00_address(rl);
254335c4bbdfSmrg            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
254405b261ecSmrg            DECODE_PRINTF("\n");
254505b261ecSmrg            TRACE_AND_STEP();
254605b261ecSmrg            *destreg = srcval;
254705b261ecSmrg        }
254805b261ecSmrg        break;
254905b261ecSmrg    case 1:
255005b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
255105b261ecSmrg            u32 *destreg;
255205b261ecSmrg            u32 srcval;
255305b261ecSmrg
255405b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
255505b261ecSmrg            DECODE_PRINTF(",");
255605b261ecSmrg            srcoffset = decode_rm01_address(rl);
255735c4bbdfSmrg            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
255805b261ecSmrg            DECODE_PRINTF("\n");
255905b261ecSmrg            TRACE_AND_STEP();
256005b261ecSmrg            *destreg = srcval;
256135c4bbdfSmrg        }
256235c4bbdfSmrg        else {
256305b261ecSmrg            u16 *destreg;
256405b261ecSmrg            u16 srcval;
256505b261ecSmrg
256605b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
256705b261ecSmrg            DECODE_PRINTF(",");
256805b261ecSmrg            srcoffset = decode_rm01_address(rl);
256935c4bbdfSmrg            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
257005b261ecSmrg            DECODE_PRINTF("\n");
257105b261ecSmrg            TRACE_AND_STEP();
257205b261ecSmrg            *destreg = srcval;
257305b261ecSmrg        }
257405b261ecSmrg        break;
257505b261ecSmrg    case 2:
257605b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
257705b261ecSmrg            u32 *destreg;
257805b261ecSmrg            u32 srcval;
257905b261ecSmrg
258005b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
258105b261ecSmrg            DECODE_PRINTF(",");
258205b261ecSmrg            srcoffset = decode_rm10_address(rl);
258335c4bbdfSmrg            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
258405b261ecSmrg            DECODE_PRINTF("\n");
258505b261ecSmrg            TRACE_AND_STEP();
258605b261ecSmrg            *destreg = srcval;
258735c4bbdfSmrg        }
258835c4bbdfSmrg        else {
258905b261ecSmrg            u16 *destreg;
259005b261ecSmrg            u16 srcval;
259105b261ecSmrg
259205b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
259305b261ecSmrg            DECODE_PRINTF(",");
259405b261ecSmrg            srcoffset = decode_rm10_address(rl);
259535c4bbdfSmrg            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
259605b261ecSmrg            DECODE_PRINTF("\n");
259705b261ecSmrg            TRACE_AND_STEP();
259805b261ecSmrg            *destreg = srcval;
259905b261ecSmrg        }
260005b261ecSmrg        break;
260135c4bbdfSmrg    case 3:                    /* register to register */
260205b261ecSmrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
260305b261ecSmrg            u32 *destreg;
260435c4bbdfSmrg            u8 *srcreg;
260505b261ecSmrg
260605b261ecSmrg            destreg = DECODE_RM_LONG_REGISTER(rh);
260705b261ecSmrg            DECODE_PRINTF(",");
260805b261ecSmrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
260905b261ecSmrg            DECODE_PRINTF("\n");
261005b261ecSmrg            TRACE_AND_STEP();
261135c4bbdfSmrg            *destreg = (s32) ((s8) * srcreg);
261235c4bbdfSmrg        }
261335c4bbdfSmrg        else {
261405b261ecSmrg            u16 *destreg;
261535c4bbdfSmrg            u8 *srcreg;
261605b261ecSmrg
261705b261ecSmrg            destreg = DECODE_RM_WORD_REGISTER(rh);
261805b261ecSmrg            DECODE_PRINTF(",");
261905b261ecSmrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
262005b261ecSmrg            DECODE_PRINTF("\n");
262105b261ecSmrg            TRACE_AND_STEP();
262235c4bbdfSmrg            *destreg = (s16) ((s8) * srcreg);
262305b261ecSmrg        }
262405b261ecSmrg        break;
262505b261ecSmrg    }
262605b261ecSmrg    DECODE_CLEAR_SEGOVR();
262705b261ecSmrg    END_OF_INSTR();
262805b261ecSmrg}
262905b261ecSmrg
263005b261ecSmrg/****************************************************************************
263105b261ecSmrgREMARKS:
263205b261ecSmrgHandles opcode 0x0f,0xbf
263305b261ecSmrg****************************************************************************/
263435c4bbdfSmrgstatic void
263535c4bbdfSmrgx86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
263605b261ecSmrg{
263705b261ecSmrg    int mod, rl, rh;
263805b261ecSmrg    uint srcoffset;
263905b261ecSmrg    u32 *destreg;
264005b261ecSmrg    u32 srcval;
264105b261ecSmrg    u16 *srcreg;
264205b261ecSmrg
264305b261ecSmrg    START_OF_INSTR();
264405b261ecSmrg    DECODE_PRINTF("MOVSX\t");
264505b261ecSmrg    FETCH_DECODE_MODRM(mod, rh, rl);
264605b261ecSmrg    switch (mod) {
264705b261ecSmrg    case 0:
264805b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
264905b261ecSmrg        DECODE_PRINTF(",");
265005b261ecSmrg        srcoffset = decode_rm00_address(rl);
265135c4bbdfSmrg        srcval = (s32) ((s16) fetch_data_word(srcoffset));
265205b261ecSmrg        DECODE_PRINTF("\n");
265305b261ecSmrg        TRACE_AND_STEP();
265405b261ecSmrg        *destreg = srcval;
265505b261ecSmrg        break;
265605b261ecSmrg    case 1:
265705b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
265805b261ecSmrg        DECODE_PRINTF(",");
265905b261ecSmrg        srcoffset = decode_rm01_address(rl);
266035c4bbdfSmrg        srcval = (s32) ((s16) fetch_data_word(srcoffset));
266105b261ecSmrg        DECODE_PRINTF("\n");
266205b261ecSmrg        TRACE_AND_STEP();
266305b261ecSmrg        *destreg = srcval;
266405b261ecSmrg        break;
266505b261ecSmrg    case 2:
266605b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
266705b261ecSmrg        DECODE_PRINTF(",");
266805b261ecSmrg        srcoffset = decode_rm10_address(rl);
266935c4bbdfSmrg        srcval = (s32) ((s16) fetch_data_word(srcoffset));
267005b261ecSmrg        DECODE_PRINTF("\n");
267105b261ecSmrg        TRACE_AND_STEP();
267205b261ecSmrg        *destreg = srcval;
267305b261ecSmrg        break;
267435c4bbdfSmrg    case 3:                    /* register to register */
267505b261ecSmrg        destreg = DECODE_RM_LONG_REGISTER(rh);
267605b261ecSmrg        DECODE_PRINTF(",");
267705b261ecSmrg        srcreg = DECODE_RM_WORD_REGISTER(rl);
267805b261ecSmrg        DECODE_PRINTF("\n");
267905b261ecSmrg        TRACE_AND_STEP();
268035c4bbdfSmrg        *destreg = (s32) ((s16) * srcreg);
268105b261ecSmrg        break;
268205b261ecSmrg    }
268305b261ecSmrg    DECODE_CLEAR_SEGOVR();
268405b261ecSmrg    END_OF_INSTR();
268505b261ecSmrg}
268605b261ecSmrg
26874642e01fSmrg/* Handles opcodes 0xc8-0xcf */
268835c4bbdfSmrgstatic void
268935c4bbdfSmrgx86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
26904642e01fSmrg{
26914642e01fSmrg    START_OF_INSTR();
26924642e01fSmrg    DECODE_PRINTF("BSWAP\n");
26934642e01fSmrg    TRACE_AND_STEP();
26944642e01fSmrg
26954642e01fSmrg    switch (op2) {
269635c4bbdfSmrg    case 0xc8:
269735c4bbdfSmrg        M.x86.R_EAX = bswap_32(M.x86.R_EAX);
269835c4bbdfSmrg        break;
269935c4bbdfSmrg    case 0xc9:
270035c4bbdfSmrg        M.x86.R_ECX = bswap_32(M.x86.R_ECX);
270135c4bbdfSmrg        break;
270235c4bbdfSmrg    case 0xca:
270335c4bbdfSmrg        M.x86.R_EDX = bswap_32(M.x86.R_EDX);
270435c4bbdfSmrg        break;
270535c4bbdfSmrg    case 0xcb:
270635c4bbdfSmrg        M.x86.R_EBX = bswap_32(M.x86.R_EBX);
270735c4bbdfSmrg        break;
270835c4bbdfSmrg    case 0xcc:
270935c4bbdfSmrg        M.x86.R_ESP = bswap_32(M.x86.R_ESP);
271035c4bbdfSmrg        break;
271135c4bbdfSmrg    case 0xcd:
271235c4bbdfSmrg        M.x86.R_EBP = bswap_32(M.x86.R_EBP);
271335c4bbdfSmrg        break;
271435c4bbdfSmrg    case 0xce:
271535c4bbdfSmrg        M.x86.R_ESI = bswap_32(M.x86.R_ESI);
271635c4bbdfSmrg        break;
271735c4bbdfSmrg    case 0xcf:
271835c4bbdfSmrg        M.x86.R_EDI = bswap_32(M.x86.R_EDI);
271935c4bbdfSmrg        break;
272035c4bbdfSmrg    default:
272135c4bbdfSmrg        /* can't happen */
272235c4bbdfSmrg        break;
27234642e01fSmrg    }
27244642e01fSmrg
27254642e01fSmrg    DECODE_CLEAR_SEGOVR();
27264642e01fSmrg    END_OF_INSTR();
27274642e01fSmrg}
27284642e01fSmrg
272905b261ecSmrg/***************************************************************************
273005b261ecSmrg * Double byte operation code table:
273105b261ecSmrg **************************************************************************/
273235c4bbdfSmrgvoid (*x86emu_optab2[256]) (u8) = {
273335c4bbdfSmrg                                        /*  0x00 */ x86emuOp2_illegal_op,
273435c4bbdfSmrg                                        /* Group F (ring 0 PM)      */
273535c4bbdfSmrg                                                /*  0x01 */ x86emuOp2_illegal_op,
273635c4bbdfSmrg                                                /* Group G (ring 0 PM)      */
273735c4bbdfSmrg                                                /*  0x02 */ x86emuOp2_illegal_op,
273835c4bbdfSmrg                                                /* lar (ring 0 PM)          */
273935c4bbdfSmrg                                                /*  0x03 */ x86emuOp2_illegal_op,
274035c4bbdfSmrg                                                /* lsl (ring 0 PM)          */
274105b261ecSmrg/*  0x04 */ x86emuOp2_illegal_op,
274235c4bbdfSmrg                                                /*  0x05 */ x86emuOp2_illegal_op,
274335c4bbdfSmrg                                                /* loadall (undocumented)   */
274435c4bbdfSmrg                                                /*  0x06 */ x86emuOp2_illegal_op,
274535c4bbdfSmrg                                                /* clts (ring 0 PM)         */
274635c4bbdfSmrg                                                /*  0x07 */ x86emuOp2_illegal_op,
274735c4bbdfSmrg                                                /* loadall (undocumented)   */
274835c4bbdfSmrg                                                /*  0x08 */ x86emuOp2_illegal_op,
274935c4bbdfSmrg                                                /* invd (ring 0 PM)         */
275035c4bbdfSmrg                                                /*  0x09 */ x86emuOp2_illegal_op,
275135c4bbdfSmrg                                                /* wbinvd (ring 0 PM)       */
275205b261ecSmrg/*  0x0a */ x86emuOp2_illegal_op,
275305b261ecSmrg/*  0x0b */ x86emuOp2_illegal_op,
275405b261ecSmrg/*  0x0c */ x86emuOp2_illegal_op,
275505b261ecSmrg/*  0x0d */ x86emuOp2_illegal_op,
275605b261ecSmrg/*  0x0e */ x86emuOp2_illegal_op,
275705b261ecSmrg/*  0x0f */ x86emuOp2_illegal_op,
275805b261ecSmrg/*  0x10 */ x86emuOp2_illegal_op,
275905b261ecSmrg/*  0x11 */ x86emuOp2_illegal_op,
276005b261ecSmrg/*  0x12 */ x86emuOp2_illegal_op,
276105b261ecSmrg/*  0x13 */ x86emuOp2_illegal_op,
276205b261ecSmrg/*  0x14 */ x86emuOp2_illegal_op,
276305b261ecSmrg/*  0x15 */ x86emuOp2_illegal_op,
276405b261ecSmrg/*  0x16 */ x86emuOp2_illegal_op,
276505b261ecSmrg/*  0x17 */ x86emuOp2_illegal_op,
276605b261ecSmrg/*  0x18 */ x86emuOp2_illegal_op,
276705b261ecSmrg/*  0x19 */ x86emuOp2_illegal_op,
276805b261ecSmrg/*  0x1a */ x86emuOp2_illegal_op,
276905b261ecSmrg/*  0x1b */ x86emuOp2_illegal_op,
277005b261ecSmrg/*  0x1c */ x86emuOp2_illegal_op,
277105b261ecSmrg/*  0x1d */ x86emuOp2_illegal_op,
277205b261ecSmrg/*  0x1e */ x86emuOp2_illegal_op,
277305b261ecSmrg/*  0x1f */ x86emuOp2_illegal_op,
277435c4bbdfSmrg                                                /*  0x20 */ x86emuOp2_illegal_op,
277535c4bbdfSmrg                                                /* mov reg32,creg (ring 0 PM) */
277635c4bbdfSmrg                                                /*  0x21 */ x86emuOp2_illegal_op,
277735c4bbdfSmrg                                                /* mov reg32,dreg (ring 0 PM) */
277835c4bbdfSmrg                                                /*  0x22 */ x86emuOp2_illegal_op,
277935c4bbdfSmrg                                                /* mov creg,reg32 (ring 0 PM) */
278035c4bbdfSmrg                                                /*  0x23 */ x86emuOp2_illegal_op,
278135c4bbdfSmrg                                                /* mov dreg,reg32 (ring 0 PM) */
278235c4bbdfSmrg                                                /*  0x24 */ x86emuOp2_illegal_op,
278335c4bbdfSmrg                                                /* mov reg32,treg (ring 0 PM) */
278405b261ecSmrg/*  0x25 */ x86emuOp2_illegal_op,
278535c4bbdfSmrg                                                /*  0x26 */ x86emuOp2_illegal_op,
278635c4bbdfSmrg                                                /* mov treg,reg32 (ring 0 PM) */
278705b261ecSmrg/*  0x27 */ x86emuOp2_illegal_op,
278805b261ecSmrg/*  0x28 */ x86emuOp2_illegal_op,
278905b261ecSmrg/*  0x29 */ x86emuOp2_illegal_op,
279005b261ecSmrg/*  0x2a */ x86emuOp2_illegal_op,
279105b261ecSmrg/*  0x2b */ x86emuOp2_illegal_op,
279205b261ecSmrg/*  0x2c */ x86emuOp2_illegal_op,
279305b261ecSmrg/*  0x2d */ x86emuOp2_illegal_op,
279405b261ecSmrg/*  0x2e */ x86emuOp2_illegal_op,
279505b261ecSmrg/*  0x2f */ x86emuOp2_illegal_op,
279605b261ecSmrg/*  0x30 */ x86emuOp2_illegal_op,
279705b261ecSmrg/*  0x31 */ x86emuOp2_rdtsc,
279805b261ecSmrg/*  0x32 */ x86emuOp2_illegal_op,
279905b261ecSmrg/*  0x33 */ x86emuOp2_illegal_op,
280005b261ecSmrg/*  0x34 */ x86emuOp2_illegal_op,
280105b261ecSmrg/*  0x35 */ x86emuOp2_illegal_op,
280205b261ecSmrg/*  0x36 */ x86emuOp2_illegal_op,
280305b261ecSmrg/*  0x37 */ x86emuOp2_illegal_op,
280405b261ecSmrg/*  0x38 */ x86emuOp2_illegal_op,
280505b261ecSmrg/*  0x39 */ x86emuOp2_illegal_op,
280605b261ecSmrg/*  0x3a */ x86emuOp2_illegal_op,
280705b261ecSmrg/*  0x3b */ x86emuOp2_illegal_op,
280805b261ecSmrg/*  0x3c */ x86emuOp2_illegal_op,
280905b261ecSmrg/*  0x3d */ x86emuOp2_illegal_op,
281005b261ecSmrg/*  0x3e */ x86emuOp2_illegal_op,
281105b261ecSmrg/*  0x3f */ x86emuOp2_illegal_op,
281205b261ecSmrg/*  0x40 */ x86emuOp2_illegal_op,
281305b261ecSmrg/*  0x41 */ x86emuOp2_illegal_op,
281405b261ecSmrg/*  0x42 */ x86emuOp2_illegal_op,
281505b261ecSmrg/*  0x43 */ x86emuOp2_illegal_op,
281605b261ecSmrg/*  0x44 */ x86emuOp2_illegal_op,
281705b261ecSmrg/*  0x45 */ x86emuOp2_illegal_op,
281805b261ecSmrg/*  0x46 */ x86emuOp2_illegal_op,
281905b261ecSmrg/*  0x47 */ x86emuOp2_illegal_op,
282005b261ecSmrg/*  0x48 */ x86emuOp2_illegal_op,
282105b261ecSmrg/*  0x49 */ x86emuOp2_illegal_op,
282205b261ecSmrg/*  0x4a */ x86emuOp2_illegal_op,
282305b261ecSmrg/*  0x4b */ x86emuOp2_illegal_op,
282405b261ecSmrg/*  0x4c */ x86emuOp2_illegal_op,
282505b261ecSmrg/*  0x4d */ x86emuOp2_illegal_op,
282605b261ecSmrg/*  0x4e */ x86emuOp2_illegal_op,
282705b261ecSmrg/*  0x4f */ x86emuOp2_illegal_op,
282805b261ecSmrg/*  0x50 */ x86emuOp2_illegal_op,
282905b261ecSmrg/*  0x51 */ x86emuOp2_illegal_op,
283005b261ecSmrg/*  0x52 */ x86emuOp2_illegal_op,
283105b261ecSmrg/*  0x53 */ x86emuOp2_illegal_op,
283205b261ecSmrg/*  0x54 */ x86emuOp2_illegal_op,
283305b261ecSmrg/*  0x55 */ x86emuOp2_illegal_op,
283405b261ecSmrg/*  0x56 */ x86emuOp2_illegal_op,
283505b261ecSmrg/*  0x57 */ x86emuOp2_illegal_op,
283605b261ecSmrg/*  0x58 */ x86emuOp2_illegal_op,
283705b261ecSmrg/*  0x59 */ x86emuOp2_illegal_op,
283805b261ecSmrg/*  0x5a */ x86emuOp2_illegal_op,
283905b261ecSmrg/*  0x5b */ x86emuOp2_illegal_op,
284005b261ecSmrg/*  0x5c */ x86emuOp2_illegal_op,
284105b261ecSmrg/*  0x5d */ x86emuOp2_illegal_op,
284205b261ecSmrg/*  0x5e */ x86emuOp2_illegal_op,
284305b261ecSmrg/*  0x5f */ x86emuOp2_illegal_op,
284405b261ecSmrg/*  0x60 */ x86emuOp2_illegal_op,
284505b261ecSmrg/*  0x61 */ x86emuOp2_illegal_op,
284605b261ecSmrg/*  0x62 */ x86emuOp2_illegal_op,
284705b261ecSmrg/*  0x63 */ x86emuOp2_illegal_op,
284805b261ecSmrg/*  0x64 */ x86emuOp2_illegal_op,
284905b261ecSmrg/*  0x65 */ x86emuOp2_illegal_op,
285005b261ecSmrg/*  0x66 */ x86emuOp2_illegal_op,
285105b261ecSmrg/*  0x67 */ x86emuOp2_illegal_op,
285205b261ecSmrg/*  0x68 */ x86emuOp2_illegal_op,
285305b261ecSmrg/*  0x69 */ x86emuOp2_illegal_op,
285405b261ecSmrg/*  0x6a */ x86emuOp2_illegal_op,
285505b261ecSmrg/*  0x6b */ x86emuOp2_illegal_op,
285605b261ecSmrg/*  0x6c */ x86emuOp2_illegal_op,
285705b261ecSmrg/*  0x6d */ x86emuOp2_illegal_op,
285805b261ecSmrg/*  0x6e */ x86emuOp2_illegal_op,
285905b261ecSmrg/*  0x6f */ x86emuOp2_illegal_op,
286005b261ecSmrg/*  0x70 */ x86emuOp2_illegal_op,
286105b261ecSmrg/*  0x71 */ x86emuOp2_illegal_op,
286205b261ecSmrg/*  0x72 */ x86emuOp2_illegal_op,
286305b261ecSmrg/*  0x73 */ x86emuOp2_illegal_op,
286405b261ecSmrg/*  0x74 */ x86emuOp2_illegal_op,
286505b261ecSmrg/*  0x75 */ x86emuOp2_illegal_op,
286605b261ecSmrg/*  0x76 */ x86emuOp2_illegal_op,
286705b261ecSmrg/*  0x77 */ x86emuOp2_illegal_op,
286805b261ecSmrg/*  0x78 */ x86emuOp2_illegal_op,
286905b261ecSmrg/*  0x79 */ x86emuOp2_illegal_op,
287005b261ecSmrg/*  0x7a */ x86emuOp2_illegal_op,
287105b261ecSmrg/*  0x7b */ x86emuOp2_illegal_op,
287205b261ecSmrg/*  0x7c */ x86emuOp2_illegal_op,
287305b261ecSmrg/*  0x7d */ x86emuOp2_illegal_op,
287405b261ecSmrg/*  0x7e */ x86emuOp2_illegal_op,
287505b261ecSmrg/*  0x7f */ x86emuOp2_illegal_op,
287605b261ecSmrg/*  0x80 */ x86emuOp2_long_jump,
287705b261ecSmrg/*  0x81 */ x86emuOp2_long_jump,
287805b261ecSmrg/*  0x82 */ x86emuOp2_long_jump,
287905b261ecSmrg/*  0x83 */ x86emuOp2_long_jump,
288005b261ecSmrg/*  0x84 */ x86emuOp2_long_jump,
288105b261ecSmrg/*  0x85 */ x86emuOp2_long_jump,
288205b261ecSmrg/*  0x86 */ x86emuOp2_long_jump,
288305b261ecSmrg/*  0x87 */ x86emuOp2_long_jump,
288405b261ecSmrg/*  0x88 */ x86emuOp2_long_jump,
288505b261ecSmrg/*  0x89 */ x86emuOp2_long_jump,
288605b261ecSmrg/*  0x8a */ x86emuOp2_long_jump,
288705b261ecSmrg/*  0x8b */ x86emuOp2_long_jump,
288805b261ecSmrg/*  0x8c */ x86emuOp2_long_jump,
288905b261ecSmrg/*  0x8d */ x86emuOp2_long_jump,
289005b261ecSmrg/*  0x8e */ x86emuOp2_long_jump,
289105b261ecSmrg/*  0x8f */ x86emuOp2_long_jump,
289205b261ecSmrg/*  0x90 */ x86emuOp2_set_byte,
289305b261ecSmrg/*  0x91 */ x86emuOp2_set_byte,
289405b261ecSmrg/*  0x92 */ x86emuOp2_set_byte,
289505b261ecSmrg/*  0x93 */ x86emuOp2_set_byte,
289605b261ecSmrg/*  0x94 */ x86emuOp2_set_byte,
289705b261ecSmrg/*  0x95 */ x86emuOp2_set_byte,
289805b261ecSmrg/*  0x96 */ x86emuOp2_set_byte,
289905b261ecSmrg/*  0x97 */ x86emuOp2_set_byte,
290005b261ecSmrg/*  0x98 */ x86emuOp2_set_byte,
290105b261ecSmrg/*  0x99 */ x86emuOp2_set_byte,
290205b261ecSmrg/*  0x9a */ x86emuOp2_set_byte,
290305b261ecSmrg/*  0x9b */ x86emuOp2_set_byte,
290405b261ecSmrg/*  0x9c */ x86emuOp2_set_byte,
290505b261ecSmrg/*  0x9d */ x86emuOp2_set_byte,
290605b261ecSmrg/*  0x9e */ x86emuOp2_set_byte,
290705b261ecSmrg/*  0x9f */ x86emuOp2_set_byte,
290805b261ecSmrg/*  0xa0 */ x86emuOp2_push_FS,
290905b261ecSmrg/*  0xa1 */ x86emuOp2_pop_FS,
29104642e01fSmrg/*  0xa2 */ x86emuOp2_cpuid,
291105b261ecSmrg/*  0xa3 */ x86emuOp2_bt_R,
291205b261ecSmrg/*  0xa4 */ x86emuOp2_shld_IMM,
291305b261ecSmrg/*  0xa5 */ x86emuOp2_shld_CL,
291405b261ecSmrg/*  0xa6 */ x86emuOp2_illegal_op,
291505b261ecSmrg/*  0xa7 */ x86emuOp2_illegal_op,
291605b261ecSmrg/*  0xa8 */ x86emuOp2_push_GS,
291705b261ecSmrg/*  0xa9 */ x86emuOp2_pop_GS,
291805b261ecSmrg/*  0xaa */ x86emuOp2_illegal_op,
291905b261ecSmrg/*  0xab */ x86emuOp2_bts_R,
292005b261ecSmrg/*  0xac */ x86emuOp2_shrd_IMM,
292105b261ecSmrg/*  0xad */ x86emuOp2_shrd_CL,
292205b261ecSmrg/*  0xae */ x86emuOp2_illegal_op,
292305b261ecSmrg/*  0xaf */ x86emuOp2_imul_R_RM,
292435c4bbdfSmrg                                                /*  0xb0 */ x86emuOp2_illegal_op,
292535c4bbdfSmrg                                                /* TODO: cmpxchg */
292635c4bbdfSmrg                                                /*  0xb1 */ x86emuOp2_illegal_op,
292735c4bbdfSmrg                                                /* TODO: cmpxchg */
292805b261ecSmrg/*  0xb2 */ x86emuOp2_lss_R_IMM,
292905b261ecSmrg/*  0xb3 */ x86emuOp2_btr_R,
293005b261ecSmrg/*  0xb4 */ x86emuOp2_lfs_R_IMM,
293105b261ecSmrg/*  0xb5 */ x86emuOp2_lgs_R_IMM,
293205b261ecSmrg/*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
293305b261ecSmrg/*  0xb7 */ x86emuOp2_movzx_word_R_RM,
293405b261ecSmrg/*  0xb8 */ x86emuOp2_illegal_op,
293505b261ecSmrg/*  0xb9 */ x86emuOp2_illegal_op,
293605b261ecSmrg/*  0xba */ x86emuOp2_btX_I,
293705b261ecSmrg/*  0xbb */ x86emuOp2_btc_R,
293805b261ecSmrg/*  0xbc */ x86emuOp2_bsf,
293905b261ecSmrg/*  0xbd */ x86emuOp2_bsr,
294005b261ecSmrg/*  0xbe */ x86emuOp2_movsx_byte_R_RM,
294105b261ecSmrg/*  0xbf */ x86emuOp2_movsx_word_R_RM,
294235c4bbdfSmrg                                                /*  0xc0 */ x86emuOp2_illegal_op,
294335c4bbdfSmrg                                                /* TODO: xadd */
294435c4bbdfSmrg                                                /*  0xc1 */ x86emuOp2_illegal_op,
294535c4bbdfSmrg                                                /* TODO: xadd */
294605b261ecSmrg/*  0xc2 */ x86emuOp2_illegal_op,
294705b261ecSmrg/*  0xc3 */ x86emuOp2_illegal_op,
294805b261ecSmrg/*  0xc4 */ x86emuOp2_illegal_op,
294905b261ecSmrg/*  0xc5 */ x86emuOp2_illegal_op,
295005b261ecSmrg/*  0xc6 */ x86emuOp2_illegal_op,
295105b261ecSmrg/*  0xc7 */ x86emuOp2_illegal_op,
29524642e01fSmrg/*  0xc8 */ x86emuOp2_bswap,
29534642e01fSmrg/*  0xc9 */ x86emuOp2_bswap,
29544642e01fSmrg/*  0xca */ x86emuOp2_bswap,
29554642e01fSmrg/*  0xcb */ x86emuOp2_bswap,
29564642e01fSmrg/*  0xcc */ x86emuOp2_bswap,
29574642e01fSmrg/*  0xcd */ x86emuOp2_bswap,
29584642e01fSmrg/*  0xce */ x86emuOp2_bswap,
29594642e01fSmrg/*  0xcf */ x86emuOp2_bswap,
296005b261ecSmrg/*  0xd0 */ x86emuOp2_illegal_op,
296105b261ecSmrg/*  0xd1 */ x86emuOp2_illegal_op,
296205b261ecSmrg/*  0xd2 */ x86emuOp2_illegal_op,
296305b261ecSmrg/*  0xd3 */ x86emuOp2_illegal_op,
296405b261ecSmrg/*  0xd4 */ x86emuOp2_illegal_op,
296505b261ecSmrg/*  0xd5 */ x86emuOp2_illegal_op,
296605b261ecSmrg/*  0xd6 */ x86emuOp2_illegal_op,
296705b261ecSmrg/*  0xd7 */ x86emuOp2_illegal_op,
296805b261ecSmrg/*  0xd8 */ x86emuOp2_illegal_op,
296905b261ecSmrg/*  0xd9 */ x86emuOp2_illegal_op,
297005b261ecSmrg/*  0xda */ x86emuOp2_illegal_op,
297105b261ecSmrg/*  0xdb */ x86emuOp2_illegal_op,
297205b261ecSmrg/*  0xdc */ x86emuOp2_illegal_op,
297305b261ecSmrg/*  0xdd */ x86emuOp2_illegal_op,
297405b261ecSmrg/*  0xde */ x86emuOp2_illegal_op,
297505b261ecSmrg/*  0xdf */ x86emuOp2_illegal_op,
297605b261ecSmrg/*  0xe0 */ x86emuOp2_illegal_op,
297705b261ecSmrg/*  0xe1 */ x86emuOp2_illegal_op,
297805b261ecSmrg/*  0xe2 */ x86emuOp2_illegal_op,
297905b261ecSmrg/*  0xe3 */ x86emuOp2_illegal_op,
298005b261ecSmrg/*  0xe4 */ x86emuOp2_illegal_op,
298105b261ecSmrg/*  0xe5 */ x86emuOp2_illegal_op,
298205b261ecSmrg/*  0xe6 */ x86emuOp2_illegal_op,
298305b261ecSmrg/*  0xe7 */ x86emuOp2_illegal_op,
298405b261ecSmrg/*  0xe8 */ x86emuOp2_illegal_op,
298505b261ecSmrg/*  0xe9 */ x86emuOp2_illegal_op,
298605b261ecSmrg/*  0xea */ x86emuOp2_illegal_op,
298705b261ecSmrg/*  0xeb */ x86emuOp2_illegal_op,
298805b261ecSmrg/*  0xec */ x86emuOp2_illegal_op,
298905b261ecSmrg/*  0xed */ x86emuOp2_illegal_op,
299005b261ecSmrg/*  0xee */ x86emuOp2_illegal_op,
299105b261ecSmrg/*  0xef */ x86emuOp2_illegal_op,
299205b261ecSmrg/*  0xf0 */ x86emuOp2_illegal_op,
299305b261ecSmrg/*  0xf1 */ x86emuOp2_illegal_op,
299405b261ecSmrg/*  0xf2 */ x86emuOp2_illegal_op,
299505b261ecSmrg/*  0xf3 */ x86emuOp2_illegal_op,
299605b261ecSmrg/*  0xf4 */ x86emuOp2_illegal_op,
299705b261ecSmrg/*  0xf5 */ x86emuOp2_illegal_op,
299805b261ecSmrg/*  0xf6 */ x86emuOp2_illegal_op,
299905b261ecSmrg/*  0xf7 */ x86emuOp2_illegal_op,
300005b261ecSmrg/*  0xf8 */ x86emuOp2_illegal_op,
300105b261ecSmrg/*  0xf9 */ x86emuOp2_illegal_op,
300205b261ecSmrg/*  0xfa */ x86emuOp2_illegal_op,
300305b261ecSmrg/*  0xfb */ x86emuOp2_illegal_op,
300405b261ecSmrg/*  0xfc */ x86emuOp2_illegal_op,
300505b261ecSmrg/*  0xfd */ x86emuOp2_illegal_op,
300605b261ecSmrg/*  0xfe */ x86emuOp2_illegal_op,
300705b261ecSmrg/*  0xff */ x86emuOp2_illegal_op,
300805b261ecSmrg};
3009