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