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