1706f2543Smrg/****************************************************************************
2706f2543Smrg*
3706f2543Smrg*						Realmode X86 Emulator Library
4706f2543Smrg*
5706f2543Smrg*            	Copyright (C) 1996-1999 SciTech Software, Inc.
6706f2543Smrg* 				     Copyright (C) David Mosberger-Tang
7706f2543Smrg* 					   Copyright (C) 1999 Egbert Eich
8706f2543Smrg*
9706f2543Smrg*  ========================================================================
10706f2543Smrg*
11706f2543Smrg*  Permission to use, copy, modify, distribute, and sell this software and
12706f2543Smrg*  its documentation for any purpose is hereby granted without fee,
13706f2543Smrg*  provided that the above copyright notice appear in all copies and that
14706f2543Smrg*  both that copyright notice and this permission notice appear in
15706f2543Smrg*  supporting documentation, and that the name of the authors not be used
16706f2543Smrg*  in advertising or publicity pertaining to distribution of the software
17706f2543Smrg*  without specific, written prior permission.  The authors makes no
18706f2543Smrg*  representations about the suitability of this software for any purpose.
19706f2543Smrg*  It is provided "as is" without express or implied warranty.
20706f2543Smrg*
21706f2543Smrg*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22706f2543Smrg*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23706f2543Smrg*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24706f2543Smrg*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25706f2543Smrg*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26706f2543Smrg*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27706f2543Smrg*  PERFORMANCE OF THIS SOFTWARE.
28706f2543Smrg*
29706f2543Smrg*  ========================================================================
30706f2543Smrg*
31706f2543Smrg* Language:		ANSI C
32706f2543Smrg* Environment:	Any
33706f2543Smrg* Developer:    Kendall Bennett
34706f2543Smrg*
35706f2543Smrg* Description:  This file includes subroutines to implement the decoding
36706f2543Smrg*               and emulation of all the x86 extended two-byte processor
37706f2543Smrg*               instructions.
38706f2543Smrg*
39706f2543Smrg****************************************************************************/
40706f2543Smrg
41706f2543Smrg#include "x86emu/x86emui.h"
42706f2543Smrg
43706f2543Smrg#undef bswap_32
44706f2543Smrg#define bswap_32(x) (((x & 0xff000000) >> 24) | \
45706f2543Smrg		     ((x & 0x00ff0000) >> 8) | \
46706f2543Smrg		     ((x & 0x0000ff00) << 8) | \
47706f2543Smrg		     ((x & 0x000000ff) << 24))
48706f2543Smrg
49706f2543Smrg/*----------------------------- Implementation ----------------------------*/
50706f2543Smrg
51706f2543Smrg/****************************************************************************
52706f2543SmrgPARAMETERS:
53706f2543Smrgop1 - Instruction op code
54706f2543Smrg
55706f2543SmrgREMARKS:
56706f2543SmrgHandles illegal opcodes.
57706f2543Smrg****************************************************************************/
58706f2543Smrgstatic void x86emuOp2_illegal_op(
59706f2543Smrg	u8 op2)
60706f2543Smrg{
61706f2543Smrg	START_OF_INSTR();
62706f2543Smrg	DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
63706f2543Smrg	TRACE_REGS();
64706f2543Smrg	printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
65706f2543Smrg		M.x86.R_CS, M.x86.R_IP-2,op2);
66706f2543Smrg    HALT_SYS();
67706f2543Smrg    END_OF_INSTR();
68706f2543Smrg}
69706f2543Smrg
70706f2543Smrg#define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
71706f2543Smrg
72706f2543Smrg/****************************************************************************
73706f2543SmrgREMARKS:
74706f2543SmrgHandles opcode 0x0f,0x31
75706f2543Smrg****************************************************************************/
76706f2543Smrgstatic void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
77706f2543Smrg{
78706f2543Smrg#ifdef __HAS_LONG_LONG__
79706f2543Smrg    static u64 counter = 0;
80706f2543Smrg#else
81706f2543Smrg    static u32 counter = 0;
82706f2543Smrg#endif
83706f2543Smrg
84706f2543Smrg    counter += 0x10000;
85706f2543Smrg
86706f2543Smrg    /* read timestamp counter */
87706f2543Smrg    /*
88706f2543Smrg     * Note that instead of actually trying to accurately measure this, we just
89706f2543Smrg     * increase the counter by a fixed amount every time we hit one of these
90706f2543Smrg     * instructions.  Feel free to come up with a better method.
91706f2543Smrg     */
92706f2543Smrg    START_OF_INSTR();
93706f2543Smrg    DECODE_PRINTF("RDTSC\n");
94706f2543Smrg    TRACE_AND_STEP();
95706f2543Smrg#ifdef __HAS_LONG_LONG__
96706f2543Smrg    M.x86.R_EAX = counter & 0xffffffff;
97706f2543Smrg    M.x86.R_EDX = counter >> 32;
98706f2543Smrg#else
99706f2543Smrg    M.x86.R_EAX = counter;
100706f2543Smrg    M.x86.R_EDX = 0;
101706f2543Smrg#endif
102706f2543Smrg    DECODE_CLEAR_SEGOVR();
103706f2543Smrg    END_OF_INSTR();
104706f2543Smrg}
105706f2543Smrg
106706f2543Smrg/****************************************************************************
107706f2543SmrgREMARKS:
108706f2543SmrgHandles opcode 0x0f,0x80-0x8F
109706f2543Smrg****************************************************************************/
110706f2543Smrgstatic void x86emuOp2_long_jump(u8 op2)
111706f2543Smrg{
112706f2543Smrg    s32 target;
113706f2543Smrg    char *name = NULL;
114706f2543Smrg    int cond = 0;
115706f2543Smrg
116706f2543Smrg    /* conditional jump to word offset. */
117706f2543Smrg    START_OF_INSTR();
118706f2543Smrg    switch (op2) {
119706f2543Smrg      case 0x80:
120706f2543Smrg        name = "JO\t";
121706f2543Smrg        cond =  ACCESS_FLAG(F_OF);
122706f2543Smrg        break;
123706f2543Smrg      case 0x81:
124706f2543Smrg        name = "JNO\t";
125706f2543Smrg        cond = !ACCESS_FLAG(F_OF);
126706f2543Smrg        break;
127706f2543Smrg      case 0x82:
128706f2543Smrg        name = "JB\t";
129706f2543Smrg        cond = ACCESS_FLAG(F_CF);
130706f2543Smrg        break;
131706f2543Smrg      case 0x83:
132706f2543Smrg        name = "JNB\t";
133706f2543Smrg        cond = !ACCESS_FLAG(F_CF);
134706f2543Smrg        break;
135706f2543Smrg      case 0x84:
136706f2543Smrg        name = "JZ\t";
137706f2543Smrg        cond = ACCESS_FLAG(F_ZF);
138706f2543Smrg        break;
139706f2543Smrg      case 0x85:
140706f2543Smrg        name = "JNZ\t";
141706f2543Smrg        cond = !ACCESS_FLAG(F_ZF);
142706f2543Smrg        break;
143706f2543Smrg      case 0x86:
144706f2543Smrg        name = "JBE\t";
145706f2543Smrg        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
146706f2543Smrg        break;
147706f2543Smrg      case 0x87:
148706f2543Smrg        name = "JNBE\t";
149706f2543Smrg        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
150706f2543Smrg        break;
151706f2543Smrg      case 0x88:
152706f2543Smrg        name = "JS\t";
153706f2543Smrg        cond = ACCESS_FLAG(F_SF);
154706f2543Smrg        break;
155706f2543Smrg      case 0x89:
156706f2543Smrg        name = "JNS\t";
157706f2543Smrg        cond = !ACCESS_FLAG(F_SF);
158706f2543Smrg        break;
159706f2543Smrg      case 0x8a:
160706f2543Smrg        name = "JP\t";
161706f2543Smrg        cond = ACCESS_FLAG(F_PF);
162706f2543Smrg        break;
163706f2543Smrg      case 0x8b:
164706f2543Smrg        name = "JNP\t";
165706f2543Smrg        cond = !ACCESS_FLAG(F_PF);
166706f2543Smrg        break;
167706f2543Smrg      case 0x8c:
168706f2543Smrg        name = "JL\t";
169706f2543Smrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
170706f2543Smrg        break;
171706f2543Smrg      case 0x8d:
172706f2543Smrg        name = "JNL\t";
173706f2543Smrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
174706f2543Smrg        break;
175706f2543Smrg      case 0x8e:
176706f2543Smrg        name = "JLE\t";
177706f2543Smrg        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
178706f2543Smrg                ACCESS_FLAG(F_ZF));
179706f2543Smrg        break;
180706f2543Smrg      case 0x8f:
181706f2543Smrg        name = "JNLE\t";
182706f2543Smrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
183706f2543Smrg                 ACCESS_FLAG(F_ZF));
184706f2543Smrg        break;
185706f2543Smrg    }
186706f2543Smrg    DECODE_PRINTF(name);
187706f2543Smrg    (void)name;
188706f2543Smrg    target = (s16) fetch_word_imm();
189706f2543Smrg    target += (s16) M.x86.R_IP;
190706f2543Smrg    DECODE_PRINTF2("%04x\n", target);
191706f2543Smrg    TRACE_AND_STEP();
192706f2543Smrg    if (cond)
193706f2543Smrg        M.x86.R_IP = (u16)target;
194706f2543Smrg    DECODE_CLEAR_SEGOVR();
195706f2543Smrg    END_OF_INSTR();
196706f2543Smrg}
197706f2543Smrg
198706f2543Smrg/****************************************************************************
199706f2543SmrgREMARKS:
200706f2543SmrgHandles opcode 0x0f,0x90-0x9F
201706f2543Smrg****************************************************************************/
202706f2543Smrgstatic void x86emuOp2_set_byte(u8 op2)
203706f2543Smrg{
204706f2543Smrg    int mod, rl, rh;
205706f2543Smrg    uint destoffset;
206706f2543Smrg    u8  *destreg;
207706f2543Smrg    char *name = NULL;
208706f2543Smrg    int cond = 0;
209706f2543Smrg
210706f2543Smrg    START_OF_INSTR();
211706f2543Smrg    switch (op2) {
212706f2543Smrg      case 0x90:
213706f2543Smrg        name = "SETO\t";
214706f2543Smrg        cond =  ACCESS_FLAG(F_OF);
215706f2543Smrg        break;
216706f2543Smrg      case 0x91:
217706f2543Smrg        name = "SETNO\t";
218706f2543Smrg        cond = !ACCESS_FLAG(F_OF);
219706f2543Smrg        break;
220706f2543Smrg      case 0x92:
221706f2543Smrg        name = "SETB\t";
222706f2543Smrg        cond = ACCESS_FLAG(F_CF);
223706f2543Smrg        break;
224706f2543Smrg      case 0x93:
225706f2543Smrg        name = "SETNB\t";
226706f2543Smrg        cond = !ACCESS_FLAG(F_CF);
227706f2543Smrg        break;
228706f2543Smrg      case 0x94:
229706f2543Smrg        name = "SETZ\t";
230706f2543Smrg        cond = ACCESS_FLAG(F_ZF);
231706f2543Smrg        break;
232706f2543Smrg      case 0x95:
233706f2543Smrg        name = "SETNZ\t";
234706f2543Smrg        cond = !ACCESS_FLAG(F_ZF);
235706f2543Smrg        break;
236706f2543Smrg      case 0x96:
237706f2543Smrg        name = "SETBE\t";
238706f2543Smrg        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
239706f2543Smrg        break;
240706f2543Smrg      case 0x97:
241706f2543Smrg        name = "SETNBE\t";
242706f2543Smrg        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
243706f2543Smrg        break;
244706f2543Smrg      case 0x98:
245706f2543Smrg        name = "SETS\t";
246706f2543Smrg        cond = ACCESS_FLAG(F_SF);
247706f2543Smrg        break;
248706f2543Smrg      case 0x99:
249706f2543Smrg        name = "SETNS\t";
250706f2543Smrg        cond = !ACCESS_FLAG(F_SF);
251706f2543Smrg        break;
252706f2543Smrg      case 0x9a:
253706f2543Smrg        name = "SETP\t";
254706f2543Smrg        cond = ACCESS_FLAG(F_PF);
255706f2543Smrg        break;
256706f2543Smrg      case 0x9b:
257706f2543Smrg        name = "SETNP\t";
258706f2543Smrg        cond = !ACCESS_FLAG(F_PF);
259706f2543Smrg        break;
260706f2543Smrg      case 0x9c:
261706f2543Smrg        name = "SETL\t";
262706f2543Smrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
263706f2543Smrg        break;
264706f2543Smrg      case 0x9d:
265706f2543Smrg        name = "SETNL\t";
266706f2543Smrg        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
267706f2543Smrg        break;
268706f2543Smrg      case 0x9e:
269706f2543Smrg        name = "SETLE\t";
270706f2543Smrg        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
271706f2543Smrg                ACCESS_FLAG(F_ZF));
272706f2543Smrg        break;
273706f2543Smrg      case 0x9f:
274706f2543Smrg        name = "SETNLE\t";
275706f2543Smrg        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
276706f2543Smrg                 ACCESS_FLAG(F_ZF));
277706f2543Smrg        break;
278706f2543Smrg    }
279706f2543Smrg    DECODE_PRINTF(name);
280706f2543Smrg    (void)name;
281706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
282706f2543Smrg    switch (mod) {
283706f2543Smrg    case 0:
284706f2543Smrg        destoffset = decode_rm00_address(rl);
285706f2543Smrg        TRACE_AND_STEP();
286706f2543Smrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
287706f2543Smrg        break;
288706f2543Smrg    case 1:
289706f2543Smrg        destoffset = decode_rm01_address(rl);
290706f2543Smrg        TRACE_AND_STEP();
291706f2543Smrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
292706f2543Smrg        break;
293706f2543Smrg    case 2:
294706f2543Smrg        destoffset = decode_rm10_address(rl);
295706f2543Smrg        TRACE_AND_STEP();
296706f2543Smrg        store_data_byte(destoffset, cond ? 0x01 : 0x00);
297706f2543Smrg        break;
298706f2543Smrg    case 3:                     /* register to register */
299706f2543Smrg        destreg = DECODE_RM_BYTE_REGISTER(rl);
300706f2543Smrg        TRACE_AND_STEP();
301706f2543Smrg        *destreg = cond ? 0x01 : 0x00;
302706f2543Smrg        break;
303706f2543Smrg    }
304706f2543Smrg    DECODE_CLEAR_SEGOVR();
305706f2543Smrg    END_OF_INSTR();
306706f2543Smrg}
307706f2543Smrg
308706f2543Smrg/****************************************************************************
309706f2543SmrgREMARKS:
310706f2543SmrgHandles opcode 0x0f,0xa0
311706f2543Smrg****************************************************************************/
312706f2543Smrgstatic void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
313706f2543Smrg{
314706f2543Smrg    START_OF_INSTR();
315706f2543Smrg    DECODE_PRINTF("PUSH\tFS\n");
316706f2543Smrg    TRACE_AND_STEP();
317706f2543Smrg    push_word(M.x86.R_FS);
318706f2543Smrg    DECODE_CLEAR_SEGOVR();
319706f2543Smrg    END_OF_INSTR();
320706f2543Smrg}
321706f2543Smrg
322706f2543Smrg/****************************************************************************
323706f2543SmrgREMARKS:
324706f2543SmrgHandles opcode 0x0f,0xa1
325706f2543Smrg****************************************************************************/
326706f2543Smrgstatic void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
327706f2543Smrg{
328706f2543Smrg    START_OF_INSTR();
329706f2543Smrg    DECODE_PRINTF("POP\tFS\n");
330706f2543Smrg    TRACE_AND_STEP();
331706f2543Smrg    M.x86.R_FS = pop_word();
332706f2543Smrg    DECODE_CLEAR_SEGOVR();
333706f2543Smrg    END_OF_INSTR();
334706f2543Smrg}
335706f2543Smrg
336706f2543Smrg/****************************************************************************
337706f2543SmrgREMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
338706f2543SmrgHandles opcode 0x0f,0xa2
339706f2543Smrg****************************************************************************/
340706f2543Smrgstatic void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
341706f2543Smrg{
342706f2543Smrg    START_OF_INSTR();
343706f2543Smrg    DECODE_PRINTF("CPUID\n");
344706f2543Smrg    TRACE_AND_STEP();
345706f2543Smrg    cpuid();
346706f2543Smrg    DECODE_CLEAR_SEGOVR();
347706f2543Smrg    END_OF_INSTR();
348706f2543Smrg}
349706f2543Smrg
350706f2543Smrg/****************************************************************************
351706f2543SmrgREMARKS:
352706f2543SmrgHandles opcode 0x0f,0xa3
353706f2543Smrg****************************************************************************/
354706f2543Smrgstatic void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
355706f2543Smrg{
356706f2543Smrg    int mod, rl, rh;
357706f2543Smrg    uint srcoffset;
358706f2543Smrg    int bit,disp;
359706f2543Smrg
360706f2543Smrg    START_OF_INSTR();
361706f2543Smrg    DECODE_PRINTF("BT\t");
362706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
363706f2543Smrg    switch (mod) {
364706f2543Smrg    case 0:
365706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
366706f2543Smrg            u32 srcval;
367706f2543Smrg            u32 *shiftreg;
368706f2543Smrg
369706f2543Smrg            srcoffset = decode_rm00_address(rl);
370706f2543Smrg            DECODE_PRINTF(",");
371706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
372706f2543Smrg            TRACE_AND_STEP();
373706f2543Smrg            bit = *shiftreg & 0x1F;
374706f2543Smrg            disp = (s16)*shiftreg >> 5;
375706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
376706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
377706f2543Smrg        } else {
378706f2543Smrg            u16 srcval;
379706f2543Smrg            u16 *shiftreg;
380706f2543Smrg
381706f2543Smrg            srcoffset = decode_rm00_address(rl);
382706f2543Smrg            DECODE_PRINTF(",");
383706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
384706f2543Smrg            TRACE_AND_STEP();
385706f2543Smrg            bit = *shiftreg & 0xF;
386706f2543Smrg            disp = (s16)*shiftreg >> 4;
387706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
388706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
389706f2543Smrg        }
390706f2543Smrg        break;
391706f2543Smrg    case 1:
392706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
393706f2543Smrg            u32 srcval;
394706f2543Smrg            u32 *shiftreg;
395706f2543Smrg
396706f2543Smrg            srcoffset = decode_rm01_address(rl);
397706f2543Smrg            DECODE_PRINTF(",");
398706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
399706f2543Smrg            TRACE_AND_STEP();
400706f2543Smrg            bit = *shiftreg & 0x1F;
401706f2543Smrg            disp = (s16)*shiftreg >> 5;
402706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
403706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
404706f2543Smrg        } else {
405706f2543Smrg            u16 srcval;
406706f2543Smrg            u16 *shiftreg;
407706f2543Smrg
408706f2543Smrg            srcoffset = decode_rm01_address(rl);
409706f2543Smrg            DECODE_PRINTF(",");
410706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
411706f2543Smrg            TRACE_AND_STEP();
412706f2543Smrg            bit = *shiftreg & 0xF;
413706f2543Smrg            disp = (s16)*shiftreg >> 4;
414706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
415706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
416706f2543Smrg        }
417706f2543Smrg        break;
418706f2543Smrg    case 2:
419706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
420706f2543Smrg            u32 srcval;
421706f2543Smrg            u32 *shiftreg;
422706f2543Smrg
423706f2543Smrg            srcoffset = decode_rm10_address(rl);
424706f2543Smrg            DECODE_PRINTF(",");
425706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
426706f2543Smrg            TRACE_AND_STEP();
427706f2543Smrg            bit = *shiftreg & 0x1F;
428706f2543Smrg            disp = (s16)*shiftreg >> 5;
429706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
430706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
431706f2543Smrg        } else {
432706f2543Smrg            u16 srcval;
433706f2543Smrg            u16 *shiftreg;
434706f2543Smrg
435706f2543Smrg            srcoffset = decode_rm10_address(rl);
436706f2543Smrg            DECODE_PRINTF(",");
437706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
438706f2543Smrg            TRACE_AND_STEP();
439706f2543Smrg            bit = *shiftreg & 0xF;
440706f2543Smrg            disp = (s16)*shiftreg >> 4;
441706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
442706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
443706f2543Smrg        }
444706f2543Smrg        break;
445706f2543Smrg    case 3:                     /* register to register */
446706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
447706f2543Smrg            u32 *srcreg,*shiftreg;
448706f2543Smrg
449706f2543Smrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
450706f2543Smrg            DECODE_PRINTF(",");
451706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
452706f2543Smrg            TRACE_AND_STEP();
453706f2543Smrg            bit = *shiftreg & 0x1F;
454706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
455706f2543Smrg        } else {
456706f2543Smrg            u16 *srcreg,*shiftreg;
457706f2543Smrg
458706f2543Smrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
459706f2543Smrg            DECODE_PRINTF(",");
460706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
461706f2543Smrg            TRACE_AND_STEP();
462706f2543Smrg            bit = *shiftreg & 0xF;
463706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
464706f2543Smrg        }
465706f2543Smrg        break;
466706f2543Smrg    }
467706f2543Smrg    DECODE_CLEAR_SEGOVR();
468706f2543Smrg    END_OF_INSTR();
469706f2543Smrg}
470706f2543Smrg
471706f2543Smrg/****************************************************************************
472706f2543SmrgREMARKS:
473706f2543SmrgHandles opcode 0x0f,0xa4
474706f2543Smrg****************************************************************************/
475706f2543Smrgstatic void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
476706f2543Smrg{
477706f2543Smrg    int mod, rl, rh;
478706f2543Smrg    uint destoffset;
479706f2543Smrg	u8 shift;
480706f2543Smrg
481706f2543Smrg    START_OF_INSTR();
482706f2543Smrg    DECODE_PRINTF("SHLD\t");
483706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
484706f2543Smrg    switch (mod) {
485706f2543Smrg    case 0:
486706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
487706f2543Smrg            u32 destval;
488706f2543Smrg            u32 *shiftreg;
489706f2543Smrg
490706f2543Smrg            destoffset = decode_rm00_address(rl);
491706f2543Smrg            DECODE_PRINTF(",");
492706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
493706f2543Smrg            DECODE_PRINTF(",");
494706f2543Smrg            shift = fetch_byte_imm();
495706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
496706f2543Smrg            TRACE_AND_STEP();
497706f2543Smrg            destval = fetch_data_long(destoffset);
498706f2543Smrg            destval = shld_long(destval,*shiftreg,shift);
499706f2543Smrg            store_data_long(destoffset, destval);
500706f2543Smrg        } else {
501706f2543Smrg            u16 destval;
502706f2543Smrg            u16 *shiftreg;
503706f2543Smrg
504706f2543Smrg            destoffset = decode_rm00_address(rl);
505706f2543Smrg            DECODE_PRINTF(",");
506706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
507706f2543Smrg            DECODE_PRINTF(",");
508706f2543Smrg            shift = fetch_byte_imm();
509706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
510706f2543Smrg            TRACE_AND_STEP();
511706f2543Smrg            destval = fetch_data_word(destoffset);
512706f2543Smrg            destval = shld_word(destval,*shiftreg,shift);
513706f2543Smrg            store_data_word(destoffset, destval);
514706f2543Smrg        }
515706f2543Smrg        break;
516706f2543Smrg    case 1:
517706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
518706f2543Smrg            u32 destval;
519706f2543Smrg            u32 *shiftreg;
520706f2543Smrg
521706f2543Smrg            destoffset = decode_rm01_address(rl);
522706f2543Smrg            DECODE_PRINTF(",");
523706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
524706f2543Smrg            DECODE_PRINTF(",");
525706f2543Smrg            shift = fetch_byte_imm();
526706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
527706f2543Smrg            TRACE_AND_STEP();
528706f2543Smrg            destval = fetch_data_long(destoffset);
529706f2543Smrg            destval = shld_long(destval,*shiftreg,shift);
530706f2543Smrg            store_data_long(destoffset, destval);
531706f2543Smrg        } else {
532706f2543Smrg            u16 destval;
533706f2543Smrg            u16 *shiftreg;
534706f2543Smrg
535706f2543Smrg            destoffset = decode_rm01_address(rl);
536706f2543Smrg            DECODE_PRINTF(",");
537706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
538706f2543Smrg            DECODE_PRINTF(",");
539706f2543Smrg            shift = fetch_byte_imm();
540706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
541706f2543Smrg            TRACE_AND_STEP();
542706f2543Smrg            destval = fetch_data_word(destoffset);
543706f2543Smrg            destval = shld_word(destval,*shiftreg,shift);
544706f2543Smrg            store_data_word(destoffset, destval);
545706f2543Smrg        }
546706f2543Smrg        break;
547706f2543Smrg    case 2:
548706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
549706f2543Smrg            u32 destval;
550706f2543Smrg            u32 *shiftreg;
551706f2543Smrg
552706f2543Smrg            destoffset = decode_rm10_address(rl);
553706f2543Smrg            DECODE_PRINTF(",");
554706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
555706f2543Smrg            DECODE_PRINTF(",");
556706f2543Smrg            shift = fetch_byte_imm();
557706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
558706f2543Smrg            TRACE_AND_STEP();
559706f2543Smrg            destval = fetch_data_long(destoffset);
560706f2543Smrg            destval = shld_long(destval,*shiftreg,shift);
561706f2543Smrg            store_data_long(destoffset, destval);
562706f2543Smrg        } else {
563706f2543Smrg            u16 destval;
564706f2543Smrg            u16 *shiftreg;
565706f2543Smrg
566706f2543Smrg            destoffset = decode_rm10_address(rl);
567706f2543Smrg            DECODE_PRINTF(",");
568706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
569706f2543Smrg            DECODE_PRINTF(",");
570706f2543Smrg            shift = fetch_byte_imm();
571706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
572706f2543Smrg            TRACE_AND_STEP();
573706f2543Smrg            destval = fetch_data_word(destoffset);
574706f2543Smrg            destval = shld_word(destval,*shiftreg,shift);
575706f2543Smrg            store_data_word(destoffset, destval);
576706f2543Smrg        }
577706f2543Smrg        break;
578706f2543Smrg    case 3:                     /* register to register */
579706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
580706f2543Smrg            u32 *destreg,*shiftreg;
581706f2543Smrg
582706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rl);
583706f2543Smrg            DECODE_PRINTF(",");
584706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
585706f2543Smrg            DECODE_PRINTF(",");
586706f2543Smrg            shift = fetch_byte_imm();
587706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
588706f2543Smrg            TRACE_AND_STEP();
589706f2543Smrg            *destreg = shld_long(*destreg,*shiftreg,shift);
590706f2543Smrg        } else {
591706f2543Smrg            u16 *destreg,*shiftreg;
592706f2543Smrg
593706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rl);
594706f2543Smrg            DECODE_PRINTF(",");
595706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
596706f2543Smrg            DECODE_PRINTF(",");
597706f2543Smrg            shift = fetch_byte_imm();
598706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
599706f2543Smrg            TRACE_AND_STEP();
600706f2543Smrg            *destreg = shld_word(*destreg,*shiftreg,shift);
601706f2543Smrg        }
602706f2543Smrg        break;
603706f2543Smrg    }
604706f2543Smrg    DECODE_CLEAR_SEGOVR();
605706f2543Smrg    END_OF_INSTR();
606706f2543Smrg}
607706f2543Smrg
608706f2543Smrg/****************************************************************************
609706f2543SmrgREMARKS:
610706f2543SmrgHandles opcode 0x0f,0xa5
611706f2543Smrg****************************************************************************/
612706f2543Smrgstatic void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
613706f2543Smrg{
614706f2543Smrg    int mod, rl, rh;
615706f2543Smrg    uint destoffset;
616706f2543Smrg
617706f2543Smrg    START_OF_INSTR();
618706f2543Smrg    DECODE_PRINTF("SHLD\t");
619706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
620706f2543Smrg    switch (mod) {
621706f2543Smrg    case 0:
622706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
623706f2543Smrg            u32 destval;
624706f2543Smrg            u32 *shiftreg;
625706f2543Smrg
626706f2543Smrg            destoffset = decode_rm00_address(rl);
627706f2543Smrg            DECODE_PRINTF(",");
628706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
629706f2543Smrg            DECODE_PRINTF(",CL\n");
630706f2543Smrg            TRACE_AND_STEP();
631706f2543Smrg            destval = fetch_data_long(destoffset);
632706f2543Smrg            destval = shld_long(destval,*shiftreg,M.x86.R_CL);
633706f2543Smrg            store_data_long(destoffset, destval);
634706f2543Smrg        } else {
635706f2543Smrg            u16 destval;
636706f2543Smrg            u16 *shiftreg;
637706f2543Smrg
638706f2543Smrg            destoffset = decode_rm00_address(rl);
639706f2543Smrg            DECODE_PRINTF(",");
640706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
641706f2543Smrg            DECODE_PRINTF(",CL\n");
642706f2543Smrg            TRACE_AND_STEP();
643706f2543Smrg            destval = fetch_data_word(destoffset);
644706f2543Smrg            destval = shld_word(destval,*shiftreg,M.x86.R_CL);
645706f2543Smrg            store_data_word(destoffset, destval);
646706f2543Smrg        }
647706f2543Smrg        break;
648706f2543Smrg    case 1:
649706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
650706f2543Smrg            u32 destval;
651706f2543Smrg            u32 *shiftreg;
652706f2543Smrg
653706f2543Smrg            destoffset = decode_rm01_address(rl);
654706f2543Smrg            DECODE_PRINTF(",");
655706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
656706f2543Smrg            DECODE_PRINTF(",CL\n");
657706f2543Smrg            TRACE_AND_STEP();
658706f2543Smrg            destval = fetch_data_long(destoffset);
659706f2543Smrg            destval = shld_long(destval,*shiftreg,M.x86.R_CL);
660706f2543Smrg            store_data_long(destoffset, destval);
661706f2543Smrg        } else {
662706f2543Smrg            u16 destval;
663706f2543Smrg            u16 *shiftreg;
664706f2543Smrg
665706f2543Smrg            destoffset = decode_rm01_address(rl);
666706f2543Smrg            DECODE_PRINTF(",");
667706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
668706f2543Smrg            DECODE_PRINTF(",CL\n");
669706f2543Smrg            TRACE_AND_STEP();
670706f2543Smrg            destval = fetch_data_word(destoffset);
671706f2543Smrg            destval = shld_word(destval,*shiftreg,M.x86.R_CL);
672706f2543Smrg            store_data_word(destoffset, destval);
673706f2543Smrg        }
674706f2543Smrg        break;
675706f2543Smrg    case 2:
676706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
677706f2543Smrg            u32 destval;
678706f2543Smrg            u32 *shiftreg;
679706f2543Smrg
680706f2543Smrg            destoffset = decode_rm10_address(rl);
681706f2543Smrg            DECODE_PRINTF(",");
682706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
683706f2543Smrg            DECODE_PRINTF(",CL\n");
684706f2543Smrg            TRACE_AND_STEP();
685706f2543Smrg            destval = fetch_data_long(destoffset);
686706f2543Smrg            destval = shld_long(destval,*shiftreg,M.x86.R_CL);
687706f2543Smrg            store_data_long(destoffset, destval);
688706f2543Smrg        } else {
689706f2543Smrg            u16 destval;
690706f2543Smrg            u16 *shiftreg;
691706f2543Smrg
692706f2543Smrg            destoffset = decode_rm10_address(rl);
693706f2543Smrg            DECODE_PRINTF(",");
694706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
695706f2543Smrg            DECODE_PRINTF(",CL\n");
696706f2543Smrg            TRACE_AND_STEP();
697706f2543Smrg            destval = fetch_data_word(destoffset);
698706f2543Smrg            destval = shld_word(destval,*shiftreg,M.x86.R_CL);
699706f2543Smrg            store_data_word(destoffset, destval);
700706f2543Smrg        }
701706f2543Smrg        break;
702706f2543Smrg    case 3:                     /* register to register */
703706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704706f2543Smrg            u32 *destreg,*shiftreg;
705706f2543Smrg
706706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rl);
707706f2543Smrg            DECODE_PRINTF(",");
708706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
709706f2543Smrg            DECODE_PRINTF(",CL\n");
710706f2543Smrg            TRACE_AND_STEP();
711706f2543Smrg            *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
712706f2543Smrg        } else {
713706f2543Smrg            u16 *destreg,*shiftreg;
714706f2543Smrg
715706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rl);
716706f2543Smrg            DECODE_PRINTF(",");
717706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
718706f2543Smrg            DECODE_PRINTF(",CL\n");
719706f2543Smrg            TRACE_AND_STEP();
720706f2543Smrg            *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
721706f2543Smrg        }
722706f2543Smrg        break;
723706f2543Smrg    }
724706f2543Smrg    DECODE_CLEAR_SEGOVR();
725706f2543Smrg    END_OF_INSTR();
726706f2543Smrg}
727706f2543Smrg
728706f2543Smrg/****************************************************************************
729706f2543SmrgREMARKS:
730706f2543SmrgHandles opcode 0x0f,0xa8
731706f2543Smrg****************************************************************************/
732706f2543Smrgstatic void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
733706f2543Smrg{
734706f2543Smrg    START_OF_INSTR();
735706f2543Smrg    DECODE_PRINTF("PUSH\tGS\n");
736706f2543Smrg    TRACE_AND_STEP();
737706f2543Smrg    push_word(M.x86.R_GS);
738706f2543Smrg    DECODE_CLEAR_SEGOVR();
739706f2543Smrg    END_OF_INSTR();
740706f2543Smrg}
741706f2543Smrg
742706f2543Smrg/****************************************************************************
743706f2543SmrgREMARKS:
744706f2543SmrgHandles opcode 0x0f,0xa9
745706f2543Smrg****************************************************************************/
746706f2543Smrgstatic void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
747706f2543Smrg{
748706f2543Smrg    START_OF_INSTR();
749706f2543Smrg    DECODE_PRINTF("POP\tGS\n");
750706f2543Smrg    TRACE_AND_STEP();
751706f2543Smrg    M.x86.R_GS = pop_word();
752706f2543Smrg    DECODE_CLEAR_SEGOVR();
753706f2543Smrg    END_OF_INSTR();
754706f2543Smrg}
755706f2543Smrg
756706f2543Smrg/****************************************************************************
757706f2543SmrgREMARKS:
758706f2543SmrgHandles opcode 0x0f,0xab
759706f2543Smrg****************************************************************************/
760706f2543Smrgstatic void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
761706f2543Smrg{
762706f2543Smrg    int mod, rl, rh;
763706f2543Smrg    uint srcoffset;
764706f2543Smrg    int bit,disp;
765706f2543Smrg
766706f2543Smrg    START_OF_INSTR();
767706f2543Smrg    DECODE_PRINTF("BTS\t");
768706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
769706f2543Smrg    switch (mod) {
770706f2543Smrg    case 0:
771706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
772706f2543Smrg            u32 srcval,mask;
773706f2543Smrg            u32 *shiftreg;
774706f2543Smrg
775706f2543Smrg            srcoffset = decode_rm00_address(rl);
776706f2543Smrg            DECODE_PRINTF(",");
777706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
778706f2543Smrg            TRACE_AND_STEP();
779706f2543Smrg            bit = *shiftreg & 0x1F;
780706f2543Smrg            disp = (s16)*shiftreg >> 5;
781706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
782706f2543Smrg            mask = (0x1 << bit);
783706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
784706f2543Smrg            store_data_long(srcoffset+disp, srcval | mask);
785706f2543Smrg        } else {
786706f2543Smrg            u16 srcval,mask;
787706f2543Smrg            u16 *shiftreg;
788706f2543Smrg
789706f2543Smrg            srcoffset = decode_rm00_address(rl);
790706f2543Smrg            DECODE_PRINTF(",");
791706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
792706f2543Smrg            TRACE_AND_STEP();
793706f2543Smrg            bit = *shiftreg & 0xF;
794706f2543Smrg            disp = (s16)*shiftreg >> 4;
795706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
796706f2543Smrg			mask = (u16)(0x1 << bit);
797706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
798706f2543Smrg            store_data_word(srcoffset+disp, srcval | mask);
799706f2543Smrg        }
800706f2543Smrg        break;
801706f2543Smrg    case 1:
802706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
803706f2543Smrg            u32 srcval,mask;
804706f2543Smrg            u32 *shiftreg;
805706f2543Smrg
806706f2543Smrg            srcoffset = decode_rm01_address(rl);
807706f2543Smrg            DECODE_PRINTF(",");
808706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
809706f2543Smrg            TRACE_AND_STEP();
810706f2543Smrg            bit = *shiftreg & 0x1F;
811706f2543Smrg            disp = (s16)*shiftreg >> 5;
812706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
813706f2543Smrg            mask = (0x1 << bit);
814706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
815706f2543Smrg            store_data_long(srcoffset+disp, srcval | mask);
816706f2543Smrg        } else {
817706f2543Smrg            u16 srcval,mask;
818706f2543Smrg            u16 *shiftreg;
819706f2543Smrg
820706f2543Smrg            srcoffset = decode_rm01_address(rl);
821706f2543Smrg            DECODE_PRINTF(",");
822706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
823706f2543Smrg            TRACE_AND_STEP();
824706f2543Smrg            bit = *shiftreg & 0xF;
825706f2543Smrg            disp = (s16)*shiftreg >> 4;
826706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
827706f2543Smrg			mask = (u16)(0x1 << bit);
828706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
829706f2543Smrg            store_data_word(srcoffset+disp, srcval | mask);
830706f2543Smrg        }
831706f2543Smrg        break;
832706f2543Smrg    case 2:
833706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
834706f2543Smrg            u32 srcval,mask;
835706f2543Smrg            u32 *shiftreg;
836706f2543Smrg
837706f2543Smrg            srcoffset = decode_rm10_address(rl);
838706f2543Smrg            DECODE_PRINTF(",");
839706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
840706f2543Smrg            TRACE_AND_STEP();
841706f2543Smrg            bit = *shiftreg & 0x1F;
842706f2543Smrg            disp = (s16)*shiftreg >> 5;
843706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
844706f2543Smrg            mask = (0x1 << bit);
845706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
846706f2543Smrg            store_data_long(srcoffset+disp, srcval | mask);
847706f2543Smrg        } else {
848706f2543Smrg            u16 srcval,mask;
849706f2543Smrg            u16 *shiftreg;
850706f2543Smrg
851706f2543Smrg			srcoffset = decode_rm10_address(rl);
852706f2543Smrg			DECODE_PRINTF(",");
853706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
854706f2543Smrg			TRACE_AND_STEP();
855706f2543Smrg			bit = *shiftreg & 0xF;
856706f2543Smrg			disp = (s16)*shiftreg >> 4;
857706f2543Smrg			srcval = fetch_data_word(srcoffset+disp);
858706f2543Smrg			mask = (u16)(0x1 << bit);
859706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
860706f2543Smrg			store_data_word(srcoffset+disp, srcval | mask);
861706f2543Smrg		}
862706f2543Smrg		break;
863706f2543Smrg	case 3:                     /* register to register */
864706f2543Smrg		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
865706f2543Smrg			u32 *srcreg,*shiftreg;
866706f2543Smrg			u32 mask;
867706f2543Smrg
868706f2543Smrg			srcreg = DECODE_RM_LONG_REGISTER(rl);
869706f2543Smrg			DECODE_PRINTF(",");
870706f2543Smrg			shiftreg = DECODE_RM_LONG_REGISTER(rh);
871706f2543Smrg			TRACE_AND_STEP();
872706f2543Smrg			bit = *shiftreg & 0x1F;
873706f2543Smrg			mask = (0x1 << bit);
874706f2543Smrg			CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
875706f2543Smrg			*srcreg |= mask;
876706f2543Smrg		} else {
877706f2543Smrg			u16 *srcreg,*shiftreg;
878706f2543Smrg			u16 mask;
879706f2543Smrg
880706f2543Smrg			srcreg = DECODE_RM_WORD_REGISTER(rl);
881706f2543Smrg			DECODE_PRINTF(",");
882706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
883706f2543Smrg			TRACE_AND_STEP();
884706f2543Smrg			bit = *shiftreg & 0xF;
885706f2543Smrg			mask = (u16)(0x1 << bit);
886706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
887706f2543Smrg            *srcreg |= mask;
888706f2543Smrg        }
889706f2543Smrg        break;
890706f2543Smrg    }
891706f2543Smrg    DECODE_CLEAR_SEGOVR();
892706f2543Smrg    END_OF_INSTR();
893706f2543Smrg}
894706f2543Smrg
895706f2543Smrg/****************************************************************************
896706f2543SmrgREMARKS:
897706f2543SmrgHandles opcode 0x0f,0xac
898706f2543Smrg****************************************************************************/
899706f2543Smrgstatic void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
900706f2543Smrg{
901706f2543Smrg    int mod, rl, rh;
902706f2543Smrg    uint destoffset;
903706f2543Smrg	u8 shift;
904706f2543Smrg
905706f2543Smrg    START_OF_INSTR();
906706f2543Smrg    DECODE_PRINTF("SHLD\t");
907706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
908706f2543Smrg    switch (mod) {
909706f2543Smrg    case 0:
910706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911706f2543Smrg            u32 destval;
912706f2543Smrg            u32 *shiftreg;
913706f2543Smrg
914706f2543Smrg            destoffset = decode_rm00_address(rl);
915706f2543Smrg            DECODE_PRINTF(",");
916706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
917706f2543Smrg            DECODE_PRINTF(",");
918706f2543Smrg            shift = fetch_byte_imm();
919706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
920706f2543Smrg            TRACE_AND_STEP();
921706f2543Smrg            destval = fetch_data_long(destoffset);
922706f2543Smrg            destval = shrd_long(destval,*shiftreg,shift);
923706f2543Smrg            store_data_long(destoffset, destval);
924706f2543Smrg        } else {
925706f2543Smrg            u16 destval;
926706f2543Smrg            u16 *shiftreg;
927706f2543Smrg
928706f2543Smrg            destoffset = decode_rm00_address(rl);
929706f2543Smrg            DECODE_PRINTF(",");
930706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
931706f2543Smrg            DECODE_PRINTF(",");
932706f2543Smrg            shift = fetch_byte_imm();
933706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
934706f2543Smrg            TRACE_AND_STEP();
935706f2543Smrg            destval = fetch_data_word(destoffset);
936706f2543Smrg            destval = shrd_word(destval,*shiftreg,shift);
937706f2543Smrg            store_data_word(destoffset, destval);
938706f2543Smrg        }
939706f2543Smrg        break;
940706f2543Smrg    case 1:
941706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
942706f2543Smrg            u32 destval;
943706f2543Smrg            u32 *shiftreg;
944706f2543Smrg
945706f2543Smrg            destoffset = decode_rm01_address(rl);
946706f2543Smrg            DECODE_PRINTF(",");
947706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
948706f2543Smrg            DECODE_PRINTF(",");
949706f2543Smrg            shift = fetch_byte_imm();
950706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
951706f2543Smrg            TRACE_AND_STEP();
952706f2543Smrg            destval = fetch_data_long(destoffset);
953706f2543Smrg            destval = shrd_long(destval,*shiftreg,shift);
954706f2543Smrg            store_data_long(destoffset, destval);
955706f2543Smrg        } else {
956706f2543Smrg            u16 destval;
957706f2543Smrg            u16 *shiftreg;
958706f2543Smrg
959706f2543Smrg            destoffset = decode_rm01_address(rl);
960706f2543Smrg            DECODE_PRINTF(",");
961706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
962706f2543Smrg            DECODE_PRINTF(",");
963706f2543Smrg            shift = fetch_byte_imm();
964706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
965706f2543Smrg            TRACE_AND_STEP();
966706f2543Smrg            destval = fetch_data_word(destoffset);
967706f2543Smrg            destval = shrd_word(destval,*shiftreg,shift);
968706f2543Smrg            store_data_word(destoffset, destval);
969706f2543Smrg        }
970706f2543Smrg        break;
971706f2543Smrg    case 2:
972706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
973706f2543Smrg            u32 destval;
974706f2543Smrg            u32 *shiftreg;
975706f2543Smrg
976706f2543Smrg            destoffset = decode_rm10_address(rl);
977706f2543Smrg            DECODE_PRINTF(",");
978706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
979706f2543Smrg            DECODE_PRINTF(",");
980706f2543Smrg            shift = fetch_byte_imm();
981706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
982706f2543Smrg            TRACE_AND_STEP();
983706f2543Smrg            destval = fetch_data_long(destoffset);
984706f2543Smrg            destval = shrd_long(destval,*shiftreg,shift);
985706f2543Smrg            store_data_long(destoffset, destval);
986706f2543Smrg        } else {
987706f2543Smrg            u16 destval;
988706f2543Smrg            u16 *shiftreg;
989706f2543Smrg
990706f2543Smrg            destoffset = decode_rm10_address(rl);
991706f2543Smrg            DECODE_PRINTF(",");
992706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
993706f2543Smrg            DECODE_PRINTF(",");
994706f2543Smrg            shift = fetch_byte_imm();
995706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
996706f2543Smrg            TRACE_AND_STEP();
997706f2543Smrg            destval = fetch_data_word(destoffset);
998706f2543Smrg            destval = shrd_word(destval,*shiftreg,shift);
999706f2543Smrg            store_data_word(destoffset, destval);
1000706f2543Smrg        }
1001706f2543Smrg        break;
1002706f2543Smrg    case 3:                     /* register to register */
1003706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1004706f2543Smrg            u32 *destreg,*shiftreg;
1005706f2543Smrg
1006706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rl);
1007706f2543Smrg            DECODE_PRINTF(",");
1008706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
1009706f2543Smrg            DECODE_PRINTF(",");
1010706f2543Smrg            shift = fetch_byte_imm();
1011706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
1012706f2543Smrg            TRACE_AND_STEP();
1013706f2543Smrg            *destreg = shrd_long(*destreg,*shiftreg,shift);
1014706f2543Smrg        } else {
1015706f2543Smrg            u16 *destreg,*shiftreg;
1016706f2543Smrg
1017706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rl);
1018706f2543Smrg            DECODE_PRINTF(",");
1019706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
1020706f2543Smrg            DECODE_PRINTF(",");
1021706f2543Smrg            shift = fetch_byte_imm();
1022706f2543Smrg            DECODE_PRINTF2("%d\n", shift);
1023706f2543Smrg            TRACE_AND_STEP();
1024706f2543Smrg            *destreg = shrd_word(*destreg,*shiftreg,shift);
1025706f2543Smrg        }
1026706f2543Smrg        break;
1027706f2543Smrg    }
1028706f2543Smrg    DECODE_CLEAR_SEGOVR();
1029706f2543Smrg    END_OF_INSTR();
1030706f2543Smrg}
1031706f2543Smrg
1032706f2543Smrg/****************************************************************************
1033706f2543SmrgREMARKS:
1034706f2543SmrgHandles opcode 0x0f,0xad
1035706f2543Smrg****************************************************************************/
1036706f2543Smrgstatic void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
1037706f2543Smrg{
1038706f2543Smrg    int mod, rl, rh;
1039706f2543Smrg    uint destoffset;
1040706f2543Smrg
1041706f2543Smrg    START_OF_INSTR();
1042706f2543Smrg    DECODE_PRINTF("SHLD\t");
1043706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1044706f2543Smrg    switch (mod) {
1045706f2543Smrg    case 0:
1046706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1047706f2543Smrg            u32 destval;
1048706f2543Smrg            u32 *shiftreg;
1049706f2543Smrg
1050706f2543Smrg            destoffset = decode_rm00_address(rl);
1051706f2543Smrg            DECODE_PRINTF(",");
1052706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
1053706f2543Smrg            DECODE_PRINTF(",CL\n");
1054706f2543Smrg            TRACE_AND_STEP();
1055706f2543Smrg            destval = fetch_data_long(destoffset);
1056706f2543Smrg            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1057706f2543Smrg            store_data_long(destoffset, destval);
1058706f2543Smrg        } else {
1059706f2543Smrg            u16 destval;
1060706f2543Smrg            u16 *shiftreg;
1061706f2543Smrg
1062706f2543Smrg            destoffset = decode_rm00_address(rl);
1063706f2543Smrg            DECODE_PRINTF(",");
1064706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
1065706f2543Smrg            DECODE_PRINTF(",CL\n");
1066706f2543Smrg            TRACE_AND_STEP();
1067706f2543Smrg            destval = fetch_data_word(destoffset);
1068706f2543Smrg            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1069706f2543Smrg            store_data_word(destoffset, destval);
1070706f2543Smrg        }
1071706f2543Smrg        break;
1072706f2543Smrg    case 1:
1073706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1074706f2543Smrg            u32 destval;
1075706f2543Smrg            u32 *shiftreg;
1076706f2543Smrg
1077706f2543Smrg            destoffset = decode_rm01_address(rl);
1078706f2543Smrg            DECODE_PRINTF(",");
1079706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
1080706f2543Smrg            DECODE_PRINTF(",CL\n");
1081706f2543Smrg            TRACE_AND_STEP();
1082706f2543Smrg            destval = fetch_data_long(destoffset);
1083706f2543Smrg            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1084706f2543Smrg            store_data_long(destoffset, destval);
1085706f2543Smrg        } else {
1086706f2543Smrg            u16 destval;
1087706f2543Smrg            u16 *shiftreg;
1088706f2543Smrg
1089706f2543Smrg            destoffset = decode_rm01_address(rl);
1090706f2543Smrg            DECODE_PRINTF(",");
1091706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
1092706f2543Smrg            DECODE_PRINTF(",CL\n");
1093706f2543Smrg            TRACE_AND_STEP();
1094706f2543Smrg            destval = fetch_data_word(destoffset);
1095706f2543Smrg            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1096706f2543Smrg            store_data_word(destoffset, destval);
1097706f2543Smrg        }
1098706f2543Smrg        break;
1099706f2543Smrg    case 2:
1100706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1101706f2543Smrg            u32 destval;
1102706f2543Smrg            u32 *shiftreg;
1103706f2543Smrg
1104706f2543Smrg            destoffset = decode_rm10_address(rl);
1105706f2543Smrg            DECODE_PRINTF(",");
1106706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
1107706f2543Smrg            DECODE_PRINTF(",CL\n");
1108706f2543Smrg            TRACE_AND_STEP();
1109706f2543Smrg            destval = fetch_data_long(destoffset);
1110706f2543Smrg            destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1111706f2543Smrg            store_data_long(destoffset, destval);
1112706f2543Smrg        } else {
1113706f2543Smrg            u16 destval;
1114706f2543Smrg            u16 *shiftreg;
1115706f2543Smrg
1116706f2543Smrg            destoffset = decode_rm10_address(rl);
1117706f2543Smrg            DECODE_PRINTF(",");
1118706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
1119706f2543Smrg            DECODE_PRINTF(",CL\n");
1120706f2543Smrg            TRACE_AND_STEP();
1121706f2543Smrg            destval = fetch_data_word(destoffset);
1122706f2543Smrg            destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1123706f2543Smrg            store_data_word(destoffset, destval);
1124706f2543Smrg        }
1125706f2543Smrg        break;
1126706f2543Smrg    case 3:                     /* register to register */
1127706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1128706f2543Smrg            u32 *destreg,*shiftreg;
1129706f2543Smrg
1130706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rl);
1131706f2543Smrg            DECODE_PRINTF(",");
1132706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
1133706f2543Smrg            DECODE_PRINTF(",CL\n");
1134706f2543Smrg            TRACE_AND_STEP();
1135706f2543Smrg            *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
1136706f2543Smrg        } else {
1137706f2543Smrg            u16 *destreg,*shiftreg;
1138706f2543Smrg
1139706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rl);
1140706f2543Smrg            DECODE_PRINTF(",");
1141706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
1142706f2543Smrg            DECODE_PRINTF(",CL\n");
1143706f2543Smrg            TRACE_AND_STEP();
1144706f2543Smrg            *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
1145706f2543Smrg        }
1146706f2543Smrg        break;
1147706f2543Smrg    }
1148706f2543Smrg    DECODE_CLEAR_SEGOVR();
1149706f2543Smrg    END_OF_INSTR();
1150706f2543Smrg}
1151706f2543Smrg
1152706f2543Smrg/****************************************************************************
1153706f2543SmrgREMARKS:
1154706f2543SmrgHandles opcode 0x0f,0xaf
1155706f2543Smrg****************************************************************************/
1156706f2543Smrgstatic void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1157706f2543Smrg{
1158706f2543Smrg    int mod, rl, rh;
1159706f2543Smrg    uint srcoffset;
1160706f2543Smrg
1161706f2543Smrg    START_OF_INSTR();
1162706f2543Smrg    DECODE_PRINTF("IMUL\t");
1163706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1164706f2543Smrg    switch (mod) {
1165706f2543Smrg    case 0:
1166706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1167706f2543Smrg            u32 *destreg;
1168706f2543Smrg            u32 srcval;
1169706f2543Smrg            u32 res_lo,res_hi;
1170706f2543Smrg
1171706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1172706f2543Smrg            DECODE_PRINTF(",");
1173706f2543Smrg            srcoffset = decode_rm00_address(rl);
1174706f2543Smrg            srcval = fetch_data_long(srcoffset);
1175706f2543Smrg            TRACE_AND_STEP();
1176706f2543Smrg            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1177706f2543Smrg            if (res_hi != 0) {
1178706f2543Smrg                SET_FLAG(F_CF);
1179706f2543Smrg                SET_FLAG(F_OF);
1180706f2543Smrg            } else {
1181706f2543Smrg                CLEAR_FLAG(F_CF);
1182706f2543Smrg                CLEAR_FLAG(F_OF);
1183706f2543Smrg            }
1184706f2543Smrg            *destreg = (u32)res_lo;
1185706f2543Smrg        } else {
1186706f2543Smrg            u16 *destreg;
1187706f2543Smrg            u16 srcval;
1188706f2543Smrg            u32 res;
1189706f2543Smrg
1190706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1191706f2543Smrg            DECODE_PRINTF(",");
1192706f2543Smrg            srcoffset = decode_rm00_address(rl);
1193706f2543Smrg            srcval = fetch_data_word(srcoffset);
1194706f2543Smrg            TRACE_AND_STEP();
1195706f2543Smrg            res = (s16)*destreg * (s16)srcval;
1196706f2543Smrg            if (res > 0xFFFF) {
1197706f2543Smrg                SET_FLAG(F_CF);
1198706f2543Smrg                SET_FLAG(F_OF);
1199706f2543Smrg            } else {
1200706f2543Smrg                CLEAR_FLAG(F_CF);
1201706f2543Smrg                CLEAR_FLAG(F_OF);
1202706f2543Smrg            }
1203706f2543Smrg            *destreg = (u16)res;
1204706f2543Smrg        }
1205706f2543Smrg        break;
1206706f2543Smrg    case 1:
1207706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1208706f2543Smrg            u32 *destreg;
1209706f2543Smrg            u32 srcval;
1210706f2543Smrg            u32 res_lo,res_hi;
1211706f2543Smrg
1212706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1213706f2543Smrg            DECODE_PRINTF(",");
1214706f2543Smrg            srcoffset = decode_rm01_address(rl);
1215706f2543Smrg            srcval = fetch_data_long(srcoffset);
1216706f2543Smrg            TRACE_AND_STEP();
1217706f2543Smrg            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1218706f2543Smrg            if (res_hi != 0) {
1219706f2543Smrg                SET_FLAG(F_CF);
1220706f2543Smrg                SET_FLAG(F_OF);
1221706f2543Smrg            } else {
1222706f2543Smrg                CLEAR_FLAG(F_CF);
1223706f2543Smrg                CLEAR_FLAG(F_OF);
1224706f2543Smrg            }
1225706f2543Smrg            *destreg = (u32)res_lo;
1226706f2543Smrg        } else {
1227706f2543Smrg            u16 *destreg;
1228706f2543Smrg            u16 srcval;
1229706f2543Smrg            u32 res;
1230706f2543Smrg
1231706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1232706f2543Smrg            DECODE_PRINTF(",");
1233706f2543Smrg            srcoffset = decode_rm01_address(rl);
1234706f2543Smrg            srcval = fetch_data_word(srcoffset);
1235706f2543Smrg            TRACE_AND_STEP();
1236706f2543Smrg            res = (s16)*destreg * (s16)srcval;
1237706f2543Smrg            if (res > 0xFFFF) {
1238706f2543Smrg                SET_FLAG(F_CF);
1239706f2543Smrg                SET_FLAG(F_OF);
1240706f2543Smrg            } else {
1241706f2543Smrg                CLEAR_FLAG(F_CF);
1242706f2543Smrg                CLEAR_FLAG(F_OF);
1243706f2543Smrg            }
1244706f2543Smrg            *destreg = (u16)res;
1245706f2543Smrg        }
1246706f2543Smrg        break;
1247706f2543Smrg    case 2:
1248706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1249706f2543Smrg            u32 *destreg;
1250706f2543Smrg            u32 srcval;
1251706f2543Smrg            u32 res_lo,res_hi;
1252706f2543Smrg
1253706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1254706f2543Smrg            DECODE_PRINTF(",");
1255706f2543Smrg            srcoffset = decode_rm10_address(rl);
1256706f2543Smrg            srcval = fetch_data_long(srcoffset);
1257706f2543Smrg            TRACE_AND_STEP();
1258706f2543Smrg            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1259706f2543Smrg            if (res_hi != 0) {
1260706f2543Smrg                SET_FLAG(F_CF);
1261706f2543Smrg                SET_FLAG(F_OF);
1262706f2543Smrg            } else {
1263706f2543Smrg                CLEAR_FLAG(F_CF);
1264706f2543Smrg                CLEAR_FLAG(F_OF);
1265706f2543Smrg            }
1266706f2543Smrg            *destreg = (u32)res_lo;
1267706f2543Smrg        } else {
1268706f2543Smrg            u16 *destreg;
1269706f2543Smrg            u16 srcval;
1270706f2543Smrg            u32 res;
1271706f2543Smrg
1272706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1273706f2543Smrg            DECODE_PRINTF(",");
1274706f2543Smrg            srcoffset = decode_rm10_address(rl);
1275706f2543Smrg            srcval = fetch_data_word(srcoffset);
1276706f2543Smrg            TRACE_AND_STEP();
1277706f2543Smrg            res = (s16)*destreg * (s16)srcval;
1278706f2543Smrg            if (res > 0xFFFF) {
1279706f2543Smrg                SET_FLAG(F_CF);
1280706f2543Smrg                SET_FLAG(F_OF);
1281706f2543Smrg            } else {
1282706f2543Smrg                CLEAR_FLAG(F_CF);
1283706f2543Smrg                CLEAR_FLAG(F_OF);
1284706f2543Smrg            }
1285706f2543Smrg            *destreg = (u16)res;
1286706f2543Smrg        }
1287706f2543Smrg        break;
1288706f2543Smrg    case 3:                     /* register to register */
1289706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1290706f2543Smrg            u32 *destreg,*srcreg;
1291706f2543Smrg            u32 res_lo,res_hi;
1292706f2543Smrg
1293706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1294706f2543Smrg            DECODE_PRINTF(",");
1295706f2543Smrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
1296706f2543Smrg            TRACE_AND_STEP();
1297706f2543Smrg            imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
1298706f2543Smrg            if (res_hi != 0) {
1299706f2543Smrg                SET_FLAG(F_CF);
1300706f2543Smrg                SET_FLAG(F_OF);
1301706f2543Smrg            } else {
1302706f2543Smrg                CLEAR_FLAG(F_CF);
1303706f2543Smrg                CLEAR_FLAG(F_OF);
1304706f2543Smrg            }
1305706f2543Smrg            *destreg = (u32)res_lo;
1306706f2543Smrg        } else {
1307706f2543Smrg            u16 *destreg,*srcreg;
1308706f2543Smrg            u32 res;
1309706f2543Smrg
1310706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1311706f2543Smrg            DECODE_PRINTF(",");
1312706f2543Smrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
1313706f2543Smrg            res = (s16)*destreg * (s16)*srcreg;
1314706f2543Smrg            if (res > 0xFFFF) {
1315706f2543Smrg                SET_FLAG(F_CF);
1316706f2543Smrg                SET_FLAG(F_OF);
1317706f2543Smrg            } else {
1318706f2543Smrg                CLEAR_FLAG(F_CF);
1319706f2543Smrg                CLEAR_FLAG(F_OF);
1320706f2543Smrg            }
1321706f2543Smrg            *destreg = (u16)res;
1322706f2543Smrg        }
1323706f2543Smrg        break;
1324706f2543Smrg    }
1325706f2543Smrg    DECODE_CLEAR_SEGOVR();
1326706f2543Smrg    END_OF_INSTR();
1327706f2543Smrg}
1328706f2543Smrg
1329706f2543Smrg/****************************************************************************
1330706f2543SmrgREMARKS:
1331706f2543SmrgHandles opcode 0x0f,0xb2
1332706f2543Smrg****************************************************************************/
1333706f2543Smrgstatic void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1334706f2543Smrg{
1335706f2543Smrg	int mod, rh, rl;
1336706f2543Smrg    u16 *dstreg;
1337706f2543Smrg    uint srcoffset;
1338706f2543Smrg
1339706f2543Smrg    START_OF_INSTR();
1340706f2543Smrg    DECODE_PRINTF("LSS\t");
1341706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1342706f2543Smrg    switch (mod) {
1343706f2543Smrg    case 0:
1344706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1345706f2543Smrg        DECODE_PRINTF(",");
1346706f2543Smrg        srcoffset = decode_rm00_address(rl);
1347706f2543Smrg        DECODE_PRINTF("\n");
1348706f2543Smrg        TRACE_AND_STEP();
1349706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1350706f2543Smrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
1351706f2543Smrg        break;
1352706f2543Smrg    case 1:
1353706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1354706f2543Smrg        DECODE_PRINTF(",");
1355706f2543Smrg        srcoffset = decode_rm01_address(rl);
1356706f2543Smrg        DECODE_PRINTF("\n");
1357706f2543Smrg        TRACE_AND_STEP();
1358706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1359706f2543Smrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
1360706f2543Smrg        break;
1361706f2543Smrg    case 2:
1362706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1363706f2543Smrg        DECODE_PRINTF(",");
1364706f2543Smrg        srcoffset = decode_rm10_address(rl);
1365706f2543Smrg        DECODE_PRINTF("\n");
1366706f2543Smrg        TRACE_AND_STEP();
1367706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1368706f2543Smrg        M.x86.R_SS = fetch_data_word(srcoffset + 2);
1369706f2543Smrg        break;
1370706f2543Smrg    case 3:                     /* register to register */
1371706f2543Smrg        /* UNDEFINED! */
1372706f2543Smrg        TRACE_AND_STEP();
1373706f2543Smrg    }
1374706f2543Smrg    DECODE_CLEAR_SEGOVR();
1375706f2543Smrg    END_OF_INSTR();
1376706f2543Smrg}
1377706f2543Smrg
1378706f2543Smrg/****************************************************************************
1379706f2543SmrgREMARKS:
1380706f2543SmrgHandles opcode 0x0f,0xb3
1381706f2543Smrg****************************************************************************/
1382706f2543Smrgstatic void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1383706f2543Smrg{
1384706f2543Smrg	int mod, rl, rh;
1385706f2543Smrg	uint srcoffset;
1386706f2543Smrg	int bit,disp;
1387706f2543Smrg
1388706f2543Smrg	START_OF_INSTR();
1389706f2543Smrg	DECODE_PRINTF("BTR\t");
1390706f2543Smrg	FETCH_DECODE_MODRM(mod, rh, rl);
1391706f2543Smrg	switch (mod) {
1392706f2543Smrg	case 0:
1393706f2543Smrg		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1394706f2543Smrg			u32 srcval,mask;
1395706f2543Smrg			u32 *shiftreg;
1396706f2543Smrg
1397706f2543Smrg			srcoffset = decode_rm00_address(rl);
1398706f2543Smrg			DECODE_PRINTF(",");
1399706f2543Smrg			shiftreg = DECODE_RM_LONG_REGISTER(rh);
1400706f2543Smrg			TRACE_AND_STEP();
1401706f2543Smrg			bit = *shiftreg & 0x1F;
1402706f2543Smrg			disp = (s16)*shiftreg >> 5;
1403706f2543Smrg			srcval = fetch_data_long(srcoffset+disp);
1404706f2543Smrg			mask = (0x1 << bit);
1405706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1406706f2543Smrg			store_data_long(srcoffset+disp, srcval & ~mask);
1407706f2543Smrg		} else {
1408706f2543Smrg			u16 srcval,mask;
1409706f2543Smrg			u16 *shiftreg;
1410706f2543Smrg
1411706f2543Smrg			srcoffset = decode_rm00_address(rl);
1412706f2543Smrg			DECODE_PRINTF(",");
1413706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
1414706f2543Smrg			TRACE_AND_STEP();
1415706f2543Smrg			bit = *shiftreg & 0xF;
1416706f2543Smrg			disp = (s16)*shiftreg >> 4;
1417706f2543Smrg			srcval = fetch_data_word(srcoffset+disp);
1418706f2543Smrg			mask = (u16)(0x1 << bit);
1419706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1420706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1421706f2543Smrg		}
1422706f2543Smrg		break;
1423706f2543Smrg	case 1:
1424706f2543Smrg		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1425706f2543Smrg			u32 srcval,mask;
1426706f2543Smrg			u32 *shiftreg;
1427706f2543Smrg
1428706f2543Smrg			srcoffset = decode_rm01_address(rl);
1429706f2543Smrg			DECODE_PRINTF(",");
1430706f2543Smrg			shiftreg = DECODE_RM_LONG_REGISTER(rh);
1431706f2543Smrg			TRACE_AND_STEP();
1432706f2543Smrg			bit = *shiftreg & 0x1F;
1433706f2543Smrg			disp = (s16)*shiftreg >> 5;
1434706f2543Smrg			srcval = fetch_data_long(srcoffset+disp);
1435706f2543Smrg			mask = (0x1 << bit);
1436706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1437706f2543Smrg			store_data_long(srcoffset+disp, srcval & ~mask);
1438706f2543Smrg		} else {
1439706f2543Smrg			u16 srcval,mask;
1440706f2543Smrg			u16 *shiftreg;
1441706f2543Smrg
1442706f2543Smrg			srcoffset = decode_rm01_address(rl);
1443706f2543Smrg			DECODE_PRINTF(",");
1444706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
1445706f2543Smrg			TRACE_AND_STEP();
1446706f2543Smrg			bit = *shiftreg & 0xF;
1447706f2543Smrg			disp = (s16)*shiftreg >> 4;
1448706f2543Smrg			srcval = fetch_data_word(srcoffset+disp);
1449706f2543Smrg			mask = (u16)(0x1 << bit);
1450706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1451706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1452706f2543Smrg		}
1453706f2543Smrg		break;
1454706f2543Smrg	case 2:
1455706f2543Smrg		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1456706f2543Smrg			u32 srcval,mask;
1457706f2543Smrg			u32 *shiftreg;
1458706f2543Smrg
1459706f2543Smrg			srcoffset = decode_rm10_address(rl);
1460706f2543Smrg			DECODE_PRINTF(",");
1461706f2543Smrg			shiftreg = DECODE_RM_LONG_REGISTER(rh);
1462706f2543Smrg			TRACE_AND_STEP();
1463706f2543Smrg			bit = *shiftreg & 0x1F;
1464706f2543Smrg			disp = (s16)*shiftreg >> 5;
1465706f2543Smrg			srcval = fetch_data_long(srcoffset+disp);
1466706f2543Smrg			mask = (0x1 << bit);
1467706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1468706f2543Smrg			store_data_long(srcoffset+disp, srcval & ~mask);
1469706f2543Smrg		} else {
1470706f2543Smrg			u16 srcval,mask;
1471706f2543Smrg			u16 *shiftreg;
1472706f2543Smrg
1473706f2543Smrg			srcoffset = decode_rm10_address(rl);
1474706f2543Smrg			DECODE_PRINTF(",");
1475706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
1476706f2543Smrg			TRACE_AND_STEP();
1477706f2543Smrg			bit = *shiftreg & 0xF;
1478706f2543Smrg			disp = (s16)*shiftreg >> 4;
1479706f2543Smrg			srcval = fetch_data_word(srcoffset+disp);
1480706f2543Smrg			mask = (u16)(0x1 << bit);
1481706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1482706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1483706f2543Smrg		}
1484706f2543Smrg		break;
1485706f2543Smrg	case 3:                     /* register to register */
1486706f2543Smrg		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1487706f2543Smrg			u32 *srcreg,*shiftreg;
1488706f2543Smrg			u32 mask;
1489706f2543Smrg
1490706f2543Smrg			srcreg = DECODE_RM_LONG_REGISTER(rl);
1491706f2543Smrg			DECODE_PRINTF(",");
1492706f2543Smrg			shiftreg = DECODE_RM_LONG_REGISTER(rh);
1493706f2543Smrg			TRACE_AND_STEP();
1494706f2543Smrg			bit = *shiftreg & 0x1F;
1495706f2543Smrg			mask = (0x1 << bit);
1496706f2543Smrg			CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1497706f2543Smrg			*srcreg &= ~mask;
1498706f2543Smrg		} else {
1499706f2543Smrg			u16 *srcreg,*shiftreg;
1500706f2543Smrg			u16 mask;
1501706f2543Smrg
1502706f2543Smrg			srcreg = DECODE_RM_WORD_REGISTER(rl);
1503706f2543Smrg			DECODE_PRINTF(",");
1504706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
1505706f2543Smrg			TRACE_AND_STEP();
1506706f2543Smrg			bit = *shiftreg & 0xF;
1507706f2543Smrg			mask = (u16)(0x1 << bit);
1508706f2543Smrg			CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1509706f2543Smrg			*srcreg &= ~mask;
1510706f2543Smrg		}
1511706f2543Smrg		break;
1512706f2543Smrg	}
1513706f2543Smrg	DECODE_CLEAR_SEGOVR();
1514706f2543Smrg	END_OF_INSTR();
1515706f2543Smrg}
1516706f2543Smrg
1517706f2543Smrg/****************************************************************************
1518706f2543SmrgREMARKS:
1519706f2543SmrgHandles opcode 0x0f,0xb4
1520706f2543Smrg****************************************************************************/
1521706f2543Smrgstatic void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1522706f2543Smrg{
1523706f2543Smrg	int mod, rh, rl;
1524706f2543Smrg    u16 *dstreg;
1525706f2543Smrg    uint srcoffset;
1526706f2543Smrg
1527706f2543Smrg    START_OF_INSTR();
1528706f2543Smrg    DECODE_PRINTF("LFS\t");
1529706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1530706f2543Smrg    switch (mod) {
1531706f2543Smrg    case 0:
1532706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1533706f2543Smrg        DECODE_PRINTF(",");
1534706f2543Smrg        srcoffset = decode_rm00_address(rl);
1535706f2543Smrg        DECODE_PRINTF("\n");
1536706f2543Smrg        TRACE_AND_STEP();
1537706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1538706f2543Smrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
1539706f2543Smrg        break;
1540706f2543Smrg    case 1:
1541706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1542706f2543Smrg        DECODE_PRINTF(",");
1543706f2543Smrg        srcoffset = decode_rm01_address(rl);
1544706f2543Smrg        DECODE_PRINTF("\n");
1545706f2543Smrg        TRACE_AND_STEP();
1546706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1547706f2543Smrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
1548706f2543Smrg        break;
1549706f2543Smrg    case 2:
1550706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1551706f2543Smrg        DECODE_PRINTF(",");
1552706f2543Smrg        srcoffset = decode_rm10_address(rl);
1553706f2543Smrg        DECODE_PRINTF("\n");
1554706f2543Smrg        TRACE_AND_STEP();
1555706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1556706f2543Smrg        M.x86.R_FS = fetch_data_word(srcoffset + 2);
1557706f2543Smrg        break;
1558706f2543Smrg    case 3:                     /* register to register */
1559706f2543Smrg        /* UNDEFINED! */
1560706f2543Smrg        TRACE_AND_STEP();
1561706f2543Smrg    }
1562706f2543Smrg    DECODE_CLEAR_SEGOVR();
1563706f2543Smrg    END_OF_INSTR();
1564706f2543Smrg}
1565706f2543Smrg
1566706f2543Smrg/****************************************************************************
1567706f2543SmrgREMARKS:
1568706f2543SmrgHandles opcode 0x0f,0xb5
1569706f2543Smrg****************************************************************************/
1570706f2543Smrgstatic void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1571706f2543Smrg{
1572706f2543Smrg	int mod, rh, rl;
1573706f2543Smrg    u16 *dstreg;
1574706f2543Smrg    uint srcoffset;
1575706f2543Smrg
1576706f2543Smrg    START_OF_INSTR();
1577706f2543Smrg    DECODE_PRINTF("LGS\t");
1578706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1579706f2543Smrg    switch (mod) {
1580706f2543Smrg    case 0:
1581706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1582706f2543Smrg        DECODE_PRINTF(",");
1583706f2543Smrg        srcoffset = decode_rm00_address(rl);
1584706f2543Smrg        DECODE_PRINTF("\n");
1585706f2543Smrg        TRACE_AND_STEP();
1586706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1587706f2543Smrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
1588706f2543Smrg        break;
1589706f2543Smrg    case 1:
1590706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1591706f2543Smrg        DECODE_PRINTF(",");
1592706f2543Smrg        srcoffset = decode_rm01_address(rl);
1593706f2543Smrg        DECODE_PRINTF("\n");
1594706f2543Smrg        TRACE_AND_STEP();
1595706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1596706f2543Smrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
1597706f2543Smrg        break;
1598706f2543Smrg    case 2:
1599706f2543Smrg        dstreg = DECODE_RM_WORD_REGISTER(rh);
1600706f2543Smrg        DECODE_PRINTF(",");
1601706f2543Smrg        srcoffset = decode_rm10_address(rl);
1602706f2543Smrg        DECODE_PRINTF("\n");
1603706f2543Smrg        TRACE_AND_STEP();
1604706f2543Smrg        *dstreg = fetch_data_word(srcoffset);
1605706f2543Smrg        M.x86.R_GS = fetch_data_word(srcoffset + 2);
1606706f2543Smrg        break;
1607706f2543Smrg    case 3:                     /* register to register */
1608706f2543Smrg        /* UNDEFINED! */
1609706f2543Smrg        TRACE_AND_STEP();
1610706f2543Smrg    }
1611706f2543Smrg    DECODE_CLEAR_SEGOVR();
1612706f2543Smrg    END_OF_INSTR();
1613706f2543Smrg}
1614706f2543Smrg
1615706f2543Smrg/****************************************************************************
1616706f2543SmrgREMARKS:
1617706f2543SmrgHandles opcode 0x0f,0xb6
1618706f2543Smrg****************************************************************************/
1619706f2543Smrgstatic void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1620706f2543Smrg{
1621706f2543Smrg    int mod, rl, rh;
1622706f2543Smrg    uint srcoffset;
1623706f2543Smrg
1624706f2543Smrg    START_OF_INSTR();
1625706f2543Smrg    DECODE_PRINTF("MOVZX\t");
1626706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1627706f2543Smrg    switch (mod) {
1628706f2543Smrg    case 0:
1629706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1630706f2543Smrg            u32 *destreg;
1631706f2543Smrg            u32 srcval;
1632706f2543Smrg
1633706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1634706f2543Smrg            DECODE_PRINTF(",");
1635706f2543Smrg            srcoffset = decode_rm00_address(rl);
1636706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1637706f2543Smrg            DECODE_PRINTF("\n");
1638706f2543Smrg            TRACE_AND_STEP();
1639706f2543Smrg            *destreg = srcval;
1640706f2543Smrg        } else {
1641706f2543Smrg            u16 *destreg;
1642706f2543Smrg            u16 srcval;
1643706f2543Smrg
1644706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1645706f2543Smrg            DECODE_PRINTF(",");
1646706f2543Smrg            srcoffset = decode_rm00_address(rl);
1647706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1648706f2543Smrg            DECODE_PRINTF("\n");
1649706f2543Smrg            TRACE_AND_STEP();
1650706f2543Smrg            *destreg = srcval;
1651706f2543Smrg        }
1652706f2543Smrg        break;
1653706f2543Smrg    case 1:
1654706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1655706f2543Smrg            u32 *destreg;
1656706f2543Smrg            u32 srcval;
1657706f2543Smrg
1658706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1659706f2543Smrg            DECODE_PRINTF(",");
1660706f2543Smrg            srcoffset = decode_rm01_address(rl);
1661706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1662706f2543Smrg            DECODE_PRINTF("\n");
1663706f2543Smrg            TRACE_AND_STEP();
1664706f2543Smrg            *destreg = srcval;
1665706f2543Smrg        } else {
1666706f2543Smrg            u16 *destreg;
1667706f2543Smrg            u16 srcval;
1668706f2543Smrg
1669706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1670706f2543Smrg            DECODE_PRINTF(",");
1671706f2543Smrg            srcoffset = decode_rm01_address(rl);
1672706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1673706f2543Smrg            DECODE_PRINTF("\n");
1674706f2543Smrg            TRACE_AND_STEP();
1675706f2543Smrg            *destreg = srcval;
1676706f2543Smrg        }
1677706f2543Smrg        break;
1678706f2543Smrg    case 2:
1679706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1680706f2543Smrg            u32 *destreg;
1681706f2543Smrg            u32 srcval;
1682706f2543Smrg
1683706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1684706f2543Smrg            DECODE_PRINTF(",");
1685706f2543Smrg            srcoffset = decode_rm10_address(rl);
1686706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1687706f2543Smrg            DECODE_PRINTF("\n");
1688706f2543Smrg            TRACE_AND_STEP();
1689706f2543Smrg            *destreg = srcval;
1690706f2543Smrg        } else {
1691706f2543Smrg            u16 *destreg;
1692706f2543Smrg            u16 srcval;
1693706f2543Smrg
1694706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1695706f2543Smrg            DECODE_PRINTF(",");
1696706f2543Smrg            srcoffset = decode_rm10_address(rl);
1697706f2543Smrg            srcval = fetch_data_byte(srcoffset);
1698706f2543Smrg            DECODE_PRINTF("\n");
1699706f2543Smrg            TRACE_AND_STEP();
1700706f2543Smrg            *destreg = srcval;
1701706f2543Smrg        }
1702706f2543Smrg        break;
1703706f2543Smrg    case 3:                     /* register to register */
1704706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1705706f2543Smrg            u32 *destreg;
1706706f2543Smrg            u8  *srcreg;
1707706f2543Smrg
1708706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
1709706f2543Smrg            DECODE_PRINTF(",");
1710706f2543Smrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
1711706f2543Smrg            DECODE_PRINTF("\n");
1712706f2543Smrg            TRACE_AND_STEP();
1713706f2543Smrg            *destreg = *srcreg;
1714706f2543Smrg        } else {
1715706f2543Smrg            u16 *destreg;
1716706f2543Smrg            u8  *srcreg;
1717706f2543Smrg
1718706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
1719706f2543Smrg            DECODE_PRINTF(",");
1720706f2543Smrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
1721706f2543Smrg            DECODE_PRINTF("\n");
1722706f2543Smrg            TRACE_AND_STEP();
1723706f2543Smrg            *destreg = *srcreg;
1724706f2543Smrg        }
1725706f2543Smrg        break;
1726706f2543Smrg    }
1727706f2543Smrg    DECODE_CLEAR_SEGOVR();
1728706f2543Smrg    END_OF_INSTR();
1729706f2543Smrg}
1730706f2543Smrg
1731706f2543Smrg/****************************************************************************
1732706f2543SmrgREMARKS:
1733706f2543SmrgHandles opcode 0x0f,0xb7
1734706f2543Smrg****************************************************************************/
1735706f2543Smrgstatic void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1736706f2543Smrg{
1737706f2543Smrg    int mod, rl, rh;
1738706f2543Smrg    uint srcoffset;
1739706f2543Smrg    u32 *destreg;
1740706f2543Smrg    u32 srcval;
1741706f2543Smrg    u16 *srcreg;
1742706f2543Smrg
1743706f2543Smrg    START_OF_INSTR();
1744706f2543Smrg    DECODE_PRINTF("MOVZX\t");
1745706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1746706f2543Smrg    switch (mod) {
1747706f2543Smrg    case 0:
1748706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
1749706f2543Smrg        DECODE_PRINTF(",");
1750706f2543Smrg        srcoffset = decode_rm00_address(rl);
1751706f2543Smrg        srcval = fetch_data_word(srcoffset);
1752706f2543Smrg        DECODE_PRINTF("\n");
1753706f2543Smrg        TRACE_AND_STEP();
1754706f2543Smrg        *destreg = srcval;
1755706f2543Smrg        break;
1756706f2543Smrg    case 1:
1757706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
1758706f2543Smrg        DECODE_PRINTF(",");
1759706f2543Smrg        srcoffset = decode_rm01_address(rl);
1760706f2543Smrg        srcval = fetch_data_word(srcoffset);
1761706f2543Smrg        DECODE_PRINTF("\n");
1762706f2543Smrg        TRACE_AND_STEP();
1763706f2543Smrg        *destreg = srcval;
1764706f2543Smrg        break;
1765706f2543Smrg    case 2:
1766706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
1767706f2543Smrg        DECODE_PRINTF(",");
1768706f2543Smrg        srcoffset = decode_rm10_address(rl);
1769706f2543Smrg        srcval = fetch_data_word(srcoffset);
1770706f2543Smrg        DECODE_PRINTF("\n");
1771706f2543Smrg        TRACE_AND_STEP();
1772706f2543Smrg        *destreg = srcval;
1773706f2543Smrg        break;
1774706f2543Smrg    case 3:                     /* register to register */
1775706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
1776706f2543Smrg        DECODE_PRINTF(",");
1777706f2543Smrg        srcreg = DECODE_RM_WORD_REGISTER(rl);
1778706f2543Smrg        DECODE_PRINTF("\n");
1779706f2543Smrg        TRACE_AND_STEP();
1780706f2543Smrg        *destreg = *srcreg;
1781706f2543Smrg        break;
1782706f2543Smrg    }
1783706f2543Smrg    DECODE_CLEAR_SEGOVR();
1784706f2543Smrg    END_OF_INSTR();
1785706f2543Smrg}
1786706f2543Smrg
1787706f2543Smrg/****************************************************************************
1788706f2543SmrgREMARKS:
1789706f2543SmrgHandles opcode 0x0f,0xba
1790706f2543Smrg****************************************************************************/
1791706f2543Smrgstatic void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1792706f2543Smrg{
1793706f2543Smrg    int mod, rl, rh;
1794706f2543Smrg    uint srcoffset;
1795706f2543Smrg    int bit;
1796706f2543Smrg
1797706f2543Smrg    START_OF_INSTR();
1798706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
1799706f2543Smrg    switch (rh) {
1800706f2543Smrg    case 4:
1801706f2543Smrg	DECODE_PRINTF("BT\t");
1802706f2543Smrg	break;
1803706f2543Smrg    case 5:
1804706f2543Smrg	DECODE_PRINTF("BTS\t");
1805706f2543Smrg	break;
1806706f2543Smrg    case 6:
1807706f2543Smrg	DECODE_PRINTF("BTR\t");
1808706f2543Smrg	break;
1809706f2543Smrg    case 7:
1810706f2543Smrg	DECODE_PRINTF("BTC\t");
1811706f2543Smrg	break;
1812706f2543Smrg    default:
1813706f2543Smrg	DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1814706f2543Smrg	TRACE_REGS();
1815706f2543Smrg	printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1816706f2543Smrg		M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1817706f2543Smrg	HALT_SYS();
1818706f2543Smrg    }
1819706f2543Smrg    switch (mod) {
1820706f2543Smrg    case 0:
1821706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1822706f2543Smrg            u32 srcval, mask;
1823706f2543Smrg            u8 shift;
1824706f2543Smrg
1825706f2543Smrg            srcoffset = decode_rm00_address(rl);
1826706f2543Smrg            DECODE_PRINTF(",");
1827706f2543Smrg            shift = fetch_byte_imm();
1828706f2543Smrg            TRACE_AND_STEP();
1829706f2543Smrg            bit = shift & 0x1F;
1830706f2543Smrg            srcval = fetch_data_long(srcoffset);
1831706f2543Smrg	    mask = (0x1 << bit);
1832706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1833706f2543Smrg	    switch (rh) {
1834706f2543Smrg	    case 5:
1835706f2543Smrg		store_data_long(srcoffset, srcval | mask);
1836706f2543Smrg		break;
1837706f2543Smrg	    case 6:
1838706f2543Smrg		store_data_long(srcoffset, srcval & ~mask);
1839706f2543Smrg		break;
1840706f2543Smrg	    case 7:
1841706f2543Smrg		store_data_long(srcoffset, srcval ^ mask);
1842706f2543Smrg		break;
1843706f2543Smrg	    default:
1844706f2543Smrg		break;
1845706f2543Smrg	    }
1846706f2543Smrg        } else {
1847706f2543Smrg            u16 srcval, mask;
1848706f2543Smrg            u8 shift;
1849706f2543Smrg
1850706f2543Smrg            srcoffset = decode_rm00_address(rl);
1851706f2543Smrg            DECODE_PRINTF(",");
1852706f2543Smrg            shift = fetch_byte_imm();
1853706f2543Smrg            TRACE_AND_STEP();
1854706f2543Smrg            bit = shift & 0xF;
1855706f2543Smrg            srcval = fetch_data_word(srcoffset);
1856706f2543Smrg	    mask = (0x1 << bit);
1857706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1858706f2543Smrg	    switch (rh) {
1859706f2543Smrg	    case 5:
1860706f2543Smrg		store_data_word(srcoffset, srcval | mask);
1861706f2543Smrg		break;
1862706f2543Smrg	    case 6:
1863706f2543Smrg		store_data_word(srcoffset, srcval & ~mask);
1864706f2543Smrg		break;
1865706f2543Smrg	    case 7:
1866706f2543Smrg		store_data_word(srcoffset, srcval ^ mask);
1867706f2543Smrg		break;
1868706f2543Smrg	    default:
1869706f2543Smrg		break;
1870706f2543Smrg	    }
1871706f2543Smrg        }
1872706f2543Smrg        break;
1873706f2543Smrg    case 1:
1874706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1875706f2543Smrg            u32 srcval, mask;
1876706f2543Smrg            u8 shift;
1877706f2543Smrg
1878706f2543Smrg            srcoffset = decode_rm01_address(rl);
1879706f2543Smrg            DECODE_PRINTF(",");
1880706f2543Smrg            shift = fetch_byte_imm();
1881706f2543Smrg            TRACE_AND_STEP();
1882706f2543Smrg            bit = shift & 0x1F;
1883706f2543Smrg            srcval = fetch_data_long(srcoffset);
1884706f2543Smrg	    mask = (0x1 << bit);
1885706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1886706f2543Smrg	    switch (rh) {
1887706f2543Smrg	    case 5:
1888706f2543Smrg		store_data_long(srcoffset, srcval | mask);
1889706f2543Smrg		break;
1890706f2543Smrg	    case 6:
1891706f2543Smrg		store_data_long(srcoffset, srcval & ~mask);
1892706f2543Smrg		break;
1893706f2543Smrg	    case 7:
1894706f2543Smrg		store_data_long(srcoffset, srcval ^ mask);
1895706f2543Smrg		break;
1896706f2543Smrg	    default:
1897706f2543Smrg		break;
1898706f2543Smrg	    }
1899706f2543Smrg        } else {
1900706f2543Smrg            u16 srcval, mask;
1901706f2543Smrg            u8 shift;
1902706f2543Smrg
1903706f2543Smrg            srcoffset = decode_rm01_address(rl);
1904706f2543Smrg            DECODE_PRINTF(",");
1905706f2543Smrg            shift = fetch_byte_imm();
1906706f2543Smrg            TRACE_AND_STEP();
1907706f2543Smrg            bit = shift & 0xF;
1908706f2543Smrg            srcval = fetch_data_word(srcoffset);
1909706f2543Smrg	    mask = (0x1 << bit);
1910706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1911706f2543Smrg	    switch (rh) {
1912706f2543Smrg	    case 5:
1913706f2543Smrg		store_data_word(srcoffset, srcval | mask);
1914706f2543Smrg		break;
1915706f2543Smrg	    case 6:
1916706f2543Smrg		store_data_word(srcoffset, srcval & ~mask);
1917706f2543Smrg		break;
1918706f2543Smrg	    case 7:
1919706f2543Smrg		store_data_word(srcoffset, srcval ^ mask);
1920706f2543Smrg		break;
1921706f2543Smrg	    default:
1922706f2543Smrg		break;
1923706f2543Smrg	    }
1924706f2543Smrg        }
1925706f2543Smrg        break;
1926706f2543Smrg    case 2:
1927706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1928706f2543Smrg            u32 srcval, mask;
1929706f2543Smrg            u8 shift;
1930706f2543Smrg
1931706f2543Smrg            srcoffset = decode_rm10_address(rl);
1932706f2543Smrg            DECODE_PRINTF(",");
1933706f2543Smrg            shift = fetch_byte_imm();
1934706f2543Smrg            TRACE_AND_STEP();
1935706f2543Smrg            bit = shift & 0x1F;
1936706f2543Smrg            srcval = fetch_data_long(srcoffset);
1937706f2543Smrg	    mask = (0x1 << bit);
1938706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1939706f2543Smrg	    switch (rh) {
1940706f2543Smrg	    case 5:
1941706f2543Smrg		store_data_long(srcoffset, srcval | mask);
1942706f2543Smrg		break;
1943706f2543Smrg	    case 6:
1944706f2543Smrg		store_data_long(srcoffset, srcval & ~mask);
1945706f2543Smrg		break;
1946706f2543Smrg	    case 7:
1947706f2543Smrg		store_data_long(srcoffset, srcval ^ mask);
1948706f2543Smrg		break;
1949706f2543Smrg	    default:
1950706f2543Smrg		break;
1951706f2543Smrg	    }
1952706f2543Smrg        } else {
1953706f2543Smrg            u16 srcval, mask;
1954706f2543Smrg            u8 shift;
1955706f2543Smrg
1956706f2543Smrg            srcoffset = decode_rm10_address(rl);
1957706f2543Smrg            DECODE_PRINTF(",");
1958706f2543Smrg            shift = fetch_byte_imm();
1959706f2543Smrg            TRACE_AND_STEP();
1960706f2543Smrg            bit = shift & 0xF;
1961706f2543Smrg            srcval = fetch_data_word(srcoffset);
1962706f2543Smrg	    mask = (0x1 << bit);
1963706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1964706f2543Smrg	    switch (rh) {
1965706f2543Smrg	    case 5:
1966706f2543Smrg		store_data_word(srcoffset, srcval | mask);
1967706f2543Smrg		break;
1968706f2543Smrg	    case 6:
1969706f2543Smrg		store_data_word(srcoffset, srcval & ~mask);
1970706f2543Smrg		break;
1971706f2543Smrg	    case 7:
1972706f2543Smrg		store_data_word(srcoffset, srcval ^ mask);
1973706f2543Smrg		break;
1974706f2543Smrg	    default:
1975706f2543Smrg		break;
1976706f2543Smrg	    }
1977706f2543Smrg        }
1978706f2543Smrg        break;
1979706f2543Smrg    case 3:                     /* register to register */
1980706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1981706f2543Smrg            u32 *srcreg;
1982706f2543Smrg	    u32 mask;
1983706f2543Smrg	    u8 shift;
1984706f2543Smrg
1985706f2543Smrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
1986706f2543Smrg            DECODE_PRINTF(",");
1987706f2543Smrg            shift = fetch_byte_imm();
1988706f2543Smrg            TRACE_AND_STEP();
1989706f2543Smrg            bit = shift & 0x1F;
1990706f2543Smrg	    mask = (0x1 << bit);
1991706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1992706f2543Smrg	    switch (rh) {
1993706f2543Smrg	    case 5:
1994706f2543Smrg		*srcreg |= mask;
1995706f2543Smrg		break;
1996706f2543Smrg	    case 6:
1997706f2543Smrg		*srcreg &= ~mask;
1998706f2543Smrg		break;
1999706f2543Smrg	    case 7:
2000706f2543Smrg		*srcreg ^= mask;
2001706f2543Smrg		break;
2002706f2543Smrg	    default:
2003706f2543Smrg		break;
2004706f2543Smrg	    }
2005706f2543Smrg        } else {
2006706f2543Smrg            u16 *srcreg;
2007706f2543Smrg	    u16 mask;
2008706f2543Smrg	    u8 shift;
2009706f2543Smrg
2010706f2543Smrg            srcreg = DECODE_RM_WORD_REGISTER(rl);
2011706f2543Smrg            DECODE_PRINTF(",");
2012706f2543Smrg            shift = fetch_byte_imm();
2013706f2543Smrg            TRACE_AND_STEP();
2014706f2543Smrg            bit = shift & 0xF;
2015706f2543Smrg	    mask = (0x1 << bit);
2016706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2017706f2543Smrg	    switch (rh) {
2018706f2543Smrg	    case 5:
2019706f2543Smrg		*srcreg |= mask;
2020706f2543Smrg		break;
2021706f2543Smrg	    case 6:
2022706f2543Smrg		*srcreg &= ~mask;
2023706f2543Smrg		break;
2024706f2543Smrg	    case 7:
2025706f2543Smrg		*srcreg ^= mask;
2026706f2543Smrg		break;
2027706f2543Smrg	    default:
2028706f2543Smrg		break;
2029706f2543Smrg	    }
2030706f2543Smrg        }
2031706f2543Smrg        break;
2032706f2543Smrg    }
2033706f2543Smrg    DECODE_CLEAR_SEGOVR();
2034706f2543Smrg    END_OF_INSTR();
2035706f2543Smrg}
2036706f2543Smrg
2037706f2543Smrg/****************************************************************************
2038706f2543SmrgREMARKS:
2039706f2543SmrgHandles opcode 0x0f,0xbb
2040706f2543Smrg****************************************************************************/
2041706f2543Smrgstatic void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
2042706f2543Smrg{
2043706f2543Smrg    int mod, rl, rh;
2044706f2543Smrg    uint srcoffset;
2045706f2543Smrg    int bit,disp;
2046706f2543Smrg
2047706f2543Smrg    START_OF_INSTR();
2048706f2543Smrg    DECODE_PRINTF("BTC\t");
2049706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
2050706f2543Smrg    switch (mod) {
2051706f2543Smrg    case 0:
2052706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2053706f2543Smrg            u32 srcval,mask;
2054706f2543Smrg            u32 *shiftreg;
2055706f2543Smrg
2056706f2543Smrg            srcoffset = decode_rm00_address(rl);
2057706f2543Smrg            DECODE_PRINTF(",");
2058706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
2059706f2543Smrg            TRACE_AND_STEP();
2060706f2543Smrg            bit = *shiftreg & 0x1F;
2061706f2543Smrg            disp = (s16)*shiftreg >> 5;
2062706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
2063706f2543Smrg            mask = (0x1 << bit);
2064706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2065706f2543Smrg            store_data_long(srcoffset+disp, srcval ^ mask);
2066706f2543Smrg        } else {
2067706f2543Smrg            u16 srcval,mask;
2068706f2543Smrg            u16 *shiftreg;
2069706f2543Smrg
2070706f2543Smrg            srcoffset = decode_rm00_address(rl);
2071706f2543Smrg            DECODE_PRINTF(",");
2072706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
2073706f2543Smrg            TRACE_AND_STEP();
2074706f2543Smrg            bit = *shiftreg & 0xF;
2075706f2543Smrg            disp = (s16)*shiftreg >> 4;
2076706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
2077706f2543Smrg			mask = (u16)(0x1 << bit);
2078706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2079706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2080706f2543Smrg        }
2081706f2543Smrg        break;
2082706f2543Smrg    case 1:
2083706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2084706f2543Smrg            u32 srcval,mask;
2085706f2543Smrg            u32 *shiftreg;
2086706f2543Smrg
2087706f2543Smrg            srcoffset = decode_rm01_address(rl);
2088706f2543Smrg            DECODE_PRINTF(",");
2089706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
2090706f2543Smrg            TRACE_AND_STEP();
2091706f2543Smrg            bit = *shiftreg & 0x1F;
2092706f2543Smrg            disp = (s16)*shiftreg >> 5;
2093706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
2094706f2543Smrg            mask = (0x1 << bit);
2095706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2096706f2543Smrg            store_data_long(srcoffset+disp, srcval ^ mask);
2097706f2543Smrg        } else {
2098706f2543Smrg            u16 srcval,mask;
2099706f2543Smrg            u16 *shiftreg;
2100706f2543Smrg
2101706f2543Smrg            srcoffset = decode_rm01_address(rl);
2102706f2543Smrg            DECODE_PRINTF(",");
2103706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
2104706f2543Smrg            TRACE_AND_STEP();
2105706f2543Smrg            bit = *shiftreg & 0xF;
2106706f2543Smrg            disp = (s16)*shiftreg >> 4;
2107706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
2108706f2543Smrg			mask = (u16)(0x1 << bit);
2109706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2110706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2111706f2543Smrg        }
2112706f2543Smrg        break;
2113706f2543Smrg    case 2:
2114706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2115706f2543Smrg            u32 srcval,mask;
2116706f2543Smrg            u32 *shiftreg;
2117706f2543Smrg
2118706f2543Smrg            srcoffset = decode_rm10_address(rl);
2119706f2543Smrg            DECODE_PRINTF(",");
2120706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
2121706f2543Smrg            TRACE_AND_STEP();
2122706f2543Smrg            bit = *shiftreg & 0x1F;
2123706f2543Smrg            disp = (s16)*shiftreg >> 5;
2124706f2543Smrg            srcval = fetch_data_long(srcoffset+disp);
2125706f2543Smrg            mask = (0x1 << bit);
2126706f2543Smrg            CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2127706f2543Smrg            store_data_long(srcoffset+disp, srcval ^ mask);
2128706f2543Smrg        } else {
2129706f2543Smrg            u16 srcval,mask;
2130706f2543Smrg            u16 *shiftreg;
2131706f2543Smrg
2132706f2543Smrg            srcoffset = decode_rm10_address(rl);
2133706f2543Smrg            DECODE_PRINTF(",");
2134706f2543Smrg            shiftreg = DECODE_RM_WORD_REGISTER(rh);
2135706f2543Smrg            TRACE_AND_STEP();
2136706f2543Smrg            bit = *shiftreg & 0xF;
2137706f2543Smrg            disp = (s16)*shiftreg >> 4;
2138706f2543Smrg            srcval = fetch_data_word(srcoffset+disp);
2139706f2543Smrg			mask = (u16)(0x1 << bit);
2140706f2543Smrg			CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2141706f2543Smrg			store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2142706f2543Smrg        }
2143706f2543Smrg        break;
2144706f2543Smrg    case 3:                     /* register to register */
2145706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2146706f2543Smrg			u32 *srcreg,*shiftreg;
2147706f2543Smrg            u32 mask;
2148706f2543Smrg
2149706f2543Smrg            srcreg = DECODE_RM_LONG_REGISTER(rl);
2150706f2543Smrg            DECODE_PRINTF(",");
2151706f2543Smrg            shiftreg = DECODE_RM_LONG_REGISTER(rh);
2152706f2543Smrg            TRACE_AND_STEP();
2153706f2543Smrg            bit = *shiftreg & 0x1F;
2154706f2543Smrg            mask = (0x1 << bit);
2155706f2543Smrg			CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2156706f2543Smrg			*srcreg ^= mask;
2157706f2543Smrg		} else {
2158706f2543Smrg			u16 *srcreg,*shiftreg;
2159706f2543Smrg			u16 mask;
2160706f2543Smrg
2161706f2543Smrg			srcreg = DECODE_RM_WORD_REGISTER(rl);
2162706f2543Smrg			DECODE_PRINTF(",");
2163706f2543Smrg			shiftreg = DECODE_RM_WORD_REGISTER(rh);
2164706f2543Smrg			TRACE_AND_STEP();
2165706f2543Smrg			bit = *shiftreg & 0xF;
2166706f2543Smrg			mask = (u16)(0x1 << bit);
2167706f2543Smrg            CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2168706f2543Smrg            *srcreg ^= mask;
2169706f2543Smrg        }
2170706f2543Smrg        break;
2171706f2543Smrg    }
2172706f2543Smrg    DECODE_CLEAR_SEGOVR();
2173706f2543Smrg    END_OF_INSTR();
2174706f2543Smrg}
2175706f2543Smrg
2176706f2543Smrg/****************************************************************************
2177706f2543SmrgREMARKS:
2178706f2543SmrgHandles opcode 0x0f,0xbc
2179706f2543Smrg****************************************************************************/
2180706f2543Smrgstatic void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2181706f2543Smrg{
2182706f2543Smrg    int mod, rl, rh;
2183706f2543Smrg    uint srcoffset;
2184706f2543Smrg
2185706f2543Smrg    START_OF_INSTR();
2186706f2543Smrg    DECODE_PRINTF("BSF\t");
2187706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
2188706f2543Smrg    switch(mod) {
2189706f2543Smrg    case 0:
2190706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2191706f2543Smrg	    u32 srcval, *dstreg;
2192706f2543Smrg
2193706f2543Smrg	    srcoffset = decode_rm00_address(rl);
2194706f2543Smrg	    DECODE_PRINTF(",");
2195706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2196706f2543Smrg	    TRACE_AND_STEP();
2197706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2198706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2199706f2543Smrg	    for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2200706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2201706f2543Smrg	} else {
2202706f2543Smrg	    u16 srcval, *dstreg;
2203706f2543Smrg
2204706f2543Smrg	    srcoffset = decode_rm00_address(rl);
2205706f2543Smrg	    DECODE_PRINTF(",");
2206706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2207706f2543Smrg	    TRACE_AND_STEP();
2208706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2209706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2210706f2543Smrg	    for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2211706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2212706f2543Smrg	}
2213706f2543Smrg	break;
2214706f2543Smrg    case 1:
2215706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2216706f2543Smrg	    u32 srcval, *dstreg;
2217706f2543Smrg
2218706f2543Smrg	    srcoffset = decode_rm01_address(rl);
2219706f2543Smrg	    DECODE_PRINTF(",");
2220706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2221706f2543Smrg	    TRACE_AND_STEP();
2222706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2223706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2224706f2543Smrg	    for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2225706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2226706f2543Smrg	} else {
2227706f2543Smrg	    u16 srcval, *dstreg;
2228706f2543Smrg
2229706f2543Smrg	    srcoffset = decode_rm01_address(rl);
2230706f2543Smrg	    DECODE_PRINTF(",");
2231706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2232706f2543Smrg	    TRACE_AND_STEP();
2233706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2234706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2235706f2543Smrg	    for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2236706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2237706f2543Smrg	}
2238706f2543Smrg	break;
2239706f2543Smrg    case 2:
2240706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2241706f2543Smrg	    u32 srcval, *dstreg;
2242706f2543Smrg
2243706f2543Smrg	    srcoffset = decode_rm10_address(rl);
2244706f2543Smrg	    DECODE_PRINTF(",");
2245706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2246706f2543Smrg	    TRACE_AND_STEP();
2247706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2248706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2249706f2543Smrg	    for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2250706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2251706f2543Smrg	} else {
2252706f2543Smrg	    u16 srcval, *dstreg;
2253706f2543Smrg
2254706f2543Smrg	    srcoffset = decode_rm10_address(rl);
2255706f2543Smrg	    DECODE_PRINTF(",");
2256706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2257706f2543Smrg	    TRACE_AND_STEP();
2258706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2259706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2260706f2543Smrg	    for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2261706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2262706f2543Smrg	}
2263706f2543Smrg	break;
2264706f2543Smrg    case 3:				/* register to register */
2265706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2266706f2543Smrg	    u32 srcval, *dstreg;
2267706f2543Smrg
2268706f2543Smrg	    srcval = *DECODE_RM_LONG_REGISTER(rl);
2269706f2543Smrg	    DECODE_PRINTF(",");
2270706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2271706f2543Smrg	    TRACE_AND_STEP();
2272706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2273706f2543Smrg	    for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2274706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2275706f2543Smrg	} else {
2276706f2543Smrg	    u16 srcval, *dstreg;
2277706f2543Smrg
2278706f2543Smrg	    srcval = *DECODE_RM_WORD_REGISTER(rl);
2279706f2543Smrg	    DECODE_PRINTF(",");
2280706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2281706f2543Smrg	    TRACE_AND_STEP();
2282706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2283706f2543Smrg	    for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2284706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2285706f2543Smrg	}
2286706f2543Smrg	break;
2287706f2543Smrg    }
2288706f2543Smrg    DECODE_CLEAR_SEGOVR();
2289706f2543Smrg    END_OF_INSTR();
2290706f2543Smrg}
2291706f2543Smrg
2292706f2543Smrg/****************************************************************************
2293706f2543SmrgREMARKS:
2294706f2543SmrgHandles opcode 0x0f,0xbd
2295706f2543Smrg****************************************************************************/
2296706f2543Smrgstatic void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2297706f2543Smrg{
2298706f2543Smrg    int mod, rl, rh;
2299706f2543Smrg    uint srcoffset;
2300706f2543Smrg
2301706f2543Smrg    START_OF_INSTR();
2302706f2543Smrg    DECODE_PRINTF("BSR\t");
2303706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
2304706f2543Smrg    switch(mod) {
2305706f2543Smrg    case 0:
2306706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2307706f2543Smrg	    u32 srcval, *dstreg;
2308706f2543Smrg
2309706f2543Smrg	    srcoffset = decode_rm00_address(rl);
2310706f2543Smrg	    DECODE_PRINTF(",");
2311706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2312706f2543Smrg	    TRACE_AND_STEP();
2313706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2314706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2315706f2543Smrg	    for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2316706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2317706f2543Smrg	} else {
2318706f2543Smrg	    u16 srcval, *dstreg;
2319706f2543Smrg
2320706f2543Smrg	    srcoffset = decode_rm00_address(rl);
2321706f2543Smrg	    DECODE_PRINTF(",");
2322706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2323706f2543Smrg	    TRACE_AND_STEP();
2324706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2325706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2326706f2543Smrg	    for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2327706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2328706f2543Smrg	}
2329706f2543Smrg	break;
2330706f2543Smrg    case 1:
2331706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2332706f2543Smrg	    u32 srcval, *dstreg;
2333706f2543Smrg
2334706f2543Smrg	    srcoffset = decode_rm01_address(rl);
2335706f2543Smrg	    DECODE_PRINTF(",");
2336706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2337706f2543Smrg	    TRACE_AND_STEP();
2338706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2339706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2340706f2543Smrg	    for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2341706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2342706f2543Smrg	} else {
2343706f2543Smrg	    u16 srcval, *dstreg;
2344706f2543Smrg
2345706f2543Smrg	    srcoffset = decode_rm01_address(rl);
2346706f2543Smrg	    DECODE_PRINTF(",");
2347706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2348706f2543Smrg	    TRACE_AND_STEP();
2349706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2350706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2351706f2543Smrg	    for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2352706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2353706f2543Smrg	}
2354706f2543Smrg	break;
2355706f2543Smrg    case 2:
2356706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2357706f2543Smrg	    u32 srcval, *dstreg;
2358706f2543Smrg
2359706f2543Smrg	    srcoffset = decode_rm10_address(rl);
2360706f2543Smrg	    DECODE_PRINTF(",");
2361706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2362706f2543Smrg	    TRACE_AND_STEP();
2363706f2543Smrg	    srcval = fetch_data_long(srcoffset);
2364706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2365706f2543Smrg	    for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2366706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2367706f2543Smrg	} else {
2368706f2543Smrg	    u16 srcval, *dstreg;
2369706f2543Smrg
2370706f2543Smrg	    srcoffset = decode_rm10_address(rl);
2371706f2543Smrg	    DECODE_PRINTF(",");
2372706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2373706f2543Smrg	    TRACE_AND_STEP();
2374706f2543Smrg	    srcval = fetch_data_word(srcoffset);
2375706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2376706f2543Smrg	    for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2377706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2378706f2543Smrg	}
2379706f2543Smrg	break;
2380706f2543Smrg    case 3:				/* register to register */
2381706f2543Smrg	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2382706f2543Smrg	    u32 srcval, *dstreg;
2383706f2543Smrg
2384706f2543Smrg	    srcval = *DECODE_RM_LONG_REGISTER(rl);
2385706f2543Smrg	    DECODE_PRINTF(",");
2386706f2543Smrg	    dstreg = DECODE_RM_LONG_REGISTER(rh);
2387706f2543Smrg	    TRACE_AND_STEP();
2388706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2389706f2543Smrg	    for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2390706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2391706f2543Smrg	} else {
2392706f2543Smrg	    u16 srcval, *dstreg;
2393706f2543Smrg
2394706f2543Smrg	    srcval = *DECODE_RM_WORD_REGISTER(rl);
2395706f2543Smrg	    DECODE_PRINTF(",");
2396706f2543Smrg	    dstreg = DECODE_RM_WORD_REGISTER(rh);
2397706f2543Smrg	    TRACE_AND_STEP();
2398706f2543Smrg	    CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2399706f2543Smrg	    for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2400706f2543Smrg		if ((srcval >> *dstreg) & 1) break;
2401706f2543Smrg	}
2402706f2543Smrg	break;
2403706f2543Smrg    }
2404706f2543Smrg    DECODE_CLEAR_SEGOVR();
2405706f2543Smrg    END_OF_INSTR();
2406706f2543Smrg}
2407706f2543Smrg
2408706f2543Smrg/****************************************************************************
2409706f2543SmrgREMARKS:
2410706f2543SmrgHandles opcode 0x0f,0xbe
2411706f2543Smrg****************************************************************************/
2412706f2543Smrgstatic void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2413706f2543Smrg{
2414706f2543Smrg    int mod, rl, rh;
2415706f2543Smrg    uint srcoffset;
2416706f2543Smrg
2417706f2543Smrg    START_OF_INSTR();
2418706f2543Smrg    DECODE_PRINTF("MOVSX\t");
2419706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
2420706f2543Smrg    switch (mod) {
2421706f2543Smrg    case 0:
2422706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2423706f2543Smrg            u32 *destreg;
2424706f2543Smrg            u32 srcval;
2425706f2543Smrg
2426706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
2427706f2543Smrg            DECODE_PRINTF(",");
2428706f2543Smrg            srcoffset = decode_rm00_address(rl);
2429706f2543Smrg            srcval = (s32)((s8)fetch_data_byte(srcoffset));
2430706f2543Smrg            DECODE_PRINTF("\n");
2431706f2543Smrg            TRACE_AND_STEP();
2432706f2543Smrg            *destreg = srcval;
2433706f2543Smrg        } else {
2434706f2543Smrg            u16 *destreg;
2435706f2543Smrg            u16 srcval;
2436706f2543Smrg
2437706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
2438706f2543Smrg            DECODE_PRINTF(",");
2439706f2543Smrg            srcoffset = decode_rm00_address(rl);
2440706f2543Smrg            srcval = (s16)((s8)fetch_data_byte(srcoffset));
2441706f2543Smrg            DECODE_PRINTF("\n");
2442706f2543Smrg            TRACE_AND_STEP();
2443706f2543Smrg            *destreg = srcval;
2444706f2543Smrg        }
2445706f2543Smrg        break;
2446706f2543Smrg    case 1:
2447706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2448706f2543Smrg            u32 *destreg;
2449706f2543Smrg            u32 srcval;
2450706f2543Smrg
2451706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
2452706f2543Smrg            DECODE_PRINTF(",");
2453706f2543Smrg            srcoffset = decode_rm01_address(rl);
2454706f2543Smrg            srcval = (s32)((s8)fetch_data_byte(srcoffset));
2455706f2543Smrg            DECODE_PRINTF("\n");
2456706f2543Smrg            TRACE_AND_STEP();
2457706f2543Smrg            *destreg = srcval;
2458706f2543Smrg        } else {
2459706f2543Smrg            u16 *destreg;
2460706f2543Smrg            u16 srcval;
2461706f2543Smrg
2462706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
2463706f2543Smrg            DECODE_PRINTF(",");
2464706f2543Smrg            srcoffset = decode_rm01_address(rl);
2465706f2543Smrg            srcval = (s16)((s8)fetch_data_byte(srcoffset));
2466706f2543Smrg            DECODE_PRINTF("\n");
2467706f2543Smrg            TRACE_AND_STEP();
2468706f2543Smrg            *destreg = srcval;
2469706f2543Smrg        }
2470706f2543Smrg        break;
2471706f2543Smrg    case 2:
2472706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2473706f2543Smrg            u32 *destreg;
2474706f2543Smrg            u32 srcval;
2475706f2543Smrg
2476706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
2477706f2543Smrg            DECODE_PRINTF(",");
2478706f2543Smrg            srcoffset = decode_rm10_address(rl);
2479706f2543Smrg            srcval = (s32)((s8)fetch_data_byte(srcoffset));
2480706f2543Smrg            DECODE_PRINTF("\n");
2481706f2543Smrg            TRACE_AND_STEP();
2482706f2543Smrg            *destreg = srcval;
2483706f2543Smrg        } else {
2484706f2543Smrg            u16 *destreg;
2485706f2543Smrg            u16 srcval;
2486706f2543Smrg
2487706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
2488706f2543Smrg            DECODE_PRINTF(",");
2489706f2543Smrg            srcoffset = decode_rm10_address(rl);
2490706f2543Smrg            srcval = (s16)((s8)fetch_data_byte(srcoffset));
2491706f2543Smrg            DECODE_PRINTF("\n");
2492706f2543Smrg            TRACE_AND_STEP();
2493706f2543Smrg            *destreg = srcval;
2494706f2543Smrg        }
2495706f2543Smrg        break;
2496706f2543Smrg    case 3:                     /* register to register */
2497706f2543Smrg        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2498706f2543Smrg            u32 *destreg;
2499706f2543Smrg            u8  *srcreg;
2500706f2543Smrg
2501706f2543Smrg            destreg = DECODE_RM_LONG_REGISTER(rh);
2502706f2543Smrg            DECODE_PRINTF(",");
2503706f2543Smrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
2504706f2543Smrg            DECODE_PRINTF("\n");
2505706f2543Smrg            TRACE_AND_STEP();
2506706f2543Smrg            *destreg = (s32)((s8)*srcreg);
2507706f2543Smrg        } else {
2508706f2543Smrg            u16 *destreg;
2509706f2543Smrg            u8  *srcreg;
2510706f2543Smrg
2511706f2543Smrg            destreg = DECODE_RM_WORD_REGISTER(rh);
2512706f2543Smrg            DECODE_PRINTF(",");
2513706f2543Smrg            srcreg = DECODE_RM_BYTE_REGISTER(rl);
2514706f2543Smrg            DECODE_PRINTF("\n");
2515706f2543Smrg            TRACE_AND_STEP();
2516706f2543Smrg            *destreg = (s16)((s8)*srcreg);
2517706f2543Smrg        }
2518706f2543Smrg        break;
2519706f2543Smrg    }
2520706f2543Smrg    DECODE_CLEAR_SEGOVR();
2521706f2543Smrg    END_OF_INSTR();
2522706f2543Smrg}
2523706f2543Smrg
2524706f2543Smrg/****************************************************************************
2525706f2543SmrgREMARKS:
2526706f2543SmrgHandles opcode 0x0f,0xbf
2527706f2543Smrg****************************************************************************/
2528706f2543Smrgstatic void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2529706f2543Smrg{
2530706f2543Smrg    int mod, rl, rh;
2531706f2543Smrg    uint srcoffset;
2532706f2543Smrg    u32 *destreg;
2533706f2543Smrg    u32 srcval;
2534706f2543Smrg    u16 *srcreg;
2535706f2543Smrg
2536706f2543Smrg    START_OF_INSTR();
2537706f2543Smrg    DECODE_PRINTF("MOVSX\t");
2538706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
2539706f2543Smrg    switch (mod) {
2540706f2543Smrg    case 0:
2541706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
2542706f2543Smrg        DECODE_PRINTF(",");
2543706f2543Smrg        srcoffset = decode_rm00_address(rl);
2544706f2543Smrg        srcval = (s32)((s16)fetch_data_word(srcoffset));
2545706f2543Smrg        DECODE_PRINTF("\n");
2546706f2543Smrg        TRACE_AND_STEP();
2547706f2543Smrg        *destreg = srcval;
2548706f2543Smrg        break;
2549706f2543Smrg    case 1:
2550706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
2551706f2543Smrg        DECODE_PRINTF(",");
2552706f2543Smrg        srcoffset = decode_rm01_address(rl);
2553706f2543Smrg        srcval = (s32)((s16)fetch_data_word(srcoffset));
2554706f2543Smrg        DECODE_PRINTF("\n");
2555706f2543Smrg        TRACE_AND_STEP();
2556706f2543Smrg        *destreg = srcval;
2557706f2543Smrg        break;
2558706f2543Smrg    case 2:
2559706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
2560706f2543Smrg        DECODE_PRINTF(",");
2561706f2543Smrg        srcoffset = decode_rm10_address(rl);
2562706f2543Smrg        srcval = (s32)((s16)fetch_data_word(srcoffset));
2563706f2543Smrg        DECODE_PRINTF("\n");
2564706f2543Smrg        TRACE_AND_STEP();
2565706f2543Smrg        *destreg = srcval;
2566706f2543Smrg        break;
2567706f2543Smrg    case 3:                     /* register to register */
2568706f2543Smrg        destreg = DECODE_RM_LONG_REGISTER(rh);
2569706f2543Smrg        DECODE_PRINTF(",");
2570706f2543Smrg        srcreg = DECODE_RM_WORD_REGISTER(rl);
2571706f2543Smrg        DECODE_PRINTF("\n");
2572706f2543Smrg        TRACE_AND_STEP();
2573706f2543Smrg        *destreg = (s32)((s16)*srcreg);
2574706f2543Smrg        break;
2575706f2543Smrg    }
2576706f2543Smrg    DECODE_CLEAR_SEGOVR();
2577706f2543Smrg    END_OF_INSTR();
2578706f2543Smrg}
2579706f2543Smrg
2580706f2543Smrg/* Handles opcodes 0xc8-0xcf */
2581706f2543Smrgstatic void x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
2582706f2543Smrg{
2583706f2543Smrg    START_OF_INSTR();
2584706f2543Smrg    DECODE_PRINTF("BSWAP\n");
2585706f2543Smrg    TRACE_AND_STEP();
2586706f2543Smrg
2587706f2543Smrg    switch (op2) {
2588706f2543Smrg	case 0xc8:
2589706f2543Smrg	    M.x86.R_EAX = bswap_32(M.x86.R_EAX);
2590706f2543Smrg	    break;
2591706f2543Smrg	case 0xc9:
2592706f2543Smrg	    M.x86.R_ECX = bswap_32(M.x86.R_ECX);
2593706f2543Smrg	    break;
2594706f2543Smrg	case 0xca:
2595706f2543Smrg	    M.x86.R_EDX = bswap_32(M.x86.R_EDX);
2596706f2543Smrg	    break;
2597706f2543Smrg	case 0xcb:
2598706f2543Smrg	    M.x86.R_EBX = bswap_32(M.x86.R_EBX);
2599706f2543Smrg	    break;
2600706f2543Smrg	case 0xcc:
2601706f2543Smrg	    M.x86.R_ESP = bswap_32(M.x86.R_ESP);
2602706f2543Smrg	    break;
2603706f2543Smrg	case 0xcd:
2604706f2543Smrg	    M.x86.R_EBP = bswap_32(M.x86.R_EBP);
2605706f2543Smrg	    break;
2606706f2543Smrg	case 0xce:
2607706f2543Smrg	    M.x86.R_ESI = bswap_32(M.x86.R_ESI);
2608706f2543Smrg	    break;
2609706f2543Smrg	case 0xcf:
2610706f2543Smrg	    M.x86.R_EDI = bswap_32(M.x86.R_EDI);
2611706f2543Smrg	    break;
2612706f2543Smrg	default:
2613706f2543Smrg	    /* can't happen */
2614706f2543Smrg	    break;
2615706f2543Smrg    }
2616706f2543Smrg
2617706f2543Smrg    DECODE_CLEAR_SEGOVR();
2618706f2543Smrg    END_OF_INSTR();
2619706f2543Smrg}
2620706f2543Smrg
2621706f2543Smrg/***************************************************************************
2622706f2543Smrg * Double byte operation code table:
2623706f2543Smrg **************************************************************************/
2624706f2543Smrgvoid (*x86emu_optab2[256])(u8) =
2625706f2543Smrg{
2626706f2543Smrg/*  0x00 */ x86emuOp2_illegal_op,  /* Group F (ring 0 PM)      */
2627706f2543Smrg/*  0x01 */ x86emuOp2_illegal_op,  /* Group G (ring 0 PM)      */
2628706f2543Smrg/*  0x02 */ x86emuOp2_illegal_op,  /* lar (ring 0 PM)          */
2629706f2543Smrg/*  0x03 */ x86emuOp2_illegal_op,  /* lsl (ring 0 PM)          */
2630706f2543Smrg/*  0x04 */ x86emuOp2_illegal_op,
2631706f2543Smrg/*  0x05 */ x86emuOp2_illegal_op,  /* loadall (undocumented)   */
2632706f2543Smrg/*  0x06 */ x86emuOp2_illegal_op,  /* clts (ring 0 PM)         */
2633706f2543Smrg/*  0x07 */ x86emuOp2_illegal_op,  /* loadall (undocumented)   */
2634706f2543Smrg/*  0x08 */ x86emuOp2_illegal_op,  /* invd (ring 0 PM)         */
2635706f2543Smrg/*  0x09 */ x86emuOp2_illegal_op,  /* wbinvd (ring 0 PM)       */
2636706f2543Smrg/*  0x0a */ x86emuOp2_illegal_op,
2637706f2543Smrg/*  0x0b */ x86emuOp2_illegal_op,
2638706f2543Smrg/*  0x0c */ x86emuOp2_illegal_op,
2639706f2543Smrg/*  0x0d */ x86emuOp2_illegal_op,
2640706f2543Smrg/*  0x0e */ x86emuOp2_illegal_op,
2641706f2543Smrg/*  0x0f */ x86emuOp2_illegal_op,
2642706f2543Smrg
2643706f2543Smrg/*  0x10 */ x86emuOp2_illegal_op,
2644706f2543Smrg/*  0x11 */ x86emuOp2_illegal_op,
2645706f2543Smrg/*  0x12 */ x86emuOp2_illegal_op,
2646706f2543Smrg/*  0x13 */ x86emuOp2_illegal_op,
2647706f2543Smrg/*  0x14 */ x86emuOp2_illegal_op,
2648706f2543Smrg/*  0x15 */ x86emuOp2_illegal_op,
2649706f2543Smrg/*  0x16 */ x86emuOp2_illegal_op,
2650706f2543Smrg/*  0x17 */ x86emuOp2_illegal_op,
2651706f2543Smrg/*  0x18 */ x86emuOp2_illegal_op,
2652706f2543Smrg/*  0x19 */ x86emuOp2_illegal_op,
2653706f2543Smrg/*  0x1a */ x86emuOp2_illegal_op,
2654706f2543Smrg/*  0x1b */ x86emuOp2_illegal_op,
2655706f2543Smrg/*  0x1c */ x86emuOp2_illegal_op,
2656706f2543Smrg/*  0x1d */ x86emuOp2_illegal_op,
2657706f2543Smrg/*  0x1e */ x86emuOp2_illegal_op,
2658706f2543Smrg/*  0x1f */ x86emuOp2_illegal_op,
2659706f2543Smrg
2660706f2543Smrg/*  0x20 */ x86emuOp2_illegal_op,  /* mov reg32,creg (ring 0 PM) */
2661706f2543Smrg/*  0x21 */ x86emuOp2_illegal_op,  /* mov reg32,dreg (ring 0 PM) */
2662706f2543Smrg/*  0x22 */ x86emuOp2_illegal_op,  /* mov creg,reg32 (ring 0 PM) */
2663706f2543Smrg/*  0x23 */ x86emuOp2_illegal_op,  /* mov dreg,reg32 (ring 0 PM) */
2664706f2543Smrg/*  0x24 */ x86emuOp2_illegal_op,  /* mov reg32,treg (ring 0 PM) */
2665706f2543Smrg/*  0x25 */ x86emuOp2_illegal_op,
2666706f2543Smrg/*  0x26 */ x86emuOp2_illegal_op,  /* mov treg,reg32 (ring 0 PM) */
2667706f2543Smrg/*  0x27 */ x86emuOp2_illegal_op,
2668706f2543Smrg/*  0x28 */ x86emuOp2_illegal_op,
2669706f2543Smrg/*  0x29 */ x86emuOp2_illegal_op,
2670706f2543Smrg/*  0x2a */ x86emuOp2_illegal_op,
2671706f2543Smrg/*  0x2b */ x86emuOp2_illegal_op,
2672706f2543Smrg/*  0x2c */ x86emuOp2_illegal_op,
2673706f2543Smrg/*  0x2d */ x86emuOp2_illegal_op,
2674706f2543Smrg/*  0x2e */ x86emuOp2_illegal_op,
2675706f2543Smrg/*  0x2f */ x86emuOp2_illegal_op,
2676706f2543Smrg
2677706f2543Smrg/*  0x30 */ x86emuOp2_illegal_op,
2678706f2543Smrg/*  0x31 */ x86emuOp2_rdtsc,
2679706f2543Smrg/*  0x32 */ x86emuOp2_illegal_op,
2680706f2543Smrg/*  0x33 */ x86emuOp2_illegal_op,
2681706f2543Smrg/*  0x34 */ x86emuOp2_illegal_op,
2682706f2543Smrg/*  0x35 */ x86emuOp2_illegal_op,
2683706f2543Smrg/*  0x36 */ x86emuOp2_illegal_op,
2684706f2543Smrg/*  0x37 */ x86emuOp2_illegal_op,
2685706f2543Smrg/*  0x38 */ x86emuOp2_illegal_op,
2686706f2543Smrg/*  0x39 */ x86emuOp2_illegal_op,
2687706f2543Smrg/*  0x3a */ x86emuOp2_illegal_op,
2688706f2543Smrg/*  0x3b */ x86emuOp2_illegal_op,
2689706f2543Smrg/*  0x3c */ x86emuOp2_illegal_op,
2690706f2543Smrg/*  0x3d */ x86emuOp2_illegal_op,
2691706f2543Smrg/*  0x3e */ x86emuOp2_illegal_op,
2692706f2543Smrg/*  0x3f */ x86emuOp2_illegal_op,
2693706f2543Smrg
2694706f2543Smrg/*  0x40 */ x86emuOp2_illegal_op,
2695706f2543Smrg/*  0x41 */ x86emuOp2_illegal_op,
2696706f2543Smrg/*  0x42 */ x86emuOp2_illegal_op,
2697706f2543Smrg/*  0x43 */ x86emuOp2_illegal_op,
2698706f2543Smrg/*  0x44 */ x86emuOp2_illegal_op,
2699706f2543Smrg/*  0x45 */ x86emuOp2_illegal_op,
2700706f2543Smrg/*  0x46 */ x86emuOp2_illegal_op,
2701706f2543Smrg/*  0x47 */ x86emuOp2_illegal_op,
2702706f2543Smrg/*  0x48 */ x86emuOp2_illegal_op,
2703706f2543Smrg/*  0x49 */ x86emuOp2_illegal_op,
2704706f2543Smrg/*  0x4a */ x86emuOp2_illegal_op,
2705706f2543Smrg/*  0x4b */ x86emuOp2_illegal_op,
2706706f2543Smrg/*  0x4c */ x86emuOp2_illegal_op,
2707706f2543Smrg/*  0x4d */ x86emuOp2_illegal_op,
2708706f2543Smrg/*  0x4e */ x86emuOp2_illegal_op,
2709706f2543Smrg/*  0x4f */ x86emuOp2_illegal_op,
2710706f2543Smrg
2711706f2543Smrg/*  0x50 */ x86emuOp2_illegal_op,
2712706f2543Smrg/*  0x51 */ x86emuOp2_illegal_op,
2713706f2543Smrg/*  0x52 */ x86emuOp2_illegal_op,
2714706f2543Smrg/*  0x53 */ x86emuOp2_illegal_op,
2715706f2543Smrg/*  0x54 */ x86emuOp2_illegal_op,
2716706f2543Smrg/*  0x55 */ x86emuOp2_illegal_op,
2717706f2543Smrg/*  0x56 */ x86emuOp2_illegal_op,
2718706f2543Smrg/*  0x57 */ x86emuOp2_illegal_op,
2719706f2543Smrg/*  0x58 */ x86emuOp2_illegal_op,
2720706f2543Smrg/*  0x59 */ x86emuOp2_illegal_op,
2721706f2543Smrg/*  0x5a */ x86emuOp2_illegal_op,
2722706f2543Smrg/*  0x5b */ x86emuOp2_illegal_op,
2723706f2543Smrg/*  0x5c */ x86emuOp2_illegal_op,
2724706f2543Smrg/*  0x5d */ x86emuOp2_illegal_op,
2725706f2543Smrg/*  0x5e */ x86emuOp2_illegal_op,
2726706f2543Smrg/*  0x5f */ x86emuOp2_illegal_op,
2727706f2543Smrg
2728706f2543Smrg/*  0x60 */ x86emuOp2_illegal_op,
2729706f2543Smrg/*  0x61 */ x86emuOp2_illegal_op,
2730706f2543Smrg/*  0x62 */ x86emuOp2_illegal_op,
2731706f2543Smrg/*  0x63 */ x86emuOp2_illegal_op,
2732706f2543Smrg/*  0x64 */ x86emuOp2_illegal_op,
2733706f2543Smrg/*  0x65 */ x86emuOp2_illegal_op,
2734706f2543Smrg/*  0x66 */ x86emuOp2_illegal_op,
2735706f2543Smrg/*  0x67 */ x86emuOp2_illegal_op,
2736706f2543Smrg/*  0x68 */ x86emuOp2_illegal_op,
2737706f2543Smrg/*  0x69 */ x86emuOp2_illegal_op,
2738706f2543Smrg/*  0x6a */ x86emuOp2_illegal_op,
2739706f2543Smrg/*  0x6b */ x86emuOp2_illegal_op,
2740706f2543Smrg/*  0x6c */ x86emuOp2_illegal_op,
2741706f2543Smrg/*  0x6d */ x86emuOp2_illegal_op,
2742706f2543Smrg/*  0x6e */ x86emuOp2_illegal_op,
2743706f2543Smrg/*  0x6f */ x86emuOp2_illegal_op,
2744706f2543Smrg
2745706f2543Smrg/*  0x70 */ x86emuOp2_illegal_op,
2746706f2543Smrg/*  0x71 */ x86emuOp2_illegal_op,
2747706f2543Smrg/*  0x72 */ x86emuOp2_illegal_op,
2748706f2543Smrg/*  0x73 */ x86emuOp2_illegal_op,
2749706f2543Smrg/*  0x74 */ x86emuOp2_illegal_op,
2750706f2543Smrg/*  0x75 */ x86emuOp2_illegal_op,
2751706f2543Smrg/*  0x76 */ x86emuOp2_illegal_op,
2752706f2543Smrg/*  0x77 */ x86emuOp2_illegal_op,
2753706f2543Smrg/*  0x78 */ x86emuOp2_illegal_op,
2754706f2543Smrg/*  0x79 */ x86emuOp2_illegal_op,
2755706f2543Smrg/*  0x7a */ x86emuOp2_illegal_op,
2756706f2543Smrg/*  0x7b */ x86emuOp2_illegal_op,
2757706f2543Smrg/*  0x7c */ x86emuOp2_illegal_op,
2758706f2543Smrg/*  0x7d */ x86emuOp2_illegal_op,
2759706f2543Smrg/*  0x7e */ x86emuOp2_illegal_op,
2760706f2543Smrg/*  0x7f */ x86emuOp2_illegal_op,
2761706f2543Smrg
2762706f2543Smrg/*  0x80 */ x86emuOp2_long_jump,
2763706f2543Smrg/*  0x81 */ x86emuOp2_long_jump,
2764706f2543Smrg/*  0x82 */ x86emuOp2_long_jump,
2765706f2543Smrg/*  0x83 */ x86emuOp2_long_jump,
2766706f2543Smrg/*  0x84 */ x86emuOp2_long_jump,
2767706f2543Smrg/*  0x85 */ x86emuOp2_long_jump,
2768706f2543Smrg/*  0x86 */ x86emuOp2_long_jump,
2769706f2543Smrg/*  0x87 */ x86emuOp2_long_jump,
2770706f2543Smrg/*  0x88 */ x86emuOp2_long_jump,
2771706f2543Smrg/*  0x89 */ x86emuOp2_long_jump,
2772706f2543Smrg/*  0x8a */ x86emuOp2_long_jump,
2773706f2543Smrg/*  0x8b */ x86emuOp2_long_jump,
2774706f2543Smrg/*  0x8c */ x86emuOp2_long_jump,
2775706f2543Smrg/*  0x8d */ x86emuOp2_long_jump,
2776706f2543Smrg/*  0x8e */ x86emuOp2_long_jump,
2777706f2543Smrg/*  0x8f */ x86emuOp2_long_jump,
2778706f2543Smrg
2779706f2543Smrg/*  0x90 */ x86emuOp2_set_byte,
2780706f2543Smrg/*  0x91 */ x86emuOp2_set_byte,
2781706f2543Smrg/*  0x92 */ x86emuOp2_set_byte,
2782706f2543Smrg/*  0x93 */ x86emuOp2_set_byte,
2783706f2543Smrg/*  0x94 */ x86emuOp2_set_byte,
2784706f2543Smrg/*  0x95 */ x86emuOp2_set_byte,
2785706f2543Smrg/*  0x96 */ x86emuOp2_set_byte,
2786706f2543Smrg/*  0x97 */ x86emuOp2_set_byte,
2787706f2543Smrg/*  0x98 */ x86emuOp2_set_byte,
2788706f2543Smrg/*  0x99 */ x86emuOp2_set_byte,
2789706f2543Smrg/*  0x9a */ x86emuOp2_set_byte,
2790706f2543Smrg/*  0x9b */ x86emuOp2_set_byte,
2791706f2543Smrg/*  0x9c */ x86emuOp2_set_byte,
2792706f2543Smrg/*  0x9d */ x86emuOp2_set_byte,
2793706f2543Smrg/*  0x9e */ x86emuOp2_set_byte,
2794706f2543Smrg/*  0x9f */ x86emuOp2_set_byte,
2795706f2543Smrg
2796706f2543Smrg/*  0xa0 */ x86emuOp2_push_FS,
2797706f2543Smrg/*  0xa1 */ x86emuOp2_pop_FS,
2798706f2543Smrg/*  0xa2 */ x86emuOp2_cpuid,
2799706f2543Smrg/*  0xa3 */ x86emuOp2_bt_R,
2800706f2543Smrg/*  0xa4 */ x86emuOp2_shld_IMM,
2801706f2543Smrg/*  0xa5 */ x86emuOp2_shld_CL,
2802706f2543Smrg/*  0xa6 */ x86emuOp2_illegal_op,
2803706f2543Smrg/*  0xa7 */ x86emuOp2_illegal_op,
2804706f2543Smrg/*  0xa8 */ x86emuOp2_push_GS,
2805706f2543Smrg/*  0xa9 */ x86emuOp2_pop_GS,
2806706f2543Smrg/*  0xaa */ x86emuOp2_illegal_op,
2807706f2543Smrg/*  0xab */ x86emuOp2_bts_R,
2808706f2543Smrg/*  0xac */ x86emuOp2_shrd_IMM,
2809706f2543Smrg/*  0xad */ x86emuOp2_shrd_CL,
2810706f2543Smrg/*  0xae */ x86emuOp2_illegal_op,
2811706f2543Smrg/*  0xaf */ x86emuOp2_imul_R_RM,
2812706f2543Smrg
2813706f2543Smrg/*  0xb0 */ x86emuOp2_illegal_op,  /* TODO: cmpxchg */
2814706f2543Smrg/*  0xb1 */ x86emuOp2_illegal_op,  /* TODO: cmpxchg */
2815706f2543Smrg/*  0xb2 */ x86emuOp2_lss_R_IMM,
2816706f2543Smrg/*  0xb3 */ x86emuOp2_btr_R,
2817706f2543Smrg/*  0xb4 */ x86emuOp2_lfs_R_IMM,
2818706f2543Smrg/*  0xb5 */ x86emuOp2_lgs_R_IMM,
2819706f2543Smrg/*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
2820706f2543Smrg/*  0xb7 */ x86emuOp2_movzx_word_R_RM,
2821706f2543Smrg/*  0xb8 */ x86emuOp2_illegal_op,
2822706f2543Smrg/*  0xb9 */ x86emuOp2_illegal_op,
2823706f2543Smrg/*  0xba */ x86emuOp2_btX_I,
2824706f2543Smrg/*  0xbb */ x86emuOp2_btc_R,
2825706f2543Smrg/*  0xbc */ x86emuOp2_bsf,
2826706f2543Smrg/*  0xbd */ x86emuOp2_bsr,
2827706f2543Smrg/*  0xbe */ x86emuOp2_movsx_byte_R_RM,
2828706f2543Smrg/*  0xbf */ x86emuOp2_movsx_word_R_RM,
2829706f2543Smrg
2830706f2543Smrg/*  0xc0 */ x86emuOp2_illegal_op,  /* TODO: xadd */
2831706f2543Smrg/*  0xc1 */ x86emuOp2_illegal_op,  /* TODO: xadd */
2832706f2543Smrg/*  0xc2 */ x86emuOp2_illegal_op,
2833706f2543Smrg/*  0xc3 */ x86emuOp2_illegal_op,
2834706f2543Smrg/*  0xc4 */ x86emuOp2_illegal_op,
2835706f2543Smrg/*  0xc5 */ x86emuOp2_illegal_op,
2836706f2543Smrg/*  0xc6 */ x86emuOp2_illegal_op,
2837706f2543Smrg/*  0xc7 */ x86emuOp2_illegal_op,
2838706f2543Smrg/*  0xc8 */ x86emuOp2_bswap,
2839706f2543Smrg/*  0xc9 */ x86emuOp2_bswap,
2840706f2543Smrg/*  0xca */ x86emuOp2_bswap,
2841706f2543Smrg/*  0xcb */ x86emuOp2_bswap,
2842706f2543Smrg/*  0xcc */ x86emuOp2_bswap,
2843706f2543Smrg/*  0xcd */ x86emuOp2_bswap,
2844706f2543Smrg/*  0xce */ x86emuOp2_bswap,
2845706f2543Smrg/*  0xcf */ x86emuOp2_bswap,
2846706f2543Smrg
2847706f2543Smrg/*  0xd0 */ x86emuOp2_illegal_op,
2848706f2543Smrg/*  0xd1 */ x86emuOp2_illegal_op,
2849706f2543Smrg/*  0xd2 */ x86emuOp2_illegal_op,
2850706f2543Smrg/*  0xd3 */ x86emuOp2_illegal_op,
2851706f2543Smrg/*  0xd4 */ x86emuOp2_illegal_op,
2852706f2543Smrg/*  0xd5 */ x86emuOp2_illegal_op,
2853706f2543Smrg/*  0xd6 */ x86emuOp2_illegal_op,
2854706f2543Smrg/*  0xd7 */ x86emuOp2_illegal_op,
2855706f2543Smrg/*  0xd8 */ x86emuOp2_illegal_op,
2856706f2543Smrg/*  0xd9 */ x86emuOp2_illegal_op,
2857706f2543Smrg/*  0xda */ x86emuOp2_illegal_op,
2858706f2543Smrg/*  0xdb */ x86emuOp2_illegal_op,
2859706f2543Smrg/*  0xdc */ x86emuOp2_illegal_op,
2860706f2543Smrg/*  0xdd */ x86emuOp2_illegal_op,
2861706f2543Smrg/*  0xde */ x86emuOp2_illegal_op,
2862706f2543Smrg/*  0xdf */ x86emuOp2_illegal_op,
2863706f2543Smrg
2864706f2543Smrg/*  0xe0 */ x86emuOp2_illegal_op,
2865706f2543Smrg/*  0xe1 */ x86emuOp2_illegal_op,
2866706f2543Smrg/*  0xe2 */ x86emuOp2_illegal_op,
2867706f2543Smrg/*  0xe3 */ x86emuOp2_illegal_op,
2868706f2543Smrg/*  0xe4 */ x86emuOp2_illegal_op,
2869706f2543Smrg/*  0xe5 */ x86emuOp2_illegal_op,
2870706f2543Smrg/*  0xe6 */ x86emuOp2_illegal_op,
2871706f2543Smrg/*  0xe7 */ x86emuOp2_illegal_op,
2872706f2543Smrg/*  0xe8 */ x86emuOp2_illegal_op,
2873706f2543Smrg/*  0xe9 */ x86emuOp2_illegal_op,
2874706f2543Smrg/*  0xea */ x86emuOp2_illegal_op,
2875706f2543Smrg/*  0xeb */ x86emuOp2_illegal_op,
2876706f2543Smrg/*  0xec */ x86emuOp2_illegal_op,
2877706f2543Smrg/*  0xed */ x86emuOp2_illegal_op,
2878706f2543Smrg/*  0xee */ x86emuOp2_illegal_op,
2879706f2543Smrg/*  0xef */ x86emuOp2_illegal_op,
2880706f2543Smrg
2881706f2543Smrg/*  0xf0 */ x86emuOp2_illegal_op,
2882706f2543Smrg/*  0xf1 */ x86emuOp2_illegal_op,
2883706f2543Smrg/*  0xf2 */ x86emuOp2_illegal_op,
2884706f2543Smrg/*  0xf3 */ x86emuOp2_illegal_op,
2885706f2543Smrg/*  0xf4 */ x86emuOp2_illegal_op,
2886706f2543Smrg/*  0xf5 */ x86emuOp2_illegal_op,
2887706f2543Smrg/*  0xf6 */ x86emuOp2_illegal_op,
2888706f2543Smrg/*  0xf7 */ x86emuOp2_illegal_op,
2889706f2543Smrg/*  0xf8 */ x86emuOp2_illegal_op,
2890706f2543Smrg/*  0xf9 */ x86emuOp2_illegal_op,
2891706f2543Smrg/*  0xfa */ x86emuOp2_illegal_op,
2892706f2543Smrg/*  0xfb */ x86emuOp2_illegal_op,
2893706f2543Smrg/*  0xfc */ x86emuOp2_illegal_op,
2894706f2543Smrg/*  0xfd */ x86emuOp2_illegal_op,
2895706f2543Smrg/*  0xfe */ x86emuOp2_illegal_op,
2896706f2543Smrg/*  0xff */ x86emuOp2_illegal_op,
2897706f2543Smrg};
2898