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