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