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 processor instructions.
37*
38* There are approximately 250 subroutines in here, which correspond
39* to the 256 byte-"opcodes" found on the 8086.  The table which
40* dispatches this is found in the files optab.[ch].
41*
42* Each opcode proc has a comment preceeding it which gives it's table
43* address.  Several opcodes are missing (undefined) in the table.
44*
45* Each proc includes information for decoding (DECODE_PRINTF and
46* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47* functions (START_OF_INSTR, END_OF_INSTR).
48*
49* Many of the procedures are *VERY* similar in coding.  This has
50* allowed for a very large amount of code to be generated in a fairly
51* short amount of time (i.e. cut, paste, and modify).  The result is
52* that much of the code below could have been folded into subroutines
53* for a large reduction in size of this file.  The downside would be
54* that there would be a penalty in execution speed.  The file could
55* also have been *MUCH* larger by inlining certain functions which
56* were called.  This could have resulted even faster execution.  The
57* prime directive I used to decide whether to inline the code or to
58* modularize it, was basically: 1) no unnecessary subroutine calls,
59* 2) no routines more than about 200 lines in size, and 3) modularize
60* any code that I might not get right the first time.  The fetch_*
61* subroutines fall into the latter category.  The The decode_* fall
62* into the second category.  The coding of the "switch(mod){ .... }"
63* in many of the subroutines below falls into the first category.
64* Especially, the coding of {add,and,or,sub,...}_{byte,word}
65* subroutines are an especially glaring case of the third guideline.
66* Since so much of the code is cloned from other modules (compare
67* opcode #00 to opcode #01), making the basic operations subroutine
68* calls is especially important; otherwise mistakes in coding an
69* "add" would represent a nightmare in maintenance.
70*
71****************************************************************************/
72
73#include "x86emu/x86emui.h"
74
75/*----------------------------- Implementation ----------------------------*/
76
77/****************************************************************************
78PARAMETERS:
79op1 - Instruction op code
80
81REMARKS:
82Handles illegal opcodes.
83****************************************************************************/
84static void x86emuOp_illegal_op(
85    u8 op1)
86{
87    START_OF_INSTR();
88    if (M.x86.R_SP != 0) {
89    DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90    TRACE_REGS();
91    DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92        M.x86.R_CS, M.x86.R_IP-1,op1));
93    HALT_SYS();
94        }
95    else {
96        /* If we get here, it means the stack pointer is back to zero
97         * so we are just returning from an emulator service call
98         * so therte is no need to display an error message. We trap
99         * the emulator with an 0xF1 opcode to finish the service
100         * call.
101         */
102        X86EMU_halt_sys();
103        }
104    END_OF_INSTR();
105}
106
107/****************************************************************************
108REMARKS:
109Handles opcode 0x00
110****************************************************************************/
111static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
112{
113    int mod, rl, rh;
114    uint destoffset;
115    u8 *destreg, *srcreg;
116    u8 destval;
117
118    START_OF_INSTR();
119    DECODE_PRINTF("ADD\t");
120    FETCH_DECODE_MODRM(mod, rh, rl);
121    switch (mod) {
122    case 0:
123        destoffset = decode_rm00_address(rl);
124        DECODE_PRINTF(",");
125        destval = fetch_data_byte(destoffset);
126        srcreg = DECODE_RM_BYTE_REGISTER(rh);
127        DECODE_PRINTF("\n");
128        TRACE_AND_STEP();
129        destval = add_byte(destval, *srcreg);
130        store_data_byte(destoffset, destval);
131        break;
132    case 1:
133        destoffset = decode_rm01_address(rl);
134        DECODE_PRINTF(",");
135        destval = fetch_data_byte(destoffset);
136        srcreg = DECODE_RM_BYTE_REGISTER(rh);
137        DECODE_PRINTF("\n");
138        TRACE_AND_STEP();
139        destval = add_byte(destval, *srcreg);
140        store_data_byte(destoffset, destval);
141        break;
142    case 2:
143        destoffset = decode_rm10_address(rl);
144        DECODE_PRINTF(",");
145        destval = fetch_data_byte(destoffset);
146        srcreg = DECODE_RM_BYTE_REGISTER(rh);
147        DECODE_PRINTF("\n");
148        TRACE_AND_STEP();
149        destval = add_byte(destval, *srcreg);
150        store_data_byte(destoffset, destval);
151        break;
152    case 3:                     /* register to register */
153        destreg = DECODE_RM_BYTE_REGISTER(rl);
154        DECODE_PRINTF(",");
155        srcreg = DECODE_RM_BYTE_REGISTER(rh);
156        DECODE_PRINTF("\n");
157        TRACE_AND_STEP();
158        *destreg = add_byte(*destreg, *srcreg);
159        break;
160    }
161    DECODE_CLEAR_SEGOVR();
162    END_OF_INSTR();
163}
164
165/****************************************************************************
166REMARKS:
167Handles opcode 0x01
168****************************************************************************/
169static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
170{
171    int mod, rl, rh;
172    uint destoffset;
173
174    START_OF_INSTR();
175    DECODE_PRINTF("ADD\t");
176    FETCH_DECODE_MODRM(mod, rh, rl);
177    switch (mod) {
178    case 0:
179        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
180            u32 destval;
181            u32 *srcreg;
182
183            destoffset = decode_rm00_address(rl);
184            DECODE_PRINTF(",");
185            destval = fetch_data_long(destoffset);
186            srcreg = DECODE_RM_LONG_REGISTER(rh);
187            DECODE_PRINTF("\n");
188            TRACE_AND_STEP();
189            destval = add_long(destval, *srcreg);
190            store_data_long(destoffset, destval);
191        } else {
192            u16 destval;
193            u16 *srcreg;
194
195            destoffset = decode_rm00_address(rl);
196            DECODE_PRINTF(",");
197            destval = fetch_data_word(destoffset);
198            srcreg = DECODE_RM_WORD_REGISTER(rh);
199            DECODE_PRINTF("\n");
200            TRACE_AND_STEP();
201            destval = add_word(destval, *srcreg);
202            store_data_word(destoffset, destval);
203        }
204        break;
205    case 1:
206        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
207            u32 destval;
208            u32 *srcreg;
209
210            destoffset = decode_rm01_address(rl);
211            DECODE_PRINTF(",");
212            destval = fetch_data_long(destoffset);
213            srcreg = DECODE_RM_LONG_REGISTER(rh);
214            DECODE_PRINTF("\n");
215            TRACE_AND_STEP();
216            destval = add_long(destval, *srcreg);
217            store_data_long(destoffset, destval);
218        } else {
219            u16 destval;
220            u16 *srcreg;
221
222            destoffset = decode_rm01_address(rl);
223            DECODE_PRINTF(",");
224            destval = fetch_data_word(destoffset);
225            srcreg = DECODE_RM_WORD_REGISTER(rh);
226            DECODE_PRINTF("\n");
227            TRACE_AND_STEP();
228            destval = add_word(destval, *srcreg);
229            store_data_word(destoffset, destval);
230        }
231        break;
232    case 2:
233        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
234            u32 destval;
235            u32 *srcreg;
236
237            destoffset = decode_rm10_address(rl);
238            DECODE_PRINTF(",");
239            destval = fetch_data_long(destoffset);
240            srcreg = DECODE_RM_LONG_REGISTER(rh);
241            DECODE_PRINTF("\n");
242            TRACE_AND_STEP();
243            destval = add_long(destval, *srcreg);
244            store_data_long(destoffset, destval);
245        } else {
246            u16 destval;
247            u16 *srcreg;
248
249            destoffset = decode_rm10_address(rl);
250            DECODE_PRINTF(",");
251            destval = fetch_data_word(destoffset);
252            srcreg = DECODE_RM_WORD_REGISTER(rh);
253            DECODE_PRINTF("\n");
254            TRACE_AND_STEP();
255            destval = add_word(destval, *srcreg);
256            store_data_word(destoffset, destval);
257        }
258        break;
259    case 3:                     /* register to register */
260        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
261            u32 *destreg,*srcreg;
262
263            destreg = DECODE_RM_LONG_REGISTER(rl);
264            DECODE_PRINTF(",");
265            srcreg = DECODE_RM_LONG_REGISTER(rh);
266            DECODE_PRINTF("\n");
267            TRACE_AND_STEP();
268            *destreg = add_long(*destreg, *srcreg);
269        } else {
270            u16 *destreg,*srcreg;
271
272            destreg = DECODE_RM_WORD_REGISTER(rl);
273            DECODE_PRINTF(",");
274            srcreg = DECODE_RM_WORD_REGISTER(rh);
275            DECODE_PRINTF("\n");
276            TRACE_AND_STEP();
277            *destreg = add_word(*destreg, *srcreg);
278        }
279        break;
280    }
281    DECODE_CLEAR_SEGOVR();
282    END_OF_INSTR();
283}
284
285/****************************************************************************
286REMARKS:
287Handles opcode 0x02
288****************************************************************************/
289static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
290{
291    int mod, rl, rh;
292    u8 *destreg, *srcreg;
293    uint srcoffset;
294    u8 srcval;
295
296    START_OF_INSTR();
297    DECODE_PRINTF("ADD\t");
298    FETCH_DECODE_MODRM(mod, rh, rl);
299    switch (mod) {
300    case 0:
301        destreg = DECODE_RM_BYTE_REGISTER(rh);
302        DECODE_PRINTF(",");
303        srcoffset = decode_rm00_address(rl);
304        srcval = fetch_data_byte(srcoffset);
305        DECODE_PRINTF("\n");
306        TRACE_AND_STEP();
307        *destreg = add_byte(*destreg, srcval);
308        break;
309    case 1:
310        destreg = DECODE_RM_BYTE_REGISTER(rh);
311        DECODE_PRINTF(",");
312        srcoffset = decode_rm01_address(rl);
313        srcval = fetch_data_byte(srcoffset);
314        DECODE_PRINTF("\n");
315        TRACE_AND_STEP();
316        *destreg = add_byte(*destreg, srcval);
317        break;
318    case 2:
319        destreg = DECODE_RM_BYTE_REGISTER(rh);
320        DECODE_PRINTF(",");
321        srcoffset = decode_rm10_address(rl);
322        srcval = fetch_data_byte(srcoffset);
323        DECODE_PRINTF("\n");
324        TRACE_AND_STEP();
325        *destreg = add_byte(*destreg, srcval);
326        break;
327    case 3:                     /* register to register */
328        destreg = DECODE_RM_BYTE_REGISTER(rh);
329        DECODE_PRINTF(",");
330        srcreg = DECODE_RM_BYTE_REGISTER(rl);
331        DECODE_PRINTF("\n");
332        TRACE_AND_STEP();
333        *destreg = add_byte(*destreg, *srcreg);
334        break;
335    }
336    DECODE_CLEAR_SEGOVR();
337    END_OF_INSTR();
338}
339
340/****************************************************************************
341REMARKS:
342Handles opcode 0x03
343****************************************************************************/
344static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
345{
346    int mod, rl, rh;
347    uint srcoffset;
348
349    START_OF_INSTR();
350    DECODE_PRINTF("ADD\t");
351    FETCH_DECODE_MODRM(mod, rh, rl);
352    switch (mod) {
353    case 0:
354        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
355            u32 *destreg;
356            u32 srcval;
357
358            destreg = DECODE_RM_LONG_REGISTER(rh);
359            DECODE_PRINTF(",");
360            srcoffset = decode_rm00_address(rl);
361            srcval = fetch_data_long(srcoffset);
362            DECODE_PRINTF("\n");
363            TRACE_AND_STEP();
364            *destreg = add_long(*destreg, srcval);
365        } else {
366            u16 *destreg;
367            u16 srcval;
368
369            destreg = DECODE_RM_WORD_REGISTER(rh);
370            DECODE_PRINTF(",");
371            srcoffset = decode_rm00_address(rl);
372            srcval = fetch_data_word(srcoffset);
373            DECODE_PRINTF("\n");
374            TRACE_AND_STEP();
375            *destreg = add_word(*destreg, srcval);
376        }
377        break;
378    case 1:
379        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
380            u32 *destreg;
381            u32 srcval;
382
383            destreg = DECODE_RM_LONG_REGISTER(rh);
384            DECODE_PRINTF(",");
385            srcoffset = decode_rm01_address(rl);
386            srcval = fetch_data_long(srcoffset);
387            DECODE_PRINTF("\n");
388            TRACE_AND_STEP();
389            *destreg = add_long(*destreg, srcval);
390        } else {
391            u16 *destreg;
392            u16 srcval;
393
394            destreg = DECODE_RM_WORD_REGISTER(rh);
395            DECODE_PRINTF(",");
396            srcoffset = decode_rm01_address(rl);
397            srcval = fetch_data_word(srcoffset);
398            DECODE_PRINTF("\n");
399            TRACE_AND_STEP();
400            *destreg = add_word(*destreg, srcval);
401        }
402        break;
403    case 2:
404        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
405            u32 *destreg;
406            u32 srcval;
407
408            destreg = DECODE_RM_LONG_REGISTER(rh);
409            DECODE_PRINTF(",");
410            srcoffset = decode_rm10_address(rl);
411            srcval = fetch_data_long(srcoffset);
412            DECODE_PRINTF("\n");
413            TRACE_AND_STEP();
414            *destreg = add_long(*destreg, srcval);
415        } else {
416            u16 *destreg;
417            u16 srcval;
418
419            destreg = DECODE_RM_WORD_REGISTER(rh);
420            DECODE_PRINTF(",");
421            srcoffset = decode_rm10_address(rl);
422            srcval = fetch_data_word(srcoffset);
423            DECODE_PRINTF("\n");
424            TRACE_AND_STEP();
425            *destreg = add_word(*destreg, srcval);
426        }
427        break;
428    case 3:                     /* register to register */
429        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
430            u32 *destreg,*srcreg;
431
432            destreg = DECODE_RM_LONG_REGISTER(rh);
433            DECODE_PRINTF(",");
434            srcreg = DECODE_RM_LONG_REGISTER(rl);
435            DECODE_PRINTF("\n");
436            TRACE_AND_STEP();
437            *destreg = add_long(*destreg, *srcreg);
438        } else {
439            u16 *destreg,*srcreg;
440
441            destreg = DECODE_RM_WORD_REGISTER(rh);
442            DECODE_PRINTF(",");
443            srcreg = DECODE_RM_WORD_REGISTER(rl);
444            DECODE_PRINTF("\n");
445            TRACE_AND_STEP();
446            *destreg = add_word(*destreg, *srcreg);
447        }
448        break;
449    }
450    DECODE_CLEAR_SEGOVR();
451    END_OF_INSTR();
452}
453
454/****************************************************************************
455REMARKS:
456Handles opcode 0x04
457****************************************************************************/
458static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
459{
460    u8 srcval;
461
462    START_OF_INSTR();
463    DECODE_PRINTF("ADD\tAL,");
464    srcval = fetch_byte_imm();
465    DECODE_PRINTF2("%x\n", srcval);
466    TRACE_AND_STEP();
467    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
468    DECODE_CLEAR_SEGOVR();
469    END_OF_INSTR();
470}
471
472/****************************************************************************
473REMARKS:
474Handles opcode 0x05
475****************************************************************************/
476static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
477{
478    u32 srcval;
479
480    START_OF_INSTR();
481    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
482        DECODE_PRINTF("ADD\tEAX,");
483        srcval = fetch_long_imm();
484    } else {
485        DECODE_PRINTF("ADD\tAX,");
486        srcval = fetch_word_imm();
487    }
488    DECODE_PRINTF2("%x\n", srcval);
489    TRACE_AND_STEP();
490    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
491        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
492    } else {
493        M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
494    }
495    DECODE_CLEAR_SEGOVR();
496    END_OF_INSTR();
497}
498
499/****************************************************************************
500REMARKS:
501Handles opcode 0x06
502****************************************************************************/
503static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
504{
505    START_OF_INSTR();
506    DECODE_PRINTF("PUSH\tES\n");
507    TRACE_AND_STEP();
508    push_word(M.x86.R_ES);
509    DECODE_CLEAR_SEGOVR();
510    END_OF_INSTR();
511}
512
513/****************************************************************************
514REMARKS:
515Handles opcode 0x07
516****************************************************************************/
517static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
518{
519    START_OF_INSTR();
520    DECODE_PRINTF("POP\tES\n");
521    TRACE_AND_STEP();
522    M.x86.R_ES = pop_word();
523    DECODE_CLEAR_SEGOVR();
524    END_OF_INSTR();
525}
526
527/****************************************************************************
528REMARKS:
529Handles opcode 0x08
530****************************************************************************/
531static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
532{
533    int mod, rl, rh;
534    u8 *destreg, *srcreg;
535    uint destoffset;
536    u8 destval;
537
538    START_OF_INSTR();
539    DECODE_PRINTF("OR\t");
540    FETCH_DECODE_MODRM(mod, rh, rl);
541    switch (mod) {
542    case 0:
543        destoffset = decode_rm00_address(rl);
544        DECODE_PRINTF(",");
545        destval = fetch_data_byte(destoffset);
546        srcreg = DECODE_RM_BYTE_REGISTER(rh);
547        DECODE_PRINTF("\n");
548        TRACE_AND_STEP();
549        destval = or_byte(destval, *srcreg);
550        store_data_byte(destoffset, destval);
551        break;
552    case 1:
553        destoffset = decode_rm01_address(rl);
554        DECODE_PRINTF(",");
555        destval = fetch_data_byte(destoffset);
556        srcreg = DECODE_RM_BYTE_REGISTER(rh);
557        DECODE_PRINTF("\n");
558        TRACE_AND_STEP();
559        destval = or_byte(destval, *srcreg);
560        store_data_byte(destoffset, destval);
561        break;
562    case 2:
563        destoffset = decode_rm10_address(rl);
564        DECODE_PRINTF(",");
565        destval = fetch_data_byte(destoffset);
566        srcreg = DECODE_RM_BYTE_REGISTER(rh);
567        DECODE_PRINTF("\n");
568        TRACE_AND_STEP();
569        destval = or_byte(destval, *srcreg);
570        store_data_byte(destoffset, destval);
571        break;
572    case 3:                     /* register to register */
573        destreg = DECODE_RM_BYTE_REGISTER(rl);
574        DECODE_PRINTF(",");
575        srcreg = DECODE_RM_BYTE_REGISTER(rh);
576        DECODE_PRINTF("\n");
577        TRACE_AND_STEP();
578        *destreg = or_byte(*destreg, *srcreg);
579        break;
580    }
581    DECODE_CLEAR_SEGOVR();
582    END_OF_INSTR();
583}
584
585/****************************************************************************
586REMARKS:
587Handles opcode 0x09
588****************************************************************************/
589static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
590{
591    int mod, rl, rh;
592    uint destoffset;
593
594    START_OF_INSTR();
595    DECODE_PRINTF("OR\t");
596    FETCH_DECODE_MODRM(mod, rh, rl);
597    switch (mod) {
598    case 0:
599        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600            u32 destval;
601            u32 *srcreg;
602
603            destoffset = decode_rm00_address(rl);
604            DECODE_PRINTF(",");
605            destval = fetch_data_long(destoffset);
606            srcreg = DECODE_RM_LONG_REGISTER(rh);
607            DECODE_PRINTF("\n");
608            TRACE_AND_STEP();
609            destval = or_long(destval, *srcreg);
610            store_data_long(destoffset, destval);
611        } else {
612            u16 destval;
613            u16 *srcreg;
614
615            destoffset = decode_rm00_address(rl);
616            DECODE_PRINTF(",");
617            destval = fetch_data_word(destoffset);
618            srcreg = DECODE_RM_WORD_REGISTER(rh);
619            DECODE_PRINTF("\n");
620            TRACE_AND_STEP();
621            destval = or_word(destval, *srcreg);
622            store_data_word(destoffset, destval);
623        }
624        break;
625    case 1:
626        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627            u32 destval;
628            u32 *srcreg;
629
630            destoffset = decode_rm01_address(rl);
631            DECODE_PRINTF(",");
632            destval = fetch_data_long(destoffset);
633            srcreg = DECODE_RM_LONG_REGISTER(rh);
634            DECODE_PRINTF("\n");
635            TRACE_AND_STEP();
636            destval = or_long(destval, *srcreg);
637            store_data_long(destoffset, destval);
638        } else {
639            u16 destval;
640            u16 *srcreg;
641
642            destoffset = decode_rm01_address(rl);
643            DECODE_PRINTF(",");
644            destval = fetch_data_word(destoffset);
645            srcreg = DECODE_RM_WORD_REGISTER(rh);
646            DECODE_PRINTF("\n");
647            TRACE_AND_STEP();
648            destval = or_word(destval, *srcreg);
649            store_data_word(destoffset, destval);
650        }
651        break;
652    case 2:
653        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
654            u32 destval;
655            u32 *srcreg;
656
657            destoffset = decode_rm10_address(rl);
658            DECODE_PRINTF(",");
659            destval = fetch_data_long(destoffset);
660            srcreg = DECODE_RM_LONG_REGISTER(rh);
661            DECODE_PRINTF("\n");
662            TRACE_AND_STEP();
663            destval = or_long(destval, *srcreg);
664            store_data_long(destoffset, destval);
665        } else {
666            u16 destval;
667            u16 *srcreg;
668
669            destoffset = decode_rm10_address(rl);
670            DECODE_PRINTF(",");
671            destval = fetch_data_word(destoffset);
672            srcreg = DECODE_RM_WORD_REGISTER(rh);
673            DECODE_PRINTF("\n");
674            TRACE_AND_STEP();
675            destval = or_word(destval, *srcreg);
676            store_data_word(destoffset, destval);
677        }
678        break;
679    case 3:                     /* register to register */
680        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
681            u32 *destreg,*srcreg;
682
683            destreg = DECODE_RM_LONG_REGISTER(rl);
684            DECODE_PRINTF(",");
685            srcreg = DECODE_RM_LONG_REGISTER(rh);
686            DECODE_PRINTF("\n");
687            TRACE_AND_STEP();
688            *destreg = or_long(*destreg, *srcreg);
689        } else {
690            u16 *destreg,*srcreg;
691
692            destreg = DECODE_RM_WORD_REGISTER(rl);
693            DECODE_PRINTF(",");
694            srcreg = DECODE_RM_WORD_REGISTER(rh);
695            DECODE_PRINTF("\n");
696            TRACE_AND_STEP();
697            *destreg = or_word(*destreg, *srcreg);
698        }
699        break;
700    }
701    DECODE_CLEAR_SEGOVR();
702    END_OF_INSTR();
703}
704
705/****************************************************************************
706REMARKS:
707Handles opcode 0x0a
708****************************************************************************/
709static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
710{
711    int mod, rl, rh;
712    u8 *destreg, *srcreg;
713    uint srcoffset;
714    u8 srcval;
715
716    START_OF_INSTR();
717    DECODE_PRINTF("OR\t");
718    FETCH_DECODE_MODRM(mod, rh, rl);
719    switch (mod) {
720    case 0:
721        destreg = DECODE_RM_BYTE_REGISTER(rh);
722        DECODE_PRINTF(",");
723        srcoffset = decode_rm00_address(rl);
724        srcval = fetch_data_byte(srcoffset);
725        DECODE_PRINTF("\n");
726        TRACE_AND_STEP();
727        *destreg = or_byte(*destreg, srcval);
728        break;
729    case 1:
730        destreg = DECODE_RM_BYTE_REGISTER(rh);
731        DECODE_PRINTF(",");
732        srcoffset = decode_rm01_address(rl);
733        srcval = fetch_data_byte(srcoffset);
734        DECODE_PRINTF("\n");
735        TRACE_AND_STEP();
736        *destreg = or_byte(*destreg, srcval);
737        break;
738    case 2:
739        destreg = DECODE_RM_BYTE_REGISTER(rh);
740        DECODE_PRINTF(",");
741        srcoffset = decode_rm10_address(rl);
742        srcval = fetch_data_byte(srcoffset);
743        DECODE_PRINTF("\n");
744        TRACE_AND_STEP();
745        *destreg = or_byte(*destreg, srcval);
746        break;
747    case 3:                     /* register to register */
748        destreg = DECODE_RM_BYTE_REGISTER(rh);
749        DECODE_PRINTF(",");
750        srcreg = DECODE_RM_BYTE_REGISTER(rl);
751        DECODE_PRINTF("\n");
752        TRACE_AND_STEP();
753        *destreg = or_byte(*destreg, *srcreg);
754        break;
755    }
756    DECODE_CLEAR_SEGOVR();
757    END_OF_INSTR();
758}
759
760/****************************************************************************
761REMARKS:
762Handles opcode 0x0b
763****************************************************************************/
764static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
765{
766    int mod, rl, rh;
767    uint srcoffset;
768
769    START_OF_INSTR();
770    DECODE_PRINTF("OR\t");
771    FETCH_DECODE_MODRM(mod, rh, rl);
772    switch (mod) {
773    case 0:
774        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
775            u32 *destreg;
776            u32 srcval;
777
778            destreg = DECODE_RM_LONG_REGISTER(rh);
779            DECODE_PRINTF(",");
780            srcoffset = decode_rm00_address(rl);
781            srcval = fetch_data_long(srcoffset);
782            DECODE_PRINTF("\n");
783            TRACE_AND_STEP();
784            *destreg = or_long(*destreg, srcval);
785        } else {
786            u16 *destreg;
787            u16 srcval;
788
789            destreg = DECODE_RM_WORD_REGISTER(rh);
790            DECODE_PRINTF(",");
791            srcoffset = decode_rm00_address(rl);
792            srcval = fetch_data_word(srcoffset);
793            DECODE_PRINTF("\n");
794            TRACE_AND_STEP();
795            *destreg = or_word(*destreg, srcval);
796        }
797        break;
798    case 1:
799        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
800            u32 *destreg;
801            u32 srcval;
802
803            destreg = DECODE_RM_LONG_REGISTER(rh);
804            DECODE_PRINTF(",");
805            srcoffset = decode_rm01_address(rl);
806            srcval = fetch_data_long(srcoffset);
807            DECODE_PRINTF("\n");
808            TRACE_AND_STEP();
809            *destreg = or_long(*destreg, srcval);
810        } else {
811            u16 *destreg;
812            u16 srcval;
813
814            destreg = DECODE_RM_WORD_REGISTER(rh);
815            DECODE_PRINTF(",");
816            srcoffset = decode_rm01_address(rl);
817            srcval = fetch_data_word(srcoffset);
818            DECODE_PRINTF("\n");
819            TRACE_AND_STEP();
820            *destreg = or_word(*destreg, srcval);
821        }
822        break;
823    case 2:
824        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
825            u32 *destreg;
826            u32 srcval;
827
828            destreg = DECODE_RM_LONG_REGISTER(rh);
829            DECODE_PRINTF(",");
830            srcoffset = decode_rm10_address(rl);
831            srcval = fetch_data_long(srcoffset);
832            DECODE_PRINTF("\n");
833            TRACE_AND_STEP();
834            *destreg = or_long(*destreg, srcval);
835        } else {
836            u16 *destreg;
837            u16 srcval;
838
839            destreg = DECODE_RM_WORD_REGISTER(rh);
840            DECODE_PRINTF(",");
841            srcoffset = decode_rm10_address(rl);
842            srcval = fetch_data_word(srcoffset);
843            DECODE_PRINTF("\n");
844            TRACE_AND_STEP();
845            *destreg = or_word(*destreg, srcval);
846        }
847        break;
848    case 3:                     /* register to register */
849        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
850            u32 *destreg,*srcreg;
851
852            destreg = DECODE_RM_LONG_REGISTER(rh);
853            DECODE_PRINTF(",");
854            srcreg = DECODE_RM_LONG_REGISTER(rl);
855            DECODE_PRINTF("\n");
856            TRACE_AND_STEP();
857            *destreg = or_long(*destreg, *srcreg);
858        } else {
859            u16 *destreg,*srcreg;
860
861            destreg = DECODE_RM_WORD_REGISTER(rh);
862            DECODE_PRINTF(",");
863            srcreg = DECODE_RM_WORD_REGISTER(rl);
864            DECODE_PRINTF("\n");
865            TRACE_AND_STEP();
866            *destreg = or_word(*destreg, *srcreg);
867        }
868        break;
869    }
870    DECODE_CLEAR_SEGOVR();
871    END_OF_INSTR();
872}
873
874/****************************************************************************
875REMARKS:
876Handles opcode 0x0c
877****************************************************************************/
878static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
879{
880    u8 srcval;
881
882    START_OF_INSTR();
883    DECODE_PRINTF("OR\tAL,");
884    srcval = fetch_byte_imm();
885    DECODE_PRINTF2("%x\n", srcval);
886    TRACE_AND_STEP();
887    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
888    DECODE_CLEAR_SEGOVR();
889    END_OF_INSTR();
890}
891
892/****************************************************************************
893REMARKS:
894Handles opcode 0x0d
895****************************************************************************/
896static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
897{
898    u32 srcval;
899
900    START_OF_INSTR();
901    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
902        DECODE_PRINTF("OR\tEAX,");
903        srcval = fetch_long_imm();
904    } else {
905        DECODE_PRINTF("OR\tAX,");
906        srcval = fetch_word_imm();
907    }
908    DECODE_PRINTF2("%x\n", srcval);
909    TRACE_AND_STEP();
910    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
912    } else {
913        M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
914    }
915    DECODE_CLEAR_SEGOVR();
916    END_OF_INSTR();
917}
918
919/****************************************************************************
920REMARKS:
921Handles opcode 0x0e
922****************************************************************************/
923static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
924{
925    START_OF_INSTR();
926    DECODE_PRINTF("PUSH\tCS\n");
927    TRACE_AND_STEP();
928    push_word(M.x86.R_CS);
929    DECODE_CLEAR_SEGOVR();
930    END_OF_INSTR();
931}
932
933/****************************************************************************
934REMARKS:
935Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
936****************************************************************************/
937static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
938{
939    u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
940    INC_DECODED_INST_LEN(1);
941    (*x86emu_optab2[op2])(op2);
942}
943
944/****************************************************************************
945REMARKS:
946Handles opcode 0x10
947****************************************************************************/
948static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
949{
950    int mod, rl, rh;
951    u8 *destreg, *srcreg;
952    uint destoffset;
953    u8 destval;
954
955    START_OF_INSTR();
956    DECODE_PRINTF("ADC\t");
957    FETCH_DECODE_MODRM(mod, rh, rl);
958    switch (mod) {
959    case 0:
960        destoffset = decode_rm00_address(rl);
961        DECODE_PRINTF(",");
962        destval = fetch_data_byte(destoffset);
963        srcreg = DECODE_RM_BYTE_REGISTER(rh);
964        DECODE_PRINTF("\n");
965        TRACE_AND_STEP();
966        destval = adc_byte(destval, *srcreg);
967        store_data_byte(destoffset, destval);
968        break;
969    case 1:
970        destoffset = decode_rm01_address(rl);
971        DECODE_PRINTF(",");
972        destval = fetch_data_byte(destoffset);
973        srcreg = DECODE_RM_BYTE_REGISTER(rh);
974        DECODE_PRINTF("\n");
975        TRACE_AND_STEP();
976        destval = adc_byte(destval, *srcreg);
977        store_data_byte(destoffset, destval);
978        break;
979    case 2:
980        destoffset = decode_rm10_address(rl);
981        DECODE_PRINTF(",");
982        destval = fetch_data_byte(destoffset);
983        srcreg = DECODE_RM_BYTE_REGISTER(rh);
984        DECODE_PRINTF("\n");
985        TRACE_AND_STEP();
986        destval = adc_byte(destval, *srcreg);
987        store_data_byte(destoffset, destval);
988        break;
989    case 3:                     /* register to register */
990        destreg = DECODE_RM_BYTE_REGISTER(rl);
991        DECODE_PRINTF(",");
992        srcreg = DECODE_RM_BYTE_REGISTER(rh);
993        DECODE_PRINTF("\n");
994        TRACE_AND_STEP();
995        *destreg = adc_byte(*destreg, *srcreg);
996        break;
997    }
998    DECODE_CLEAR_SEGOVR();
999    END_OF_INSTR();
1000}
1001
1002/****************************************************************************
1003REMARKS:
1004Handles opcode 0x11
1005****************************************************************************/
1006static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1007{
1008    int mod, rl, rh;
1009    uint destoffset;
1010
1011    START_OF_INSTR();
1012    DECODE_PRINTF("ADC\t");
1013    FETCH_DECODE_MODRM(mod, rh, rl);
1014    switch (mod) {
1015    case 0:
1016        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1017            u32 destval;
1018            u32 *srcreg;
1019
1020            destoffset = decode_rm00_address(rl);
1021            DECODE_PRINTF(",");
1022            destval = fetch_data_long(destoffset);
1023            srcreg = DECODE_RM_LONG_REGISTER(rh);
1024            DECODE_PRINTF("\n");
1025            TRACE_AND_STEP();
1026            destval = adc_long(destval, *srcreg);
1027            store_data_long(destoffset, destval);
1028        } else {
1029            u16 destval;
1030            u16 *srcreg;
1031
1032            destoffset = decode_rm00_address(rl);
1033            DECODE_PRINTF(",");
1034            destval = fetch_data_word(destoffset);
1035            srcreg = DECODE_RM_WORD_REGISTER(rh);
1036            DECODE_PRINTF("\n");
1037            TRACE_AND_STEP();
1038            destval = adc_word(destval, *srcreg);
1039            store_data_word(destoffset, destval);
1040        }
1041        break;
1042    case 1:
1043        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1044            u32 destval;
1045            u32 *srcreg;
1046
1047            destoffset = decode_rm01_address(rl);
1048            DECODE_PRINTF(",");
1049            destval = fetch_data_long(destoffset);
1050            srcreg = DECODE_RM_LONG_REGISTER(rh);
1051            DECODE_PRINTF("\n");
1052            TRACE_AND_STEP();
1053            destval = adc_long(destval, *srcreg);
1054            store_data_long(destoffset, destval);
1055        } else {
1056            u16 destval;
1057            u16 *srcreg;
1058
1059            destoffset = decode_rm01_address(rl);
1060            DECODE_PRINTF(",");
1061            destval = fetch_data_word(destoffset);
1062            srcreg = DECODE_RM_WORD_REGISTER(rh);
1063            DECODE_PRINTF("\n");
1064            TRACE_AND_STEP();
1065            destval = adc_word(destval, *srcreg);
1066            store_data_word(destoffset, destval);
1067        }
1068        break;
1069    case 2:
1070        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1071            u32 destval;
1072            u32 *srcreg;
1073
1074            destoffset = decode_rm10_address(rl);
1075            DECODE_PRINTF(",");
1076            destval = fetch_data_long(destoffset);
1077            srcreg = DECODE_RM_LONG_REGISTER(rh);
1078            DECODE_PRINTF("\n");
1079            TRACE_AND_STEP();
1080            destval = adc_long(destval, *srcreg);
1081            store_data_long(destoffset, destval);
1082        } else {
1083            u16 destval;
1084            u16 *srcreg;
1085
1086            destoffset = decode_rm10_address(rl);
1087            DECODE_PRINTF(",");
1088            destval = fetch_data_word(destoffset);
1089            srcreg = DECODE_RM_WORD_REGISTER(rh);
1090            DECODE_PRINTF("\n");
1091            TRACE_AND_STEP();
1092            destval = adc_word(destval, *srcreg);
1093            store_data_word(destoffset, destval);
1094        }
1095        break;
1096    case 3:                     /* register to register */
1097        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1098            u32 *destreg,*srcreg;
1099
1100            destreg = DECODE_RM_LONG_REGISTER(rl);
1101            DECODE_PRINTF(",");
1102            srcreg = DECODE_RM_LONG_REGISTER(rh);
1103            DECODE_PRINTF("\n");
1104            TRACE_AND_STEP();
1105            *destreg = adc_long(*destreg, *srcreg);
1106        } else {
1107            u16 *destreg,*srcreg;
1108
1109            destreg = DECODE_RM_WORD_REGISTER(rl);
1110            DECODE_PRINTF(",");
1111            srcreg = DECODE_RM_WORD_REGISTER(rh);
1112            DECODE_PRINTF("\n");
1113            TRACE_AND_STEP();
1114            *destreg = adc_word(*destreg, *srcreg);
1115        }
1116        break;
1117    }
1118    DECODE_CLEAR_SEGOVR();
1119    END_OF_INSTR();
1120}
1121
1122/****************************************************************************
1123REMARKS:
1124Handles opcode 0x12
1125****************************************************************************/
1126static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1127{
1128    int mod, rl, rh;
1129    u8 *destreg, *srcreg;
1130    uint srcoffset;
1131    u8 srcval;
1132
1133    START_OF_INSTR();
1134    DECODE_PRINTF("ADC\t");
1135    FETCH_DECODE_MODRM(mod, rh, rl);
1136    switch (mod) {
1137    case 0:
1138        destreg = DECODE_RM_BYTE_REGISTER(rh);
1139        DECODE_PRINTF(",");
1140        srcoffset = decode_rm00_address(rl);
1141        srcval = fetch_data_byte(srcoffset);
1142        DECODE_PRINTF("\n");
1143        TRACE_AND_STEP();
1144        *destreg = adc_byte(*destreg, srcval);
1145        break;
1146    case 1:
1147        destreg = DECODE_RM_BYTE_REGISTER(rh);
1148        DECODE_PRINTF(",");
1149        srcoffset = decode_rm01_address(rl);
1150        srcval = fetch_data_byte(srcoffset);
1151        DECODE_PRINTF("\n");
1152        TRACE_AND_STEP();
1153        *destreg = adc_byte(*destreg, srcval);
1154        break;
1155    case 2:
1156        destreg = DECODE_RM_BYTE_REGISTER(rh);
1157        DECODE_PRINTF(",");
1158        srcoffset = decode_rm10_address(rl);
1159        srcval = fetch_data_byte(srcoffset);
1160        DECODE_PRINTF("\n");
1161        TRACE_AND_STEP();
1162        *destreg = adc_byte(*destreg, srcval);
1163        break;
1164    case 3:                     /* register to register */
1165        destreg = DECODE_RM_BYTE_REGISTER(rh);
1166        DECODE_PRINTF(",");
1167        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1168        DECODE_PRINTF("\n");
1169        TRACE_AND_STEP();
1170        *destreg = adc_byte(*destreg, *srcreg);
1171        break;
1172    }
1173    DECODE_CLEAR_SEGOVR();
1174    END_OF_INSTR();
1175}
1176
1177/****************************************************************************
1178REMARKS:
1179Handles opcode 0x13
1180****************************************************************************/
1181static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1182{
1183    int mod, rl, rh;
1184    uint srcoffset;
1185
1186    START_OF_INSTR();
1187    DECODE_PRINTF("ADC\t");
1188    FETCH_DECODE_MODRM(mod, rh, rl);
1189    switch (mod) {
1190    case 0:
1191        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1192            u32 *destreg;
1193            u32 srcval;
1194
1195            destreg = DECODE_RM_LONG_REGISTER(rh);
1196            DECODE_PRINTF(",");
1197            srcoffset = decode_rm00_address(rl);
1198            srcval = fetch_data_long(srcoffset);
1199            DECODE_PRINTF("\n");
1200            TRACE_AND_STEP();
1201            *destreg = adc_long(*destreg, srcval);
1202        } else {
1203            u16 *destreg;
1204            u16 srcval;
1205
1206            destreg = DECODE_RM_WORD_REGISTER(rh);
1207            DECODE_PRINTF(",");
1208            srcoffset = decode_rm00_address(rl);
1209            srcval = fetch_data_word(srcoffset);
1210            DECODE_PRINTF("\n");
1211            TRACE_AND_STEP();
1212            *destreg = adc_word(*destreg, srcval);
1213        }
1214        break;
1215    case 1:
1216        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217            u32 *destreg;
1218            u32 srcval;
1219
1220            destreg = DECODE_RM_LONG_REGISTER(rh);
1221            DECODE_PRINTF(",");
1222            srcoffset = decode_rm01_address(rl);
1223            srcval = fetch_data_long(srcoffset);
1224            DECODE_PRINTF("\n");
1225            TRACE_AND_STEP();
1226            *destreg = adc_long(*destreg, srcval);
1227        } else {
1228            u16 *destreg;
1229            u16 srcval;
1230
1231            destreg = DECODE_RM_WORD_REGISTER(rh);
1232            DECODE_PRINTF(",");
1233            srcoffset = decode_rm01_address(rl);
1234            srcval = fetch_data_word(srcoffset);
1235            DECODE_PRINTF("\n");
1236            TRACE_AND_STEP();
1237            *destreg = adc_word(*destreg, srcval);
1238        }
1239        break;
1240    case 2:
1241        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1242            u32 *destreg;
1243            u32 srcval;
1244
1245            destreg = DECODE_RM_LONG_REGISTER(rh);
1246            DECODE_PRINTF(",");
1247            srcoffset = decode_rm10_address(rl);
1248            srcval = fetch_data_long(srcoffset);
1249            DECODE_PRINTF("\n");
1250            TRACE_AND_STEP();
1251            *destreg = adc_long(*destreg, srcval);
1252        } else {
1253            u16 *destreg;
1254            u16 srcval;
1255
1256            destreg = DECODE_RM_WORD_REGISTER(rh);
1257            DECODE_PRINTF(",");
1258            srcoffset = decode_rm10_address(rl);
1259            srcval = fetch_data_word(srcoffset);
1260            DECODE_PRINTF("\n");
1261            TRACE_AND_STEP();
1262            *destreg = adc_word(*destreg, srcval);
1263        }
1264        break;
1265    case 3:                     /* register to register */
1266        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1267            u32 *destreg,*srcreg;
1268
1269            destreg = DECODE_RM_LONG_REGISTER(rh);
1270            DECODE_PRINTF(",");
1271            srcreg = DECODE_RM_LONG_REGISTER(rl);
1272            DECODE_PRINTF("\n");
1273            TRACE_AND_STEP();
1274            *destreg = adc_long(*destreg, *srcreg);
1275        } else {
1276            u16 *destreg,*srcreg;
1277
1278            destreg = DECODE_RM_WORD_REGISTER(rh);
1279            DECODE_PRINTF(",");
1280            srcreg = DECODE_RM_WORD_REGISTER(rl);
1281            DECODE_PRINTF("\n");
1282            TRACE_AND_STEP();
1283            *destreg = adc_word(*destreg, *srcreg);
1284        }
1285        break;
1286    }
1287    DECODE_CLEAR_SEGOVR();
1288    END_OF_INSTR();
1289}
1290
1291/****************************************************************************
1292REMARKS:
1293Handles opcode 0x14
1294****************************************************************************/
1295static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1296{
1297    u8 srcval;
1298
1299    START_OF_INSTR();
1300    DECODE_PRINTF("ADC\tAL,");
1301    srcval = fetch_byte_imm();
1302    DECODE_PRINTF2("%x\n", srcval);
1303    TRACE_AND_STEP();
1304    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1305    DECODE_CLEAR_SEGOVR();
1306    END_OF_INSTR();
1307}
1308
1309/****************************************************************************
1310REMARKS:
1311Handles opcode 0x15
1312****************************************************************************/
1313static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1314{
1315    u32 srcval;
1316
1317    START_OF_INSTR();
1318    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1319        DECODE_PRINTF("ADC\tEAX,");
1320        srcval = fetch_long_imm();
1321    } else {
1322        DECODE_PRINTF("ADC\tAX,");
1323        srcval = fetch_word_imm();
1324    }
1325    DECODE_PRINTF2("%x\n", srcval);
1326    TRACE_AND_STEP();
1327    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1328        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1329    } else {
1330        M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1331    }
1332    DECODE_CLEAR_SEGOVR();
1333    END_OF_INSTR();
1334}
1335
1336/****************************************************************************
1337REMARKS:
1338Handles opcode 0x16
1339****************************************************************************/
1340static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1341{
1342    START_OF_INSTR();
1343    DECODE_PRINTF("PUSH\tSS\n");
1344    TRACE_AND_STEP();
1345    push_word(M.x86.R_SS);
1346    DECODE_CLEAR_SEGOVR();
1347    END_OF_INSTR();
1348}
1349
1350/****************************************************************************
1351REMARKS:
1352Handles opcode 0x17
1353****************************************************************************/
1354static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1355{
1356    START_OF_INSTR();
1357    DECODE_PRINTF("POP\tSS\n");
1358    TRACE_AND_STEP();
1359    M.x86.R_SS = pop_word();
1360    DECODE_CLEAR_SEGOVR();
1361    END_OF_INSTR();
1362}
1363
1364/****************************************************************************
1365REMARKS:
1366Handles opcode 0x18
1367****************************************************************************/
1368static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1369{
1370    int mod, rl, rh;
1371    u8 *destreg, *srcreg;
1372    uint destoffset;
1373    u8 destval;
1374
1375    START_OF_INSTR();
1376    DECODE_PRINTF("SBB\t");
1377    FETCH_DECODE_MODRM(mod, rh, rl);
1378    switch (mod) {
1379    case 0:
1380        destoffset = decode_rm00_address(rl);
1381        DECODE_PRINTF(",");
1382        destval = fetch_data_byte(destoffset);
1383        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1384        DECODE_PRINTF("\n");
1385        TRACE_AND_STEP();
1386        destval = sbb_byte(destval, *srcreg);
1387        store_data_byte(destoffset, destval);
1388        break;
1389    case 1:
1390        destoffset = decode_rm01_address(rl);
1391        DECODE_PRINTF(",");
1392        destval = fetch_data_byte(destoffset);
1393        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1394        DECODE_PRINTF("\n");
1395        TRACE_AND_STEP();
1396        destval = sbb_byte(destval, *srcreg);
1397        store_data_byte(destoffset, destval);
1398        break;
1399    case 2:
1400        destoffset = decode_rm10_address(rl);
1401        DECODE_PRINTF(",");
1402        destval = fetch_data_byte(destoffset);
1403        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1404        DECODE_PRINTF("\n");
1405        TRACE_AND_STEP();
1406        destval = sbb_byte(destval, *srcreg);
1407        store_data_byte(destoffset, destval);
1408        break;
1409    case 3:                     /* register to register */
1410        destreg = DECODE_RM_BYTE_REGISTER(rl);
1411        DECODE_PRINTF(",");
1412        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1413        DECODE_PRINTF("\n");
1414        TRACE_AND_STEP();
1415        *destreg = sbb_byte(*destreg, *srcreg);
1416        break;
1417    }
1418    DECODE_CLEAR_SEGOVR();
1419    END_OF_INSTR();
1420}
1421
1422/****************************************************************************
1423REMARKS:
1424Handles opcode 0x19
1425****************************************************************************/
1426static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1427{
1428    int mod, rl, rh;
1429    uint destoffset;
1430
1431    START_OF_INSTR();
1432    DECODE_PRINTF("SBB\t");
1433    FETCH_DECODE_MODRM(mod, rh, rl);
1434    switch (mod) {
1435    case 0:
1436        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1437            u32 destval;
1438            u32 *srcreg;
1439
1440            destoffset = decode_rm00_address(rl);
1441            DECODE_PRINTF(",");
1442            destval = fetch_data_long(destoffset);
1443            srcreg = DECODE_RM_LONG_REGISTER(rh);
1444            DECODE_PRINTF("\n");
1445            TRACE_AND_STEP();
1446            destval = sbb_long(destval, *srcreg);
1447            store_data_long(destoffset, destval);
1448        } else {
1449            u16 destval;
1450            u16 *srcreg;
1451
1452            destoffset = decode_rm00_address(rl);
1453            DECODE_PRINTF(",");
1454            destval = fetch_data_word(destoffset);
1455            srcreg = DECODE_RM_WORD_REGISTER(rh);
1456            DECODE_PRINTF("\n");
1457            TRACE_AND_STEP();
1458            destval = sbb_word(destval, *srcreg);
1459            store_data_word(destoffset, destval);
1460        }
1461        break;
1462    case 1:
1463        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1464            u32 destval;
1465            u32 *srcreg;
1466
1467            destoffset = decode_rm01_address(rl);
1468            DECODE_PRINTF(",");
1469            destval = fetch_data_long(destoffset);
1470            srcreg = DECODE_RM_LONG_REGISTER(rh);
1471            DECODE_PRINTF("\n");
1472            TRACE_AND_STEP();
1473            destval = sbb_long(destval, *srcreg);
1474            store_data_long(destoffset, destval);
1475        } else {
1476            u16 destval;
1477            u16 *srcreg;
1478
1479            destoffset = decode_rm01_address(rl);
1480            DECODE_PRINTF(",");
1481            destval = fetch_data_word(destoffset);
1482            srcreg = DECODE_RM_WORD_REGISTER(rh);
1483            DECODE_PRINTF("\n");
1484            TRACE_AND_STEP();
1485            destval = sbb_word(destval, *srcreg);
1486            store_data_word(destoffset, destval);
1487        }
1488        break;
1489    case 2:
1490        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1491            u32 destval;
1492            u32 *srcreg;
1493
1494            destoffset = decode_rm10_address(rl);
1495            DECODE_PRINTF(",");
1496            destval = fetch_data_long(destoffset);
1497            srcreg = DECODE_RM_LONG_REGISTER(rh);
1498            DECODE_PRINTF("\n");
1499            TRACE_AND_STEP();
1500            destval = sbb_long(destval, *srcreg);
1501            store_data_long(destoffset, destval);
1502        } else {
1503            u16 destval;
1504            u16 *srcreg;
1505
1506            destoffset = decode_rm10_address(rl);
1507            DECODE_PRINTF(",");
1508            destval = fetch_data_word(destoffset);
1509            srcreg = DECODE_RM_WORD_REGISTER(rh);
1510            DECODE_PRINTF("\n");
1511            TRACE_AND_STEP();
1512            destval = sbb_word(destval, *srcreg);
1513            store_data_word(destoffset, destval);
1514        }
1515        break;
1516    case 3:                     /* register to register */
1517        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1518            u32 *destreg,*srcreg;
1519
1520            destreg = DECODE_RM_LONG_REGISTER(rl);
1521            DECODE_PRINTF(",");
1522            srcreg = DECODE_RM_LONG_REGISTER(rh);
1523            DECODE_PRINTF("\n");
1524            TRACE_AND_STEP();
1525            *destreg = sbb_long(*destreg, *srcreg);
1526        } else {
1527            u16 *destreg,*srcreg;
1528
1529            destreg = DECODE_RM_WORD_REGISTER(rl);
1530            DECODE_PRINTF(",");
1531            srcreg = DECODE_RM_WORD_REGISTER(rh);
1532            DECODE_PRINTF("\n");
1533            TRACE_AND_STEP();
1534            *destreg = sbb_word(*destreg, *srcreg);
1535        }
1536        break;
1537    }
1538    DECODE_CLEAR_SEGOVR();
1539    END_OF_INSTR();
1540}
1541
1542/****************************************************************************
1543REMARKS:
1544Handles opcode 0x1a
1545****************************************************************************/
1546static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1547{
1548    int mod, rl, rh;
1549    u8 *destreg, *srcreg;
1550    uint srcoffset;
1551    u8 srcval;
1552
1553    START_OF_INSTR();
1554    DECODE_PRINTF("SBB\t");
1555    FETCH_DECODE_MODRM(mod, rh, rl);
1556    switch (mod) {
1557    case 0:
1558        destreg = DECODE_RM_BYTE_REGISTER(rh);
1559        DECODE_PRINTF(",");
1560        srcoffset = decode_rm00_address(rl);
1561        srcval = fetch_data_byte(srcoffset);
1562        DECODE_PRINTF("\n");
1563        TRACE_AND_STEP();
1564        *destreg = sbb_byte(*destreg, srcval);
1565        break;
1566    case 1:
1567        destreg = DECODE_RM_BYTE_REGISTER(rh);
1568        DECODE_PRINTF(",");
1569        srcoffset = decode_rm01_address(rl);
1570        srcval = fetch_data_byte(srcoffset);
1571        DECODE_PRINTF("\n");
1572        TRACE_AND_STEP();
1573        *destreg = sbb_byte(*destreg, srcval);
1574        break;
1575    case 2:
1576        destreg = DECODE_RM_BYTE_REGISTER(rh);
1577        DECODE_PRINTF(",");
1578        srcoffset = decode_rm10_address(rl);
1579        srcval = fetch_data_byte(srcoffset);
1580        DECODE_PRINTF("\n");
1581        TRACE_AND_STEP();
1582        *destreg = sbb_byte(*destreg, srcval);
1583        break;
1584    case 3:                     /* register to register */
1585        destreg = DECODE_RM_BYTE_REGISTER(rh);
1586        DECODE_PRINTF(",");
1587        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1588        DECODE_PRINTF("\n");
1589        TRACE_AND_STEP();
1590        *destreg = sbb_byte(*destreg, *srcreg);
1591        break;
1592    }
1593    DECODE_CLEAR_SEGOVR();
1594    END_OF_INSTR();
1595}
1596
1597/****************************************************************************
1598REMARKS:
1599Handles opcode 0x1b
1600****************************************************************************/
1601static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1602{
1603    int mod, rl, rh;
1604    uint srcoffset;
1605
1606    START_OF_INSTR();
1607    DECODE_PRINTF("SBB\t");
1608    FETCH_DECODE_MODRM(mod, rh, rl);
1609    switch (mod) {
1610    case 0:
1611        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1612            u32 *destreg;
1613            u32 srcval;
1614
1615            destreg = DECODE_RM_LONG_REGISTER(rh);
1616            DECODE_PRINTF(",");
1617            srcoffset = decode_rm00_address(rl);
1618            srcval = fetch_data_long(srcoffset);
1619            DECODE_PRINTF("\n");
1620            TRACE_AND_STEP();
1621            *destreg = sbb_long(*destreg, srcval);
1622        } else {
1623            u16 *destreg;
1624            u16 srcval;
1625
1626            destreg = DECODE_RM_WORD_REGISTER(rh);
1627            DECODE_PRINTF(",");
1628            srcoffset = decode_rm00_address(rl);
1629            srcval = fetch_data_word(srcoffset);
1630            DECODE_PRINTF("\n");
1631            TRACE_AND_STEP();
1632            *destreg = sbb_word(*destreg, srcval);
1633        }
1634        break;
1635    case 1:
1636        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1637            u32 *destreg;
1638            u32 srcval;
1639
1640            destreg = DECODE_RM_LONG_REGISTER(rh);
1641            DECODE_PRINTF(",");
1642            srcoffset = decode_rm01_address(rl);
1643            srcval = fetch_data_long(srcoffset);
1644            DECODE_PRINTF("\n");
1645            TRACE_AND_STEP();
1646            *destreg = sbb_long(*destreg, srcval);
1647        } else {
1648            u16 *destreg;
1649            u16 srcval;
1650
1651            destreg = DECODE_RM_WORD_REGISTER(rh);
1652            DECODE_PRINTF(",");
1653            srcoffset = decode_rm01_address(rl);
1654            srcval = fetch_data_word(srcoffset);
1655            DECODE_PRINTF("\n");
1656            TRACE_AND_STEP();
1657            *destreg = sbb_word(*destreg, srcval);
1658        }
1659        break;
1660    case 2:
1661        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1662            u32 *destreg;
1663            u32 srcval;
1664
1665            destreg = DECODE_RM_LONG_REGISTER(rh);
1666            DECODE_PRINTF(",");
1667            srcoffset = decode_rm10_address(rl);
1668            srcval = fetch_data_long(srcoffset);
1669            DECODE_PRINTF("\n");
1670            TRACE_AND_STEP();
1671            *destreg = sbb_long(*destreg, srcval);
1672        } else {
1673            u16 *destreg;
1674            u16 srcval;
1675
1676            destreg = DECODE_RM_WORD_REGISTER(rh);
1677            DECODE_PRINTF(",");
1678            srcoffset = decode_rm10_address(rl);
1679            srcval = fetch_data_word(srcoffset);
1680            DECODE_PRINTF("\n");
1681            TRACE_AND_STEP();
1682            *destreg = sbb_word(*destreg, srcval);
1683        }
1684        break;
1685    case 3:                     /* register to register */
1686        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1687            u32 *destreg,*srcreg;
1688
1689            destreg = DECODE_RM_LONG_REGISTER(rh);
1690            DECODE_PRINTF(",");
1691            srcreg = DECODE_RM_LONG_REGISTER(rl);
1692            DECODE_PRINTF("\n");
1693            TRACE_AND_STEP();
1694            *destreg = sbb_long(*destreg, *srcreg);
1695        } else {
1696            u16 *destreg,*srcreg;
1697
1698            destreg = DECODE_RM_WORD_REGISTER(rh);
1699            DECODE_PRINTF(",");
1700            srcreg = DECODE_RM_WORD_REGISTER(rl);
1701            DECODE_PRINTF("\n");
1702            TRACE_AND_STEP();
1703            *destreg = sbb_word(*destreg, *srcreg);
1704        }
1705        break;
1706    }
1707    DECODE_CLEAR_SEGOVR();
1708    END_OF_INSTR();
1709}
1710
1711/****************************************************************************
1712REMARKS:
1713Handles opcode 0x1c
1714****************************************************************************/
1715static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1716{
1717    u8 srcval;
1718
1719    START_OF_INSTR();
1720    DECODE_PRINTF("SBB\tAL,");
1721    srcval = fetch_byte_imm();
1722    DECODE_PRINTF2("%x\n", srcval);
1723    TRACE_AND_STEP();
1724    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1725    DECODE_CLEAR_SEGOVR();
1726    END_OF_INSTR();
1727}
1728
1729/****************************************************************************
1730REMARKS:
1731Handles opcode 0x1d
1732****************************************************************************/
1733static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1734{
1735    u32 srcval;
1736
1737    START_OF_INSTR();
1738    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1739        DECODE_PRINTF("SBB\tEAX,");
1740        srcval = fetch_long_imm();
1741    } else {
1742        DECODE_PRINTF("SBB\tAX,");
1743        srcval = fetch_word_imm();
1744    }
1745    DECODE_PRINTF2("%x\n", srcval);
1746    TRACE_AND_STEP();
1747    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1748        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1749    } else {
1750        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1751    }
1752    DECODE_CLEAR_SEGOVR();
1753    END_OF_INSTR();
1754}
1755
1756/****************************************************************************
1757REMARKS:
1758Handles opcode 0x1e
1759****************************************************************************/
1760static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1761{
1762    START_OF_INSTR();
1763    DECODE_PRINTF("PUSH\tDS\n");
1764    TRACE_AND_STEP();
1765    push_word(M.x86.R_DS);
1766    DECODE_CLEAR_SEGOVR();
1767    END_OF_INSTR();
1768}
1769
1770/****************************************************************************
1771REMARKS:
1772Handles opcode 0x1f
1773****************************************************************************/
1774static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1775{
1776    START_OF_INSTR();
1777    DECODE_PRINTF("POP\tDS\n");
1778    TRACE_AND_STEP();
1779    M.x86.R_DS = pop_word();
1780    DECODE_CLEAR_SEGOVR();
1781    END_OF_INSTR();
1782}
1783
1784/****************************************************************************
1785REMARKS:
1786Handles opcode 0x20
1787****************************************************************************/
1788static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1789{
1790    int mod, rl, rh;
1791    u8 *destreg, *srcreg;
1792    uint destoffset;
1793    u8 destval;
1794
1795    START_OF_INSTR();
1796    DECODE_PRINTF("AND\t");
1797    FETCH_DECODE_MODRM(mod, rh, rl);
1798
1799    switch (mod) {
1800    case 0:
1801        destoffset = decode_rm00_address(rl);
1802        DECODE_PRINTF(",");
1803        destval = fetch_data_byte(destoffset);
1804        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1805        DECODE_PRINTF("\n");
1806        TRACE_AND_STEP();
1807        destval = and_byte(destval, *srcreg);
1808        store_data_byte(destoffset, destval);
1809        break;
1810
1811    case 1:
1812        destoffset = decode_rm01_address(rl);
1813        DECODE_PRINTF(",");
1814        destval = fetch_data_byte(destoffset);
1815        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1816        DECODE_PRINTF("\n");
1817        TRACE_AND_STEP();
1818        destval = and_byte(destval, *srcreg);
1819        store_data_byte(destoffset, destval);
1820        break;
1821
1822    case 2:
1823        destoffset = decode_rm10_address(rl);
1824        DECODE_PRINTF(",");
1825        destval = fetch_data_byte(destoffset);
1826        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1827        DECODE_PRINTF("\n");
1828        TRACE_AND_STEP();
1829        destval = and_byte(destval, *srcreg);
1830        store_data_byte(destoffset, destval);
1831        break;
1832
1833    case 3:                     /* register to register */
1834        destreg = DECODE_RM_BYTE_REGISTER(rl);
1835        DECODE_PRINTF(",");
1836        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1837        DECODE_PRINTF("\n");
1838        TRACE_AND_STEP();
1839        *destreg = and_byte(*destreg, *srcreg);
1840        break;
1841    }
1842    DECODE_CLEAR_SEGOVR();
1843    END_OF_INSTR();
1844}
1845
1846/****************************************************************************
1847REMARKS:
1848Handles opcode 0x21
1849****************************************************************************/
1850static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1851{
1852    int mod, rl, rh;
1853    uint destoffset;
1854
1855    START_OF_INSTR();
1856    DECODE_PRINTF("AND\t");
1857    FETCH_DECODE_MODRM(mod, rh, rl);
1858    switch (mod) {
1859    case 0:
1860        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1861            u32 destval;
1862            u32 *srcreg;
1863
1864            destoffset = decode_rm00_address(rl);
1865            DECODE_PRINTF(",");
1866            destval = fetch_data_long(destoffset);
1867            srcreg = DECODE_RM_LONG_REGISTER(rh);
1868            DECODE_PRINTF("\n");
1869            TRACE_AND_STEP();
1870            destval = and_long(destval, *srcreg);
1871            store_data_long(destoffset, destval);
1872        } else {
1873            u16 destval;
1874            u16 *srcreg;
1875
1876            destoffset = decode_rm00_address(rl);
1877            DECODE_PRINTF(",");
1878            destval = fetch_data_word(destoffset);
1879            srcreg = DECODE_RM_WORD_REGISTER(rh);
1880            DECODE_PRINTF("\n");
1881            TRACE_AND_STEP();
1882            destval = and_word(destval, *srcreg);
1883            store_data_word(destoffset, destval);
1884        }
1885        break;
1886    case 1:
1887        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1888            u32 destval;
1889            u32 *srcreg;
1890
1891            destoffset = decode_rm01_address(rl);
1892            DECODE_PRINTF(",");
1893            destval = fetch_data_long(destoffset);
1894            srcreg = DECODE_RM_LONG_REGISTER(rh);
1895            DECODE_PRINTF("\n");
1896            TRACE_AND_STEP();
1897            destval = and_long(destval, *srcreg);
1898            store_data_long(destoffset, destval);
1899        } else {
1900            u16 destval;
1901            u16 *srcreg;
1902
1903            destoffset = decode_rm01_address(rl);
1904            DECODE_PRINTF(",");
1905            destval = fetch_data_word(destoffset);
1906            srcreg = DECODE_RM_WORD_REGISTER(rh);
1907            DECODE_PRINTF("\n");
1908            TRACE_AND_STEP();
1909            destval = and_word(destval, *srcreg);
1910            store_data_word(destoffset, destval);
1911        }
1912        break;
1913    case 2:
1914        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1915            u32 destval;
1916            u32 *srcreg;
1917
1918            destoffset = decode_rm10_address(rl);
1919            DECODE_PRINTF(",");
1920            destval = fetch_data_long(destoffset);
1921            srcreg = DECODE_RM_LONG_REGISTER(rh);
1922            DECODE_PRINTF("\n");
1923            TRACE_AND_STEP();
1924            destval = and_long(destval, *srcreg);
1925            store_data_long(destoffset, destval);
1926        } else {
1927            u16 destval;
1928            u16 *srcreg;
1929
1930            destoffset = decode_rm10_address(rl);
1931            DECODE_PRINTF(",");
1932            destval = fetch_data_word(destoffset);
1933            srcreg = DECODE_RM_WORD_REGISTER(rh);
1934            DECODE_PRINTF("\n");
1935            TRACE_AND_STEP();
1936            destval = and_word(destval, *srcreg);
1937            store_data_word(destoffset, destval);
1938        }
1939        break;
1940    case 3:                     /* register to register */
1941        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1942            u32 *destreg,*srcreg;
1943
1944            destreg = DECODE_RM_LONG_REGISTER(rl);
1945            DECODE_PRINTF(",");
1946            srcreg = DECODE_RM_LONG_REGISTER(rh);
1947            DECODE_PRINTF("\n");
1948            TRACE_AND_STEP();
1949            *destreg = and_long(*destreg, *srcreg);
1950        } else {
1951            u16 *destreg,*srcreg;
1952
1953            destreg = DECODE_RM_WORD_REGISTER(rl);
1954            DECODE_PRINTF(",");
1955            srcreg = DECODE_RM_WORD_REGISTER(rh);
1956            DECODE_PRINTF("\n");
1957            TRACE_AND_STEP();
1958            *destreg = and_word(*destreg, *srcreg);
1959        }
1960        break;
1961    }
1962    DECODE_CLEAR_SEGOVR();
1963    END_OF_INSTR();
1964}
1965
1966/****************************************************************************
1967REMARKS:
1968Handles opcode 0x22
1969****************************************************************************/
1970static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1971{
1972    int mod, rl, rh;
1973    u8 *destreg, *srcreg;
1974    uint srcoffset;
1975    u8 srcval;
1976
1977    START_OF_INSTR();
1978    DECODE_PRINTF("AND\t");
1979    FETCH_DECODE_MODRM(mod, rh, rl);
1980    switch (mod) {
1981    case 0:
1982        destreg = DECODE_RM_BYTE_REGISTER(rh);
1983        DECODE_PRINTF(",");
1984        srcoffset = decode_rm00_address(rl);
1985        srcval = fetch_data_byte(srcoffset);
1986        DECODE_PRINTF("\n");
1987        TRACE_AND_STEP();
1988        *destreg = and_byte(*destreg, srcval);
1989        break;
1990    case 1:
1991        destreg = DECODE_RM_BYTE_REGISTER(rh);
1992        DECODE_PRINTF(",");
1993        srcoffset = decode_rm01_address(rl);
1994        srcval = fetch_data_byte(srcoffset);
1995        DECODE_PRINTF("\n");
1996        TRACE_AND_STEP();
1997        *destreg = and_byte(*destreg, srcval);
1998        break;
1999    case 2:
2000        destreg = DECODE_RM_BYTE_REGISTER(rh);
2001        DECODE_PRINTF(",");
2002        srcoffset = decode_rm10_address(rl);
2003        srcval = fetch_data_byte(srcoffset);
2004        DECODE_PRINTF("\n");
2005        TRACE_AND_STEP();
2006        *destreg = and_byte(*destreg, srcval);
2007        break;
2008    case 3:                     /* register to register */
2009        destreg = DECODE_RM_BYTE_REGISTER(rh);
2010        DECODE_PRINTF(",");
2011        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2012        DECODE_PRINTF("\n");
2013        TRACE_AND_STEP();
2014        *destreg = and_byte(*destreg, *srcreg);
2015        break;
2016    }
2017    DECODE_CLEAR_SEGOVR();
2018    END_OF_INSTR();
2019}
2020
2021/****************************************************************************
2022REMARKS:
2023Handles opcode 0x23
2024****************************************************************************/
2025static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2026{
2027    int mod, rl, rh;
2028    uint srcoffset;
2029
2030    START_OF_INSTR();
2031    DECODE_PRINTF("AND\t");
2032    FETCH_DECODE_MODRM(mod, rh, rl);
2033    switch (mod) {
2034    case 0:
2035        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2036            u32 *destreg;
2037            u32 srcval;
2038
2039            destreg = DECODE_RM_LONG_REGISTER(rh);
2040            DECODE_PRINTF(",");
2041            srcoffset = decode_rm00_address(rl);
2042            srcval = fetch_data_long(srcoffset);
2043            DECODE_PRINTF("\n");
2044            TRACE_AND_STEP();
2045            *destreg = and_long(*destreg, srcval);
2046        } else {
2047            u16 *destreg;
2048            u16 srcval;
2049
2050            destreg = DECODE_RM_WORD_REGISTER(rh);
2051            DECODE_PRINTF(",");
2052            srcoffset = decode_rm00_address(rl);
2053            srcval = fetch_data_word(srcoffset);
2054            DECODE_PRINTF("\n");
2055            TRACE_AND_STEP();
2056            *destreg = and_word(*destreg, srcval);
2057        }
2058        break;
2059    case 1:
2060        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2061            u32 *destreg;
2062            u32 srcval;
2063
2064            destreg = DECODE_RM_LONG_REGISTER(rh);
2065            DECODE_PRINTF(",");
2066            srcoffset = decode_rm01_address(rl);
2067            srcval = fetch_data_long(srcoffset);
2068            DECODE_PRINTF("\n");
2069            TRACE_AND_STEP();
2070            *destreg = and_long(*destreg, srcval);
2071            break;
2072        } else {
2073            u16 *destreg;
2074            u16 srcval;
2075
2076            destreg = DECODE_RM_WORD_REGISTER(rh);
2077            DECODE_PRINTF(",");
2078            srcoffset = decode_rm01_address(rl);
2079            srcval = fetch_data_word(srcoffset);
2080            DECODE_PRINTF("\n");
2081            TRACE_AND_STEP();
2082            *destreg = and_word(*destreg, srcval);
2083            break;
2084        }
2085    case 2:
2086        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2087            u32 *destreg;
2088            u32 srcval;
2089
2090            destreg = DECODE_RM_LONG_REGISTER(rh);
2091            DECODE_PRINTF(",");
2092            srcoffset = decode_rm10_address(rl);
2093            srcval = fetch_data_long(srcoffset);
2094            DECODE_PRINTF("\n");
2095            TRACE_AND_STEP();
2096            *destreg = and_long(*destreg, srcval);
2097        } else {
2098            u16 *destreg;
2099            u16 srcval;
2100
2101            destreg = DECODE_RM_WORD_REGISTER(rh);
2102            DECODE_PRINTF(",");
2103            srcoffset = decode_rm10_address(rl);
2104            srcval = fetch_data_word(srcoffset);
2105            DECODE_PRINTF("\n");
2106            TRACE_AND_STEP();
2107            *destreg = and_word(*destreg, srcval);
2108        }
2109        break;
2110    case 3:                     /* register to register */
2111        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2112            u32 *destreg,*srcreg;
2113
2114            destreg = DECODE_RM_LONG_REGISTER(rh);
2115            DECODE_PRINTF(",");
2116            srcreg = DECODE_RM_LONG_REGISTER(rl);
2117            DECODE_PRINTF("\n");
2118            TRACE_AND_STEP();
2119            *destreg = and_long(*destreg, *srcreg);
2120        } else {
2121            u16 *destreg,*srcreg;
2122
2123            destreg = DECODE_RM_WORD_REGISTER(rh);
2124            DECODE_PRINTF(",");
2125            srcreg = DECODE_RM_WORD_REGISTER(rl);
2126            DECODE_PRINTF("\n");
2127            TRACE_AND_STEP();
2128            *destreg = and_word(*destreg, *srcreg);
2129        }
2130        break;
2131    }
2132    DECODE_CLEAR_SEGOVR();
2133    END_OF_INSTR();
2134}
2135
2136/****************************************************************************
2137REMARKS:
2138Handles opcode 0x24
2139****************************************************************************/
2140static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2141{
2142    u8 srcval;
2143
2144    START_OF_INSTR();
2145    DECODE_PRINTF("AND\tAL,");
2146    srcval = fetch_byte_imm();
2147    DECODE_PRINTF2("%x\n", srcval);
2148    TRACE_AND_STEP();
2149    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2150    DECODE_CLEAR_SEGOVR();
2151    END_OF_INSTR();
2152}
2153
2154/****************************************************************************
2155REMARKS:
2156Handles opcode 0x25
2157****************************************************************************/
2158static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2159{
2160    u32 srcval;
2161
2162    START_OF_INSTR();
2163    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2164        DECODE_PRINTF("AND\tEAX,");
2165        srcval = fetch_long_imm();
2166    } else {
2167        DECODE_PRINTF("AND\tAX,");
2168        srcval = fetch_word_imm();
2169    }
2170    DECODE_PRINTF2("%x\n", srcval);
2171    TRACE_AND_STEP();
2172    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2174    } else {
2175        M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2176    }
2177    DECODE_CLEAR_SEGOVR();
2178    END_OF_INSTR();
2179}
2180
2181/****************************************************************************
2182REMARKS:
2183Handles opcode 0x26
2184****************************************************************************/
2185static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2186{
2187    START_OF_INSTR();
2188    DECODE_PRINTF("ES:\n");
2189    TRACE_AND_STEP();
2190    M.x86.mode |= SYSMODE_SEGOVR_ES;
2191    /*
2192     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2193     * opcode subroutines we do not want to do this.
2194     */
2195    END_OF_INSTR();
2196}
2197
2198/****************************************************************************
2199REMARKS:
2200Handles opcode 0x27
2201****************************************************************************/
2202static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2203{
2204    START_OF_INSTR();
2205    DECODE_PRINTF("DAA\n");
2206    TRACE_AND_STEP();
2207    M.x86.R_AL = daa_byte(M.x86.R_AL);
2208    DECODE_CLEAR_SEGOVR();
2209    END_OF_INSTR();
2210}
2211
2212/****************************************************************************
2213REMARKS:
2214Handles opcode 0x28
2215****************************************************************************/
2216static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2217{
2218    int mod, rl, rh;
2219    u8 *destreg, *srcreg;
2220    uint destoffset;
2221    u8 destval;
2222
2223    START_OF_INSTR();
2224    DECODE_PRINTF("SUB\t");
2225    FETCH_DECODE_MODRM(mod, rh, rl);
2226    switch (mod) {
2227    case 0:
2228        destoffset = decode_rm00_address(rl);
2229        DECODE_PRINTF(",");
2230        destval = fetch_data_byte(destoffset);
2231        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2232        DECODE_PRINTF("\n");
2233        TRACE_AND_STEP();
2234        destval = sub_byte(destval, *srcreg);
2235        store_data_byte(destoffset, destval);
2236        break;
2237    case 1:
2238        destoffset = decode_rm01_address(rl);
2239        DECODE_PRINTF(",");
2240        destval = fetch_data_byte(destoffset);
2241        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2242        DECODE_PRINTF("\n");
2243        TRACE_AND_STEP();
2244        destval = sub_byte(destval, *srcreg);
2245        store_data_byte(destoffset, destval);
2246        break;
2247    case 2:
2248        destoffset = decode_rm10_address(rl);
2249        DECODE_PRINTF(",");
2250        destval = fetch_data_byte(destoffset);
2251        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2252        DECODE_PRINTF("\n");
2253        TRACE_AND_STEP();
2254        destval = sub_byte(destval, *srcreg);
2255        store_data_byte(destoffset, destval);
2256        break;
2257    case 3:                     /* register to register */
2258        destreg = DECODE_RM_BYTE_REGISTER(rl);
2259        DECODE_PRINTF(",");
2260        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2261        DECODE_PRINTF("\n");
2262        TRACE_AND_STEP();
2263        *destreg = sub_byte(*destreg, *srcreg);
2264        break;
2265    }
2266    DECODE_CLEAR_SEGOVR();
2267    END_OF_INSTR();
2268}
2269
2270/****************************************************************************
2271REMARKS:
2272Handles opcode 0x29
2273****************************************************************************/
2274static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2275{
2276    int mod, rl, rh;
2277    uint destoffset;
2278
2279    START_OF_INSTR();
2280    DECODE_PRINTF("SUB\t");
2281    FETCH_DECODE_MODRM(mod, rh, rl);
2282    switch (mod) {
2283    case 0:
2284        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285            u32 destval;
2286            u32 *srcreg;
2287
2288            destoffset = decode_rm00_address(rl);
2289            DECODE_PRINTF(",");
2290            destval = fetch_data_long(destoffset);
2291            srcreg = DECODE_RM_LONG_REGISTER(rh);
2292            DECODE_PRINTF("\n");
2293            TRACE_AND_STEP();
2294            destval = sub_long(destval, *srcreg);
2295            store_data_long(destoffset, destval);
2296        } else {
2297            u16 destval;
2298            u16 *srcreg;
2299
2300            destoffset = decode_rm00_address(rl);
2301            DECODE_PRINTF(",");
2302            destval = fetch_data_word(destoffset);
2303            srcreg = DECODE_RM_WORD_REGISTER(rh);
2304            DECODE_PRINTF("\n");
2305            TRACE_AND_STEP();
2306            destval = sub_word(destval, *srcreg);
2307            store_data_word(destoffset, destval);
2308        }
2309        break;
2310    case 1:
2311        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2312            u32 destval;
2313            u32 *srcreg;
2314
2315            destoffset = decode_rm01_address(rl);
2316            DECODE_PRINTF(",");
2317            destval = fetch_data_long(destoffset);
2318            srcreg = DECODE_RM_LONG_REGISTER(rh);
2319            DECODE_PRINTF("\n");
2320            TRACE_AND_STEP();
2321            destval = sub_long(destval, *srcreg);
2322            store_data_long(destoffset, destval);
2323        } else {
2324            u16 destval;
2325            u16 *srcreg;
2326
2327            destoffset = decode_rm01_address(rl);
2328            DECODE_PRINTF(",");
2329            destval = fetch_data_word(destoffset);
2330            srcreg = DECODE_RM_WORD_REGISTER(rh);
2331            DECODE_PRINTF("\n");
2332            TRACE_AND_STEP();
2333            destval = sub_word(destval, *srcreg);
2334            store_data_word(destoffset, destval);
2335        }
2336        break;
2337    case 2:
2338        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2339            u32 destval;
2340            u32 *srcreg;
2341
2342            destoffset = decode_rm10_address(rl);
2343            DECODE_PRINTF(",");
2344            destval = fetch_data_long(destoffset);
2345            srcreg = DECODE_RM_LONG_REGISTER(rh);
2346            DECODE_PRINTF("\n");
2347            TRACE_AND_STEP();
2348            destval = sub_long(destval, *srcreg);
2349            store_data_long(destoffset, destval);
2350        } else {
2351            u16 destval;
2352            u16 *srcreg;
2353
2354            destoffset = decode_rm10_address(rl);
2355            DECODE_PRINTF(",");
2356            destval = fetch_data_word(destoffset);
2357            srcreg = DECODE_RM_WORD_REGISTER(rh);
2358            DECODE_PRINTF("\n");
2359            TRACE_AND_STEP();
2360            destval = sub_word(destval, *srcreg);
2361            store_data_word(destoffset, destval);
2362        }
2363        break;
2364    case 3:                     /* register to register */
2365        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2366            u32 *destreg,*srcreg;
2367
2368            destreg = DECODE_RM_LONG_REGISTER(rl);
2369            DECODE_PRINTF(",");
2370            srcreg = DECODE_RM_LONG_REGISTER(rh);
2371            DECODE_PRINTF("\n");
2372            TRACE_AND_STEP();
2373            *destreg = sub_long(*destreg, *srcreg);
2374        } else {
2375            u16 *destreg,*srcreg;
2376
2377            destreg = DECODE_RM_WORD_REGISTER(rl);
2378            DECODE_PRINTF(",");
2379            srcreg = DECODE_RM_WORD_REGISTER(rh);
2380            DECODE_PRINTF("\n");
2381            TRACE_AND_STEP();
2382            *destreg = sub_word(*destreg, *srcreg);
2383        }
2384        break;
2385    }
2386    DECODE_CLEAR_SEGOVR();
2387    END_OF_INSTR();
2388}
2389
2390/****************************************************************************
2391REMARKS:
2392Handles opcode 0x2a
2393****************************************************************************/
2394static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2395{
2396    int mod, rl, rh;
2397    u8 *destreg, *srcreg;
2398    uint srcoffset;
2399    u8 srcval;
2400
2401    START_OF_INSTR();
2402    DECODE_PRINTF("SUB\t");
2403    FETCH_DECODE_MODRM(mod, rh, rl);
2404    switch (mod) {
2405    case 0:
2406        destreg = DECODE_RM_BYTE_REGISTER(rh);
2407        DECODE_PRINTF(",");
2408        srcoffset = decode_rm00_address(rl);
2409        srcval = fetch_data_byte(srcoffset);
2410        DECODE_PRINTF("\n");
2411        TRACE_AND_STEP();
2412        *destreg = sub_byte(*destreg, srcval);
2413        break;
2414    case 1:
2415        destreg = DECODE_RM_BYTE_REGISTER(rh);
2416        DECODE_PRINTF(",");
2417        srcoffset = decode_rm01_address(rl);
2418        srcval = fetch_data_byte(srcoffset);
2419        DECODE_PRINTF("\n");
2420        TRACE_AND_STEP();
2421        *destreg = sub_byte(*destreg, srcval);
2422        break;
2423    case 2:
2424        destreg = DECODE_RM_BYTE_REGISTER(rh);
2425        DECODE_PRINTF(",");
2426        srcoffset = decode_rm10_address(rl);
2427        srcval = fetch_data_byte(srcoffset);
2428        DECODE_PRINTF("\n");
2429        TRACE_AND_STEP();
2430        *destreg = sub_byte(*destreg, srcval);
2431        break;
2432    case 3:                     /* register to register */
2433        destreg = DECODE_RM_BYTE_REGISTER(rh);
2434        DECODE_PRINTF(",");
2435        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2436        DECODE_PRINTF("\n");
2437        TRACE_AND_STEP();
2438        *destreg = sub_byte(*destreg, *srcreg);
2439        break;
2440    }
2441    DECODE_CLEAR_SEGOVR();
2442    END_OF_INSTR();
2443}
2444
2445/****************************************************************************
2446REMARKS:
2447Handles opcode 0x2b
2448****************************************************************************/
2449static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2450{
2451    int mod, rl, rh;
2452    uint srcoffset;
2453
2454    START_OF_INSTR();
2455    DECODE_PRINTF("SUB\t");
2456    FETCH_DECODE_MODRM(mod, rh, rl);
2457    switch (mod) {
2458    case 0:
2459        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2460            u32 *destreg;
2461            u32 srcval;
2462
2463            destreg = DECODE_RM_LONG_REGISTER(rh);
2464            DECODE_PRINTF(",");
2465            srcoffset = decode_rm00_address(rl);
2466            srcval = fetch_data_long(srcoffset);
2467            DECODE_PRINTF("\n");
2468            TRACE_AND_STEP();
2469            *destreg = sub_long(*destreg, srcval);
2470        } else {
2471            u16 *destreg;
2472            u16 srcval;
2473
2474            destreg = DECODE_RM_WORD_REGISTER(rh);
2475            DECODE_PRINTF(",");
2476            srcoffset = decode_rm00_address(rl);
2477            srcval = fetch_data_word(srcoffset);
2478            DECODE_PRINTF("\n");
2479            TRACE_AND_STEP();
2480            *destreg = sub_word(*destreg, srcval);
2481        }
2482        break;
2483    case 1:
2484        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2485            u32 *destreg;
2486            u32 srcval;
2487
2488            destreg = DECODE_RM_LONG_REGISTER(rh);
2489            DECODE_PRINTF(",");
2490            srcoffset = decode_rm01_address(rl);
2491            srcval = fetch_data_long(srcoffset);
2492            DECODE_PRINTF("\n");
2493            TRACE_AND_STEP();
2494            *destreg = sub_long(*destreg, srcval);
2495        } else {
2496            u16 *destreg;
2497            u16 srcval;
2498
2499            destreg = DECODE_RM_WORD_REGISTER(rh);
2500            DECODE_PRINTF(",");
2501            srcoffset = decode_rm01_address(rl);
2502            srcval = fetch_data_word(srcoffset);
2503            DECODE_PRINTF("\n");
2504            TRACE_AND_STEP();
2505            *destreg = sub_word(*destreg, srcval);
2506        }
2507        break;
2508    case 2:
2509        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2510            u32 *destreg;
2511            u32 srcval;
2512
2513            destreg = DECODE_RM_LONG_REGISTER(rh);
2514            DECODE_PRINTF(",");
2515            srcoffset = decode_rm10_address(rl);
2516            srcval = fetch_data_long(srcoffset);
2517            DECODE_PRINTF("\n");
2518            TRACE_AND_STEP();
2519            *destreg = sub_long(*destreg, srcval);
2520        } else {
2521            u16 *destreg;
2522            u16 srcval;
2523
2524            destreg = DECODE_RM_WORD_REGISTER(rh);
2525            DECODE_PRINTF(",");
2526            srcoffset = decode_rm10_address(rl);
2527            srcval = fetch_data_word(srcoffset);
2528            DECODE_PRINTF("\n");
2529            TRACE_AND_STEP();
2530            *destreg = sub_word(*destreg, srcval);
2531        }
2532        break;
2533    case 3:                     /* register to register */
2534        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2535            u32 *destreg,*srcreg;
2536
2537            destreg = DECODE_RM_LONG_REGISTER(rh);
2538            DECODE_PRINTF(",");
2539            srcreg = DECODE_RM_LONG_REGISTER(rl);
2540            DECODE_PRINTF("\n");
2541            TRACE_AND_STEP();
2542            *destreg = sub_long(*destreg, *srcreg);
2543        } else {
2544            u16 *destreg,*srcreg;
2545
2546            destreg = DECODE_RM_WORD_REGISTER(rh);
2547            DECODE_PRINTF(",");
2548            srcreg = DECODE_RM_WORD_REGISTER(rl);
2549            DECODE_PRINTF("\n");
2550            TRACE_AND_STEP();
2551            *destreg = sub_word(*destreg, *srcreg);
2552        }
2553        break;
2554    }
2555    DECODE_CLEAR_SEGOVR();
2556    END_OF_INSTR();
2557}
2558
2559/****************************************************************************
2560REMARKS:
2561Handles opcode 0x2c
2562****************************************************************************/
2563static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2564{
2565    u8 srcval;
2566
2567    START_OF_INSTR();
2568    DECODE_PRINTF("SUB\tAL,");
2569    srcval = fetch_byte_imm();
2570    DECODE_PRINTF2("%x\n", srcval);
2571    TRACE_AND_STEP();
2572    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2573    DECODE_CLEAR_SEGOVR();
2574    END_OF_INSTR();
2575}
2576
2577/****************************************************************************
2578REMARKS:
2579Handles opcode 0x2d
2580****************************************************************************/
2581static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2582{
2583    u32 srcval;
2584
2585    START_OF_INSTR();
2586    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2587        DECODE_PRINTF("SUB\tEAX,");
2588        srcval = fetch_long_imm();
2589    } else {
2590        DECODE_PRINTF("SUB\tAX,");
2591        srcval = fetch_word_imm();
2592    }
2593    DECODE_PRINTF2("%x\n", srcval);
2594    TRACE_AND_STEP();
2595    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2596        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2597    } else {
2598        M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2599    }
2600    DECODE_CLEAR_SEGOVR();
2601    END_OF_INSTR();
2602}
2603
2604/****************************************************************************
2605REMARKS:
2606Handles opcode 0x2e
2607****************************************************************************/
2608static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2609{
2610    START_OF_INSTR();
2611    DECODE_PRINTF("CS:\n");
2612    TRACE_AND_STEP();
2613    M.x86.mode |= SYSMODE_SEGOVR_CS;
2614    /* note no DECODE_CLEAR_SEGOVR here. */
2615    END_OF_INSTR();
2616}
2617
2618/****************************************************************************
2619REMARKS:
2620Handles opcode 0x2f
2621****************************************************************************/
2622static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2623{
2624    START_OF_INSTR();
2625    DECODE_PRINTF("DAS\n");
2626    TRACE_AND_STEP();
2627    M.x86.R_AL = das_byte(M.x86.R_AL);
2628    DECODE_CLEAR_SEGOVR();
2629    END_OF_INSTR();
2630}
2631
2632/****************************************************************************
2633REMARKS:
2634Handles opcode 0x30
2635****************************************************************************/
2636static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2637{
2638    int mod, rl, rh;
2639    u8 *destreg, *srcreg;
2640    uint destoffset;
2641    u8 destval;
2642
2643    START_OF_INSTR();
2644    DECODE_PRINTF("XOR\t");
2645    FETCH_DECODE_MODRM(mod, rh, rl);
2646    switch (mod) {
2647    case 0:
2648        destoffset = decode_rm00_address(rl);
2649        DECODE_PRINTF(",");
2650        destval = fetch_data_byte(destoffset);
2651        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2652        DECODE_PRINTF("\n");
2653        TRACE_AND_STEP();
2654        destval = xor_byte(destval, *srcreg);
2655        store_data_byte(destoffset, destval);
2656        break;
2657    case 1:
2658        destoffset = decode_rm01_address(rl);
2659        DECODE_PRINTF(",");
2660        destval = fetch_data_byte(destoffset);
2661        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2662        DECODE_PRINTF("\n");
2663        TRACE_AND_STEP();
2664        destval = xor_byte(destval, *srcreg);
2665        store_data_byte(destoffset, destval);
2666        break;
2667    case 2:
2668        destoffset = decode_rm10_address(rl);
2669        DECODE_PRINTF(",");
2670        destval = fetch_data_byte(destoffset);
2671        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2672        DECODE_PRINTF("\n");
2673        TRACE_AND_STEP();
2674        destval = xor_byte(destval, *srcreg);
2675        store_data_byte(destoffset, destval);
2676        break;
2677    case 3:                     /* register to register */
2678        destreg = DECODE_RM_BYTE_REGISTER(rl);
2679        DECODE_PRINTF(",");
2680        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2681        DECODE_PRINTF("\n");
2682        TRACE_AND_STEP();
2683        *destreg = xor_byte(*destreg, *srcreg);
2684        break;
2685    }
2686    DECODE_CLEAR_SEGOVR();
2687    END_OF_INSTR();
2688}
2689
2690/****************************************************************************
2691REMARKS:
2692Handles opcode 0x31
2693****************************************************************************/
2694static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2695{
2696    int mod, rl, rh;
2697    uint destoffset;
2698
2699    START_OF_INSTR();
2700    DECODE_PRINTF("XOR\t");
2701    FETCH_DECODE_MODRM(mod, rh, rl);
2702    switch (mod) {
2703    case 0:
2704        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2705            u32 destval;
2706            u32 *srcreg;
2707
2708            destoffset = decode_rm00_address(rl);
2709            DECODE_PRINTF(",");
2710            destval = fetch_data_long(destoffset);
2711            srcreg = DECODE_RM_LONG_REGISTER(rh);
2712            DECODE_PRINTF("\n");
2713            TRACE_AND_STEP();
2714            destval = xor_long(destval, *srcreg);
2715            store_data_long(destoffset, destval);
2716        } else {
2717            u16 destval;
2718            u16 *srcreg;
2719
2720            destoffset = decode_rm00_address(rl);
2721            DECODE_PRINTF(",");
2722            destval = fetch_data_word(destoffset);
2723            srcreg = DECODE_RM_WORD_REGISTER(rh);
2724            DECODE_PRINTF("\n");
2725            TRACE_AND_STEP();
2726            destval = xor_word(destval, *srcreg);
2727            store_data_word(destoffset, destval);
2728        }
2729        break;
2730    case 1:
2731        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2732            u32 destval;
2733            u32 *srcreg;
2734
2735            destoffset = decode_rm01_address(rl);
2736            DECODE_PRINTF(",");
2737            destval = fetch_data_long(destoffset);
2738            srcreg = DECODE_RM_LONG_REGISTER(rh);
2739            DECODE_PRINTF("\n");
2740            TRACE_AND_STEP();
2741            destval = xor_long(destval, *srcreg);
2742            store_data_long(destoffset, destval);
2743        } else {
2744            u16 destval;
2745            u16 *srcreg;
2746
2747            destoffset = decode_rm01_address(rl);
2748            DECODE_PRINTF(",");
2749            destval = fetch_data_word(destoffset);
2750            srcreg = DECODE_RM_WORD_REGISTER(rh);
2751            DECODE_PRINTF("\n");
2752            TRACE_AND_STEP();
2753            destval = xor_word(destval, *srcreg);
2754            store_data_word(destoffset, destval);
2755        }
2756        break;
2757    case 2:
2758        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2759            u32 destval;
2760            u32 *srcreg;
2761
2762            destoffset = decode_rm10_address(rl);
2763            DECODE_PRINTF(",");
2764            destval = fetch_data_long(destoffset);
2765            srcreg = DECODE_RM_LONG_REGISTER(rh);
2766            DECODE_PRINTF("\n");
2767            TRACE_AND_STEP();
2768            destval = xor_long(destval, *srcreg);
2769            store_data_long(destoffset, destval);
2770        } else {
2771            u16 destval;
2772            u16 *srcreg;
2773
2774            destoffset = decode_rm10_address(rl);
2775            DECODE_PRINTF(",");
2776            destval = fetch_data_word(destoffset);
2777            srcreg = DECODE_RM_WORD_REGISTER(rh);
2778            DECODE_PRINTF("\n");
2779            TRACE_AND_STEP();
2780            destval = xor_word(destval, *srcreg);
2781            store_data_word(destoffset, destval);
2782        }
2783        break;
2784    case 3:                     /* register to register */
2785        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786            u32 *destreg,*srcreg;
2787
2788            destreg = DECODE_RM_LONG_REGISTER(rl);
2789            DECODE_PRINTF(",");
2790            srcreg = DECODE_RM_LONG_REGISTER(rh);
2791            DECODE_PRINTF("\n");
2792            TRACE_AND_STEP();
2793            *destreg = xor_long(*destreg, *srcreg);
2794        } else {
2795            u16 *destreg,*srcreg;
2796
2797            destreg = DECODE_RM_WORD_REGISTER(rl);
2798            DECODE_PRINTF(",");
2799            srcreg = DECODE_RM_WORD_REGISTER(rh);
2800            DECODE_PRINTF("\n");
2801            TRACE_AND_STEP();
2802            *destreg = xor_word(*destreg, *srcreg);
2803        }
2804        break;
2805    }
2806    DECODE_CLEAR_SEGOVR();
2807    END_OF_INSTR();
2808}
2809
2810/****************************************************************************
2811REMARKS:
2812Handles opcode 0x32
2813****************************************************************************/
2814static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2815{
2816    int mod, rl, rh;
2817    u8 *destreg, *srcreg;
2818    uint srcoffset;
2819    u8 srcval;
2820
2821    START_OF_INSTR();
2822    DECODE_PRINTF("XOR\t");
2823    FETCH_DECODE_MODRM(mod, rh, rl);
2824    switch (mod) {
2825    case 0:
2826        destreg = DECODE_RM_BYTE_REGISTER(rh);
2827        DECODE_PRINTF(",");
2828        srcoffset = decode_rm00_address(rl);
2829        srcval = fetch_data_byte(srcoffset);
2830        DECODE_PRINTF("\n");
2831        TRACE_AND_STEP();
2832        *destreg = xor_byte(*destreg, srcval);
2833        break;
2834    case 1:
2835        destreg = DECODE_RM_BYTE_REGISTER(rh);
2836        DECODE_PRINTF(",");
2837        srcoffset = decode_rm01_address(rl);
2838        srcval = fetch_data_byte(srcoffset);
2839        DECODE_PRINTF("\n");
2840        TRACE_AND_STEP();
2841        *destreg = xor_byte(*destreg, srcval);
2842        break;
2843    case 2:
2844        destreg = DECODE_RM_BYTE_REGISTER(rh);
2845        DECODE_PRINTF(",");
2846        srcoffset = decode_rm10_address(rl);
2847        srcval = fetch_data_byte(srcoffset);
2848        DECODE_PRINTF("\n");
2849        TRACE_AND_STEP();
2850        *destreg = xor_byte(*destreg, srcval);
2851        break;
2852    case 3:                     /* register to register */
2853        destreg = DECODE_RM_BYTE_REGISTER(rh);
2854        DECODE_PRINTF(",");
2855        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2856        DECODE_PRINTF("\n");
2857        TRACE_AND_STEP();
2858        *destreg = xor_byte(*destreg, *srcreg);
2859        break;
2860    }
2861    DECODE_CLEAR_SEGOVR();
2862    END_OF_INSTR();
2863}
2864
2865/****************************************************************************
2866REMARKS:
2867Handles opcode 0x33
2868****************************************************************************/
2869static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2870{
2871    int mod, rl, rh;
2872    uint srcoffset;
2873
2874    START_OF_INSTR();
2875    DECODE_PRINTF("XOR\t");
2876    FETCH_DECODE_MODRM(mod, rh, rl);
2877    switch (mod) {
2878    case 0:
2879        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2880            u32 *destreg;
2881            u32 srcval;
2882
2883            destreg = DECODE_RM_LONG_REGISTER(rh);
2884            DECODE_PRINTF(",");
2885            srcoffset = decode_rm00_address(rl);
2886            srcval = fetch_data_long(srcoffset);
2887            DECODE_PRINTF("\n");
2888            TRACE_AND_STEP();
2889            *destreg = xor_long(*destreg, srcval);
2890        } else {
2891            u16 *destreg;
2892            u16 srcval;
2893
2894            destreg = DECODE_RM_WORD_REGISTER(rh);
2895            DECODE_PRINTF(",");
2896            srcoffset = decode_rm00_address(rl);
2897            srcval = fetch_data_word(srcoffset);
2898            DECODE_PRINTF("\n");
2899            TRACE_AND_STEP();
2900            *destreg = xor_word(*destreg, srcval);
2901        }
2902        break;
2903    case 1:
2904        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2905            u32 *destreg;
2906            u32 srcval;
2907
2908            destreg = DECODE_RM_LONG_REGISTER(rh);
2909            DECODE_PRINTF(",");
2910            srcoffset = decode_rm01_address(rl);
2911            srcval = fetch_data_long(srcoffset);
2912            DECODE_PRINTF("\n");
2913            TRACE_AND_STEP();
2914            *destreg = xor_long(*destreg, srcval);
2915        } else {
2916            u16 *destreg;
2917            u16 srcval;
2918
2919            destreg = DECODE_RM_WORD_REGISTER(rh);
2920            DECODE_PRINTF(",");
2921            srcoffset = decode_rm01_address(rl);
2922            srcval = fetch_data_word(srcoffset);
2923            DECODE_PRINTF("\n");
2924            TRACE_AND_STEP();
2925            *destreg = xor_word(*destreg, srcval);
2926        }
2927        break;
2928    case 2:
2929        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2930            u32 *destreg;
2931            u32 srcval;
2932
2933            destreg = DECODE_RM_LONG_REGISTER(rh);
2934            DECODE_PRINTF(",");
2935            srcoffset = decode_rm10_address(rl);
2936            srcval = fetch_data_long(srcoffset);
2937            DECODE_PRINTF("\n");
2938            TRACE_AND_STEP();
2939            *destreg = xor_long(*destreg, srcval);
2940        } else {
2941            u16 *destreg;
2942            u16 srcval;
2943
2944            destreg = DECODE_RM_WORD_REGISTER(rh);
2945            DECODE_PRINTF(",");
2946            srcoffset = decode_rm10_address(rl);
2947            srcval = fetch_data_word(srcoffset);
2948            DECODE_PRINTF("\n");
2949            TRACE_AND_STEP();
2950            *destreg = xor_word(*destreg, srcval);
2951        }
2952        break;
2953    case 3:                     /* register to register */
2954        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955            u32 *destreg,*srcreg;
2956
2957            destreg = DECODE_RM_LONG_REGISTER(rh);
2958            DECODE_PRINTF(",");
2959            srcreg = DECODE_RM_LONG_REGISTER(rl);
2960            DECODE_PRINTF("\n");
2961            TRACE_AND_STEP();
2962            *destreg = xor_long(*destreg, *srcreg);
2963        } else {
2964            u16 *destreg,*srcreg;
2965
2966            destreg = DECODE_RM_WORD_REGISTER(rh);
2967            DECODE_PRINTF(",");
2968            srcreg = DECODE_RM_WORD_REGISTER(rl);
2969            DECODE_PRINTF("\n");
2970            TRACE_AND_STEP();
2971            *destreg = xor_word(*destreg, *srcreg);
2972        }
2973        break;
2974    }
2975    DECODE_CLEAR_SEGOVR();
2976    END_OF_INSTR();
2977}
2978
2979/****************************************************************************
2980REMARKS:
2981Handles opcode 0x34
2982****************************************************************************/
2983static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2984{
2985    u8 srcval;
2986
2987    START_OF_INSTR();
2988    DECODE_PRINTF("XOR\tAL,");
2989    srcval = fetch_byte_imm();
2990    DECODE_PRINTF2("%x\n", srcval);
2991    TRACE_AND_STEP();
2992    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2993    DECODE_CLEAR_SEGOVR();
2994    END_OF_INSTR();
2995}
2996
2997/****************************************************************************
2998REMARKS:
2999Handles opcode 0x35
3000****************************************************************************/
3001static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3002{
3003    u32 srcval;
3004
3005    START_OF_INSTR();
3006    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3007        DECODE_PRINTF("XOR\tEAX,");
3008        srcval = fetch_long_imm();
3009    } else {
3010        DECODE_PRINTF("XOR\tAX,");
3011        srcval = fetch_word_imm();
3012    }
3013    DECODE_PRINTF2("%x\n", srcval);
3014    TRACE_AND_STEP();
3015    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3016        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3017    } else {
3018        M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3019    }
3020    DECODE_CLEAR_SEGOVR();
3021    END_OF_INSTR();
3022}
3023
3024/****************************************************************************
3025REMARKS:
3026Handles opcode 0x36
3027****************************************************************************/
3028static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3029{
3030    START_OF_INSTR();
3031    DECODE_PRINTF("SS:\n");
3032    TRACE_AND_STEP();
3033    M.x86.mode |= SYSMODE_SEGOVR_SS;
3034    /* no DECODE_CLEAR_SEGOVR ! */
3035    END_OF_INSTR();
3036}
3037
3038/****************************************************************************
3039REMARKS:
3040Handles opcode 0x37
3041****************************************************************************/
3042static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3043{
3044    START_OF_INSTR();
3045    DECODE_PRINTF("AAA\n");
3046    TRACE_AND_STEP();
3047    M.x86.R_AX = aaa_word(M.x86.R_AX);
3048    DECODE_CLEAR_SEGOVR();
3049    END_OF_INSTR();
3050}
3051
3052/****************************************************************************
3053REMARKS:
3054Handles opcode 0x38
3055****************************************************************************/
3056static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3057{
3058    int mod, rl, rh;
3059    uint destoffset;
3060    u8 *destreg, *srcreg;
3061    u8 destval;
3062
3063    START_OF_INSTR();
3064    DECODE_PRINTF("CMP\t");
3065    FETCH_DECODE_MODRM(mod, rh, rl);
3066    switch (mod) {
3067    case 0:
3068        destoffset = decode_rm00_address(rl);
3069        DECODE_PRINTF(",");
3070        destval = fetch_data_byte(destoffset);
3071        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3072        DECODE_PRINTF("\n");
3073        TRACE_AND_STEP();
3074        cmp_byte(destval, *srcreg);
3075        break;
3076    case 1:
3077        destoffset = decode_rm01_address(rl);
3078        DECODE_PRINTF(",");
3079        destval = fetch_data_byte(destoffset);
3080        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3081        DECODE_PRINTF("\n");
3082        TRACE_AND_STEP();
3083        cmp_byte(destval, *srcreg);
3084        break;
3085    case 2:
3086        destoffset = decode_rm10_address(rl);
3087        DECODE_PRINTF(",");
3088        destval = fetch_data_byte(destoffset);
3089        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3090        DECODE_PRINTF("\n");
3091        TRACE_AND_STEP();
3092        cmp_byte(destval, *srcreg);
3093        break;
3094    case 3:                     /* register to register */
3095        destreg = DECODE_RM_BYTE_REGISTER(rl);
3096        DECODE_PRINTF(",");
3097        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3098        DECODE_PRINTF("\n");
3099        TRACE_AND_STEP();
3100        cmp_byte(*destreg, *srcreg);
3101        break;
3102    }
3103    DECODE_CLEAR_SEGOVR();
3104    END_OF_INSTR();
3105}
3106
3107/****************************************************************************
3108REMARKS:
3109Handles opcode 0x39
3110****************************************************************************/
3111static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3112{
3113    int mod, rl, rh;
3114    uint destoffset;
3115
3116    START_OF_INSTR();
3117    DECODE_PRINTF("CMP\t");
3118    FETCH_DECODE_MODRM(mod, rh, rl);
3119    switch (mod) {
3120    case 0:
3121        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3122            u32 destval;
3123            u32 *srcreg;
3124
3125            destoffset = decode_rm00_address(rl);
3126            DECODE_PRINTF(",");
3127            destval = fetch_data_long(destoffset);
3128            srcreg = DECODE_RM_LONG_REGISTER(rh);
3129            DECODE_PRINTF("\n");
3130            TRACE_AND_STEP();
3131            cmp_long(destval, *srcreg);
3132        } else {
3133            u16 destval;
3134            u16 *srcreg;
3135
3136            destoffset = decode_rm00_address(rl);
3137            DECODE_PRINTF(",");
3138            destval = fetch_data_word(destoffset);
3139            srcreg = DECODE_RM_WORD_REGISTER(rh);
3140            DECODE_PRINTF("\n");
3141            TRACE_AND_STEP();
3142            cmp_word(destval, *srcreg);
3143        }
3144        break;
3145    case 1:
3146        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3147            u32 destval;
3148            u32 *srcreg;
3149
3150            destoffset = decode_rm01_address(rl);
3151            DECODE_PRINTF(",");
3152            destval = fetch_data_long(destoffset);
3153            srcreg = DECODE_RM_LONG_REGISTER(rh);
3154            DECODE_PRINTF("\n");
3155            TRACE_AND_STEP();
3156            cmp_long(destval, *srcreg);
3157        } else {
3158            u16 destval;
3159            u16 *srcreg;
3160
3161            destoffset = decode_rm01_address(rl);
3162            DECODE_PRINTF(",");
3163            destval = fetch_data_word(destoffset);
3164            srcreg = DECODE_RM_WORD_REGISTER(rh);
3165            DECODE_PRINTF("\n");
3166            TRACE_AND_STEP();
3167            cmp_word(destval, *srcreg);
3168        }
3169        break;
3170    case 2:
3171        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3172            u32 destval;
3173            u32 *srcreg;
3174
3175            destoffset = decode_rm10_address(rl);
3176            DECODE_PRINTF(",");
3177            destval = fetch_data_long(destoffset);
3178            srcreg = DECODE_RM_LONG_REGISTER(rh);
3179            DECODE_PRINTF("\n");
3180            TRACE_AND_STEP();
3181            cmp_long(destval, *srcreg);
3182        } else {
3183            u16 destval;
3184            u16 *srcreg;
3185
3186            destoffset = decode_rm10_address(rl);
3187            DECODE_PRINTF(",");
3188            destval = fetch_data_word(destoffset);
3189            srcreg = DECODE_RM_WORD_REGISTER(rh);
3190            DECODE_PRINTF("\n");
3191            TRACE_AND_STEP();
3192            cmp_word(destval, *srcreg);
3193        }
3194        break;
3195    case 3:                     /* register to register */
3196        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3197            u32 *destreg,*srcreg;
3198
3199            destreg = DECODE_RM_LONG_REGISTER(rl);
3200            DECODE_PRINTF(",");
3201            srcreg = DECODE_RM_LONG_REGISTER(rh);
3202            DECODE_PRINTF("\n");
3203            TRACE_AND_STEP();
3204            cmp_long(*destreg, *srcreg);
3205        } else {
3206            u16 *destreg,*srcreg;
3207
3208            destreg = DECODE_RM_WORD_REGISTER(rl);
3209            DECODE_PRINTF(",");
3210            srcreg = DECODE_RM_WORD_REGISTER(rh);
3211            DECODE_PRINTF("\n");
3212            TRACE_AND_STEP();
3213            cmp_word(*destreg, *srcreg);
3214        }
3215        break;
3216    }
3217    DECODE_CLEAR_SEGOVR();
3218    END_OF_INSTR();
3219}
3220
3221/****************************************************************************
3222REMARKS:
3223Handles opcode 0x3a
3224****************************************************************************/
3225static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3226{
3227    int mod, rl, rh;
3228    u8 *destreg, *srcreg;
3229    uint srcoffset;
3230    u8 srcval;
3231
3232    START_OF_INSTR();
3233    DECODE_PRINTF("CMP\t");
3234    FETCH_DECODE_MODRM(mod, rh, rl);
3235    switch (mod) {
3236    case 0:
3237        destreg = DECODE_RM_BYTE_REGISTER(rh);
3238        DECODE_PRINTF(",");
3239        srcoffset = decode_rm00_address(rl);
3240        srcval = fetch_data_byte(srcoffset);
3241        DECODE_PRINTF("\n");
3242        TRACE_AND_STEP();
3243        cmp_byte(*destreg, srcval);
3244        break;
3245    case 1:
3246        destreg = DECODE_RM_BYTE_REGISTER(rh);
3247        DECODE_PRINTF(",");
3248        srcoffset = decode_rm01_address(rl);
3249        srcval = fetch_data_byte(srcoffset);
3250        DECODE_PRINTF("\n");
3251        TRACE_AND_STEP();
3252        cmp_byte(*destreg, srcval);
3253        break;
3254    case 2:
3255        destreg = DECODE_RM_BYTE_REGISTER(rh);
3256        DECODE_PRINTF(",");
3257        srcoffset = decode_rm10_address(rl);
3258        srcval = fetch_data_byte(srcoffset);
3259        DECODE_PRINTF("\n");
3260        TRACE_AND_STEP();
3261        cmp_byte(*destreg, srcval);
3262        break;
3263    case 3:                     /* register to register */
3264        destreg = DECODE_RM_BYTE_REGISTER(rh);
3265        DECODE_PRINTF(",");
3266        srcreg = DECODE_RM_BYTE_REGISTER(rl);
3267        DECODE_PRINTF("\n");
3268        TRACE_AND_STEP();
3269        cmp_byte(*destreg, *srcreg);
3270        break;
3271    }
3272    DECODE_CLEAR_SEGOVR();
3273    END_OF_INSTR();
3274}
3275
3276/****************************************************************************
3277REMARKS:
3278Handles opcode 0x3b
3279****************************************************************************/
3280static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3281{
3282    int mod, rl, rh;
3283    uint srcoffset;
3284
3285    START_OF_INSTR();
3286    DECODE_PRINTF("CMP\t");
3287    FETCH_DECODE_MODRM(mod, rh, rl);
3288    switch (mod) {
3289    case 0:
3290        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3291            u32 *destreg;
3292            u32 srcval;
3293
3294            destreg = DECODE_RM_LONG_REGISTER(rh);
3295            DECODE_PRINTF(",");
3296            srcoffset = decode_rm00_address(rl);
3297            srcval = fetch_data_long(srcoffset);
3298            DECODE_PRINTF("\n");
3299            TRACE_AND_STEP();
3300            cmp_long(*destreg, srcval);
3301        } else {
3302            u16 *destreg;
3303            u16 srcval;
3304
3305            destreg = DECODE_RM_WORD_REGISTER(rh);
3306            DECODE_PRINTF(",");
3307            srcoffset = decode_rm00_address(rl);
3308            srcval = fetch_data_word(srcoffset);
3309            DECODE_PRINTF("\n");
3310            TRACE_AND_STEP();
3311            cmp_word(*destreg, srcval);
3312        }
3313        break;
3314    case 1:
3315        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3316            u32 *destreg;
3317            u32 srcval;
3318
3319            destreg = DECODE_RM_LONG_REGISTER(rh);
3320            DECODE_PRINTF(",");
3321            srcoffset = decode_rm01_address(rl);
3322            srcval = fetch_data_long(srcoffset);
3323            DECODE_PRINTF("\n");
3324            TRACE_AND_STEP();
3325            cmp_long(*destreg, srcval);
3326        } else {
3327            u16 *destreg;
3328            u16 srcval;
3329
3330            destreg = DECODE_RM_WORD_REGISTER(rh);
3331            DECODE_PRINTF(",");
3332            srcoffset = decode_rm01_address(rl);
3333            srcval = fetch_data_word(srcoffset);
3334            DECODE_PRINTF("\n");
3335            TRACE_AND_STEP();
3336            cmp_word(*destreg, srcval);
3337        }
3338        break;
3339    case 2:
3340        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3341            u32 *destreg;
3342            u32 srcval;
3343
3344            destreg = DECODE_RM_LONG_REGISTER(rh);
3345            DECODE_PRINTF(",");
3346            srcoffset = decode_rm10_address(rl);
3347            srcval = fetch_data_long(srcoffset);
3348            DECODE_PRINTF("\n");
3349            TRACE_AND_STEP();
3350            cmp_long(*destreg, srcval);
3351        } else {
3352            u16 *destreg;
3353            u16 srcval;
3354
3355            destreg = DECODE_RM_WORD_REGISTER(rh);
3356            DECODE_PRINTF(",");
3357            srcoffset = decode_rm10_address(rl);
3358            srcval = fetch_data_word(srcoffset);
3359            DECODE_PRINTF("\n");
3360            TRACE_AND_STEP();
3361            cmp_word(*destreg, srcval);
3362        }
3363        break;
3364    case 3:                     /* register to register */
3365        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3366            u32 *destreg,*srcreg;
3367
3368            destreg = DECODE_RM_LONG_REGISTER(rh);
3369            DECODE_PRINTF(",");
3370            srcreg = DECODE_RM_LONG_REGISTER(rl);
3371            DECODE_PRINTF("\n");
3372            TRACE_AND_STEP();
3373            cmp_long(*destreg, *srcreg);
3374        } else {
3375            u16 *destreg,*srcreg;
3376
3377            destreg = DECODE_RM_WORD_REGISTER(rh);
3378            DECODE_PRINTF(",");
3379            srcreg = DECODE_RM_WORD_REGISTER(rl);
3380            DECODE_PRINTF("\n");
3381            TRACE_AND_STEP();
3382            cmp_word(*destreg, *srcreg);
3383        }
3384        break;
3385    }
3386    DECODE_CLEAR_SEGOVR();
3387    END_OF_INSTR();
3388}
3389
3390/****************************************************************************
3391REMARKS:
3392Handles opcode 0x3c
3393****************************************************************************/
3394static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3395{
3396    u8 srcval;
3397
3398    START_OF_INSTR();
3399    DECODE_PRINTF("CMP\tAL,");
3400    srcval = fetch_byte_imm();
3401    DECODE_PRINTF2("%x\n", srcval);
3402    TRACE_AND_STEP();
3403    cmp_byte(M.x86.R_AL, srcval);
3404    DECODE_CLEAR_SEGOVR();
3405    END_OF_INSTR();
3406}
3407
3408/****************************************************************************
3409REMARKS:
3410Handles opcode 0x3d
3411****************************************************************************/
3412static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3413{
3414    u32 srcval;
3415
3416    START_OF_INSTR();
3417    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3418        DECODE_PRINTF("CMP\tEAX,");
3419        srcval = fetch_long_imm();
3420    } else {
3421        DECODE_PRINTF("CMP\tAX,");
3422        srcval = fetch_word_imm();
3423    }
3424    DECODE_PRINTF2("%x\n", srcval);
3425    TRACE_AND_STEP();
3426    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3427        cmp_long(M.x86.R_EAX, srcval);
3428    } else {
3429        cmp_word(M.x86.R_AX, (u16)srcval);
3430    }
3431    DECODE_CLEAR_SEGOVR();
3432    END_OF_INSTR();
3433}
3434
3435/****************************************************************************
3436REMARKS:
3437Handles opcode 0x3e
3438****************************************************************************/
3439static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3440{
3441    START_OF_INSTR();
3442    DECODE_PRINTF("DS:\n");
3443    TRACE_AND_STEP();
3444    M.x86.mode |= SYSMODE_SEGOVR_DS;
3445    /* NO DECODE_CLEAR_SEGOVR! */
3446    END_OF_INSTR();
3447}
3448
3449/****************************************************************************
3450REMARKS:
3451Handles opcode 0x3f
3452****************************************************************************/
3453static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3454{
3455    START_OF_INSTR();
3456    DECODE_PRINTF("AAS\n");
3457    TRACE_AND_STEP();
3458    M.x86.R_AX = aas_word(M.x86.R_AX);
3459    DECODE_CLEAR_SEGOVR();
3460    END_OF_INSTR();
3461}
3462
3463/****************************************************************************
3464REMARKS:
3465Handles opcode 0x40
3466****************************************************************************/
3467static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3468{
3469    START_OF_INSTR();
3470    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3471        DECODE_PRINTF("INC\tEAX\n");
3472    } else {
3473        DECODE_PRINTF("INC\tAX\n");
3474    }
3475    TRACE_AND_STEP();
3476    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3477        M.x86.R_EAX = inc_long(M.x86.R_EAX);
3478    } else {
3479        M.x86.R_AX = inc_word(M.x86.R_AX);
3480    }
3481    DECODE_CLEAR_SEGOVR();
3482    END_OF_INSTR();
3483}
3484
3485/****************************************************************************
3486REMARKS:
3487Handles opcode 0x41
3488****************************************************************************/
3489static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3490{
3491    START_OF_INSTR();
3492    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3493        DECODE_PRINTF("INC\tECX\n");
3494    } else {
3495        DECODE_PRINTF("INC\tCX\n");
3496    }
3497    TRACE_AND_STEP();
3498    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3499        M.x86.R_ECX = inc_long(M.x86.R_ECX);
3500    } else {
3501        M.x86.R_CX = inc_word(M.x86.R_CX);
3502    }
3503    DECODE_CLEAR_SEGOVR();
3504    END_OF_INSTR();
3505}
3506
3507/****************************************************************************
3508REMARKS:
3509Handles opcode 0x42
3510****************************************************************************/
3511static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3512{
3513    START_OF_INSTR();
3514    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3515        DECODE_PRINTF("INC\tEDX\n");
3516    } else {
3517        DECODE_PRINTF("INC\tDX\n");
3518    }
3519    TRACE_AND_STEP();
3520    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3521        M.x86.R_EDX = inc_long(M.x86.R_EDX);
3522    } else {
3523        M.x86.R_DX = inc_word(M.x86.R_DX);
3524    }
3525    DECODE_CLEAR_SEGOVR();
3526    END_OF_INSTR();
3527}
3528
3529/****************************************************************************
3530REMARKS:
3531Handles opcode 0x43
3532****************************************************************************/
3533static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3534{
3535    START_OF_INSTR();
3536    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3537        DECODE_PRINTF("INC\tEBX\n");
3538    } else {
3539        DECODE_PRINTF("INC\tBX\n");
3540    }
3541    TRACE_AND_STEP();
3542    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3543        M.x86.R_EBX = inc_long(M.x86.R_EBX);
3544    } else {
3545        M.x86.R_BX = inc_word(M.x86.R_BX);
3546    }
3547    DECODE_CLEAR_SEGOVR();
3548    END_OF_INSTR();
3549}
3550
3551/****************************************************************************
3552REMARKS:
3553Handles opcode 0x44
3554****************************************************************************/
3555static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3556{
3557    START_OF_INSTR();
3558    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559        DECODE_PRINTF("INC\tESP\n");
3560    } else {
3561        DECODE_PRINTF("INC\tSP\n");
3562    }
3563    TRACE_AND_STEP();
3564    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3565        M.x86.R_ESP = inc_long(M.x86.R_ESP);
3566    } else {
3567        M.x86.R_SP = inc_word(M.x86.R_SP);
3568    }
3569    DECODE_CLEAR_SEGOVR();
3570    END_OF_INSTR();
3571}
3572
3573/****************************************************************************
3574REMARKS:
3575Handles opcode 0x45
3576****************************************************************************/
3577static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3578{
3579    START_OF_INSTR();
3580    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3581        DECODE_PRINTF("INC\tEBP\n");
3582    } else {
3583        DECODE_PRINTF("INC\tBP\n");
3584    }
3585    TRACE_AND_STEP();
3586    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3587        M.x86.R_EBP = inc_long(M.x86.R_EBP);
3588    } else {
3589        M.x86.R_BP = inc_word(M.x86.R_BP);
3590    }
3591    DECODE_CLEAR_SEGOVR();
3592    END_OF_INSTR();
3593}
3594
3595/****************************************************************************
3596REMARKS:
3597Handles opcode 0x46
3598****************************************************************************/
3599static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3600{
3601    START_OF_INSTR();
3602    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3603        DECODE_PRINTF("INC\tESI\n");
3604    } else {
3605        DECODE_PRINTF("INC\tSI\n");
3606    }
3607    TRACE_AND_STEP();
3608    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3609        M.x86.R_ESI = inc_long(M.x86.R_ESI);
3610    } else {
3611        M.x86.R_SI = inc_word(M.x86.R_SI);
3612    }
3613    DECODE_CLEAR_SEGOVR();
3614    END_OF_INSTR();
3615}
3616
3617/****************************************************************************
3618REMARKS:
3619Handles opcode 0x47
3620****************************************************************************/
3621static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3622{
3623    START_OF_INSTR();
3624    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3625        DECODE_PRINTF("INC\tEDI\n");
3626    } else {
3627        DECODE_PRINTF("INC\tDI\n");
3628    }
3629    TRACE_AND_STEP();
3630    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3631        M.x86.R_EDI = inc_long(M.x86.R_EDI);
3632    } else {
3633        M.x86.R_DI = inc_word(M.x86.R_DI);
3634    }
3635    DECODE_CLEAR_SEGOVR();
3636    END_OF_INSTR();
3637}
3638
3639/****************************************************************************
3640REMARKS:
3641Handles opcode 0x48
3642****************************************************************************/
3643static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3644{
3645    START_OF_INSTR();
3646    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3647        DECODE_PRINTF("DEC\tEAX\n");
3648    } else {
3649        DECODE_PRINTF("DEC\tAX\n");
3650    }
3651    TRACE_AND_STEP();
3652    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3653        M.x86.R_EAX = dec_long(M.x86.R_EAX);
3654    } else {
3655        M.x86.R_AX = dec_word(M.x86.R_AX);
3656    }
3657    DECODE_CLEAR_SEGOVR();
3658    END_OF_INSTR();
3659}
3660
3661/****************************************************************************
3662REMARKS:
3663Handles opcode 0x49
3664****************************************************************************/
3665static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3666{
3667    START_OF_INSTR();
3668    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3669        DECODE_PRINTF("DEC\tECX\n");
3670    } else {
3671        DECODE_PRINTF("DEC\tCX\n");
3672    }
3673    TRACE_AND_STEP();
3674    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3675        M.x86.R_ECX = dec_long(M.x86.R_ECX);
3676    } else {
3677        M.x86.R_CX = dec_word(M.x86.R_CX);
3678    }
3679    DECODE_CLEAR_SEGOVR();
3680    END_OF_INSTR();
3681}
3682
3683/****************************************************************************
3684REMARKS:
3685Handles opcode 0x4a
3686****************************************************************************/
3687static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3688{
3689    START_OF_INSTR();
3690    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3691        DECODE_PRINTF("DEC\tEDX\n");
3692    } else {
3693        DECODE_PRINTF("DEC\tDX\n");
3694    }
3695    TRACE_AND_STEP();
3696    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3697        M.x86.R_EDX = dec_long(M.x86.R_EDX);
3698    } else {
3699        M.x86.R_DX = dec_word(M.x86.R_DX);
3700    }
3701    DECODE_CLEAR_SEGOVR();
3702    END_OF_INSTR();
3703}
3704
3705/****************************************************************************
3706REMARKS:
3707Handles opcode 0x4b
3708****************************************************************************/
3709static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3710{
3711    START_OF_INSTR();
3712    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3713        DECODE_PRINTF("DEC\tEBX\n");
3714    } else {
3715        DECODE_PRINTF("DEC\tBX\n");
3716    }
3717    TRACE_AND_STEP();
3718    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3719        M.x86.R_EBX = dec_long(M.x86.R_EBX);
3720    } else {
3721        M.x86.R_BX = dec_word(M.x86.R_BX);
3722    }
3723    DECODE_CLEAR_SEGOVR();
3724    END_OF_INSTR();
3725}
3726
3727/****************************************************************************
3728REMARKS:
3729Handles opcode 0x4c
3730****************************************************************************/
3731static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3732{
3733    START_OF_INSTR();
3734    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3735        DECODE_PRINTF("DEC\tESP\n");
3736    } else {
3737        DECODE_PRINTF("DEC\tSP\n");
3738    }
3739    TRACE_AND_STEP();
3740    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3741        M.x86.R_ESP = dec_long(M.x86.R_ESP);
3742    } else {
3743        M.x86.R_SP = dec_word(M.x86.R_SP);
3744    }
3745    DECODE_CLEAR_SEGOVR();
3746    END_OF_INSTR();
3747}
3748
3749/****************************************************************************
3750REMARKS:
3751Handles opcode 0x4d
3752****************************************************************************/
3753static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3754{
3755    START_OF_INSTR();
3756    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3757        DECODE_PRINTF("DEC\tEBP\n");
3758    } else {
3759        DECODE_PRINTF("DEC\tBP\n");
3760    }
3761    TRACE_AND_STEP();
3762    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3763        M.x86.R_EBP = dec_long(M.x86.R_EBP);
3764    } else {
3765        M.x86.R_BP = dec_word(M.x86.R_BP);
3766    }
3767    DECODE_CLEAR_SEGOVR();
3768    END_OF_INSTR();
3769}
3770
3771/****************************************************************************
3772REMARKS:
3773Handles opcode 0x4e
3774****************************************************************************/
3775static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3776{
3777    START_OF_INSTR();
3778    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3779        DECODE_PRINTF("DEC\tESI\n");
3780    } else {
3781        DECODE_PRINTF("DEC\tSI\n");
3782    }
3783    TRACE_AND_STEP();
3784    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3785        M.x86.R_ESI = dec_long(M.x86.R_ESI);
3786    } else {
3787        M.x86.R_SI = dec_word(M.x86.R_SI);
3788    }
3789    DECODE_CLEAR_SEGOVR();
3790    END_OF_INSTR();
3791}
3792
3793/****************************************************************************
3794REMARKS:
3795Handles opcode 0x4f
3796****************************************************************************/
3797static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3798{
3799    START_OF_INSTR();
3800    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3801        DECODE_PRINTF("DEC\tEDI\n");
3802    } else {
3803        DECODE_PRINTF("DEC\tDI\n");
3804    }
3805    TRACE_AND_STEP();
3806    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3807        M.x86.R_EDI = dec_long(M.x86.R_EDI);
3808    } else {
3809        M.x86.R_DI = dec_word(M.x86.R_DI);
3810    }
3811    DECODE_CLEAR_SEGOVR();
3812    END_OF_INSTR();
3813}
3814
3815/****************************************************************************
3816REMARKS:
3817Handles opcode 0x50
3818****************************************************************************/
3819static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3820{
3821    START_OF_INSTR();
3822    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3823        DECODE_PRINTF("PUSH\tEAX\n");
3824    } else {
3825        DECODE_PRINTF("PUSH\tAX\n");
3826    }
3827    TRACE_AND_STEP();
3828    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3829        push_long(M.x86.R_EAX);
3830    } else {
3831        push_word(M.x86.R_AX);
3832    }
3833    DECODE_CLEAR_SEGOVR();
3834    END_OF_INSTR();
3835}
3836
3837/****************************************************************************
3838REMARKS:
3839Handles opcode 0x51
3840****************************************************************************/
3841static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3842{
3843    START_OF_INSTR();
3844    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3845        DECODE_PRINTF("PUSH\tECX\n");
3846    } else {
3847        DECODE_PRINTF("PUSH\tCX\n");
3848    }
3849    TRACE_AND_STEP();
3850    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3851        push_long(M.x86.R_ECX);
3852    } else {
3853        push_word(M.x86.R_CX);
3854    }
3855    DECODE_CLEAR_SEGOVR();
3856    END_OF_INSTR();
3857}
3858
3859/****************************************************************************
3860REMARKS:
3861Handles opcode 0x52
3862****************************************************************************/
3863static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3864{
3865    START_OF_INSTR();
3866    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867        DECODE_PRINTF("PUSH\tEDX\n");
3868    } else {
3869        DECODE_PRINTF("PUSH\tDX\n");
3870    }
3871    TRACE_AND_STEP();
3872    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3873        push_long(M.x86.R_EDX);
3874    } else {
3875        push_word(M.x86.R_DX);
3876    }
3877    DECODE_CLEAR_SEGOVR();
3878    END_OF_INSTR();
3879}
3880
3881/****************************************************************************
3882REMARKS:
3883Handles opcode 0x53
3884****************************************************************************/
3885static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3886{
3887    START_OF_INSTR();
3888    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3889        DECODE_PRINTF("PUSH\tEBX\n");
3890    } else {
3891        DECODE_PRINTF("PUSH\tBX\n");
3892    }
3893    TRACE_AND_STEP();
3894    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3895        push_long(M.x86.R_EBX);
3896    } else {
3897        push_word(M.x86.R_BX);
3898    }
3899    DECODE_CLEAR_SEGOVR();
3900    END_OF_INSTR();
3901}
3902
3903/****************************************************************************
3904REMARKS:
3905Handles opcode 0x54
3906****************************************************************************/
3907static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3908{
3909    START_OF_INSTR();
3910    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3911        DECODE_PRINTF("PUSH\tESP\n");
3912    } else {
3913        DECODE_PRINTF("PUSH\tSP\n");
3914    }
3915    TRACE_AND_STEP();
3916	/* Always push (E)SP, since we are emulating an i386 and above
3917	 * processor. This is necessary as some BIOS'es use this to check
3918	 * what type of processor is in the system.
3919	 */
3920	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3921		push_long(M.x86.R_ESP);
3922	} else {
3923		push_word((u16)(M.x86.R_SP));
3924    }
3925    DECODE_CLEAR_SEGOVR();
3926    END_OF_INSTR();
3927}
3928
3929/****************************************************************************
3930REMARKS:
3931Handles opcode 0x55
3932****************************************************************************/
3933static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3934{
3935    START_OF_INSTR();
3936    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3937        DECODE_PRINTF("PUSH\tEBP\n");
3938    } else {
3939        DECODE_PRINTF("PUSH\tBP\n");
3940    }
3941    TRACE_AND_STEP();
3942    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3943        push_long(M.x86.R_EBP);
3944    } else {
3945        push_word(M.x86.R_BP);
3946    }
3947    DECODE_CLEAR_SEGOVR();
3948    END_OF_INSTR();
3949}
3950
3951/****************************************************************************
3952REMARKS:
3953Handles opcode 0x56
3954****************************************************************************/
3955static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3956{
3957    START_OF_INSTR();
3958    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3959        DECODE_PRINTF("PUSH\tESI\n");
3960    } else {
3961        DECODE_PRINTF("PUSH\tSI\n");
3962    }
3963    TRACE_AND_STEP();
3964    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3965        push_long(M.x86.R_ESI);
3966    } else {
3967        push_word(M.x86.R_SI);
3968    }
3969    DECODE_CLEAR_SEGOVR();
3970    END_OF_INSTR();
3971}
3972
3973/****************************************************************************
3974REMARKS:
3975Handles opcode 0x57
3976****************************************************************************/
3977static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3978{
3979    START_OF_INSTR();
3980    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3981        DECODE_PRINTF("PUSH\tEDI\n");
3982    } else {
3983        DECODE_PRINTF("PUSH\tDI\n");
3984    }
3985    TRACE_AND_STEP();
3986    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3987        push_long(M.x86.R_EDI);
3988    } else {
3989        push_word(M.x86.R_DI);
3990    }
3991    DECODE_CLEAR_SEGOVR();
3992    END_OF_INSTR();
3993}
3994
3995/****************************************************************************
3996REMARKS:
3997Handles opcode 0x58
3998****************************************************************************/
3999static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4000{
4001    START_OF_INSTR();
4002    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4003        DECODE_PRINTF("POP\tEAX\n");
4004    } else {
4005        DECODE_PRINTF("POP\tAX\n");
4006    }
4007    TRACE_AND_STEP();
4008    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4009        M.x86.R_EAX = pop_long();
4010    } else {
4011        M.x86.R_AX = pop_word();
4012    }
4013    DECODE_CLEAR_SEGOVR();
4014    END_OF_INSTR();
4015}
4016
4017/****************************************************************************
4018REMARKS:
4019Handles opcode 0x59
4020****************************************************************************/
4021static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4022{
4023    START_OF_INSTR();
4024    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4025        DECODE_PRINTF("POP\tECX\n");
4026    } else {
4027        DECODE_PRINTF("POP\tCX\n");
4028    }
4029    TRACE_AND_STEP();
4030    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4031        M.x86.R_ECX = pop_long();
4032    } else {
4033        M.x86.R_CX = pop_word();
4034    }
4035    DECODE_CLEAR_SEGOVR();
4036    END_OF_INSTR();
4037}
4038
4039/****************************************************************************
4040REMARKS:
4041Handles opcode 0x5a
4042****************************************************************************/
4043static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4044{
4045    START_OF_INSTR();
4046    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4047        DECODE_PRINTF("POP\tEDX\n");
4048    } else {
4049        DECODE_PRINTF("POP\tDX\n");
4050    }
4051    TRACE_AND_STEP();
4052    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4053        M.x86.R_EDX = pop_long();
4054    } else {
4055        M.x86.R_DX = pop_word();
4056    }
4057    DECODE_CLEAR_SEGOVR();
4058    END_OF_INSTR();
4059}
4060
4061/****************************************************************************
4062REMARKS:
4063Handles opcode 0x5b
4064****************************************************************************/
4065static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4066{
4067    START_OF_INSTR();
4068    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4069        DECODE_PRINTF("POP\tEBX\n");
4070    } else {
4071        DECODE_PRINTF("POP\tBX\n");
4072    }
4073    TRACE_AND_STEP();
4074    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4075        M.x86.R_EBX = pop_long();
4076    } else {
4077        M.x86.R_BX = pop_word();
4078    }
4079    DECODE_CLEAR_SEGOVR();
4080    END_OF_INSTR();
4081}
4082
4083/****************************************************************************
4084REMARKS:
4085Handles opcode 0x5c
4086****************************************************************************/
4087static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4088{
4089    START_OF_INSTR();
4090    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4091        DECODE_PRINTF("POP\tESP\n");
4092    } else {
4093        DECODE_PRINTF("POP\tSP\n");
4094    }
4095    TRACE_AND_STEP();
4096    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4097        M.x86.R_ESP = pop_long();
4098    } else {
4099        M.x86.R_SP = pop_word();
4100    }
4101    DECODE_CLEAR_SEGOVR();
4102    END_OF_INSTR();
4103}
4104
4105/****************************************************************************
4106REMARKS:
4107Handles opcode 0x5d
4108****************************************************************************/
4109static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4110{
4111    START_OF_INSTR();
4112    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4113        DECODE_PRINTF("POP\tEBP\n");
4114    } else {
4115        DECODE_PRINTF("POP\tBP\n");
4116    }
4117    TRACE_AND_STEP();
4118    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4119        M.x86.R_EBP = pop_long();
4120    } else {
4121        M.x86.R_BP = pop_word();
4122    }
4123    DECODE_CLEAR_SEGOVR();
4124    END_OF_INSTR();
4125}
4126
4127/****************************************************************************
4128REMARKS:
4129Handles opcode 0x5e
4130****************************************************************************/
4131static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4132{
4133    START_OF_INSTR();
4134    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4135        DECODE_PRINTF("POP\tESI\n");
4136    } else {
4137        DECODE_PRINTF("POP\tSI\n");
4138    }
4139    TRACE_AND_STEP();
4140    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4141        M.x86.R_ESI = pop_long();
4142    } else {
4143        M.x86.R_SI = pop_word();
4144    }
4145    DECODE_CLEAR_SEGOVR();
4146    END_OF_INSTR();
4147}
4148
4149/****************************************************************************
4150REMARKS:
4151Handles opcode 0x5f
4152****************************************************************************/
4153static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4154{
4155    START_OF_INSTR();
4156    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4157        DECODE_PRINTF("POP\tEDI\n");
4158    } else {
4159        DECODE_PRINTF("POP\tDI\n");
4160    }
4161    TRACE_AND_STEP();
4162    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4163        M.x86.R_EDI = pop_long();
4164    } else {
4165        M.x86.R_DI = pop_word();
4166    }
4167    DECODE_CLEAR_SEGOVR();
4168    END_OF_INSTR();
4169}
4170
4171/****************************************************************************
4172REMARKS:
4173Handles opcode 0x60
4174****************************************************************************/
4175static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4176{
4177    START_OF_INSTR();
4178    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4179        DECODE_PRINTF("PUSHAD\n");
4180    } else {
4181        DECODE_PRINTF("PUSHA\n");
4182    }
4183    TRACE_AND_STEP();
4184    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4185        u32 old_sp = M.x86.R_ESP;
4186
4187        push_long(M.x86.R_EAX);
4188        push_long(M.x86.R_ECX);
4189        push_long(M.x86.R_EDX);
4190        push_long(M.x86.R_EBX);
4191        push_long(old_sp);
4192        push_long(M.x86.R_EBP);
4193        push_long(M.x86.R_ESI);
4194        push_long(M.x86.R_EDI);
4195    } else {
4196        u16 old_sp = M.x86.R_SP;
4197
4198        push_word(M.x86.R_AX);
4199        push_word(M.x86.R_CX);
4200        push_word(M.x86.R_DX);
4201        push_word(M.x86.R_BX);
4202        push_word(old_sp);
4203        push_word(M.x86.R_BP);
4204        push_word(M.x86.R_SI);
4205        push_word(M.x86.R_DI);
4206    }
4207    DECODE_CLEAR_SEGOVR();
4208    END_OF_INSTR();
4209}
4210
4211/****************************************************************************
4212REMARKS:
4213Handles opcode 0x61
4214****************************************************************************/
4215static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4216{
4217    START_OF_INSTR();
4218    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4219        DECODE_PRINTF("POPAD\n");
4220    } else {
4221        DECODE_PRINTF("POPA\n");
4222    }
4223    TRACE_AND_STEP();
4224    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4225        M.x86.R_EDI = pop_long();
4226        M.x86.R_ESI = pop_long();
4227        M.x86.R_EBP = pop_long();
4228        M.x86.R_ESP += 4;              /* skip ESP */
4229        M.x86.R_EBX = pop_long();
4230        M.x86.R_EDX = pop_long();
4231        M.x86.R_ECX = pop_long();
4232        M.x86.R_EAX = pop_long();
4233    } else {
4234        M.x86.R_DI = pop_word();
4235        M.x86.R_SI = pop_word();
4236        M.x86.R_BP = pop_word();
4237        M.x86.R_SP += 2;               /* skip SP */
4238        M.x86.R_BX = pop_word();
4239        M.x86.R_DX = pop_word();
4240        M.x86.R_CX = pop_word();
4241        M.x86.R_AX = pop_word();
4242    }
4243    DECODE_CLEAR_SEGOVR();
4244    END_OF_INSTR();
4245}
4246
4247/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4248/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4249
4250/****************************************************************************
4251REMARKS:
4252Handles opcode 0x64
4253****************************************************************************/
4254static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4255{
4256    START_OF_INSTR();
4257    DECODE_PRINTF("FS:\n");
4258    TRACE_AND_STEP();
4259    M.x86.mode |= SYSMODE_SEGOVR_FS;
4260    /*
4261     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4262     * opcode subroutines we do not want to do this.
4263     */
4264    END_OF_INSTR();
4265}
4266
4267/****************************************************************************
4268REMARKS:
4269Handles opcode 0x65
4270****************************************************************************/
4271static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4272{
4273    START_OF_INSTR();
4274    DECODE_PRINTF("GS:\n");
4275    TRACE_AND_STEP();
4276    M.x86.mode |= SYSMODE_SEGOVR_GS;
4277    /*
4278     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4279     * opcode subroutines we do not want to do this.
4280     */
4281    END_OF_INSTR();
4282}
4283
4284/****************************************************************************
4285REMARKS:
4286Handles opcode 0x66 - prefix for 32-bit register
4287****************************************************************************/
4288static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4289{
4290    START_OF_INSTR();
4291    DECODE_PRINTF("DATA:\n");
4292    TRACE_AND_STEP();
4293    M.x86.mode |= SYSMODE_PREFIX_DATA;
4294    /* note no DECODE_CLEAR_SEGOVR here. */
4295    END_OF_INSTR();
4296}
4297
4298/****************************************************************************
4299REMARKS:
4300Handles opcode 0x67 - prefix for 32-bit address
4301****************************************************************************/
4302static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4303{
4304    START_OF_INSTR();
4305    DECODE_PRINTF("ADDR:\n");
4306    TRACE_AND_STEP();
4307    M.x86.mode |= SYSMODE_PREFIX_ADDR;
4308    /* note no DECODE_CLEAR_SEGOVR here. */
4309    END_OF_INSTR();
4310}
4311
4312/****************************************************************************
4313REMARKS:
4314Handles opcode 0x68
4315****************************************************************************/
4316static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4317{
4318    u32 imm;
4319
4320    START_OF_INSTR();
4321    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322        imm = fetch_long_imm();
4323    } else {
4324        imm = fetch_word_imm();
4325    }
4326    DECODE_PRINTF2("PUSH\t%x\n", imm);
4327    TRACE_AND_STEP();
4328    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4329        push_long(imm);
4330    } else {
4331        push_word((u16)imm);
4332    }
4333    DECODE_CLEAR_SEGOVR();
4334    END_OF_INSTR();
4335}
4336
4337/****************************************************************************
4338REMARKS:
4339Handles opcode 0x69
4340****************************************************************************/
4341static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4342{
4343    int mod, rl, rh;
4344    uint srcoffset;
4345
4346    START_OF_INSTR();
4347    DECODE_PRINTF("IMUL\t");
4348    FETCH_DECODE_MODRM(mod, rh, rl);
4349    switch (mod) {
4350    case 0:
4351        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4352            u32 *destreg;
4353            u32 srcval;
4354            u32 res_lo,res_hi;
4355            s32 imm;
4356
4357            destreg = DECODE_RM_LONG_REGISTER(rh);
4358            DECODE_PRINTF(",");
4359            srcoffset = decode_rm00_address(rl);
4360            srcval = fetch_data_long(srcoffset);
4361            imm = fetch_long_imm();
4362            DECODE_PRINTF2(",%d\n", (s32)imm);
4363            TRACE_AND_STEP();
4364            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4365            if (res_hi != 0) {
4366                SET_FLAG(F_CF);
4367                SET_FLAG(F_OF);
4368            } else {
4369                CLEAR_FLAG(F_CF);
4370                CLEAR_FLAG(F_OF);
4371            }
4372            *destreg = (u32)res_lo;
4373        } else {
4374            u16 *destreg;
4375            u16 srcval;
4376            u32 res;
4377            s16 imm;
4378
4379            destreg = DECODE_RM_WORD_REGISTER(rh);
4380            DECODE_PRINTF(",");
4381            srcoffset = decode_rm00_address(rl);
4382            srcval = fetch_data_word(srcoffset);
4383            imm = fetch_word_imm();
4384            DECODE_PRINTF2(",%d\n", (s32)imm);
4385            TRACE_AND_STEP();
4386            res = (s16)srcval * (s16)imm;
4387            if (res > 0xFFFF) {
4388                SET_FLAG(F_CF);
4389                SET_FLAG(F_OF);
4390            } else {
4391                CLEAR_FLAG(F_CF);
4392                CLEAR_FLAG(F_OF);
4393            }
4394            *destreg = (u16)res;
4395        }
4396        break;
4397    case 1:
4398        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4399            u32 *destreg;
4400            u32 srcval;
4401            u32 res_lo,res_hi;
4402            s32 imm;
4403
4404            destreg = DECODE_RM_LONG_REGISTER(rh);
4405            DECODE_PRINTF(",");
4406            srcoffset = decode_rm01_address(rl);
4407            srcval = fetch_data_long(srcoffset);
4408            imm = fetch_long_imm();
4409            DECODE_PRINTF2(",%d\n", (s32)imm);
4410            TRACE_AND_STEP();
4411            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4412            if (res_hi != 0) {
4413                SET_FLAG(F_CF);
4414                SET_FLAG(F_OF);
4415            } else {
4416                CLEAR_FLAG(F_CF);
4417                CLEAR_FLAG(F_OF);
4418            }
4419            *destreg = (u32)res_lo;
4420        } else {
4421            u16 *destreg;
4422            u16 srcval;
4423            u32 res;
4424            s16 imm;
4425
4426            destreg = DECODE_RM_WORD_REGISTER(rh);
4427            DECODE_PRINTF(",");
4428            srcoffset = decode_rm01_address(rl);
4429            srcval = fetch_data_word(srcoffset);
4430            imm = fetch_word_imm();
4431            DECODE_PRINTF2(",%d\n", (s32)imm);
4432            TRACE_AND_STEP();
4433            res = (s16)srcval * (s16)imm;
4434            if (res > 0xFFFF) {
4435                SET_FLAG(F_CF);
4436                SET_FLAG(F_OF);
4437            } else {
4438                CLEAR_FLAG(F_CF);
4439                CLEAR_FLAG(F_OF);
4440            }
4441            *destreg = (u16)res;
4442        }
4443        break;
4444    case 2:
4445        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4446            u32 *destreg;
4447            u32 srcval;
4448            u32 res_lo,res_hi;
4449            s32 imm;
4450
4451            destreg = DECODE_RM_LONG_REGISTER(rh);
4452            DECODE_PRINTF(",");
4453            srcoffset = decode_rm10_address(rl);
4454            srcval = fetch_data_long(srcoffset);
4455            imm = fetch_long_imm();
4456            DECODE_PRINTF2(",%d\n", (s32)imm);
4457            TRACE_AND_STEP();
4458            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4459            if (res_hi != 0) {
4460                SET_FLAG(F_CF);
4461                SET_FLAG(F_OF);
4462            } else {
4463                CLEAR_FLAG(F_CF);
4464                CLEAR_FLAG(F_OF);
4465            }
4466            *destreg = (u32)res_lo;
4467        } else {
4468            u16 *destreg;
4469            u16 srcval;
4470            u32 res;
4471            s16 imm;
4472
4473            destreg = DECODE_RM_WORD_REGISTER(rh);
4474            DECODE_PRINTF(",");
4475            srcoffset = decode_rm10_address(rl);
4476            srcval = fetch_data_word(srcoffset);
4477            imm = fetch_word_imm();
4478            DECODE_PRINTF2(",%d\n", (s32)imm);
4479            TRACE_AND_STEP();
4480            res = (s16)srcval * (s16)imm;
4481            if (res > 0xFFFF) {
4482                SET_FLAG(F_CF);
4483                SET_FLAG(F_OF);
4484            } else {
4485                CLEAR_FLAG(F_CF);
4486                CLEAR_FLAG(F_OF);
4487            }
4488            *destreg = (u16)res;
4489        }
4490        break;
4491    case 3:                     /* register to register */
4492        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4493            u32 *destreg,*srcreg;
4494            u32 res_lo,res_hi;
4495            s32 imm;
4496
4497            destreg = DECODE_RM_LONG_REGISTER(rh);
4498            DECODE_PRINTF(",");
4499            srcreg = DECODE_RM_LONG_REGISTER(rl);
4500            imm = fetch_long_imm();
4501            DECODE_PRINTF2(",%d\n", (s32)imm);
4502            TRACE_AND_STEP();
4503            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4504            if (res_hi != 0) {
4505                SET_FLAG(F_CF);
4506                SET_FLAG(F_OF);
4507            } else {
4508                CLEAR_FLAG(F_CF);
4509                CLEAR_FLAG(F_OF);
4510            }
4511            *destreg = (u32)res_lo;
4512        } else {
4513            u16 *destreg,*srcreg;
4514            u32 res;
4515            s16 imm;
4516
4517            destreg = DECODE_RM_WORD_REGISTER(rh);
4518            DECODE_PRINTF(",");
4519            srcreg = DECODE_RM_WORD_REGISTER(rl);
4520            imm = fetch_word_imm();
4521            DECODE_PRINTF2(",%d\n", (s32)imm);
4522            res = (s16)*srcreg * (s16)imm;
4523            if (res > 0xFFFF) {
4524                SET_FLAG(F_CF);
4525                SET_FLAG(F_OF);
4526            } else {
4527                CLEAR_FLAG(F_CF);
4528                CLEAR_FLAG(F_OF);
4529            }
4530            *destreg = (u16)res;
4531        }
4532        break;
4533    }
4534    DECODE_CLEAR_SEGOVR();
4535    END_OF_INSTR();
4536}
4537
4538/****************************************************************************
4539REMARKS:
4540Handles opcode 0x6a
4541****************************************************************************/
4542static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4543{
4544    s16 imm;
4545
4546    START_OF_INSTR();
4547    imm = (s8)fetch_byte_imm();
4548    DECODE_PRINTF2("PUSH\t%d\n", imm);
4549    TRACE_AND_STEP();
4550    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4551	push_long((s32)imm);
4552    } else {
4553	push_word(imm);
4554    }
4555    DECODE_CLEAR_SEGOVR();
4556    END_OF_INSTR();
4557}
4558
4559/****************************************************************************
4560REMARKS:
4561Handles opcode 0x6b
4562****************************************************************************/
4563static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4564{
4565    int mod, rl, rh;
4566    uint srcoffset;
4567    s8  imm;
4568
4569    START_OF_INSTR();
4570    DECODE_PRINTF("IMUL\t");
4571    FETCH_DECODE_MODRM(mod, rh, rl);
4572    switch (mod) {
4573    case 0:
4574        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4575            u32 *destreg;
4576            u32 srcval;
4577            u32 res_lo,res_hi;
4578
4579            destreg = DECODE_RM_LONG_REGISTER(rh);
4580            DECODE_PRINTF(",");
4581            srcoffset = decode_rm00_address(rl);
4582            srcval = fetch_data_long(srcoffset);
4583            imm = fetch_byte_imm();
4584            DECODE_PRINTF2(",%d\n", (s32)imm);
4585            TRACE_AND_STEP();
4586            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4587            if (res_hi != 0) {
4588                SET_FLAG(F_CF);
4589                SET_FLAG(F_OF);
4590            } else {
4591                CLEAR_FLAG(F_CF);
4592                CLEAR_FLAG(F_OF);
4593            }
4594            *destreg = (u32)res_lo;
4595        } else {
4596            u16 *destreg;
4597            u16 srcval;
4598            u32 res;
4599
4600            destreg = DECODE_RM_WORD_REGISTER(rh);
4601            DECODE_PRINTF(",");
4602            srcoffset = decode_rm00_address(rl);
4603            srcval = fetch_data_word(srcoffset);
4604            imm = fetch_byte_imm();
4605            DECODE_PRINTF2(",%d\n", (s32)imm);
4606            TRACE_AND_STEP();
4607            res = (s16)srcval * (s16)imm;
4608            if (res > 0xFFFF) {
4609                SET_FLAG(F_CF);
4610                SET_FLAG(F_OF);
4611            } else {
4612                CLEAR_FLAG(F_CF);
4613                CLEAR_FLAG(F_OF);
4614            }
4615            *destreg = (u16)res;
4616        }
4617        break;
4618    case 1:
4619        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4620            u32 *destreg;
4621            u32 srcval;
4622            u32 res_lo,res_hi;
4623
4624            destreg = DECODE_RM_LONG_REGISTER(rh);
4625            DECODE_PRINTF(",");
4626            srcoffset = decode_rm01_address(rl);
4627            srcval = fetch_data_long(srcoffset);
4628            imm = fetch_byte_imm();
4629            DECODE_PRINTF2(",%d\n", (s32)imm);
4630            TRACE_AND_STEP();
4631            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4632            if (res_hi != 0) {
4633                SET_FLAG(F_CF);
4634                SET_FLAG(F_OF);
4635            } else {
4636                CLEAR_FLAG(F_CF);
4637                CLEAR_FLAG(F_OF);
4638            }
4639            *destreg = (u32)res_lo;
4640        } else {
4641            u16 *destreg;
4642            u16 srcval;
4643            u32 res;
4644
4645            destreg = DECODE_RM_WORD_REGISTER(rh);
4646            DECODE_PRINTF(",");
4647            srcoffset = decode_rm01_address(rl);
4648            srcval = fetch_data_word(srcoffset);
4649            imm = fetch_byte_imm();
4650            DECODE_PRINTF2(",%d\n", (s32)imm);
4651            TRACE_AND_STEP();
4652            res = (s16)srcval * (s16)imm;
4653            if (res > 0xFFFF) {
4654                SET_FLAG(F_CF);
4655                SET_FLAG(F_OF);
4656            } else {
4657                CLEAR_FLAG(F_CF);
4658                CLEAR_FLAG(F_OF);
4659            }
4660            *destreg = (u16)res;
4661        }
4662        break;
4663    case 2:
4664        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4665            u32 *destreg;
4666            u32 srcval;
4667            u32 res_lo,res_hi;
4668
4669            destreg = DECODE_RM_LONG_REGISTER(rh);
4670            DECODE_PRINTF(",");
4671            srcoffset = decode_rm10_address(rl);
4672            srcval = fetch_data_long(srcoffset);
4673            imm = fetch_byte_imm();
4674            DECODE_PRINTF2(",%d\n", (s32)imm);
4675            TRACE_AND_STEP();
4676            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4677            if (res_hi != 0) {
4678                SET_FLAG(F_CF);
4679                SET_FLAG(F_OF);
4680            } else {
4681                CLEAR_FLAG(F_CF);
4682                CLEAR_FLAG(F_OF);
4683            }
4684            *destreg = (u32)res_lo;
4685        } else {
4686            u16 *destreg;
4687            u16 srcval;
4688            u32 res;
4689
4690            destreg = DECODE_RM_WORD_REGISTER(rh);
4691            DECODE_PRINTF(",");
4692            srcoffset = decode_rm10_address(rl);
4693            srcval = fetch_data_word(srcoffset);
4694            imm = fetch_byte_imm();
4695            DECODE_PRINTF2(",%d\n", (s32)imm);
4696            TRACE_AND_STEP();
4697            res = (s16)srcval * (s16)imm;
4698            if (res > 0xFFFF) {
4699                SET_FLAG(F_CF);
4700                SET_FLAG(F_OF);
4701            } else {
4702                CLEAR_FLAG(F_CF);
4703                CLEAR_FLAG(F_OF);
4704            }
4705            *destreg = (u16)res;
4706        }
4707        break;
4708    case 3:                     /* register to register */
4709        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4710            u32 *destreg,*srcreg;
4711            u32 res_lo,res_hi;
4712
4713            destreg = DECODE_RM_LONG_REGISTER(rh);
4714            DECODE_PRINTF(",");
4715            srcreg = DECODE_RM_LONG_REGISTER(rl);
4716            imm = fetch_byte_imm();
4717            DECODE_PRINTF2(",%d\n", (s32)imm);
4718            TRACE_AND_STEP();
4719            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4720            if (res_hi != 0) {
4721                SET_FLAG(F_CF);
4722                SET_FLAG(F_OF);
4723            } else {
4724                CLEAR_FLAG(F_CF);
4725                CLEAR_FLAG(F_OF);
4726            }
4727            *destreg = (u32)res_lo;
4728        } else {
4729            u16 *destreg,*srcreg;
4730            u32 res;
4731
4732            destreg = DECODE_RM_WORD_REGISTER(rh);
4733            DECODE_PRINTF(",");
4734            srcreg = DECODE_RM_WORD_REGISTER(rl);
4735            imm = fetch_byte_imm();
4736            DECODE_PRINTF2(",%d\n", (s32)imm);
4737            res = (s16)*srcreg * (s16)imm;
4738            if (res > 0xFFFF) {
4739                SET_FLAG(F_CF);
4740                SET_FLAG(F_OF);
4741            } else {
4742                CLEAR_FLAG(F_CF);
4743                CLEAR_FLAG(F_OF);
4744            }
4745            *destreg = (u16)res;
4746        }
4747        break;
4748    }
4749    DECODE_CLEAR_SEGOVR();
4750    END_OF_INSTR();
4751}
4752
4753/****************************************************************************
4754REMARKS:
4755Handles opcode 0x6c
4756****************************************************************************/
4757static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4758{
4759    START_OF_INSTR();
4760    DECODE_PRINTF("INSB\n");
4761    ins(1);
4762    TRACE_AND_STEP();
4763    DECODE_CLEAR_SEGOVR();
4764    END_OF_INSTR();
4765}
4766
4767/****************************************************************************
4768REMARKS:
4769Handles opcode 0x6d
4770****************************************************************************/
4771static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4772{
4773    START_OF_INSTR();
4774    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4775        DECODE_PRINTF("INSD\n");
4776        ins(4);
4777    } else {
4778        DECODE_PRINTF("INSW\n");
4779        ins(2);
4780    }
4781    TRACE_AND_STEP();
4782    DECODE_CLEAR_SEGOVR();
4783    END_OF_INSTR();
4784}
4785
4786/****************************************************************************
4787REMARKS:
4788Handles opcode 0x6e
4789****************************************************************************/
4790static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4791{
4792    START_OF_INSTR();
4793    DECODE_PRINTF("OUTSB\n");
4794    outs(1);
4795    TRACE_AND_STEP();
4796    DECODE_CLEAR_SEGOVR();
4797    END_OF_INSTR();
4798}
4799
4800/****************************************************************************
4801REMARKS:
4802Handles opcode 0x6f
4803****************************************************************************/
4804static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4805{
4806    START_OF_INSTR();
4807    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4808        DECODE_PRINTF("OUTSD\n");
4809        outs(4);
4810    } else {
4811        DECODE_PRINTF("OUTSW\n");
4812        outs(2);
4813    }
4814    TRACE_AND_STEP();
4815    DECODE_CLEAR_SEGOVR();
4816    END_OF_INSTR();
4817}
4818
4819/****************************************************************************
4820REMARKS:
4821Handles opcode 0x70
4822****************************************************************************/
4823static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4824{
4825    s8 offset;
4826    u16 target;
4827
4828    /* jump to byte offset if overflow flag is set */
4829    START_OF_INSTR();
4830    DECODE_PRINTF("JO\t");
4831    offset = (s8)fetch_byte_imm();
4832    target = (u16)(M.x86.R_IP + (s16)offset);
4833    DECODE_PRINTF2("%x\n", target);
4834    TRACE_AND_STEP();
4835    if (ACCESS_FLAG(F_OF))
4836        M.x86.R_IP = target;
4837    DECODE_CLEAR_SEGOVR();
4838    END_OF_INSTR();
4839}
4840
4841/****************************************************************************
4842REMARKS:
4843Handles opcode 0x71
4844****************************************************************************/
4845static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4846{
4847    s8 offset;
4848    u16 target;
4849
4850    /* jump to byte offset if overflow is not set */
4851    START_OF_INSTR();
4852    DECODE_PRINTF("JNO\t");
4853    offset = (s8)fetch_byte_imm();
4854    target = (u16)(M.x86.R_IP + (s16)offset);
4855    DECODE_PRINTF2("%x\n", target);
4856    TRACE_AND_STEP();
4857    if (!ACCESS_FLAG(F_OF))
4858        M.x86.R_IP = target;
4859    DECODE_CLEAR_SEGOVR();
4860    END_OF_INSTR();
4861}
4862
4863/****************************************************************************
4864REMARKS:
4865Handles opcode 0x72
4866****************************************************************************/
4867static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4868{
4869    s8 offset;
4870    u16 target;
4871
4872    /* jump to byte offset if carry flag is set. */
4873    START_OF_INSTR();
4874    DECODE_PRINTF("JB\t");
4875    offset = (s8)fetch_byte_imm();
4876    target = (u16)(M.x86.R_IP + (s16)offset);
4877    DECODE_PRINTF2("%x\n", target);
4878    TRACE_AND_STEP();
4879    if (ACCESS_FLAG(F_CF))
4880        M.x86.R_IP = target;
4881    DECODE_CLEAR_SEGOVR();
4882    END_OF_INSTR();
4883}
4884
4885/****************************************************************************
4886REMARKS:
4887Handles opcode 0x73
4888****************************************************************************/
4889static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4890{
4891    s8 offset;
4892    u16 target;
4893
4894    /* jump to byte offset if carry flag is clear. */
4895    START_OF_INSTR();
4896    DECODE_PRINTF("JNB\t");
4897    offset = (s8)fetch_byte_imm();
4898    target = (u16)(M.x86.R_IP + (s16)offset);
4899    DECODE_PRINTF2("%x\n", target);
4900    TRACE_AND_STEP();
4901    if (!ACCESS_FLAG(F_CF))
4902        M.x86.R_IP = target;
4903    DECODE_CLEAR_SEGOVR();
4904    END_OF_INSTR();
4905}
4906
4907/****************************************************************************
4908REMARKS:
4909Handles opcode 0x74
4910****************************************************************************/
4911static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4912{
4913    s8 offset;
4914    u16 target;
4915
4916    /* jump to byte offset if zero flag is set. */
4917    START_OF_INSTR();
4918    DECODE_PRINTF("JZ\t");
4919    offset = (s8)fetch_byte_imm();
4920    target = (u16)(M.x86.R_IP + (s16)offset);
4921    DECODE_PRINTF2("%x\n", target);
4922    TRACE_AND_STEP();
4923    if (ACCESS_FLAG(F_ZF))
4924        M.x86.R_IP = target;
4925    DECODE_CLEAR_SEGOVR();
4926    END_OF_INSTR();
4927}
4928
4929/****************************************************************************
4930REMARKS:
4931Handles opcode 0x75
4932****************************************************************************/
4933static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4934{
4935    s8 offset;
4936    u16 target;
4937
4938    /* jump to byte offset if zero flag is clear. */
4939    START_OF_INSTR();
4940    DECODE_PRINTF("JNZ\t");
4941    offset = (s8)fetch_byte_imm();
4942    target = (u16)(M.x86.R_IP + (s16)offset);
4943    DECODE_PRINTF2("%x\n", target);
4944    TRACE_AND_STEP();
4945    if (!ACCESS_FLAG(F_ZF))
4946        M.x86.R_IP = target;
4947    DECODE_CLEAR_SEGOVR();
4948    END_OF_INSTR();
4949}
4950
4951/****************************************************************************
4952REMARKS:
4953Handles opcode 0x76
4954****************************************************************************/
4955static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4956{
4957    s8 offset;
4958    u16 target;
4959
4960    /* jump to byte offset if carry flag is set or if the zero
4961       flag is set. */
4962    START_OF_INSTR();
4963    DECODE_PRINTF("JBE\t");
4964    offset = (s8)fetch_byte_imm();
4965    target = (u16)(M.x86.R_IP + (s16)offset);
4966    DECODE_PRINTF2("%x\n", target);
4967    TRACE_AND_STEP();
4968    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4969        M.x86.R_IP = target;
4970    DECODE_CLEAR_SEGOVR();
4971    END_OF_INSTR();
4972}
4973
4974/****************************************************************************
4975REMARKS:
4976Handles opcode 0x77
4977****************************************************************************/
4978static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4979{
4980    s8 offset;
4981    u16 target;
4982
4983    /* jump to byte offset if carry flag is clear and if the zero
4984       flag is clear */
4985    START_OF_INSTR();
4986    DECODE_PRINTF("JNBE\t");
4987    offset = (s8)fetch_byte_imm();
4988    target = (u16)(M.x86.R_IP + (s16)offset);
4989    DECODE_PRINTF2("%x\n", target);
4990    TRACE_AND_STEP();
4991    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4992        M.x86.R_IP = target;
4993    DECODE_CLEAR_SEGOVR();
4994    END_OF_INSTR();
4995}
4996
4997/****************************************************************************
4998REMARKS:
4999Handles opcode 0x78
5000****************************************************************************/
5001static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5002{
5003    s8 offset;
5004    u16 target;
5005
5006    /* jump to byte offset if sign flag is set */
5007    START_OF_INSTR();
5008    DECODE_PRINTF("JS\t");
5009    offset = (s8)fetch_byte_imm();
5010    target = (u16)(M.x86.R_IP + (s16)offset);
5011    DECODE_PRINTF2("%x\n", target);
5012    TRACE_AND_STEP();
5013    if (ACCESS_FLAG(F_SF))
5014        M.x86.R_IP = target;
5015    DECODE_CLEAR_SEGOVR();
5016    END_OF_INSTR();
5017}
5018
5019/****************************************************************************
5020REMARKS:
5021Handles opcode 0x79
5022****************************************************************************/
5023static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5024{
5025    s8 offset;
5026    u16 target;
5027
5028    /* jump to byte offset if sign flag is clear */
5029    START_OF_INSTR();
5030    DECODE_PRINTF("JNS\t");
5031    offset = (s8)fetch_byte_imm();
5032    target = (u16)(M.x86.R_IP + (s16)offset);
5033    DECODE_PRINTF2("%x\n", target);
5034    TRACE_AND_STEP();
5035    if (!ACCESS_FLAG(F_SF))
5036        M.x86.R_IP = target;
5037    DECODE_CLEAR_SEGOVR();
5038    END_OF_INSTR();
5039}
5040
5041/****************************************************************************
5042REMARKS:
5043Handles opcode 0x7a
5044****************************************************************************/
5045static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5046{
5047    s8 offset;
5048    u16 target;
5049
5050    /* jump to byte offset if parity flag is set (even parity) */
5051    START_OF_INSTR();
5052    DECODE_PRINTF("JP\t");
5053    offset = (s8)fetch_byte_imm();
5054    target = (u16)(M.x86.R_IP + (s16)offset);
5055    DECODE_PRINTF2("%x\n", target);
5056    TRACE_AND_STEP();
5057    if (ACCESS_FLAG(F_PF))
5058        M.x86.R_IP = target;
5059    DECODE_CLEAR_SEGOVR();
5060    END_OF_INSTR();
5061}
5062
5063/****************************************************************************
5064REMARKS:
5065Handles opcode 0x7b
5066****************************************************************************/
5067static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5068{
5069    s8 offset;
5070    u16 target;
5071
5072    /* jump to byte offset if parity flag is clear (odd parity) */
5073    START_OF_INSTR();
5074    DECODE_PRINTF("JNP\t");
5075    offset = (s8)fetch_byte_imm();
5076    target = (u16)(M.x86.R_IP + (s16)offset);
5077    DECODE_PRINTF2("%x\n", target);
5078    TRACE_AND_STEP();
5079    if (!ACCESS_FLAG(F_PF))
5080        M.x86.R_IP = target;
5081    DECODE_CLEAR_SEGOVR();
5082    END_OF_INSTR();
5083}
5084
5085/****************************************************************************
5086REMARKS:
5087Handles opcode 0x7c
5088****************************************************************************/
5089static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5090{
5091    s8 offset;
5092    u16 target;
5093    int sf, of;
5094
5095    /* jump to byte offset if sign flag not equal to overflow flag. */
5096    START_OF_INSTR();
5097    DECODE_PRINTF("JL\t");
5098    offset = (s8)fetch_byte_imm();
5099    target = (u16)(M.x86.R_IP + (s16)offset);
5100    DECODE_PRINTF2("%x\n", target);
5101    TRACE_AND_STEP();
5102    sf = ACCESS_FLAG(F_SF) != 0;
5103    of = ACCESS_FLAG(F_OF) != 0;
5104    if (sf ^ of)
5105        M.x86.R_IP = target;
5106    DECODE_CLEAR_SEGOVR();
5107    END_OF_INSTR();
5108}
5109
5110/****************************************************************************
5111REMARKS:
5112Handles opcode 0x7d
5113****************************************************************************/
5114static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5115{
5116    s8 offset;
5117    u16 target;
5118    int sf, of;
5119
5120    /* jump to byte offset if sign flag not equal to overflow flag. */
5121    START_OF_INSTR();
5122    DECODE_PRINTF("JNL\t");
5123    offset = (s8)fetch_byte_imm();
5124    target = (u16)(M.x86.R_IP + (s16)offset);
5125    DECODE_PRINTF2("%x\n", target);
5126    TRACE_AND_STEP();
5127    sf = ACCESS_FLAG(F_SF) != 0;
5128    of = ACCESS_FLAG(F_OF) != 0;
5129    /* note: inverse of above, but using == instead of xor. */
5130    if (sf == of)
5131        M.x86.R_IP = target;
5132    DECODE_CLEAR_SEGOVR();
5133    END_OF_INSTR();
5134}
5135
5136/****************************************************************************
5137REMARKS:
5138Handles opcode 0x7e
5139****************************************************************************/
5140static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5141{
5142    s8 offset;
5143    u16 target;
5144    int sf, of;
5145
5146    /* jump to byte offset if sign flag not equal to overflow flag
5147       or the zero flag is set */
5148    START_OF_INSTR();
5149    DECODE_PRINTF("JLE\t");
5150    offset = (s8)fetch_byte_imm();
5151    target = (u16)(M.x86.R_IP + (s16)offset);
5152    DECODE_PRINTF2("%x\n", target);
5153    TRACE_AND_STEP();
5154    sf = ACCESS_FLAG(F_SF) != 0;
5155    of = ACCESS_FLAG(F_OF) != 0;
5156    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5157        M.x86.R_IP = target;
5158    DECODE_CLEAR_SEGOVR();
5159    END_OF_INSTR();
5160}
5161
5162/****************************************************************************
5163REMARKS:
5164Handles opcode 0x7f
5165****************************************************************************/
5166static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5167{
5168    s8 offset;
5169    u16 target;
5170    int sf, of;
5171
5172    /* jump to byte offset if sign flag equal to overflow flag.
5173       and the zero flag is clear */
5174    START_OF_INSTR();
5175    DECODE_PRINTF("JNLE\t");
5176    offset = (s8)fetch_byte_imm();
5177    target = (u16)(M.x86.R_IP + (s16)offset);
5178    DECODE_PRINTF2("%x\n", target);
5179    TRACE_AND_STEP();
5180    sf = ACCESS_FLAG(F_SF) != 0;
5181    of = ACCESS_FLAG(F_OF) != 0;
5182    if ((sf == of) && !ACCESS_FLAG(F_ZF))
5183        M.x86.R_IP = target;
5184    DECODE_CLEAR_SEGOVR();
5185    END_OF_INSTR();
5186}
5187
5188static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5189{
5190    add_byte,           /* 00 */
5191    or_byte,            /* 01 */
5192    adc_byte,           /* 02 */
5193    sbb_byte,           /* 03 */
5194    and_byte,           /* 04 */
5195    sub_byte,           /* 05 */
5196    xor_byte,           /* 06 */
5197    cmp_byte,           /* 07 */
5198};
5199
5200/****************************************************************************
5201REMARKS:
5202Handles opcode 0x80
5203****************************************************************************/
5204static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5205{
5206    int mod, rl, rh;
5207    u8 *destreg;
5208    uint destoffset;
5209    u8 imm;
5210    u8 destval;
5211
5212    /*
5213     * Weirdo special case instruction format.  Part of the opcode
5214     * held below in "RH".  Doubly nested case would result, except
5215     * that the decoded instruction
5216     */
5217    START_OF_INSTR();
5218    FETCH_DECODE_MODRM(mod, rh, rl);
5219#ifdef DEBUG
5220    if (DEBUG_DECODE()) {
5221        /* XXX DECODE_PRINTF may be changed to something more
5222           general, so that it is important to leave the strings
5223           in the same format, even though the result is that the
5224           above test is done twice. */
5225
5226        switch (rh) {
5227        case 0:
5228            DECODE_PRINTF("ADD\t");
5229            break;
5230        case 1:
5231            DECODE_PRINTF("OR\t");
5232            break;
5233        case 2:
5234            DECODE_PRINTF("ADC\t");
5235            break;
5236        case 3:
5237            DECODE_PRINTF("SBB\t");
5238            break;
5239        case 4:
5240            DECODE_PRINTF("AND\t");
5241            break;
5242        case 5:
5243            DECODE_PRINTF("SUB\t");
5244            break;
5245        case 6:
5246            DECODE_PRINTF("XOR\t");
5247            break;
5248        case 7:
5249            DECODE_PRINTF("CMP\t");
5250            break;
5251        }
5252    }
5253#endif
5254    /* know operation, decode the mod byte to find the addressing
5255       mode. */
5256    switch (mod) {
5257    case 0:
5258        DECODE_PRINTF("BYTE PTR ");
5259        destoffset = decode_rm00_address(rl);
5260        DECODE_PRINTF(",");
5261        destval = fetch_data_byte(destoffset);
5262        imm = fetch_byte_imm();
5263        DECODE_PRINTF2("%x\n", imm);
5264        TRACE_AND_STEP();
5265        destval = (*opc80_byte_operation[rh]) (destval, imm);
5266        if (rh != 7)
5267            store_data_byte(destoffset, destval);
5268        break;
5269    case 1:
5270        DECODE_PRINTF("BYTE PTR ");
5271        destoffset = decode_rm01_address(rl);
5272        DECODE_PRINTF(",");
5273        destval = fetch_data_byte(destoffset);
5274        imm = fetch_byte_imm();
5275        DECODE_PRINTF2("%x\n", imm);
5276        TRACE_AND_STEP();
5277        destval = (*opc80_byte_operation[rh]) (destval, imm);
5278        if (rh != 7)
5279            store_data_byte(destoffset, destval);
5280        break;
5281    case 2:
5282        DECODE_PRINTF("BYTE PTR ");
5283        destoffset = decode_rm10_address(rl);
5284        DECODE_PRINTF(",");
5285        destval = fetch_data_byte(destoffset);
5286        imm = fetch_byte_imm();
5287        DECODE_PRINTF2("%x\n", imm);
5288        TRACE_AND_STEP();
5289        destval = (*opc80_byte_operation[rh]) (destval, imm);
5290        if (rh != 7)
5291            store_data_byte(destoffset, destval);
5292        break;
5293    case 3:                     /* register to register */
5294        destreg = DECODE_RM_BYTE_REGISTER(rl);
5295        DECODE_PRINTF(",");
5296        imm = fetch_byte_imm();
5297        DECODE_PRINTF2("%x\n", imm);
5298        TRACE_AND_STEP();
5299        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5300        if (rh != 7)
5301            *destreg = destval;
5302        break;
5303    }
5304    DECODE_CLEAR_SEGOVR();
5305    END_OF_INSTR();
5306}
5307
5308static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5309{
5310    add_word,           /*00 */
5311    or_word,            /*01 */
5312    adc_word,           /*02 */
5313    sbb_word,           /*03 */
5314    and_word,           /*04 */
5315    sub_word,           /*05 */
5316    xor_word,           /*06 */
5317    cmp_word,           /*07 */
5318};
5319
5320static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5321{
5322    add_long,           /*00 */
5323    or_long,            /*01 */
5324    adc_long,           /*02 */
5325    sbb_long,           /*03 */
5326    and_long,           /*04 */
5327    sub_long,           /*05 */
5328    xor_long,           /*06 */
5329    cmp_long,           /*07 */
5330};
5331
5332/****************************************************************************
5333REMARKS:
5334Handles opcode 0x81
5335****************************************************************************/
5336static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5337{
5338    int mod, rl, rh;
5339    uint destoffset;
5340
5341    /*
5342     * Weirdo special case instruction format.  Part of the opcode
5343     * held below in "RH".  Doubly nested case would result, except
5344     * that the decoded instruction
5345     */
5346    START_OF_INSTR();
5347    FETCH_DECODE_MODRM(mod, rh, rl);
5348#ifdef DEBUG
5349    if (DEBUG_DECODE()) {
5350        /* XXX DECODE_PRINTF may be changed to something more
5351           general, so that it is important to leave the strings
5352           in the same format, even though the result is that the
5353           above test is done twice. */
5354
5355        switch (rh) {
5356        case 0:
5357            DECODE_PRINTF("ADD\t");
5358            break;
5359        case 1:
5360            DECODE_PRINTF("OR\t");
5361            break;
5362        case 2:
5363            DECODE_PRINTF("ADC\t");
5364            break;
5365        case 3:
5366            DECODE_PRINTF("SBB\t");
5367            break;
5368        case 4:
5369            DECODE_PRINTF("AND\t");
5370            break;
5371        case 5:
5372            DECODE_PRINTF("SUB\t");
5373            break;
5374        case 6:
5375            DECODE_PRINTF("XOR\t");
5376            break;
5377        case 7:
5378            DECODE_PRINTF("CMP\t");
5379            break;
5380        }
5381    }
5382#endif
5383    /*
5384     * Know operation, decode the mod byte to find the addressing
5385     * mode.
5386     */
5387    switch (mod) {
5388    case 0:
5389        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5390            u32 destval,imm;
5391
5392            DECODE_PRINTF("DWORD PTR ");
5393            destoffset = decode_rm00_address(rl);
5394            DECODE_PRINTF(",");
5395            destval = fetch_data_long(destoffset);
5396            imm = fetch_long_imm();
5397            DECODE_PRINTF2("%x\n", imm);
5398            TRACE_AND_STEP();
5399            destval = (*opc81_long_operation[rh]) (destval, imm);
5400            if (rh != 7)
5401                store_data_long(destoffset, destval);
5402        } else {
5403            u16 destval,imm;
5404
5405            DECODE_PRINTF("WORD PTR ");
5406            destoffset = decode_rm00_address(rl);
5407            DECODE_PRINTF(",");
5408            destval = fetch_data_word(destoffset);
5409            imm = fetch_word_imm();
5410            DECODE_PRINTF2("%x\n", imm);
5411            TRACE_AND_STEP();
5412            destval = (*opc81_word_operation[rh]) (destval, imm);
5413            if (rh != 7)
5414                store_data_word(destoffset, destval);
5415        }
5416        break;
5417    case 1:
5418        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5419            u32 destval,imm;
5420
5421            DECODE_PRINTF("DWORD PTR ");
5422            destoffset = decode_rm01_address(rl);
5423            DECODE_PRINTF(",");
5424            destval = fetch_data_long(destoffset);
5425            imm = fetch_long_imm();
5426            DECODE_PRINTF2("%x\n", imm);
5427            TRACE_AND_STEP();
5428            destval = (*opc81_long_operation[rh]) (destval, imm);
5429            if (rh != 7)
5430                store_data_long(destoffset, destval);
5431        } else {
5432            u16 destval,imm;
5433
5434            DECODE_PRINTF("WORD PTR ");
5435            destoffset = decode_rm01_address(rl);
5436            DECODE_PRINTF(",");
5437            destval = fetch_data_word(destoffset);
5438            imm = fetch_word_imm();
5439            DECODE_PRINTF2("%x\n", imm);
5440            TRACE_AND_STEP();
5441            destval = (*opc81_word_operation[rh]) (destval, imm);
5442            if (rh != 7)
5443                store_data_word(destoffset, destval);
5444        }
5445        break;
5446    case 2:
5447        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5448            u32 destval,imm;
5449
5450            DECODE_PRINTF("DWORD PTR ");
5451            destoffset = decode_rm10_address(rl);
5452            DECODE_PRINTF(",");
5453            destval = fetch_data_long(destoffset);
5454            imm = fetch_long_imm();
5455            DECODE_PRINTF2("%x\n", imm);
5456            TRACE_AND_STEP();
5457            destval = (*opc81_long_operation[rh]) (destval, imm);
5458            if (rh != 7)
5459                store_data_long(destoffset, destval);
5460        } else {
5461            u16 destval,imm;
5462
5463            DECODE_PRINTF("WORD PTR ");
5464            destoffset = decode_rm10_address(rl);
5465            DECODE_PRINTF(",");
5466            destval = fetch_data_word(destoffset);
5467            imm = fetch_word_imm();
5468            DECODE_PRINTF2("%x\n", imm);
5469            TRACE_AND_STEP();
5470            destval = (*opc81_word_operation[rh]) (destval, imm);
5471            if (rh != 7)
5472                store_data_word(destoffset, destval);
5473        }
5474        break;
5475    case 3:                     /* register to register */
5476        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5477            u32 *destreg;
5478            u32 destval,imm;
5479
5480            destreg = DECODE_RM_LONG_REGISTER(rl);
5481            DECODE_PRINTF(",");
5482            imm = fetch_long_imm();
5483            DECODE_PRINTF2("%x\n", imm);
5484            TRACE_AND_STEP();
5485            destval = (*opc81_long_operation[rh]) (*destreg, imm);
5486            if (rh != 7)
5487                *destreg = destval;
5488        } else {
5489            u16 *destreg;
5490            u16 destval,imm;
5491
5492            destreg = DECODE_RM_WORD_REGISTER(rl);
5493            DECODE_PRINTF(",");
5494            imm = fetch_word_imm();
5495            DECODE_PRINTF2("%x\n", imm);
5496            TRACE_AND_STEP();
5497            destval = (*opc81_word_operation[rh]) (*destreg, imm);
5498            if (rh != 7)
5499                *destreg = destval;
5500        }
5501        break;
5502    }
5503    DECODE_CLEAR_SEGOVR();
5504    END_OF_INSTR();
5505}
5506
5507static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5508{
5509    add_byte,           /*00 */
5510    or_byte,            /*01 *//*YYY UNUSED ???? */
5511    adc_byte,           /*02 */
5512    sbb_byte,           /*03 */
5513    and_byte,           /*04 *//*YYY UNUSED ???? */
5514    sub_byte,           /*05 */
5515    xor_byte,           /*06 *//*YYY UNUSED ???? */
5516    cmp_byte,           /*07 */
5517};
5518
5519/****************************************************************************
5520REMARKS:
5521Handles opcode 0x82
5522****************************************************************************/
5523static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5524{
5525    int mod, rl, rh;
5526    u8 *destreg;
5527    uint destoffset;
5528    u8 imm;
5529    u8 destval;
5530
5531    /*
5532     * Weirdo special case instruction format.  Part of the opcode
5533     * held below in "RH".  Doubly nested case would result, except
5534     * that the decoded instruction Similar to opcode 81, except that
5535     * the immediate byte is sign extended to a word length.
5536     */
5537    START_OF_INSTR();
5538    FETCH_DECODE_MODRM(mod, rh, rl);
5539#ifdef DEBUG
5540    if (DEBUG_DECODE()) {
5541        /* XXX DECODE_PRINTF may be changed to something more
5542           general, so that it is important to leave the strings
5543           in the same format, even though the result is that the
5544           above test is done twice. */
5545        switch (rh) {
5546        case 0:
5547            DECODE_PRINTF("ADD\t");
5548            break;
5549        case 1:
5550            DECODE_PRINTF("OR\t");
5551            break;
5552        case 2:
5553            DECODE_PRINTF("ADC\t");
5554            break;
5555        case 3:
5556            DECODE_PRINTF("SBB\t");
5557            break;
5558        case 4:
5559            DECODE_PRINTF("AND\t");
5560            break;
5561        case 5:
5562            DECODE_PRINTF("SUB\t");
5563            break;
5564        case 6:
5565            DECODE_PRINTF("XOR\t");
5566            break;
5567        case 7:
5568            DECODE_PRINTF("CMP\t");
5569            break;
5570        }
5571    }
5572#endif
5573    /* know operation, decode the mod byte to find the addressing
5574       mode. */
5575    switch (mod) {
5576    case 0:
5577        DECODE_PRINTF("BYTE PTR ");
5578        destoffset = decode_rm00_address(rl);
5579        destval = fetch_data_byte(destoffset);
5580        imm = fetch_byte_imm();
5581        DECODE_PRINTF2(",%x\n", imm);
5582        TRACE_AND_STEP();
5583        destval = (*opc82_byte_operation[rh]) (destval, imm);
5584        if (rh != 7)
5585            store_data_byte(destoffset, destval);
5586        break;
5587    case 1:
5588        DECODE_PRINTF("BYTE PTR ");
5589        destoffset = decode_rm01_address(rl);
5590        destval = fetch_data_byte(destoffset);
5591        imm = fetch_byte_imm();
5592        DECODE_PRINTF2(",%x\n", imm);
5593        TRACE_AND_STEP();
5594        destval = (*opc82_byte_operation[rh]) (destval, imm);
5595        if (rh != 7)
5596            store_data_byte(destoffset, destval);
5597        break;
5598    case 2:
5599        DECODE_PRINTF("BYTE PTR ");
5600        destoffset = decode_rm10_address(rl);
5601        destval = fetch_data_byte(destoffset);
5602        imm = fetch_byte_imm();
5603        DECODE_PRINTF2(",%x\n", imm);
5604        TRACE_AND_STEP();
5605        destval = (*opc82_byte_operation[rh]) (destval, imm);
5606        if (rh != 7)
5607            store_data_byte(destoffset, destval);
5608        break;
5609    case 3:                     /* register to register */
5610        destreg = DECODE_RM_BYTE_REGISTER(rl);
5611        imm = fetch_byte_imm();
5612        DECODE_PRINTF2(",%x\n", imm);
5613        TRACE_AND_STEP();
5614        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5615        if (rh != 7)
5616            *destreg = destval;
5617        break;
5618    }
5619    DECODE_CLEAR_SEGOVR();
5620    END_OF_INSTR();
5621}
5622
5623static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5624{
5625    add_word,           /*00 */
5626    or_word,            /*01 *//*YYY UNUSED ???? */
5627    adc_word,           /*02 */
5628    sbb_word,           /*03 */
5629    and_word,           /*04 *//*YYY UNUSED ???? */
5630    sub_word,           /*05 */
5631    xor_word,           /*06 *//*YYY UNUSED ???? */
5632    cmp_word,           /*07 */
5633};
5634
5635static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5636{
5637    add_long,           /*00 */
5638    or_long,            /*01 *//*YYY UNUSED ???? */
5639    adc_long,           /*02 */
5640    sbb_long,           /*03 */
5641    and_long,           /*04 *//*YYY UNUSED ???? */
5642    sub_long,           /*05 */
5643    xor_long,           /*06 *//*YYY UNUSED ???? */
5644    cmp_long,           /*07 */
5645};
5646
5647/****************************************************************************
5648REMARKS:
5649Handles opcode 0x83
5650****************************************************************************/
5651static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5652{
5653    int mod, rl, rh;
5654    uint destoffset;
5655
5656    /*
5657     * Weirdo special case instruction format.  Part of the opcode
5658     * held below in "RH".  Doubly nested case would result, except
5659     * that the decoded instruction Similar to opcode 81, except that
5660     * the immediate byte is sign extended to a word length.
5661     */
5662    START_OF_INSTR();
5663    FETCH_DECODE_MODRM(mod, rh, rl);
5664#ifdef DEBUG
5665    if (DEBUG_DECODE()) {
5666        /* XXX DECODE_PRINTF may be changed to something more
5667           general, so that it is important to leave the strings
5668           in the same format, even though the result is that the
5669           above test is done twice. */
5670       switch (rh) {
5671        case 0:
5672            DECODE_PRINTF("ADD\t");
5673            break;
5674        case 1:
5675            DECODE_PRINTF("OR\t");
5676            break;
5677        case 2:
5678            DECODE_PRINTF("ADC\t");
5679            break;
5680        case 3:
5681            DECODE_PRINTF("SBB\t");
5682            break;
5683        case 4:
5684            DECODE_PRINTF("AND\t");
5685            break;
5686        case 5:
5687            DECODE_PRINTF("SUB\t");
5688            break;
5689        case 6:
5690            DECODE_PRINTF("XOR\t");
5691            break;
5692        case 7:
5693            DECODE_PRINTF("CMP\t");
5694            break;
5695        }
5696    }
5697#endif
5698    /* know operation, decode the mod byte to find the addressing
5699       mode. */
5700    switch (mod) {
5701    case 0:
5702        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5703            u32 destval,imm;
5704
5705            DECODE_PRINTF("DWORD PTR ");
5706            destoffset = decode_rm00_address(rl);
5707            destval = fetch_data_long(destoffset);
5708            imm = (s8) fetch_byte_imm();
5709            DECODE_PRINTF2(",%x\n", imm);
5710            TRACE_AND_STEP();
5711            destval = (*opc83_long_operation[rh]) (destval, imm);
5712            if (rh != 7)
5713                store_data_long(destoffset, destval);
5714        } else {
5715            u16 destval,imm;
5716
5717            DECODE_PRINTF("WORD PTR ");
5718            destoffset = decode_rm00_address(rl);
5719            destval = fetch_data_word(destoffset);
5720            imm = (s8) fetch_byte_imm();
5721            DECODE_PRINTF2(",%x\n", imm);
5722            TRACE_AND_STEP();
5723            destval = (*opc83_word_operation[rh]) (destval, imm);
5724            if (rh != 7)
5725                store_data_word(destoffset, destval);
5726        }
5727        break;
5728    case 1:
5729        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5730            u32 destval,imm;
5731
5732            DECODE_PRINTF("DWORD PTR ");
5733            destoffset = decode_rm01_address(rl);
5734            destval = fetch_data_long(destoffset);
5735            imm = (s8) fetch_byte_imm();
5736            DECODE_PRINTF2(",%x\n", imm);
5737            TRACE_AND_STEP();
5738            destval = (*opc83_long_operation[rh]) (destval, imm);
5739            if (rh != 7)
5740                store_data_long(destoffset, destval);
5741        } else {
5742            u16 destval,imm;
5743
5744            DECODE_PRINTF("WORD PTR ");
5745            destoffset = decode_rm01_address(rl);
5746            destval = fetch_data_word(destoffset);
5747            imm = (s8) fetch_byte_imm();
5748            DECODE_PRINTF2(",%x\n", imm);
5749            TRACE_AND_STEP();
5750            destval = (*opc83_word_operation[rh]) (destval, imm);
5751            if (rh != 7)
5752                store_data_word(destoffset, destval);
5753        }
5754        break;
5755    case 2:
5756        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5757            u32 destval,imm;
5758
5759            DECODE_PRINTF("DWORD PTR ");
5760            destoffset = decode_rm10_address(rl);
5761            destval = fetch_data_long(destoffset);
5762            imm = (s8) fetch_byte_imm();
5763            DECODE_PRINTF2(",%x\n", imm);
5764            TRACE_AND_STEP();
5765            destval = (*opc83_long_operation[rh]) (destval, imm);
5766            if (rh != 7)
5767                store_data_long(destoffset, destval);
5768        } else {
5769            u16 destval,imm;
5770
5771            DECODE_PRINTF("WORD PTR ");
5772            destoffset = decode_rm10_address(rl);
5773            destval = fetch_data_word(destoffset);
5774            imm = (s8) fetch_byte_imm();
5775            DECODE_PRINTF2(",%x\n", imm);
5776            TRACE_AND_STEP();
5777            destval = (*opc83_word_operation[rh]) (destval, imm);
5778            if (rh != 7)
5779                store_data_word(destoffset, destval);
5780        }
5781        break;
5782    case 3:                     /* register to register */
5783        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5784            u32 *destreg;
5785            u32 destval,imm;
5786
5787            destreg = DECODE_RM_LONG_REGISTER(rl);
5788            imm = (s8) fetch_byte_imm();
5789            DECODE_PRINTF2(",%x\n", imm);
5790            TRACE_AND_STEP();
5791            destval = (*opc83_long_operation[rh]) (*destreg, imm);
5792            if (rh != 7)
5793                *destreg = destval;
5794        } else {
5795            u16 *destreg;
5796            u16 destval,imm;
5797
5798            destreg = DECODE_RM_WORD_REGISTER(rl);
5799            imm = (s8) fetch_byte_imm();
5800            DECODE_PRINTF2(",%x\n", imm);
5801            TRACE_AND_STEP();
5802            destval = (*opc83_word_operation[rh]) (*destreg, imm);
5803            if (rh != 7)
5804                *destreg = destval;
5805        }
5806        break;
5807    }
5808    DECODE_CLEAR_SEGOVR();
5809    END_OF_INSTR();
5810}
5811
5812/****************************************************************************
5813REMARKS:
5814Handles opcode 0x84
5815****************************************************************************/
5816static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5817{
5818    int mod, rl, rh;
5819    u8 *destreg, *srcreg;
5820    uint destoffset;
5821    u8 destval;
5822
5823    START_OF_INSTR();
5824    DECODE_PRINTF("TEST\t");
5825    FETCH_DECODE_MODRM(mod, rh, rl);
5826    switch (mod) {
5827    case 0:
5828        destoffset = decode_rm00_address(rl);
5829        DECODE_PRINTF(",");
5830        destval = fetch_data_byte(destoffset);
5831        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5832        DECODE_PRINTF("\n");
5833        TRACE_AND_STEP();
5834        test_byte(destval, *srcreg);
5835        break;
5836    case 1:
5837        destoffset = decode_rm01_address(rl);
5838        DECODE_PRINTF(",");
5839        destval = fetch_data_byte(destoffset);
5840        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5841        DECODE_PRINTF("\n");
5842        TRACE_AND_STEP();
5843        test_byte(destval, *srcreg);
5844        break;
5845    case 2:
5846        destoffset = decode_rm10_address(rl);
5847        DECODE_PRINTF(",");
5848        destval = fetch_data_byte(destoffset);
5849        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5850        DECODE_PRINTF("\n");
5851        TRACE_AND_STEP();
5852        test_byte(destval, *srcreg);
5853        break;
5854    case 3:                     /* register to register */
5855        destreg = DECODE_RM_BYTE_REGISTER(rl);
5856        DECODE_PRINTF(",");
5857        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5858        DECODE_PRINTF("\n");
5859        TRACE_AND_STEP();
5860        test_byte(*destreg, *srcreg);
5861        break;
5862    }
5863    DECODE_CLEAR_SEGOVR();
5864    END_OF_INSTR();
5865}
5866
5867/****************************************************************************
5868REMARKS:
5869Handles opcode 0x85
5870****************************************************************************/
5871static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5872{
5873    int mod, rl, rh;
5874    uint destoffset;
5875
5876    START_OF_INSTR();
5877    DECODE_PRINTF("TEST\t");
5878    FETCH_DECODE_MODRM(mod, rh, rl);
5879    switch (mod) {
5880    case 0:
5881        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5882            u32 destval;
5883            u32 *srcreg;
5884
5885            destoffset = decode_rm00_address(rl);
5886            DECODE_PRINTF(",");
5887            destval = fetch_data_long(destoffset);
5888            srcreg = DECODE_RM_LONG_REGISTER(rh);
5889            DECODE_PRINTF("\n");
5890            TRACE_AND_STEP();
5891            test_long(destval, *srcreg);
5892        } else {
5893            u16 destval;
5894            u16 *srcreg;
5895
5896            destoffset = decode_rm00_address(rl);
5897            DECODE_PRINTF(",");
5898            destval = fetch_data_word(destoffset);
5899            srcreg = DECODE_RM_WORD_REGISTER(rh);
5900            DECODE_PRINTF("\n");
5901            TRACE_AND_STEP();
5902            test_word(destval, *srcreg);
5903        }
5904        break;
5905    case 1:
5906        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5907            u32 destval;
5908            u32 *srcreg;
5909
5910            destoffset = decode_rm01_address(rl);
5911            DECODE_PRINTF(",");
5912            destval = fetch_data_long(destoffset);
5913            srcreg = DECODE_RM_LONG_REGISTER(rh);
5914            DECODE_PRINTF("\n");
5915            TRACE_AND_STEP();
5916            test_long(destval, *srcreg);
5917        } else {
5918            u16 destval;
5919            u16 *srcreg;
5920
5921            destoffset = decode_rm01_address(rl);
5922            DECODE_PRINTF(",");
5923            destval = fetch_data_word(destoffset);
5924            srcreg = DECODE_RM_WORD_REGISTER(rh);
5925            DECODE_PRINTF("\n");
5926            TRACE_AND_STEP();
5927            test_word(destval, *srcreg);
5928        }
5929        break;
5930    case 2:
5931        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5932            u32 destval;
5933            u32 *srcreg;
5934
5935            destoffset = decode_rm10_address(rl);
5936            DECODE_PRINTF(",");
5937            destval = fetch_data_long(destoffset);
5938            srcreg = DECODE_RM_LONG_REGISTER(rh);
5939            DECODE_PRINTF("\n");
5940            TRACE_AND_STEP();
5941            test_long(destval, *srcreg);
5942        } else {
5943            u16 destval;
5944            u16 *srcreg;
5945
5946            destoffset = decode_rm10_address(rl);
5947            DECODE_PRINTF(",");
5948            destval = fetch_data_word(destoffset);
5949            srcreg = DECODE_RM_WORD_REGISTER(rh);
5950            DECODE_PRINTF("\n");
5951            TRACE_AND_STEP();
5952            test_word(destval, *srcreg);
5953        }
5954        break;
5955    case 3:                     /* register to register */
5956        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5957            u32 *destreg,*srcreg;
5958
5959            destreg = DECODE_RM_LONG_REGISTER(rl);
5960            DECODE_PRINTF(",");
5961            srcreg = DECODE_RM_LONG_REGISTER(rh);
5962            DECODE_PRINTF("\n");
5963            TRACE_AND_STEP();
5964            test_long(*destreg, *srcreg);
5965        } else {
5966            u16 *destreg,*srcreg;
5967
5968            destreg = DECODE_RM_WORD_REGISTER(rl);
5969            DECODE_PRINTF(",");
5970            srcreg = DECODE_RM_WORD_REGISTER(rh);
5971            DECODE_PRINTF("\n");
5972            TRACE_AND_STEP();
5973            test_word(*destreg, *srcreg);
5974        }
5975        break;
5976    }
5977    DECODE_CLEAR_SEGOVR();
5978    END_OF_INSTR();
5979}
5980
5981/****************************************************************************
5982REMARKS:
5983Handles opcode 0x86
5984****************************************************************************/
5985static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5986{
5987    int mod, rl, rh;
5988    u8 *destreg, *srcreg;
5989    uint destoffset;
5990    u8 destval;
5991    u8 tmp;
5992
5993    START_OF_INSTR();
5994    DECODE_PRINTF("XCHG\t");
5995    FETCH_DECODE_MODRM(mod, rh, rl);
5996    switch (mod) {
5997    case 0:
5998        destoffset = decode_rm00_address(rl);
5999        DECODE_PRINTF(",");
6000        destval = fetch_data_byte(destoffset);
6001        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6002        DECODE_PRINTF("\n");
6003        TRACE_AND_STEP();
6004        tmp = *srcreg;
6005        *srcreg = destval;
6006        destval = tmp;
6007        store_data_byte(destoffset, destval);
6008        break;
6009    case 1:
6010        destoffset = decode_rm01_address(rl);
6011        DECODE_PRINTF(",");
6012        destval = fetch_data_byte(destoffset);
6013        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6014        DECODE_PRINTF("\n");
6015        TRACE_AND_STEP();
6016        tmp = *srcreg;
6017        *srcreg = destval;
6018        destval = tmp;
6019        store_data_byte(destoffset, destval);
6020        break;
6021    case 2:
6022        destoffset = decode_rm10_address(rl);
6023        DECODE_PRINTF(",");
6024        destval = fetch_data_byte(destoffset);
6025        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6026        DECODE_PRINTF("\n");
6027        TRACE_AND_STEP();
6028        tmp = *srcreg;
6029        *srcreg = destval;
6030        destval = tmp;
6031        store_data_byte(destoffset, destval);
6032        break;
6033    case 3:                     /* register to register */
6034        destreg = DECODE_RM_BYTE_REGISTER(rl);
6035        DECODE_PRINTF(",");
6036        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6037        DECODE_PRINTF("\n");
6038        TRACE_AND_STEP();
6039        tmp = *srcreg;
6040        *srcreg = *destreg;
6041        *destreg = tmp;
6042        break;
6043    }
6044    DECODE_CLEAR_SEGOVR();
6045    END_OF_INSTR();
6046}
6047
6048/****************************************************************************
6049REMARKS:
6050Handles opcode 0x87
6051****************************************************************************/
6052static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6053{
6054    int mod, rl, rh;
6055    uint destoffset;
6056
6057    START_OF_INSTR();
6058    DECODE_PRINTF("XCHG\t");
6059    FETCH_DECODE_MODRM(mod, rh, rl);
6060    switch (mod) {
6061    case 0:
6062        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6063            u32 *srcreg;
6064            u32 destval,tmp;
6065
6066            destoffset = decode_rm00_address(rl);
6067            DECODE_PRINTF(",");
6068            destval = fetch_data_long(destoffset);
6069            srcreg = DECODE_RM_LONG_REGISTER(rh);
6070            DECODE_PRINTF("\n");
6071            TRACE_AND_STEP();
6072            tmp = *srcreg;
6073            *srcreg = destval;
6074            destval = tmp;
6075            store_data_long(destoffset, destval);
6076        } else {
6077            u16 *srcreg;
6078            u16 destval,tmp;
6079
6080            destoffset = decode_rm00_address(rl);
6081            DECODE_PRINTF(",");
6082            destval = fetch_data_word(destoffset);
6083            srcreg = DECODE_RM_WORD_REGISTER(rh);
6084            DECODE_PRINTF("\n");
6085            TRACE_AND_STEP();
6086            tmp = *srcreg;
6087            *srcreg = destval;
6088            destval = tmp;
6089            store_data_word(destoffset, destval);
6090        }
6091        break;
6092    case 1:
6093        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6094            u32 *srcreg;
6095            u32 destval,tmp;
6096
6097            destoffset = decode_rm01_address(rl);
6098            DECODE_PRINTF(",");
6099            destval = fetch_data_long(destoffset);
6100            srcreg = DECODE_RM_LONG_REGISTER(rh);
6101            DECODE_PRINTF("\n");
6102            TRACE_AND_STEP();
6103            tmp = *srcreg;
6104            *srcreg = destval;
6105            destval = tmp;
6106            store_data_long(destoffset, destval);
6107        } else {
6108            u16 *srcreg;
6109            u16 destval,tmp;
6110
6111            destoffset = decode_rm01_address(rl);
6112            DECODE_PRINTF(",");
6113            destval = fetch_data_word(destoffset);
6114            srcreg = DECODE_RM_WORD_REGISTER(rh);
6115            DECODE_PRINTF("\n");
6116            TRACE_AND_STEP();
6117            tmp = *srcreg;
6118            *srcreg = destval;
6119            destval = tmp;
6120            store_data_word(destoffset, destval);
6121        }
6122        break;
6123    case 2:
6124        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6125            u32 *srcreg;
6126            u32 destval,tmp;
6127
6128            destoffset = decode_rm10_address(rl);
6129            DECODE_PRINTF(",");
6130            destval = fetch_data_long(destoffset);
6131            srcreg = DECODE_RM_LONG_REGISTER(rh);
6132            DECODE_PRINTF("\n");
6133            TRACE_AND_STEP();
6134            tmp = *srcreg;
6135            *srcreg = destval;
6136            destval = tmp;
6137            store_data_long(destoffset, destval);
6138        } else {
6139            u16 *srcreg;
6140            u16 destval,tmp;
6141
6142            destoffset = decode_rm10_address(rl);
6143            DECODE_PRINTF(",");
6144            destval = fetch_data_word(destoffset);
6145            srcreg = DECODE_RM_WORD_REGISTER(rh);
6146            DECODE_PRINTF("\n");
6147            TRACE_AND_STEP();
6148            tmp = *srcreg;
6149            *srcreg = destval;
6150            destval = tmp;
6151            store_data_word(destoffset, destval);
6152        }
6153        break;
6154    case 3:                     /* register to register */
6155        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6156            u32 *destreg,*srcreg;
6157            u32 tmp;
6158
6159            destreg = DECODE_RM_LONG_REGISTER(rl);
6160            DECODE_PRINTF(",");
6161            srcreg = DECODE_RM_LONG_REGISTER(rh);
6162            DECODE_PRINTF("\n");
6163            TRACE_AND_STEP();
6164            tmp = *srcreg;
6165            *srcreg = *destreg;
6166            *destreg = tmp;
6167        } else {
6168            u16 *destreg,*srcreg;
6169            u16 tmp;
6170
6171            destreg = DECODE_RM_WORD_REGISTER(rl);
6172            DECODE_PRINTF(",");
6173            srcreg = DECODE_RM_WORD_REGISTER(rh);
6174            DECODE_PRINTF("\n");
6175            TRACE_AND_STEP();
6176            tmp = *srcreg;
6177            *srcreg = *destreg;
6178            *destreg = tmp;
6179        }
6180        break;
6181    }
6182    DECODE_CLEAR_SEGOVR();
6183    END_OF_INSTR();
6184}
6185
6186/****************************************************************************
6187REMARKS:
6188Handles opcode 0x88
6189****************************************************************************/
6190static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6191{
6192    int mod, rl, rh;
6193    u8 *destreg, *srcreg;
6194    uint destoffset;
6195
6196    START_OF_INSTR();
6197    DECODE_PRINTF("MOV\t");
6198    FETCH_DECODE_MODRM(mod, rh, rl);
6199    switch (mod) {
6200    case 0:
6201        destoffset = decode_rm00_address(rl);
6202        DECODE_PRINTF(",");
6203        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6204        DECODE_PRINTF("\n");
6205        TRACE_AND_STEP();
6206        store_data_byte(destoffset, *srcreg);
6207        break;
6208    case 1:
6209        destoffset = decode_rm01_address(rl);
6210        DECODE_PRINTF(",");
6211        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6212        DECODE_PRINTF("\n");
6213        TRACE_AND_STEP();
6214        store_data_byte(destoffset, *srcreg);
6215        break;
6216    case 2:
6217        destoffset = decode_rm10_address(rl);
6218        DECODE_PRINTF(",");
6219        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6220        DECODE_PRINTF("\n");
6221        TRACE_AND_STEP();
6222        store_data_byte(destoffset, *srcreg);
6223        break;
6224    case 3:                     /* register to register */
6225        destreg = DECODE_RM_BYTE_REGISTER(rl);
6226        DECODE_PRINTF(",");
6227        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6228        DECODE_PRINTF("\n");
6229        TRACE_AND_STEP();
6230        *destreg = *srcreg;
6231        break;
6232    }
6233    DECODE_CLEAR_SEGOVR();
6234    END_OF_INSTR();
6235}
6236
6237/****************************************************************************
6238REMARKS:
6239Handles opcode 0x89
6240****************************************************************************/
6241static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6242{
6243    int mod, rl, rh;
6244    u32 destoffset;
6245
6246    START_OF_INSTR();
6247    DECODE_PRINTF("MOV\t");
6248    FETCH_DECODE_MODRM(mod, rh, rl);
6249    switch (mod) {
6250    case 0:
6251        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252            u32 *srcreg;
6253
6254            destoffset = decode_rm00_address(rl);
6255            DECODE_PRINTF(",");
6256            srcreg = DECODE_RM_LONG_REGISTER(rh);
6257            DECODE_PRINTF("\n");
6258            TRACE_AND_STEP();
6259            store_data_long(destoffset, *srcreg);
6260        } else {
6261            u16 *srcreg;
6262
6263            destoffset = decode_rm00_address(rl);
6264            DECODE_PRINTF(",");
6265            srcreg = DECODE_RM_WORD_REGISTER(rh);
6266            DECODE_PRINTF("\n");
6267            TRACE_AND_STEP();
6268            store_data_word(destoffset, *srcreg);
6269        }
6270        break;
6271    case 1:
6272        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6273            u32 *srcreg;
6274
6275            destoffset = decode_rm01_address(rl);
6276            DECODE_PRINTF(",");
6277            srcreg = DECODE_RM_LONG_REGISTER(rh);
6278            DECODE_PRINTF("\n");
6279            TRACE_AND_STEP();
6280            store_data_long(destoffset, *srcreg);
6281        } else {
6282            u16 *srcreg;
6283
6284            destoffset = decode_rm01_address(rl);
6285            DECODE_PRINTF(",");
6286            srcreg = DECODE_RM_WORD_REGISTER(rh);
6287            DECODE_PRINTF("\n");
6288            TRACE_AND_STEP();
6289            store_data_word(destoffset, *srcreg);
6290        }
6291        break;
6292    case 2:
6293        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6294            u32 *srcreg;
6295
6296            destoffset = decode_rm10_address(rl);
6297            DECODE_PRINTF(",");
6298            srcreg = DECODE_RM_LONG_REGISTER(rh);
6299            DECODE_PRINTF("\n");
6300            TRACE_AND_STEP();
6301            store_data_long(destoffset, *srcreg);
6302        } else {
6303            u16 *srcreg;
6304
6305            destoffset = decode_rm10_address(rl);
6306            DECODE_PRINTF(",");
6307            srcreg = DECODE_RM_WORD_REGISTER(rh);
6308            DECODE_PRINTF("\n");
6309            TRACE_AND_STEP();
6310            store_data_word(destoffset, *srcreg);
6311        }
6312        break;
6313    case 3:                     /* register to register */
6314        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6315            u32 *destreg,*srcreg;
6316
6317            destreg = DECODE_RM_LONG_REGISTER(rl);
6318            DECODE_PRINTF(",");
6319            srcreg = DECODE_RM_LONG_REGISTER(rh);
6320            DECODE_PRINTF("\n");
6321            TRACE_AND_STEP();
6322            *destreg = *srcreg;
6323        } else {
6324            u16 *destreg,*srcreg;
6325
6326            destreg = DECODE_RM_WORD_REGISTER(rl);
6327            DECODE_PRINTF(",");
6328            srcreg = DECODE_RM_WORD_REGISTER(rh);
6329            DECODE_PRINTF("\n");
6330            TRACE_AND_STEP();
6331            *destreg = *srcreg;
6332        }
6333        break;
6334    }
6335    DECODE_CLEAR_SEGOVR();
6336    END_OF_INSTR();
6337}
6338
6339/****************************************************************************
6340REMARKS:
6341Handles opcode 0x8a
6342****************************************************************************/
6343static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6344{
6345    int mod, rl, rh;
6346    u8 *destreg, *srcreg;
6347    uint srcoffset;
6348    u8 srcval;
6349
6350    START_OF_INSTR();
6351    DECODE_PRINTF("MOV\t");
6352    FETCH_DECODE_MODRM(mod, rh, rl);
6353    switch (mod) {
6354    case 0:
6355        destreg = DECODE_RM_BYTE_REGISTER(rh);
6356        DECODE_PRINTF(",");
6357        srcoffset = decode_rm00_address(rl);
6358        srcval = fetch_data_byte(srcoffset);
6359        DECODE_PRINTF("\n");
6360        TRACE_AND_STEP();
6361        *destreg = srcval;
6362        break;
6363    case 1:
6364        destreg = DECODE_RM_BYTE_REGISTER(rh);
6365        DECODE_PRINTF(",");
6366        srcoffset = decode_rm01_address(rl);
6367        srcval = fetch_data_byte(srcoffset);
6368        DECODE_PRINTF("\n");
6369        TRACE_AND_STEP();
6370        *destreg = srcval;
6371        break;
6372    case 2:
6373        destreg = DECODE_RM_BYTE_REGISTER(rh);
6374        DECODE_PRINTF(",");
6375        srcoffset = decode_rm10_address(rl);
6376        srcval = fetch_data_byte(srcoffset);
6377        DECODE_PRINTF("\n");
6378        TRACE_AND_STEP();
6379        *destreg = srcval;
6380        break;
6381    case 3:                     /* register to register */
6382        destreg = DECODE_RM_BYTE_REGISTER(rh);
6383        DECODE_PRINTF(",");
6384        srcreg = DECODE_RM_BYTE_REGISTER(rl);
6385        DECODE_PRINTF("\n");
6386        TRACE_AND_STEP();
6387        *destreg = *srcreg;
6388        break;
6389    }
6390    DECODE_CLEAR_SEGOVR();
6391    END_OF_INSTR();
6392}
6393
6394/****************************************************************************
6395REMARKS:
6396Handles opcode 0x8b
6397****************************************************************************/
6398static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6399{
6400    int mod, rl, rh;
6401    uint srcoffset;
6402
6403    START_OF_INSTR();
6404    DECODE_PRINTF("MOV\t");
6405    FETCH_DECODE_MODRM(mod, rh, rl);
6406    switch (mod) {
6407    case 0:
6408        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6409            u32 *destreg;
6410            u32 srcval;
6411
6412            destreg = DECODE_RM_LONG_REGISTER(rh);
6413            DECODE_PRINTF(",");
6414            srcoffset = decode_rm00_address(rl);
6415            srcval = fetch_data_long(srcoffset);
6416            DECODE_PRINTF("\n");
6417            TRACE_AND_STEP();
6418            *destreg = srcval;
6419        } else {
6420            u16 *destreg;
6421            u16 srcval;
6422
6423            destreg = DECODE_RM_WORD_REGISTER(rh);
6424            DECODE_PRINTF(",");
6425            srcoffset = decode_rm00_address(rl);
6426            srcval = fetch_data_word(srcoffset);
6427            DECODE_PRINTF("\n");
6428            TRACE_AND_STEP();
6429            *destreg = srcval;
6430        }
6431        break;
6432    case 1:
6433        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6434            u32 *destreg;
6435            u32 srcval;
6436
6437            destreg = DECODE_RM_LONG_REGISTER(rh);
6438            DECODE_PRINTF(",");
6439            srcoffset = decode_rm01_address(rl);
6440            srcval = fetch_data_long(srcoffset);
6441            DECODE_PRINTF("\n");
6442            TRACE_AND_STEP();
6443            *destreg = srcval;
6444        } else {
6445            u16 *destreg;
6446            u16 srcval;
6447
6448            destreg = DECODE_RM_WORD_REGISTER(rh);
6449            DECODE_PRINTF(",");
6450            srcoffset = decode_rm01_address(rl);
6451            srcval = fetch_data_word(srcoffset);
6452            DECODE_PRINTF("\n");
6453            TRACE_AND_STEP();
6454            *destreg = srcval;
6455        }
6456        break;
6457    case 2:
6458        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6459            u32 *destreg;
6460            u32 srcval;
6461
6462            destreg = DECODE_RM_LONG_REGISTER(rh);
6463            DECODE_PRINTF(",");
6464            srcoffset = decode_rm10_address(rl);
6465            srcval = fetch_data_long(srcoffset);
6466            DECODE_PRINTF("\n");
6467            TRACE_AND_STEP();
6468            *destreg = srcval;
6469        } else {
6470            u16 *destreg;
6471            u16 srcval;
6472
6473            destreg = DECODE_RM_WORD_REGISTER(rh);
6474            DECODE_PRINTF(",");
6475            srcoffset = decode_rm10_address(rl);
6476            srcval = fetch_data_word(srcoffset);
6477            DECODE_PRINTF("\n");
6478            TRACE_AND_STEP();
6479            *destreg = srcval;
6480        }
6481        break;
6482    case 3:                     /* register to register */
6483        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6484            u32 *destreg, *srcreg;
6485
6486            destreg = DECODE_RM_LONG_REGISTER(rh);
6487            DECODE_PRINTF(",");
6488            srcreg = DECODE_RM_LONG_REGISTER(rl);
6489            DECODE_PRINTF("\n");
6490            TRACE_AND_STEP();
6491            *destreg = *srcreg;
6492        } else {
6493            u16 *destreg, *srcreg;
6494
6495            destreg = DECODE_RM_WORD_REGISTER(rh);
6496            DECODE_PRINTF(",");
6497            srcreg = DECODE_RM_WORD_REGISTER(rl);
6498            DECODE_PRINTF("\n");
6499            TRACE_AND_STEP();
6500            *destreg = *srcreg;
6501        }
6502        break;
6503    }
6504    DECODE_CLEAR_SEGOVR();
6505    END_OF_INSTR();
6506}
6507
6508/****************************************************************************
6509REMARKS:
6510Handles opcode 0x8c
6511****************************************************************************/
6512static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6513{
6514    int mod, rl, rh;
6515    u16 *destreg, *srcreg;
6516    uint destoffset;
6517    u16 destval;
6518
6519    START_OF_INSTR();
6520    DECODE_PRINTF("MOV\t");
6521    FETCH_DECODE_MODRM(mod, rh, rl);
6522    switch (mod) {
6523    case 0:
6524        destoffset = decode_rm00_address(rl);
6525        DECODE_PRINTF(",");
6526        srcreg = decode_rm_seg_register(rh);
6527        DECODE_PRINTF("\n");
6528        TRACE_AND_STEP();
6529        destval = *srcreg;
6530        store_data_word(destoffset, destval);
6531        break;
6532    case 1:
6533        destoffset = decode_rm01_address(rl);
6534        DECODE_PRINTF(",");
6535        srcreg = decode_rm_seg_register(rh);
6536        DECODE_PRINTF("\n");
6537        TRACE_AND_STEP();
6538        destval = *srcreg;
6539        store_data_word(destoffset, destval);
6540        break;
6541    case 2:
6542        destoffset = decode_rm10_address(rl);
6543        DECODE_PRINTF(",");
6544        srcreg = decode_rm_seg_register(rh);
6545        DECODE_PRINTF("\n");
6546        TRACE_AND_STEP();
6547        destval = *srcreg;
6548        store_data_word(destoffset, destval);
6549        break;
6550    case 3:                     /* register to register */
6551        destreg = DECODE_RM_WORD_REGISTER(rl);
6552        DECODE_PRINTF(",");
6553        srcreg = decode_rm_seg_register(rh);
6554        DECODE_PRINTF("\n");
6555        TRACE_AND_STEP();
6556        *destreg = *srcreg;
6557        break;
6558    }
6559    DECODE_CLEAR_SEGOVR();
6560    END_OF_INSTR();
6561}
6562
6563/****************************************************************************
6564REMARKS:
6565Handles opcode 0x8d
6566****************************************************************************/
6567static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6568{
6569    int mod, rl, rh;
6570    uint destoffset;
6571
6572    START_OF_INSTR();
6573    DECODE_PRINTF("LEA\t");
6574    FETCH_DECODE_MODRM(mod, rh, rl);
6575    switch (mod) {
6576    case 0:
6577        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6578            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6579            DECODE_PRINTF(",");
6580            destoffset = decode_rm00_address(rl);
6581            DECODE_PRINTF("\n");
6582            TRACE_AND_STEP();
6583            *srcreg = (u32)destoffset;
6584        } else {
6585            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6586            DECODE_PRINTF(",");
6587            destoffset = decode_rm00_address(rl);
6588            DECODE_PRINTF("\n");
6589            TRACE_AND_STEP();
6590            *srcreg = (u16)destoffset;
6591        }
6592        break;
6593    case 1:
6594        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6595            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6596            DECODE_PRINTF(",");
6597            destoffset = decode_rm01_address(rl);
6598            DECODE_PRINTF("\n");
6599            TRACE_AND_STEP();
6600            *srcreg = (u32)destoffset;
6601        } else {
6602            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6603            DECODE_PRINTF(",");
6604            destoffset = decode_rm01_address(rl);
6605            DECODE_PRINTF("\n");
6606            TRACE_AND_STEP();
6607            *srcreg = (u16)destoffset;
6608        }
6609        break;
6610    case 2:
6611        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6612            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6613            DECODE_PRINTF(",");
6614            destoffset = decode_rm10_address(rl);
6615            DECODE_PRINTF("\n");
6616            TRACE_AND_STEP();
6617            *srcreg = (u32)destoffset;
6618        } else {
6619            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6620            DECODE_PRINTF(",");
6621            destoffset = decode_rm10_address(rl);
6622            DECODE_PRINTF("\n");
6623            TRACE_AND_STEP();
6624            *srcreg = (u16)destoffset;
6625        }
6626        break;
6627    case 3:                     /* register to register */
6628        /* undefined.  Do nothing. */
6629        break;
6630    }
6631    DECODE_CLEAR_SEGOVR();
6632    END_OF_INSTR();
6633}
6634
6635/****************************************************************************
6636REMARKS:
6637Handles opcode 0x8e
6638****************************************************************************/
6639static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6640{
6641    int mod, rl, rh;
6642    u16 *destreg, *srcreg;
6643    uint srcoffset;
6644    u16 srcval;
6645
6646    START_OF_INSTR();
6647    DECODE_PRINTF("MOV\t");
6648    FETCH_DECODE_MODRM(mod, rh, rl);
6649    switch (mod) {
6650    case 0:
6651        destreg = decode_rm_seg_register(rh);
6652        DECODE_PRINTF(",");
6653        srcoffset = decode_rm00_address(rl);
6654        srcval = fetch_data_word(srcoffset);
6655        DECODE_PRINTF("\n");
6656        TRACE_AND_STEP();
6657        *destreg = srcval;
6658        break;
6659    case 1:
6660        destreg = decode_rm_seg_register(rh);
6661        DECODE_PRINTF(",");
6662        srcoffset = decode_rm01_address(rl);
6663        srcval = fetch_data_word(srcoffset);
6664        DECODE_PRINTF("\n");
6665        TRACE_AND_STEP();
6666        *destreg = srcval;
6667        break;
6668    case 2:
6669        destreg = decode_rm_seg_register(rh);
6670        DECODE_PRINTF(",");
6671        srcoffset = decode_rm10_address(rl);
6672        srcval = fetch_data_word(srcoffset);
6673        DECODE_PRINTF("\n");
6674        TRACE_AND_STEP();
6675        *destreg = srcval;
6676        break;
6677    case 3:                     /* register to register */
6678        destreg = decode_rm_seg_register(rh);
6679        DECODE_PRINTF(",");
6680        srcreg = DECODE_RM_WORD_REGISTER(rl);
6681        DECODE_PRINTF("\n");
6682        TRACE_AND_STEP();
6683        *destreg = *srcreg;
6684        break;
6685    }
6686    /*
6687     * Clean up, and reset all the R_xSP pointers to the correct
6688     * locations.  This is about 3x too much overhead (doing all the
6689     * segreg ptrs when only one is needed, but this instruction
6690     * *cannot* be that common, and this isn't too much work anyway.
6691     */
6692    DECODE_CLEAR_SEGOVR();
6693    END_OF_INSTR();
6694}
6695
6696/****************************************************************************
6697REMARKS:
6698Handles opcode 0x8f
6699****************************************************************************/
6700static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6701{
6702    int mod, rl, rh;
6703    uint destoffset;
6704
6705    START_OF_INSTR();
6706    DECODE_PRINTF("POP\t");
6707    FETCH_DECODE_MODRM(mod, rh, rl);
6708    if (rh != 0) {
6709        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6710        HALT_SYS();
6711    }
6712    switch (mod) {
6713    case 0:
6714        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6715            u32 destval;
6716
6717            destoffset = decode_rm00_address(rl);
6718            DECODE_PRINTF("\n");
6719            TRACE_AND_STEP();
6720            destval = pop_long();
6721            store_data_long(destoffset, destval);
6722        } else {
6723            u16 destval;
6724
6725            destoffset = decode_rm00_address(rl);
6726            DECODE_PRINTF("\n");
6727            TRACE_AND_STEP();
6728            destval = pop_word();
6729            store_data_word(destoffset, destval);
6730        }
6731        break;
6732    case 1:
6733        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6734            u32 destval;
6735
6736            destoffset = decode_rm01_address(rl);
6737            DECODE_PRINTF("\n");
6738            TRACE_AND_STEP();
6739            destval = pop_long();
6740            store_data_long(destoffset, destval);
6741        } else {
6742            u16 destval;
6743
6744            destoffset = decode_rm01_address(rl);
6745            DECODE_PRINTF("\n");
6746            TRACE_AND_STEP();
6747            destval = pop_word();
6748            store_data_word(destoffset, destval);
6749        }
6750        break;
6751    case 2:
6752        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6753            u32 destval;
6754
6755            destoffset = decode_rm10_address(rl);
6756            DECODE_PRINTF("\n");
6757            TRACE_AND_STEP();
6758            destval = pop_long();
6759            store_data_long(destoffset, destval);
6760        } else {
6761            u16 destval;
6762
6763            destoffset = decode_rm10_address(rl);
6764            DECODE_PRINTF("\n");
6765            TRACE_AND_STEP();
6766            destval = pop_word();
6767            store_data_word(destoffset, destval);
6768        }
6769        break;
6770    case 3:                     /* register to register */
6771        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6772            u32 *destreg;
6773
6774            destreg = DECODE_RM_LONG_REGISTER(rl);
6775            DECODE_PRINTF("\n");
6776            TRACE_AND_STEP();
6777            *destreg = pop_long();
6778        } else {
6779            u16 *destreg;
6780
6781            destreg = DECODE_RM_WORD_REGISTER(rl);
6782            DECODE_PRINTF("\n");
6783            TRACE_AND_STEP();
6784            *destreg = pop_word();
6785        }
6786        break;
6787    }
6788    DECODE_CLEAR_SEGOVR();
6789    END_OF_INSTR();
6790}
6791
6792/****************************************************************************
6793REMARKS:
6794Handles opcode 0x90
6795****************************************************************************/
6796static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6797{
6798    START_OF_INSTR();
6799    DECODE_PRINTF("NOP\n");
6800    TRACE_AND_STEP();
6801    DECODE_CLEAR_SEGOVR();
6802    END_OF_INSTR();
6803}
6804
6805/****************************************************************************
6806REMARKS:
6807Handles opcode 0x91
6808****************************************************************************/
6809static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6810{
6811    u32 tmp;
6812
6813    START_OF_INSTR();
6814    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6815        DECODE_PRINTF("XCHG\tEAX,ECX\n");
6816    } else {
6817        DECODE_PRINTF("XCHG\tAX,CX\n");
6818    }
6819    TRACE_AND_STEP();
6820    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6821        tmp = M.x86.R_EAX;
6822        M.x86.R_EAX = M.x86.R_ECX;
6823        M.x86.R_ECX = tmp;
6824    } else {
6825        tmp = M.x86.R_AX;
6826        M.x86.R_AX = M.x86.R_CX;
6827        M.x86.R_CX = (u16)tmp;
6828    }
6829    DECODE_CLEAR_SEGOVR();
6830    END_OF_INSTR();
6831}
6832
6833/****************************************************************************
6834REMARKS:
6835Handles opcode 0x92
6836****************************************************************************/
6837static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6838{
6839    u32 tmp;
6840
6841    START_OF_INSTR();
6842    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6843        DECODE_PRINTF("XCHG\tEAX,EDX\n");
6844    } else {
6845        DECODE_PRINTF("XCHG\tAX,DX\n");
6846    }
6847    TRACE_AND_STEP();
6848    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6849        tmp = M.x86.R_EAX;
6850        M.x86.R_EAX = M.x86.R_EDX;
6851        M.x86.R_EDX = tmp;
6852    } else {
6853        tmp = M.x86.R_AX;
6854        M.x86.R_AX = M.x86.R_DX;
6855        M.x86.R_DX = (u16)tmp;
6856    }
6857    DECODE_CLEAR_SEGOVR();
6858    END_OF_INSTR();
6859}
6860
6861/****************************************************************************
6862REMARKS:
6863Handles opcode 0x93
6864****************************************************************************/
6865static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6866{
6867    u32 tmp;
6868
6869    START_OF_INSTR();
6870    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6871        DECODE_PRINTF("XCHG\tEAX,EBX\n");
6872    } else {
6873        DECODE_PRINTF("XCHG\tAX,BX\n");
6874    }
6875    TRACE_AND_STEP();
6876    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6877        tmp = M.x86.R_EAX;
6878        M.x86.R_EAX = M.x86.R_EBX;
6879        M.x86.R_EBX = tmp;
6880    } else {
6881        tmp = M.x86.R_AX;
6882        M.x86.R_AX = M.x86.R_BX;
6883        M.x86.R_BX = (u16)tmp;
6884    }
6885    DECODE_CLEAR_SEGOVR();
6886    END_OF_INSTR();
6887}
6888
6889/****************************************************************************
6890REMARKS:
6891Handles opcode 0x94
6892****************************************************************************/
6893static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6894{
6895    u32 tmp;
6896
6897    START_OF_INSTR();
6898    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6899        DECODE_PRINTF("XCHG\tEAX,ESP\n");
6900    } else {
6901        DECODE_PRINTF("XCHG\tAX,SP\n");
6902    }
6903    TRACE_AND_STEP();
6904    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6905        tmp = M.x86.R_EAX;
6906        M.x86.R_EAX = M.x86.R_ESP;
6907        M.x86.R_ESP = tmp;
6908    } else {
6909        tmp = M.x86.R_AX;
6910        M.x86.R_AX = M.x86.R_SP;
6911        M.x86.R_SP = (u16)tmp;
6912    }
6913    DECODE_CLEAR_SEGOVR();
6914    END_OF_INSTR();
6915}
6916
6917/****************************************************************************
6918REMARKS:
6919Handles opcode 0x95
6920****************************************************************************/
6921static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6922{
6923    u32 tmp;
6924
6925    START_OF_INSTR();
6926    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6927        DECODE_PRINTF("XCHG\tEAX,EBP\n");
6928    } else {
6929        DECODE_PRINTF("XCHG\tAX,BP\n");
6930    }
6931    TRACE_AND_STEP();
6932    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6933        tmp = M.x86.R_EAX;
6934        M.x86.R_EAX = M.x86.R_EBP;
6935        M.x86.R_EBP = tmp;
6936    } else {
6937        tmp = M.x86.R_AX;
6938        M.x86.R_AX = M.x86.R_BP;
6939        M.x86.R_BP = (u16)tmp;
6940    }
6941    DECODE_CLEAR_SEGOVR();
6942    END_OF_INSTR();
6943}
6944
6945/****************************************************************************
6946REMARKS:
6947Handles opcode 0x96
6948****************************************************************************/
6949static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6950{
6951    u32 tmp;
6952
6953    START_OF_INSTR();
6954    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6955        DECODE_PRINTF("XCHG\tEAX,ESI\n");
6956    } else {
6957        DECODE_PRINTF("XCHG\tAX,SI\n");
6958    }
6959    TRACE_AND_STEP();
6960    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6961        tmp = M.x86.R_EAX;
6962        M.x86.R_EAX = M.x86.R_ESI;
6963        M.x86.R_ESI = tmp;
6964    } else {
6965        tmp = M.x86.R_AX;
6966        M.x86.R_AX = M.x86.R_SI;
6967        M.x86.R_SI = (u16)tmp;
6968    }
6969    DECODE_CLEAR_SEGOVR();
6970    END_OF_INSTR();
6971}
6972
6973/****************************************************************************
6974REMARKS:
6975Handles opcode 0x97
6976****************************************************************************/
6977static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6978{
6979    u32 tmp;
6980
6981    START_OF_INSTR();
6982    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6983        DECODE_PRINTF("XCHG\tEAX,EDI\n");
6984    } else {
6985        DECODE_PRINTF("XCHG\tAX,DI\n");
6986    }
6987    TRACE_AND_STEP();
6988    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6989        tmp = M.x86.R_EAX;
6990        M.x86.R_EAX = M.x86.R_EDI;
6991        M.x86.R_EDI = tmp;
6992    } else {
6993        tmp = M.x86.R_AX;
6994        M.x86.R_AX = M.x86.R_DI;
6995        M.x86.R_DI = (u16)tmp;
6996    }
6997    DECODE_CLEAR_SEGOVR();
6998    END_OF_INSTR();
6999}
7000
7001/****************************************************************************
7002REMARKS:
7003Handles opcode 0x98
7004****************************************************************************/
7005static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7006{
7007    START_OF_INSTR();
7008    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7009        DECODE_PRINTF("CWDE\n");
7010    } else {
7011        DECODE_PRINTF("CBW\n");
7012    }
7013    TRACE_AND_STEP();
7014    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7015        if (M.x86.R_AX & 0x8000) {
7016            M.x86.R_EAX |= 0xffff0000;
7017        } else {
7018            M.x86.R_EAX &= 0x0000ffff;
7019        }
7020    } else {
7021        if (M.x86.R_AL & 0x80) {
7022            M.x86.R_AH = 0xff;
7023        } else {
7024            M.x86.R_AH = 0x0;
7025        }
7026    }
7027    DECODE_CLEAR_SEGOVR();
7028    END_OF_INSTR();
7029}
7030
7031/****************************************************************************
7032REMARKS:
7033Handles opcode 0x99
7034****************************************************************************/
7035static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7036{
7037    START_OF_INSTR();
7038    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7039        DECODE_PRINTF("CDQ\n");
7040    } else {
7041        DECODE_PRINTF("CWD\n");
7042    }
7043    DECODE_PRINTF("CWD\n");
7044    TRACE_AND_STEP();
7045    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7046        if (M.x86.R_EAX & 0x80000000) {
7047            M.x86.R_EDX = 0xffffffff;
7048        } else {
7049            M.x86.R_EDX = 0x0;
7050        }
7051    } else {
7052        if (M.x86.R_AX & 0x8000) {
7053            M.x86.R_DX = 0xffff;
7054        } else {
7055            M.x86.R_DX = 0x0;
7056        }
7057    }
7058    DECODE_CLEAR_SEGOVR();
7059    END_OF_INSTR();
7060}
7061
7062/****************************************************************************
7063REMARKS:
7064Handles opcode 0x9a
7065****************************************************************************/
7066static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7067{
7068    u32 farseg, faroff;
7069
7070    START_OF_INSTR();
7071    DECODE_PRINTF("CALL\t");
7072    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7073	faroff = fetch_long_imm();
7074	farseg = fetch_word_imm();
7075    } else {
7076	faroff = fetch_word_imm();
7077	farseg = fetch_word_imm();
7078    }
7079    DECODE_PRINTF2("%04x:", farseg);
7080    DECODE_PRINTF2("%04x\n", faroff);
7081    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7082
7083    /* XXX
7084     *
7085     * Hooked interrupt vectors calling into our "BIOS" will cause
7086     * problems unless all intersegment stuff is checked for BIOS
7087     * access.  Check needed here.  For moment, let it alone.
7088     */
7089    TRACE_AND_STEP();
7090    push_word(M.x86.R_CS);
7091    M.x86.R_CS = farseg;
7092    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7093	push_long(M.x86.R_EIP);
7094    } else {
7095	push_word(M.x86.R_IP);
7096    }
7097    M.x86.R_EIP = faroff & 0xffff;
7098    DECODE_CLEAR_SEGOVR();
7099    END_OF_INSTR();
7100}
7101
7102/****************************************************************************
7103REMARKS:
7104Handles opcode 0x9b
7105****************************************************************************/
7106static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7107{
7108    START_OF_INSTR();
7109    DECODE_PRINTF("WAIT");
7110    TRACE_AND_STEP();
7111    /* NADA.  */
7112    DECODE_CLEAR_SEGOVR();
7113    END_OF_INSTR();
7114}
7115
7116/****************************************************************************
7117REMARKS:
7118Handles opcode 0x9c
7119****************************************************************************/
7120static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7121{
7122    u32 flags;
7123
7124    START_OF_INSTR();
7125    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7126        DECODE_PRINTF("PUSHFD\n");
7127    } else {
7128        DECODE_PRINTF("PUSHF\n");
7129    }
7130    TRACE_AND_STEP();
7131
7132    /* clear out *all* bits not representing flags, and turn on real bits */
7133    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7134    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7135        push_long(flags);
7136    } else {
7137        push_word((u16)flags);
7138    }
7139    DECODE_CLEAR_SEGOVR();
7140    END_OF_INSTR();
7141}
7142
7143/****************************************************************************
7144REMARKS:
7145Handles opcode 0x9d
7146****************************************************************************/
7147static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7148{
7149    START_OF_INSTR();
7150    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7151        DECODE_PRINTF("POPFD\n");
7152    } else {
7153        DECODE_PRINTF("POPF\n");
7154    }
7155    TRACE_AND_STEP();
7156    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7157        M.x86.R_EFLG = pop_long();
7158    } else {
7159        M.x86.R_FLG = pop_word();
7160    }
7161    DECODE_CLEAR_SEGOVR();
7162    END_OF_INSTR();
7163}
7164
7165/****************************************************************************
7166REMARKS:
7167Handles opcode 0x9e
7168****************************************************************************/
7169static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7170{
7171    START_OF_INSTR();
7172    DECODE_PRINTF("SAHF\n");
7173    TRACE_AND_STEP();
7174    /* clear the lower bits of the flag register */
7175    M.x86.R_FLG &= 0xffffff00;
7176    /* or in the AH register into the flags register */
7177    M.x86.R_FLG |= M.x86.R_AH;
7178    DECODE_CLEAR_SEGOVR();
7179    END_OF_INSTR();
7180}
7181
7182/****************************************************************************
7183REMARKS:
7184Handles opcode 0x9f
7185****************************************************************************/
7186static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7187{
7188    START_OF_INSTR();
7189    DECODE_PRINTF("LAHF\n");
7190    TRACE_AND_STEP();
7191	M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7192    /*undocumented TC++ behavior??? Nope.  It's documented, but
7193       you have too look real hard to notice it. */
7194    M.x86.R_AH |= 0x2;
7195    DECODE_CLEAR_SEGOVR();
7196    END_OF_INSTR();
7197}
7198
7199/****************************************************************************
7200REMARKS:
7201Handles opcode 0xa0
7202****************************************************************************/
7203static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7204{
7205    u16 offset;
7206
7207    START_OF_INSTR();
7208    DECODE_PRINTF("MOV\tAL,");
7209    offset = fetch_word_imm();
7210    DECODE_PRINTF2("[%04x]\n", offset);
7211    TRACE_AND_STEP();
7212    M.x86.R_AL = fetch_data_byte(offset);
7213    DECODE_CLEAR_SEGOVR();
7214    END_OF_INSTR();
7215}
7216
7217/****************************************************************************
7218REMARKS:
7219Handles opcode 0xa1
7220****************************************************************************/
7221static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7222{
7223    u16 offset;
7224
7225    START_OF_INSTR();
7226    offset = fetch_word_imm();
7227    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7228        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7229    } else {
7230        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7231    }
7232    TRACE_AND_STEP();
7233    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7234        M.x86.R_EAX = fetch_data_long(offset);
7235    } else {
7236        M.x86.R_AX = fetch_data_word(offset);
7237    }
7238    DECODE_CLEAR_SEGOVR();
7239    END_OF_INSTR();
7240}
7241
7242/****************************************************************************
7243REMARKS:
7244Handles opcode 0xa2
7245****************************************************************************/
7246static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7247{
7248    u16 offset;
7249
7250    START_OF_INSTR();
7251    DECODE_PRINTF("MOV\t");
7252    offset = fetch_word_imm();
7253    DECODE_PRINTF2("[%04x],AL\n", offset);
7254    TRACE_AND_STEP();
7255    store_data_byte(offset, M.x86.R_AL);
7256    DECODE_CLEAR_SEGOVR();
7257    END_OF_INSTR();
7258}
7259
7260/****************************************************************************
7261REMARKS:
7262Handles opcode 0xa3
7263****************************************************************************/
7264static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7265{
7266    u16 offset;
7267
7268    START_OF_INSTR();
7269    offset = fetch_word_imm();
7270    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7271        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7272    } else {
7273        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7274    }
7275    TRACE_AND_STEP();
7276    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7277        store_data_long(offset, M.x86.R_EAX);
7278    } else {
7279        store_data_word(offset, M.x86.R_AX);
7280    }
7281    DECODE_CLEAR_SEGOVR();
7282    END_OF_INSTR();
7283}
7284
7285/****************************************************************************
7286REMARKS:
7287Handles opcode 0xa4
7288****************************************************************************/
7289static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7290{
7291    u8  val;
7292    u32 count;
7293    int inc;
7294
7295    START_OF_INSTR();
7296    DECODE_PRINTF("MOVS\tBYTE\n");
7297    if (ACCESS_FLAG(F_DF))   /* down */
7298        inc = -1;
7299    else
7300        inc = 1;
7301    TRACE_AND_STEP();
7302    count = 1;
7303    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7304        /* dont care whether REPE or REPNE */
7305        /* move them until CX is ZERO. */
7306        count = M.x86.R_CX;
7307        M.x86.R_CX = 0;
7308        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7309    }
7310    while (count--) {
7311        val = fetch_data_byte(M.x86.R_SI);
7312        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7313        M.x86.R_SI += inc;
7314        M.x86.R_DI += inc;
7315    }
7316    DECODE_CLEAR_SEGOVR();
7317    END_OF_INSTR();
7318}
7319
7320/****************************************************************************
7321REMARKS:
7322Handles opcode 0xa5
7323****************************************************************************/
7324static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7325{
7326    u32 val;
7327    int inc;
7328    u32 count;
7329
7330    START_OF_INSTR();
7331    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7332        DECODE_PRINTF("MOVS\tDWORD\n");
7333        if (ACCESS_FLAG(F_DF))      /* down */
7334            inc = -4;
7335        else
7336            inc = 4;
7337    } else {
7338        DECODE_PRINTF("MOVS\tWORD\n");
7339        if (ACCESS_FLAG(F_DF))      /* down */
7340            inc = -2;
7341        else
7342            inc = 2;
7343    }
7344    TRACE_AND_STEP();
7345    count = 1;
7346    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7347        /* dont care whether REPE or REPNE */
7348        /* move them until CX is ZERO. */
7349        count = M.x86.R_CX;
7350        M.x86.R_CX = 0;
7351        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7352    }
7353    while (count--) {
7354        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7355            val = fetch_data_long(M.x86.R_SI);
7356            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7357        } else {
7358            val = fetch_data_word(M.x86.R_SI);
7359            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7360        }
7361        M.x86.R_SI += inc;
7362        M.x86.R_DI += inc;
7363    }
7364    DECODE_CLEAR_SEGOVR();
7365    END_OF_INSTR();
7366}
7367
7368/****************************************************************************
7369REMARKS:
7370Handles opcode 0xa6
7371****************************************************************************/
7372static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7373{
7374    s8 val1, val2;
7375    int inc;
7376
7377    START_OF_INSTR();
7378    DECODE_PRINTF("CMPS\tBYTE\n");
7379    TRACE_AND_STEP();
7380    if (ACCESS_FLAG(F_DF))   /* down */
7381        inc = -1;
7382    else
7383        inc = 1;
7384
7385    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7386        /* REPE  */
7387        /* move them until CX is ZERO. */
7388        while (M.x86.R_CX != 0) {
7389            val1 = fetch_data_byte(M.x86.R_SI);
7390            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7391                     cmp_byte(val1, val2);
7392            M.x86.R_CX -= 1;
7393            M.x86.R_SI += inc;
7394            M.x86.R_DI += inc;
7395            if (ACCESS_FLAG(F_ZF) == 0)
7396                break;
7397        }
7398        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7399    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7400        /* REPNE  */
7401        /* move them until CX is ZERO. */
7402        while (M.x86.R_CX != 0) {
7403            val1 = fetch_data_byte(M.x86.R_SI);
7404            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7405            cmp_byte(val1, val2);
7406            M.x86.R_CX -= 1;
7407            M.x86.R_SI += inc;
7408            M.x86.R_DI += inc;
7409            if (ACCESS_FLAG(F_ZF))
7410                break;          /* zero flag set means equal */
7411        }
7412        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7413    } else {
7414        val1 = fetch_data_byte(M.x86.R_SI);
7415        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7416        cmp_byte(val1, val2);
7417        M.x86.R_SI += inc;
7418        M.x86.R_DI += inc;
7419    }
7420    DECODE_CLEAR_SEGOVR();
7421    END_OF_INSTR();
7422}
7423
7424/****************************************************************************
7425REMARKS:
7426Handles opcode 0xa7
7427****************************************************************************/
7428static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7429{
7430    u32 val1,val2;
7431    int inc;
7432
7433    START_OF_INSTR();
7434    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7435        DECODE_PRINTF("CMPS\tDWORD\n");
7436        if (ACCESS_FLAG(F_DF))   /* down */
7437            inc = -4;
7438        else
7439            inc = 4;
7440    } else {
7441        DECODE_PRINTF("CMPS\tWORD\n");
7442        if (ACCESS_FLAG(F_DF))   /* down */
7443            inc = -2;
7444        else
7445            inc = 2;
7446    }
7447    TRACE_AND_STEP();
7448    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7449        /* REPE  */
7450        /* move them until CX is ZERO. */
7451        while (M.x86.R_CX != 0) {
7452            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7453                val1 = fetch_data_long(M.x86.R_SI);
7454                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7455                cmp_long(val1, val2);
7456            } else {
7457                val1 = fetch_data_word(M.x86.R_SI);
7458                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7459                cmp_word((u16)val1, (u16)val2);
7460            }
7461            M.x86.R_CX -= 1;
7462            M.x86.R_SI += inc;
7463            M.x86.R_DI += inc;
7464            if (ACCESS_FLAG(F_ZF) == 0)
7465                break;
7466        }
7467        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7468    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7469        /* REPNE  */
7470        /* move them until CX is ZERO. */
7471        while (M.x86.R_CX != 0) {
7472            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7473                val1 = fetch_data_long(M.x86.R_SI);
7474                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7475                cmp_long(val1, val2);
7476            } else {
7477                val1 = fetch_data_word(M.x86.R_SI);
7478                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7479                cmp_word((u16)val1, (u16)val2);
7480            }
7481            M.x86.R_CX -= 1;
7482            M.x86.R_SI += inc;
7483            M.x86.R_DI += inc;
7484            if (ACCESS_FLAG(F_ZF))
7485                break;          /* zero flag set means equal */
7486        }
7487        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7488    } else {
7489        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7490            val1 = fetch_data_long(M.x86.R_SI);
7491            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7492            cmp_long(val1, val2);
7493        } else {
7494            val1 = fetch_data_word(M.x86.R_SI);
7495            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7496            cmp_word((u16)val1, (u16)val2);
7497        }
7498        M.x86.R_SI += inc;
7499        M.x86.R_DI += inc;
7500    }
7501    DECODE_CLEAR_SEGOVR();
7502    END_OF_INSTR();
7503}
7504
7505/****************************************************************************
7506REMARKS:
7507Handles opcode 0xa8
7508****************************************************************************/
7509static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7510{
7511    int imm;
7512
7513    START_OF_INSTR();
7514    DECODE_PRINTF("TEST\tAL,");
7515    imm = fetch_byte_imm();
7516    DECODE_PRINTF2("%04x\n", imm);
7517    TRACE_AND_STEP();
7518	test_byte(M.x86.R_AL, (u8)imm);
7519    DECODE_CLEAR_SEGOVR();
7520    END_OF_INSTR();
7521}
7522
7523/****************************************************************************
7524REMARKS:
7525Handles opcode 0xa9
7526****************************************************************************/
7527static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7528{
7529    u32 srcval;
7530
7531    START_OF_INSTR();
7532    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7533        DECODE_PRINTF("TEST\tEAX,");
7534        srcval = fetch_long_imm();
7535    } else {
7536        DECODE_PRINTF("TEST\tAX,");
7537        srcval = fetch_word_imm();
7538    }
7539    DECODE_PRINTF2("%x\n", srcval);
7540    TRACE_AND_STEP();
7541    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7542        test_long(M.x86.R_EAX, srcval);
7543    } else {
7544        test_word(M.x86.R_AX, (u16)srcval);
7545    }
7546    DECODE_CLEAR_SEGOVR();
7547    END_OF_INSTR();
7548}
7549
7550/****************************************************************************
7551REMARKS:
7552Handles opcode 0xaa
7553****************************************************************************/
7554static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7555{
7556    int inc;
7557
7558    START_OF_INSTR();
7559    DECODE_PRINTF("STOS\tBYTE\n");
7560    if (ACCESS_FLAG(F_DF))   /* down */
7561        inc = -1;
7562    else
7563        inc = 1;
7564    TRACE_AND_STEP();
7565    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7566        /* dont care whether REPE or REPNE */
7567        /* move them until CX is ZERO. */
7568        while (M.x86.R_CX != 0) {
7569            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7570            M.x86.R_CX -= 1;
7571            M.x86.R_DI += inc;
7572        }
7573        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7574    } else {
7575        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7576        M.x86.R_DI += inc;
7577    }
7578    DECODE_CLEAR_SEGOVR();
7579    END_OF_INSTR();
7580}
7581
7582/****************************************************************************
7583REMARKS:
7584Handles opcode 0xab
7585****************************************************************************/
7586static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7587{
7588    int inc;
7589    u32 count;
7590
7591    START_OF_INSTR();
7592    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7593        DECODE_PRINTF("STOS\tDWORD\n");
7594        if (ACCESS_FLAG(F_DF))   /* down */
7595            inc = -4;
7596        else
7597            inc = 4;
7598    } else {
7599        DECODE_PRINTF("STOS\tWORD\n");
7600        if (ACCESS_FLAG(F_DF))   /* down */
7601            inc = -2;
7602        else
7603            inc = 2;
7604    }
7605    TRACE_AND_STEP();
7606    count = 1;
7607    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7608        /* dont care whether REPE or REPNE */
7609        /* move them until CX is ZERO. */
7610        count = M.x86.R_CX;
7611        M.x86.R_CX = 0;
7612        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7613    }
7614    while (count--) {
7615        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7616            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7617        } else {
7618            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7619        }
7620        M.x86.R_DI += inc;
7621    }
7622    DECODE_CLEAR_SEGOVR();
7623    END_OF_INSTR();
7624}
7625
7626/****************************************************************************
7627REMARKS:
7628Handles opcode 0xac
7629****************************************************************************/
7630static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7631{
7632    int inc;
7633
7634    START_OF_INSTR();
7635    DECODE_PRINTF("LODS\tBYTE\n");
7636    TRACE_AND_STEP();
7637    if (ACCESS_FLAG(F_DF))   /* down */
7638        inc = -1;
7639    else
7640        inc = 1;
7641    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7642        /* dont care whether REPE or REPNE */
7643        /* move them until CX is ZERO. */
7644        while (M.x86.R_CX != 0) {
7645            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7646            M.x86.R_CX -= 1;
7647            M.x86.R_SI += inc;
7648        }
7649        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7650    } else {
7651        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7652        M.x86.R_SI += inc;
7653    }
7654    DECODE_CLEAR_SEGOVR();
7655    END_OF_INSTR();
7656}
7657
7658/****************************************************************************
7659REMARKS:
7660Handles opcode 0xad
7661****************************************************************************/
7662static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7663{
7664    int inc;
7665    u32 count;
7666
7667    START_OF_INSTR();
7668    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7669        DECODE_PRINTF("LODS\tDWORD\n");
7670        if (ACCESS_FLAG(F_DF))   /* down */
7671            inc = -4;
7672        else
7673            inc = 4;
7674    } else {
7675        DECODE_PRINTF("LODS\tWORD\n");
7676        if (ACCESS_FLAG(F_DF))   /* down */
7677            inc = -2;
7678        else
7679            inc = 2;
7680    }
7681    TRACE_AND_STEP();
7682    count = 1;
7683    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7684        /* dont care whether REPE or REPNE */
7685        /* move them until CX is ZERO. */
7686        count = M.x86.R_CX;
7687        M.x86.R_CX = 0;
7688        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7689    }
7690    while (count--) {
7691        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7692            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7693        } else {
7694            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7695        }
7696        M.x86.R_SI += inc;
7697    }
7698    DECODE_CLEAR_SEGOVR();
7699    END_OF_INSTR();
7700}
7701
7702/****************************************************************************
7703REMARKS:
7704Handles opcode 0xae
7705****************************************************************************/
7706static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7707{
7708    s8 val2;
7709    int inc;
7710
7711    START_OF_INSTR();
7712    DECODE_PRINTF("SCAS\tBYTE\n");
7713    TRACE_AND_STEP();
7714    if (ACCESS_FLAG(F_DF))   /* down */
7715        inc = -1;
7716    else
7717        inc = 1;
7718    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7719        /* REPE  */
7720        /* move them until CX is ZERO. */
7721        while (M.x86.R_CX != 0) {
7722            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7723            cmp_byte(M.x86.R_AL, val2);
7724            M.x86.R_CX -= 1;
7725            M.x86.R_DI += inc;
7726            if (ACCESS_FLAG(F_ZF) == 0)
7727                break;
7728        }
7729        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7730    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7731        /* REPNE  */
7732        /* move them until CX is ZERO. */
7733        while (M.x86.R_CX != 0) {
7734            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7735            cmp_byte(M.x86.R_AL, val2);
7736            M.x86.R_CX -= 1;
7737            M.x86.R_DI += inc;
7738            if (ACCESS_FLAG(F_ZF))
7739                break;          /* zero flag set means equal */
7740        }
7741        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7742    } else {
7743        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7744        cmp_byte(M.x86.R_AL, val2);
7745        M.x86.R_DI += inc;
7746    }
7747    DECODE_CLEAR_SEGOVR();
7748    END_OF_INSTR();
7749}
7750
7751/****************************************************************************
7752REMARKS:
7753Handles opcode 0xaf
7754****************************************************************************/
7755static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7756{
7757    int inc;
7758    u32 val;
7759
7760    START_OF_INSTR();
7761    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7762        DECODE_PRINTF("SCAS\tDWORD\n");
7763        if (ACCESS_FLAG(F_DF))   /* down */
7764            inc = -4;
7765        else
7766            inc = 4;
7767    } else {
7768        DECODE_PRINTF("SCAS\tWORD\n");
7769        if (ACCESS_FLAG(F_DF))   /* down */
7770            inc = -2;
7771        else
7772            inc = 2;
7773    }
7774    TRACE_AND_STEP();
7775    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7776        /* REPE  */
7777        /* move them until CX is ZERO. */
7778        while (M.x86.R_CX != 0) {
7779            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7780                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7781                cmp_long(M.x86.R_EAX, val);
7782            } else {
7783                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7784                cmp_word(M.x86.R_AX, (u16)val);
7785            }
7786            M.x86.R_CX -= 1;
7787            M.x86.R_DI += inc;
7788            if (ACCESS_FLAG(F_ZF) == 0)
7789                break;
7790        }
7791        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7792    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7793        /* REPNE  */
7794        /* move them until CX is ZERO. */
7795        while (M.x86.R_CX != 0) {
7796            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7797                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7798                cmp_long(M.x86.R_EAX, val);
7799            } else {
7800                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7801                cmp_word(M.x86.R_AX, (u16)val);
7802            }
7803            M.x86.R_CX -= 1;
7804            M.x86.R_DI += inc;
7805            if (ACCESS_FLAG(F_ZF))
7806                break;          /* zero flag set means equal */
7807        }
7808        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7809    } else {
7810        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7811            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7812            cmp_long(M.x86.R_EAX, val);
7813        } else {
7814            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7815            cmp_word(M.x86.R_AX, (u16)val);
7816        }
7817        M.x86.R_DI += inc;
7818    }
7819    DECODE_CLEAR_SEGOVR();
7820    END_OF_INSTR();
7821}
7822
7823/****************************************************************************
7824REMARKS:
7825Handles opcode 0xb0
7826****************************************************************************/
7827static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7828{
7829    u8 imm;
7830
7831    START_OF_INSTR();
7832    DECODE_PRINTF("MOV\tAL,");
7833    imm = fetch_byte_imm();
7834    DECODE_PRINTF2("%x\n", imm);
7835    TRACE_AND_STEP();
7836    M.x86.R_AL = imm;
7837    DECODE_CLEAR_SEGOVR();
7838    END_OF_INSTR();
7839}
7840
7841/****************************************************************************
7842REMARKS:
7843Handles opcode 0xb1
7844****************************************************************************/
7845static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7846{
7847    u8 imm;
7848
7849    START_OF_INSTR();
7850    DECODE_PRINTF("MOV\tCL,");
7851    imm = fetch_byte_imm();
7852    DECODE_PRINTF2("%x\n", imm);
7853    TRACE_AND_STEP();
7854    M.x86.R_CL = imm;
7855    DECODE_CLEAR_SEGOVR();
7856    END_OF_INSTR();
7857}
7858
7859/****************************************************************************
7860REMARKS:
7861Handles opcode 0xb2
7862****************************************************************************/
7863static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7864{
7865    u8 imm;
7866
7867    START_OF_INSTR();
7868    DECODE_PRINTF("MOV\tDL,");
7869    imm = fetch_byte_imm();
7870    DECODE_PRINTF2("%x\n", imm);
7871    TRACE_AND_STEP();
7872    M.x86.R_DL = imm;
7873    DECODE_CLEAR_SEGOVR();
7874    END_OF_INSTR();
7875}
7876
7877/****************************************************************************
7878REMARKS:
7879Handles opcode 0xb3
7880****************************************************************************/
7881static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7882{
7883    u8 imm;
7884
7885    START_OF_INSTR();
7886    DECODE_PRINTF("MOV\tBL,");
7887    imm = fetch_byte_imm();
7888    DECODE_PRINTF2("%x\n", imm);
7889    TRACE_AND_STEP();
7890    M.x86.R_BL = imm;
7891    DECODE_CLEAR_SEGOVR();
7892    END_OF_INSTR();
7893}
7894
7895/****************************************************************************
7896REMARKS:
7897Handles opcode 0xb4
7898****************************************************************************/
7899static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7900{
7901    u8 imm;
7902
7903    START_OF_INSTR();
7904    DECODE_PRINTF("MOV\tAH,");
7905    imm = fetch_byte_imm();
7906    DECODE_PRINTF2("%x\n", imm);
7907    TRACE_AND_STEP();
7908    M.x86.R_AH = imm;
7909    DECODE_CLEAR_SEGOVR();
7910    END_OF_INSTR();
7911}
7912
7913/****************************************************************************
7914REMARKS:
7915Handles opcode 0xb5
7916****************************************************************************/
7917static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7918{
7919    u8 imm;
7920
7921    START_OF_INSTR();
7922    DECODE_PRINTF("MOV\tCH,");
7923    imm = fetch_byte_imm();
7924    DECODE_PRINTF2("%x\n", imm);
7925    TRACE_AND_STEP();
7926    M.x86.R_CH = imm;
7927    DECODE_CLEAR_SEGOVR();
7928    END_OF_INSTR();
7929}
7930
7931/****************************************************************************
7932REMARKS:
7933Handles opcode 0xb6
7934****************************************************************************/
7935static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7936{
7937    u8 imm;
7938
7939    START_OF_INSTR();
7940    DECODE_PRINTF("MOV\tDH,");
7941    imm = fetch_byte_imm();
7942    DECODE_PRINTF2("%x\n", imm);
7943    TRACE_AND_STEP();
7944    M.x86.R_DH = imm;
7945    DECODE_CLEAR_SEGOVR();
7946    END_OF_INSTR();
7947}
7948
7949/****************************************************************************
7950REMARKS:
7951Handles opcode 0xb7
7952****************************************************************************/
7953static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7954{
7955    u8 imm;
7956
7957    START_OF_INSTR();
7958    DECODE_PRINTF("MOV\tBH,");
7959    imm = fetch_byte_imm();
7960    DECODE_PRINTF2("%x\n", imm);
7961    TRACE_AND_STEP();
7962    M.x86.R_BH = imm;
7963    DECODE_CLEAR_SEGOVR();
7964    END_OF_INSTR();
7965}
7966
7967/****************************************************************************
7968REMARKS:
7969Handles opcode 0xb8
7970****************************************************************************/
7971static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7972{
7973    u32 srcval;
7974
7975    START_OF_INSTR();
7976    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7977        DECODE_PRINTF("MOV\tEAX,");
7978        srcval = fetch_long_imm();
7979    } else {
7980        DECODE_PRINTF("MOV\tAX,");
7981        srcval = fetch_word_imm();
7982    }
7983    DECODE_PRINTF2("%x\n", srcval);
7984    TRACE_AND_STEP();
7985    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7986        M.x86.R_EAX = srcval;
7987    } else {
7988        M.x86.R_AX = (u16)srcval;
7989    }
7990    DECODE_CLEAR_SEGOVR();
7991    END_OF_INSTR();
7992}
7993
7994/****************************************************************************
7995REMARKS:
7996Handles opcode 0xb9
7997****************************************************************************/
7998static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7999{
8000    u32 srcval;
8001
8002    START_OF_INSTR();
8003    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8004        DECODE_PRINTF("MOV\tECX,");
8005        srcval = fetch_long_imm();
8006    } else {
8007        DECODE_PRINTF("MOV\tCX,");
8008        srcval = fetch_word_imm();
8009    }
8010    DECODE_PRINTF2("%x\n", srcval);
8011    TRACE_AND_STEP();
8012    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8013        M.x86.R_ECX = srcval;
8014    } else {
8015        M.x86.R_CX = (u16)srcval;
8016    }
8017    DECODE_CLEAR_SEGOVR();
8018    END_OF_INSTR();
8019}
8020
8021/****************************************************************************
8022REMARKS:
8023Handles opcode 0xba
8024****************************************************************************/
8025static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8026{
8027    u32 srcval;
8028
8029    START_OF_INSTR();
8030    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8031        DECODE_PRINTF("MOV\tEDX,");
8032        srcval = fetch_long_imm();
8033    } else {
8034        DECODE_PRINTF("MOV\tDX,");
8035        srcval = fetch_word_imm();
8036    }
8037    DECODE_PRINTF2("%x\n", srcval);
8038    TRACE_AND_STEP();
8039    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8040        M.x86.R_EDX = srcval;
8041    } else {
8042        M.x86.R_DX = (u16)srcval;
8043    }
8044    DECODE_CLEAR_SEGOVR();
8045    END_OF_INSTR();
8046}
8047
8048/****************************************************************************
8049REMARKS:
8050Handles opcode 0xbb
8051****************************************************************************/
8052static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8053{
8054    u32 srcval;
8055
8056    START_OF_INSTR();
8057    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8058        DECODE_PRINTF("MOV\tEBX,");
8059        srcval = fetch_long_imm();
8060    } else {
8061        DECODE_PRINTF("MOV\tBX,");
8062        srcval = fetch_word_imm();
8063    }
8064    DECODE_PRINTF2("%x\n", srcval);
8065    TRACE_AND_STEP();
8066    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8067        M.x86.R_EBX = srcval;
8068    } else {
8069        M.x86.R_BX = (u16)srcval;
8070    }
8071    DECODE_CLEAR_SEGOVR();
8072    END_OF_INSTR();
8073}
8074
8075/****************************************************************************
8076REMARKS:
8077Handles opcode 0xbc
8078****************************************************************************/
8079static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8080{
8081    u32 srcval;
8082
8083    START_OF_INSTR();
8084    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8085        DECODE_PRINTF("MOV\tESP,");
8086        srcval = fetch_long_imm();
8087    } else {
8088        DECODE_PRINTF("MOV\tSP,");
8089        srcval = fetch_word_imm();
8090    }
8091    DECODE_PRINTF2("%x\n", srcval);
8092    TRACE_AND_STEP();
8093    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8094        M.x86.R_ESP = srcval;
8095    } else {
8096        M.x86.R_SP = (u16)srcval;
8097    }
8098    DECODE_CLEAR_SEGOVR();
8099    END_OF_INSTR();
8100}
8101
8102/****************************************************************************
8103REMARKS:
8104Handles opcode 0xbd
8105****************************************************************************/
8106static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8107{
8108    u32 srcval;
8109
8110    START_OF_INSTR();
8111    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8112        DECODE_PRINTF("MOV\tEBP,");
8113        srcval = fetch_long_imm();
8114    } else {
8115        DECODE_PRINTF("MOV\tBP,");
8116        srcval = fetch_word_imm();
8117    }
8118    DECODE_PRINTF2("%x\n", srcval);
8119    TRACE_AND_STEP();
8120    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8121        M.x86.R_EBP = srcval;
8122    } else {
8123        M.x86.R_BP = (u16)srcval;
8124    }
8125    DECODE_CLEAR_SEGOVR();
8126    END_OF_INSTR();
8127}
8128
8129/****************************************************************************
8130REMARKS:
8131Handles opcode 0xbe
8132****************************************************************************/
8133static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8134{
8135    u32 srcval;
8136
8137    START_OF_INSTR();
8138    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8139        DECODE_PRINTF("MOV\tESI,");
8140        srcval = fetch_long_imm();
8141    } else {
8142        DECODE_PRINTF("MOV\tSI,");
8143        srcval = fetch_word_imm();
8144    }
8145    DECODE_PRINTF2("%x\n", srcval);
8146    TRACE_AND_STEP();
8147    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8148        M.x86.R_ESI = srcval;
8149    } else {
8150        M.x86.R_SI = (u16)srcval;
8151    }
8152    DECODE_CLEAR_SEGOVR();
8153    END_OF_INSTR();
8154}
8155
8156/****************************************************************************
8157REMARKS:
8158Handles opcode 0xbf
8159****************************************************************************/
8160static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8161{
8162    u32 srcval;
8163
8164    START_OF_INSTR();
8165    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8166        DECODE_PRINTF("MOV\tEDI,");
8167        srcval = fetch_long_imm();
8168    } else {
8169        DECODE_PRINTF("MOV\tDI,");
8170        srcval = fetch_word_imm();
8171    }
8172    DECODE_PRINTF2("%x\n", srcval);
8173    TRACE_AND_STEP();
8174    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8175        M.x86.R_EDI = srcval;
8176    } else {
8177        M.x86.R_DI = (u16)srcval;
8178    }
8179    DECODE_CLEAR_SEGOVR();
8180    END_OF_INSTR();
8181}
8182
8183/* used by opcodes c0, d0, and d2. */
8184static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8185{
8186    rol_byte,
8187    ror_byte,
8188    rcl_byte,
8189    rcr_byte,
8190    shl_byte,
8191    shr_byte,
8192    shl_byte,           /* sal_byte === shl_byte  by definition */
8193    sar_byte,
8194};
8195
8196/****************************************************************************
8197REMARKS:
8198Handles opcode 0xc0
8199****************************************************************************/
8200static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8201{
8202    int mod, rl, rh;
8203    u8 *destreg;
8204    uint destoffset;
8205    u8 destval;
8206    u8 amt;
8207
8208    /*
8209     * Yet another weirdo special case instruction format.  Part of
8210     * the opcode held below in "RH".  Doubly nested case would
8211     * result, except that the decoded instruction
8212     */
8213    START_OF_INSTR();
8214    FETCH_DECODE_MODRM(mod, rh, rl);
8215#ifdef DEBUG
8216    if (DEBUG_DECODE()) {
8217        /* XXX DECODE_PRINTF may be changed to something more
8218           general, so that it is important to leave the strings
8219           in the same format, even though the result is that the
8220           above test is done twice. */
8221
8222        switch (rh) {
8223        case 0:
8224            DECODE_PRINTF("ROL\t");
8225            break;
8226        case 1:
8227            DECODE_PRINTF("ROR\t");
8228            break;
8229        case 2:
8230            DECODE_PRINTF("RCL\t");
8231            break;
8232        case 3:
8233            DECODE_PRINTF("RCR\t");
8234            break;
8235        case 4:
8236            DECODE_PRINTF("SHL\t");
8237            break;
8238        case 5:
8239            DECODE_PRINTF("SHR\t");
8240            break;
8241        case 6:
8242            DECODE_PRINTF("SAL\t");
8243            break;
8244        case 7:
8245            DECODE_PRINTF("SAR\t");
8246            break;
8247        }
8248    }
8249#endif
8250    /* know operation, decode the mod byte to find the addressing
8251       mode. */
8252    switch (mod) {
8253    case 0:
8254        DECODE_PRINTF("BYTE PTR ");
8255        destoffset = decode_rm00_address(rl);
8256        amt = fetch_byte_imm();
8257        DECODE_PRINTF2(",%x\n", amt);
8258        destval = fetch_data_byte(destoffset);
8259        TRACE_AND_STEP();
8260        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8261        store_data_byte(destoffset, destval);
8262        break;
8263    case 1:
8264        DECODE_PRINTF("BYTE PTR ");
8265        destoffset = decode_rm01_address(rl);
8266        amt = fetch_byte_imm();
8267        DECODE_PRINTF2(",%x\n", amt);
8268        destval = fetch_data_byte(destoffset);
8269        TRACE_AND_STEP();
8270        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8271        store_data_byte(destoffset, destval);
8272        break;
8273    case 2:
8274        DECODE_PRINTF("BYTE PTR ");
8275        destoffset = decode_rm10_address(rl);
8276        amt = fetch_byte_imm();
8277        DECODE_PRINTF2(",%x\n", amt);
8278        destval = fetch_data_byte(destoffset);
8279        TRACE_AND_STEP();
8280        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8281        store_data_byte(destoffset, destval);
8282        break;
8283    case 3:                     /* register to register */
8284        destreg = DECODE_RM_BYTE_REGISTER(rl);
8285        amt = fetch_byte_imm();
8286        DECODE_PRINTF2(",%x\n", amt);
8287        TRACE_AND_STEP();
8288        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8289        *destreg = destval;
8290        break;
8291    }
8292    DECODE_CLEAR_SEGOVR();
8293    END_OF_INSTR();
8294}
8295
8296/* used by opcodes c1, d1, and d3. */
8297static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8298{
8299    rol_word,
8300    ror_word,
8301    rcl_word,
8302    rcr_word,
8303    shl_word,
8304    shr_word,
8305    shl_word,           /* sal_byte === shl_byte  by definition */
8306    sar_word,
8307};
8308
8309/* used by opcodes c1, d1, and d3. */
8310static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8311{
8312    rol_long,
8313    ror_long,
8314    rcl_long,
8315    rcr_long,
8316    shl_long,
8317    shr_long,
8318    shl_long,           /* sal_byte === shl_byte  by definition */
8319    sar_long,
8320};
8321
8322/****************************************************************************
8323REMARKS:
8324Handles opcode 0xc1
8325****************************************************************************/
8326static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8327{
8328    int mod, rl, rh;
8329    uint destoffset;
8330    u8 amt;
8331
8332    /*
8333     * Yet another weirdo special case instruction format.  Part of
8334     * the opcode held below in "RH".  Doubly nested case would
8335     * result, except that the decoded instruction
8336     */
8337    START_OF_INSTR();
8338    FETCH_DECODE_MODRM(mod, rh, rl);
8339#ifdef DEBUG
8340    if (DEBUG_DECODE()) {
8341        /* XXX DECODE_PRINTF may be changed to something more
8342           general, so that it is important to leave the strings
8343           in the same format, even though the result is that the
8344           above test is done twice. */
8345
8346        switch (rh) {
8347        case 0:
8348            DECODE_PRINTF("ROL\t");
8349            break;
8350        case 1:
8351            DECODE_PRINTF("ROR\t");
8352            break;
8353        case 2:
8354            DECODE_PRINTF("RCL\t");
8355            break;
8356        case 3:
8357            DECODE_PRINTF("RCR\t");
8358            break;
8359        case 4:
8360            DECODE_PRINTF("SHL\t");
8361            break;
8362        case 5:
8363            DECODE_PRINTF("SHR\t");
8364            break;
8365        case 6:
8366            DECODE_PRINTF("SAL\t");
8367            break;
8368        case 7:
8369            DECODE_PRINTF("SAR\t");
8370            break;
8371        }
8372    }
8373#endif
8374    /* know operation, decode the mod byte to find the addressing
8375       mode. */
8376    switch (mod) {
8377    case 0:
8378        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8379            u32 destval;
8380
8381            DECODE_PRINTF("DWORD PTR ");
8382            destoffset = decode_rm00_address(rl);
8383            amt = fetch_byte_imm();
8384            DECODE_PRINTF2(",%x\n", amt);
8385            destval = fetch_data_long(destoffset);
8386            TRACE_AND_STEP();
8387            destval = (*opcD1_long_operation[rh]) (destval, amt);
8388            store_data_long(destoffset, destval);
8389        } else {
8390            u16 destval;
8391
8392            DECODE_PRINTF("WORD PTR ");
8393            destoffset = decode_rm00_address(rl);
8394            amt = fetch_byte_imm();
8395            DECODE_PRINTF2(",%x\n", amt);
8396            destval = fetch_data_word(destoffset);
8397            TRACE_AND_STEP();
8398            destval = (*opcD1_word_operation[rh]) (destval, amt);
8399            store_data_word(destoffset, destval);
8400        }
8401        break;
8402    case 1:
8403        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8404            u32 destval;
8405
8406            DECODE_PRINTF("DWORD PTR ");
8407            destoffset = decode_rm01_address(rl);
8408            amt = fetch_byte_imm();
8409            DECODE_PRINTF2(",%x\n", amt);
8410            destval = fetch_data_long(destoffset);
8411            TRACE_AND_STEP();
8412            destval = (*opcD1_long_operation[rh]) (destval, amt);
8413            store_data_long(destoffset, destval);
8414        } else {
8415            u16 destval;
8416
8417            DECODE_PRINTF("WORD PTR ");
8418            destoffset = decode_rm01_address(rl);
8419            amt = fetch_byte_imm();
8420            DECODE_PRINTF2(",%x\n", amt);
8421            destval = fetch_data_word(destoffset);
8422            TRACE_AND_STEP();
8423            destval = (*opcD1_word_operation[rh]) (destval, amt);
8424            store_data_word(destoffset, destval);
8425        }
8426        break;
8427    case 2:
8428        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8429            u32 destval;
8430
8431            DECODE_PRINTF("DWORD PTR ");
8432            destoffset = decode_rm10_address(rl);
8433            amt = fetch_byte_imm();
8434            DECODE_PRINTF2(",%x\n", amt);
8435            destval = fetch_data_long(destoffset);
8436            TRACE_AND_STEP();
8437            destval = (*opcD1_long_operation[rh]) (destval, amt);
8438            store_data_long(destoffset, destval);
8439        } else {
8440            u16 destval;
8441
8442            DECODE_PRINTF("WORD PTR ");
8443            destoffset = decode_rm10_address(rl);
8444            amt = fetch_byte_imm();
8445            DECODE_PRINTF2(",%x\n", amt);
8446            destval = fetch_data_word(destoffset);
8447            TRACE_AND_STEP();
8448            destval = (*opcD1_word_operation[rh]) (destval, amt);
8449            store_data_word(destoffset, destval);
8450        }
8451        break;
8452    case 3:                     /* register to register */
8453        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8454            u32 *destreg;
8455
8456            destreg = DECODE_RM_LONG_REGISTER(rl);
8457            amt = fetch_byte_imm();
8458            DECODE_PRINTF2(",%x\n", amt);
8459            TRACE_AND_STEP();
8460            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8461        } else {
8462            u16 *destreg;
8463
8464            destreg = DECODE_RM_WORD_REGISTER(rl);
8465            amt = fetch_byte_imm();
8466            DECODE_PRINTF2(",%x\n", amt);
8467            TRACE_AND_STEP();
8468            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8469        }
8470        break;
8471    }
8472    DECODE_CLEAR_SEGOVR();
8473    END_OF_INSTR();
8474}
8475
8476/****************************************************************************
8477REMARKS:
8478Handles opcode 0xc2
8479****************************************************************************/
8480static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8481{
8482    u16 imm;
8483
8484    START_OF_INSTR();
8485    DECODE_PRINTF("RET\t");
8486    imm = fetch_word_imm();
8487    DECODE_PRINTF2("%x\n", imm);
8488	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8489	TRACE_AND_STEP();
8490    M.x86.R_IP = pop_word();
8491    M.x86.R_SP += imm;
8492    DECODE_CLEAR_SEGOVR();
8493    END_OF_INSTR();
8494}
8495
8496/****************************************************************************
8497REMARKS:
8498Handles opcode 0xc3
8499****************************************************************************/
8500static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8501{
8502    START_OF_INSTR();
8503    DECODE_PRINTF("RET\n");
8504	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8505	TRACE_AND_STEP();
8506    M.x86.R_IP = pop_word();
8507    DECODE_CLEAR_SEGOVR();
8508    END_OF_INSTR();
8509}
8510
8511/****************************************************************************
8512REMARKS:
8513Handles opcode 0xc4
8514****************************************************************************/
8515static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8516{
8517    int mod, rh, rl;
8518    u16 *dstreg;
8519    uint srcoffset;
8520
8521    START_OF_INSTR();
8522    DECODE_PRINTF("LES\t");
8523    FETCH_DECODE_MODRM(mod, rh, rl);
8524    switch (mod) {
8525    case 0:
8526        dstreg = DECODE_RM_WORD_REGISTER(rh);
8527        DECODE_PRINTF(",");
8528        srcoffset = decode_rm00_address(rl);
8529        DECODE_PRINTF("\n");
8530        TRACE_AND_STEP();
8531        *dstreg = fetch_data_word(srcoffset);
8532        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8533        break;
8534    case 1:
8535        dstreg = DECODE_RM_WORD_REGISTER(rh);
8536        DECODE_PRINTF(",");
8537        srcoffset = decode_rm01_address(rl);
8538        DECODE_PRINTF("\n");
8539        TRACE_AND_STEP();
8540        *dstreg = fetch_data_word(srcoffset);
8541        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8542        break;
8543    case 2:
8544        dstreg = DECODE_RM_WORD_REGISTER(rh);
8545        DECODE_PRINTF(",");
8546        srcoffset = decode_rm10_address(rl);
8547        DECODE_PRINTF("\n");
8548        TRACE_AND_STEP();
8549        *dstreg = fetch_data_word(srcoffset);
8550        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8551        break;
8552    case 3:                     /* register to register */
8553        /* UNDEFINED! */
8554        TRACE_AND_STEP();
8555    }
8556    DECODE_CLEAR_SEGOVR();
8557    END_OF_INSTR();
8558}
8559
8560/****************************************************************************
8561REMARKS:
8562Handles opcode 0xc5
8563****************************************************************************/
8564static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8565{
8566    int mod, rh, rl;
8567    u16 *dstreg;
8568    uint srcoffset;
8569
8570    START_OF_INSTR();
8571    DECODE_PRINTF("LDS\t");
8572    FETCH_DECODE_MODRM(mod, rh, rl);
8573    switch (mod) {
8574    case 0:
8575        dstreg = DECODE_RM_WORD_REGISTER(rh);
8576        DECODE_PRINTF(",");
8577        srcoffset = decode_rm00_address(rl);
8578        DECODE_PRINTF("\n");
8579        TRACE_AND_STEP();
8580        *dstreg = fetch_data_word(srcoffset);
8581        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8582        break;
8583    case 1:
8584        dstreg = DECODE_RM_WORD_REGISTER(rh);
8585        DECODE_PRINTF(",");
8586        srcoffset = decode_rm01_address(rl);
8587        DECODE_PRINTF("\n");
8588        TRACE_AND_STEP();
8589        *dstreg = fetch_data_word(srcoffset);
8590        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8591        break;
8592    case 2:
8593        dstreg = DECODE_RM_WORD_REGISTER(rh);
8594        DECODE_PRINTF(",");
8595        srcoffset = decode_rm10_address(rl);
8596        DECODE_PRINTF("\n");
8597        TRACE_AND_STEP();
8598        *dstreg = fetch_data_word(srcoffset);
8599        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8600        break;
8601    case 3:                     /* register to register */
8602        /* UNDEFINED! */
8603        TRACE_AND_STEP();
8604    }
8605    DECODE_CLEAR_SEGOVR();
8606    END_OF_INSTR();
8607}
8608
8609/****************************************************************************
8610REMARKS:
8611Handles opcode 0xc6
8612****************************************************************************/
8613static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8614{
8615    int mod, rl, rh;
8616    u8 *destreg;
8617    uint destoffset;
8618    u8 imm;
8619
8620    START_OF_INSTR();
8621    DECODE_PRINTF("MOV\t");
8622    FETCH_DECODE_MODRM(mod, rh, rl);
8623    if (rh != 0) {
8624        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8625        HALT_SYS();
8626    }
8627    switch (mod) {
8628    case 0:
8629        DECODE_PRINTF("BYTE PTR ");
8630        destoffset = decode_rm00_address(rl);
8631        imm = fetch_byte_imm();
8632        DECODE_PRINTF2(",%2x\n", imm);
8633        TRACE_AND_STEP();
8634        store_data_byte(destoffset, imm);
8635        break;
8636    case 1:
8637        DECODE_PRINTF("BYTE PTR ");
8638        destoffset = decode_rm01_address(rl);
8639        imm = fetch_byte_imm();
8640        DECODE_PRINTF2(",%2x\n", imm);
8641        TRACE_AND_STEP();
8642        store_data_byte(destoffset, imm);
8643        break;
8644    case 2:
8645        DECODE_PRINTF("BYTE PTR ");
8646        destoffset = decode_rm10_address(rl);
8647        imm = fetch_byte_imm();
8648        DECODE_PRINTF2(",%2x\n", imm);
8649        TRACE_AND_STEP();
8650        store_data_byte(destoffset, imm);
8651        break;
8652    case 3:                     /* register to register */
8653        destreg = DECODE_RM_BYTE_REGISTER(rl);
8654        imm = fetch_byte_imm();
8655        DECODE_PRINTF2(",%2x\n", imm);
8656        TRACE_AND_STEP();
8657        *destreg = imm;
8658        break;
8659    }
8660    DECODE_CLEAR_SEGOVR();
8661    END_OF_INSTR();
8662}
8663
8664/****************************************************************************
8665REMARKS:
8666Handles opcode 0xc7
8667****************************************************************************/
8668static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8669{
8670    int mod, rl, rh;
8671    uint destoffset;
8672
8673    START_OF_INSTR();
8674    DECODE_PRINTF("MOV\t");
8675    FETCH_DECODE_MODRM(mod, rh, rl);
8676    if (rh != 0) {
8677        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8678        HALT_SYS();
8679    }
8680    switch (mod) {
8681    case 0:
8682        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8683            u32 imm;
8684
8685            DECODE_PRINTF("DWORD PTR ");
8686            destoffset = decode_rm00_address(rl);
8687            imm = fetch_long_imm();
8688            DECODE_PRINTF2(",%x\n", imm);
8689            TRACE_AND_STEP();
8690            store_data_long(destoffset, imm);
8691        } else {
8692            u16 imm;
8693
8694            DECODE_PRINTF("WORD PTR ");
8695            destoffset = decode_rm00_address(rl);
8696            imm = fetch_word_imm();
8697            DECODE_PRINTF2(",%x\n", imm);
8698            TRACE_AND_STEP();
8699            store_data_word(destoffset, imm);
8700        }
8701        break;
8702    case 1:
8703        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8704            u32 imm;
8705
8706            DECODE_PRINTF("DWORD PTR ");
8707            destoffset = decode_rm01_address(rl);
8708            imm = fetch_long_imm();
8709            DECODE_PRINTF2(",%x\n", imm);
8710            TRACE_AND_STEP();
8711            store_data_long(destoffset, imm);
8712        } else {
8713            u16 imm;
8714
8715            DECODE_PRINTF("WORD PTR ");
8716            destoffset = decode_rm01_address(rl);
8717            imm = fetch_word_imm();
8718            DECODE_PRINTF2(",%x\n", imm);
8719            TRACE_AND_STEP();
8720            store_data_word(destoffset, imm);
8721        }
8722        break;
8723    case 2:
8724        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8725            u32 imm;
8726
8727            DECODE_PRINTF("DWORD PTR ");
8728            destoffset = decode_rm10_address(rl);
8729            imm = fetch_long_imm();
8730            DECODE_PRINTF2(",%x\n", imm);
8731            TRACE_AND_STEP();
8732            store_data_long(destoffset, imm);
8733        } else {
8734            u16 imm;
8735
8736            DECODE_PRINTF("WORD PTR ");
8737            destoffset = decode_rm10_address(rl);
8738            imm = fetch_word_imm();
8739            DECODE_PRINTF2(",%x\n", imm);
8740            TRACE_AND_STEP();
8741            store_data_word(destoffset, imm);
8742        }
8743        break;
8744    case 3:                     /* register to register */
8745        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8746			u32 *destreg;
8747			u32 imm;
8748
8749            destreg = DECODE_RM_LONG_REGISTER(rl);
8750            imm = fetch_long_imm();
8751            DECODE_PRINTF2(",%x\n", imm);
8752            TRACE_AND_STEP();
8753            *destreg = imm;
8754        } else {
8755			u16 *destreg;
8756			u16 imm;
8757
8758            destreg = DECODE_RM_WORD_REGISTER(rl);
8759            imm = fetch_word_imm();
8760            DECODE_PRINTF2(",%x\n", imm);
8761            TRACE_AND_STEP();
8762            *destreg = imm;
8763        }
8764        break;
8765    }
8766    DECODE_CLEAR_SEGOVR();
8767    END_OF_INSTR();
8768}
8769
8770/****************************************************************************
8771REMARKS:
8772Handles opcode 0xc8
8773****************************************************************************/
8774static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8775{
8776    u16 local,frame_pointer;
8777    u8  nesting;
8778    int i;
8779
8780    START_OF_INSTR();
8781    local = fetch_word_imm();
8782    nesting = fetch_byte_imm();
8783    DECODE_PRINTF2("ENTER %x\n", local);
8784    DECODE_PRINTF2(",%x\n", nesting);
8785    TRACE_AND_STEP();
8786    push_word(M.x86.R_BP);
8787    frame_pointer = M.x86.R_SP;
8788    if (nesting > 0) {
8789        for (i = 1; i < nesting; i++) {
8790            M.x86.R_BP -= 2;
8791            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8792            }
8793        push_word(frame_pointer);
8794        }
8795    M.x86.R_BP = frame_pointer;
8796    M.x86.R_SP = (u16)(M.x86.R_SP - local);
8797    DECODE_CLEAR_SEGOVR();
8798    END_OF_INSTR();
8799}
8800
8801/****************************************************************************
8802REMARKS:
8803Handles opcode 0xc9
8804****************************************************************************/
8805static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8806{
8807    START_OF_INSTR();
8808    DECODE_PRINTF("LEAVE\n");
8809    TRACE_AND_STEP();
8810    M.x86.R_SP = M.x86.R_BP;
8811    M.x86.R_BP = pop_word();
8812    DECODE_CLEAR_SEGOVR();
8813    END_OF_INSTR();
8814}
8815
8816/****************************************************************************
8817REMARKS:
8818Handles opcode 0xca
8819****************************************************************************/
8820static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8821{
8822    u16 imm;
8823
8824    START_OF_INSTR();
8825    DECODE_PRINTF("RETF\t");
8826    imm = fetch_word_imm();
8827    DECODE_PRINTF2("%x\n", imm);
8828	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8829	TRACE_AND_STEP();
8830    M.x86.R_IP = pop_word();
8831    M.x86.R_CS = pop_word();
8832    M.x86.R_SP += imm;
8833    DECODE_CLEAR_SEGOVR();
8834    END_OF_INSTR();
8835}
8836
8837/****************************************************************************
8838REMARKS:
8839Handles opcode 0xcb
8840****************************************************************************/
8841static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8842{
8843    START_OF_INSTR();
8844    DECODE_PRINTF("RETF\n");
8845	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8846	TRACE_AND_STEP();
8847    M.x86.R_IP = pop_word();
8848    M.x86.R_CS = pop_word();
8849    DECODE_CLEAR_SEGOVR();
8850    END_OF_INSTR();
8851}
8852
8853/****************************************************************************
8854REMARKS:
8855Handles opcode 0xcc
8856****************************************************************************/
8857static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8858{
8859    START_OF_INSTR();
8860    DECODE_PRINTF("INT 3\n");
8861    TRACE_AND_STEP();
8862    if (_X86EMU_intrTab[3]) {
8863	(*_X86EMU_intrTab[3])(3);
8864    } else {
8865        push_word((u16)M.x86.R_FLG);
8866        CLEAR_FLAG(F_IF);
8867        CLEAR_FLAG(F_TF);
8868        push_word(M.x86.R_CS);
8869        M.x86.R_CS = mem_access_word(3 * 4 + 2);
8870        push_word(M.x86.R_IP);
8871        M.x86.R_IP = mem_access_word(3 * 4);
8872    }
8873    DECODE_CLEAR_SEGOVR();
8874    END_OF_INSTR();
8875}
8876
8877/****************************************************************************
8878REMARKS:
8879Handles opcode 0xcd
8880****************************************************************************/
8881static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8882{
8883    u8 intnum;
8884
8885    START_OF_INSTR();
8886    DECODE_PRINTF("INT\t");
8887    intnum = fetch_byte_imm();
8888    DECODE_PRINTF2("%x\n", intnum);
8889    TRACE_AND_STEP();
8890    if (_X86EMU_intrTab[intnum]) {
8891	(*_X86EMU_intrTab[intnum])(intnum);
8892    } else {
8893        push_word((u16)M.x86.R_FLG);
8894        CLEAR_FLAG(F_IF);
8895        CLEAR_FLAG(F_TF);
8896        push_word(M.x86.R_CS);
8897        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8898        push_word(M.x86.R_IP);
8899        M.x86.R_IP = mem_access_word(intnum * 4);
8900    }
8901    DECODE_CLEAR_SEGOVR();
8902    END_OF_INSTR();
8903}
8904
8905/****************************************************************************
8906REMARKS:
8907Handles opcode 0xce
8908****************************************************************************/
8909static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8910{
8911    START_OF_INSTR();
8912    DECODE_PRINTF("INTO\n");
8913    TRACE_AND_STEP();
8914    if (ACCESS_FLAG(F_OF)) {
8915	if (_X86EMU_intrTab[4]) {
8916	    (*_X86EMU_intrTab[4])(4);
8917        } else {
8918            push_word((u16)M.x86.R_FLG);
8919            CLEAR_FLAG(F_IF);
8920            CLEAR_FLAG(F_TF);
8921            push_word(M.x86.R_CS);
8922            M.x86.R_CS = mem_access_word(4 * 4 + 2);
8923            push_word(M.x86.R_IP);
8924            M.x86.R_IP = mem_access_word(4 * 4);
8925        }
8926    }
8927    DECODE_CLEAR_SEGOVR();
8928    END_OF_INSTR();
8929}
8930
8931/****************************************************************************
8932REMARKS:
8933Handles opcode 0xcf
8934****************************************************************************/
8935static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8936{
8937    START_OF_INSTR();
8938    DECODE_PRINTF("IRET\n");
8939
8940    TRACE_AND_STEP();
8941
8942    M.x86.R_IP = pop_word();
8943    M.x86.R_CS = pop_word();
8944    M.x86.R_FLG = pop_word();
8945    DECODE_CLEAR_SEGOVR();
8946    END_OF_INSTR();
8947}
8948
8949/****************************************************************************
8950REMARKS:
8951Handles opcode 0xd0
8952****************************************************************************/
8953static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8954{
8955    int mod, rl, rh;
8956    u8 *destreg;
8957    uint destoffset;
8958    u8 destval;
8959
8960    /*
8961     * Yet another weirdo special case instruction format.  Part of
8962     * the opcode held below in "RH".  Doubly nested case would
8963     * result, except that the decoded instruction
8964     */
8965    START_OF_INSTR();
8966    FETCH_DECODE_MODRM(mod, rh, rl);
8967#ifdef DEBUG
8968    if (DEBUG_DECODE()) {
8969        /* XXX DECODE_PRINTF may be changed to something more
8970           general, so that it is important to leave the strings
8971           in the same format, even though the result is that the
8972           above test is done twice. */
8973        switch (rh) {
8974        case 0:
8975            DECODE_PRINTF("ROL\t");
8976            break;
8977        case 1:
8978            DECODE_PRINTF("ROR\t");
8979            break;
8980        case 2:
8981            DECODE_PRINTF("RCL\t");
8982            break;
8983        case 3:
8984            DECODE_PRINTF("RCR\t");
8985            break;
8986        case 4:
8987            DECODE_PRINTF("SHL\t");
8988            break;
8989        case 5:
8990            DECODE_PRINTF("SHR\t");
8991            break;
8992        case 6:
8993            DECODE_PRINTF("SAL\t");
8994            break;
8995        case 7:
8996            DECODE_PRINTF("SAR\t");
8997            break;
8998        }
8999    }
9000#endif
9001    /* know operation, decode the mod byte to find the addressing
9002       mode. */
9003    switch (mod) {
9004    case 0:
9005        DECODE_PRINTF("BYTE PTR ");
9006        destoffset = decode_rm00_address(rl);
9007        DECODE_PRINTF(",1\n");
9008        destval = fetch_data_byte(destoffset);
9009        TRACE_AND_STEP();
9010        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9011        store_data_byte(destoffset, destval);
9012        break;
9013    case 1:
9014        DECODE_PRINTF("BYTE PTR ");
9015        destoffset = decode_rm01_address(rl);
9016        DECODE_PRINTF(",1\n");
9017        destval = fetch_data_byte(destoffset);
9018        TRACE_AND_STEP();
9019        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9020        store_data_byte(destoffset, destval);
9021        break;
9022    case 2:
9023        DECODE_PRINTF("BYTE PTR ");
9024        destoffset = decode_rm10_address(rl);
9025        DECODE_PRINTF(",1\n");
9026        destval = fetch_data_byte(destoffset);
9027        TRACE_AND_STEP();
9028        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9029        store_data_byte(destoffset, destval);
9030        break;
9031    case 3:                     /* register to register */
9032        destreg = DECODE_RM_BYTE_REGISTER(rl);
9033        DECODE_PRINTF(",1\n");
9034        TRACE_AND_STEP();
9035        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9036        *destreg = destval;
9037        break;
9038    }
9039    DECODE_CLEAR_SEGOVR();
9040    END_OF_INSTR();
9041}
9042
9043/****************************************************************************
9044REMARKS:
9045Handles opcode 0xd1
9046****************************************************************************/
9047static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9048{
9049    int mod, rl, rh;
9050    uint destoffset;
9051
9052    /*
9053     * Yet another weirdo special case instruction format.  Part of
9054     * the opcode held below in "RH".  Doubly nested case would
9055     * result, except that the decoded instruction
9056     */
9057    START_OF_INSTR();
9058    FETCH_DECODE_MODRM(mod, rh, rl);
9059#ifdef DEBUG
9060    if (DEBUG_DECODE()) {
9061        /* XXX DECODE_PRINTF may be changed to something more
9062           general, so that it is important to leave the strings
9063           in the same format, even though the result is that the
9064           above test is done twice. */
9065        switch (rh) {
9066        case 0:
9067            DECODE_PRINTF("ROL\t");
9068            break;
9069        case 1:
9070            DECODE_PRINTF("ROR\t");
9071            break;
9072        case 2:
9073            DECODE_PRINTF("RCL\t");
9074            break;
9075        case 3:
9076            DECODE_PRINTF("RCR\t");
9077            break;
9078        case 4:
9079            DECODE_PRINTF("SHL\t");
9080            break;
9081        case 5:
9082            DECODE_PRINTF("SHR\t");
9083            break;
9084        case 6:
9085            DECODE_PRINTF("SAL\t");
9086            break;
9087        case 7:
9088            DECODE_PRINTF("SAR\t");
9089            break;
9090        }
9091    }
9092#endif
9093    /* know operation, decode the mod byte to find the addressing
9094       mode. */
9095    switch (mod) {
9096    case 0:
9097        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9098            u32 destval;
9099
9100            DECODE_PRINTF("DWORD PTR ");
9101            destoffset = decode_rm00_address(rl);
9102            DECODE_PRINTF(",1\n");
9103            destval = fetch_data_long(destoffset);
9104            TRACE_AND_STEP();
9105            destval = (*opcD1_long_operation[rh]) (destval, 1);
9106            store_data_long(destoffset, destval);
9107        } else {
9108            u16 destval;
9109
9110            DECODE_PRINTF("WORD PTR ");
9111            destoffset = decode_rm00_address(rl);
9112            DECODE_PRINTF(",1\n");
9113            destval = fetch_data_word(destoffset);
9114            TRACE_AND_STEP();
9115            destval = (*opcD1_word_operation[rh]) (destval, 1);
9116            store_data_word(destoffset, destval);
9117        }
9118        break;
9119    case 1:
9120        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9121            u32 destval;
9122
9123            DECODE_PRINTF("DWORD PTR ");
9124            destoffset = decode_rm01_address(rl);
9125            DECODE_PRINTF(",1\n");
9126            destval = fetch_data_long(destoffset);
9127            TRACE_AND_STEP();
9128            destval = (*opcD1_long_operation[rh]) (destval, 1);
9129            store_data_long(destoffset, destval);
9130        } else {
9131            u16 destval;
9132
9133            DECODE_PRINTF("WORD PTR ");
9134            destoffset = decode_rm01_address(rl);
9135            DECODE_PRINTF(",1\n");
9136            destval = fetch_data_word(destoffset);
9137            TRACE_AND_STEP();
9138            destval = (*opcD1_word_operation[rh]) (destval, 1);
9139            store_data_word(destoffset, destval);
9140        }
9141        break;
9142    case 2:
9143        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9144            u32 destval;
9145
9146            DECODE_PRINTF("DWORD PTR ");
9147            destoffset = decode_rm10_address(rl);
9148            DECODE_PRINTF(",1\n");
9149            destval = fetch_data_long(destoffset);
9150            TRACE_AND_STEP();
9151            destval = (*opcD1_long_operation[rh]) (destval, 1);
9152            store_data_long(destoffset, destval);
9153        } else {
9154            u16 destval;
9155
9156            DECODE_PRINTF("BYTE PTR ");
9157            destoffset = decode_rm10_address(rl);
9158            DECODE_PRINTF(",1\n");
9159            destval = fetch_data_word(destoffset);
9160            TRACE_AND_STEP();
9161            destval = (*opcD1_word_operation[rh]) (destval, 1);
9162            store_data_word(destoffset, destval);
9163        }
9164        break;
9165    case 3:                     /* register to register */
9166        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9167			u32 destval;
9168			u32 *destreg;
9169
9170            destreg = DECODE_RM_LONG_REGISTER(rl);
9171            DECODE_PRINTF(",1\n");
9172            TRACE_AND_STEP();
9173            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9174            *destreg = destval;
9175        } else {
9176			u16 destval;
9177			u16 *destreg;
9178
9179            destreg = DECODE_RM_WORD_REGISTER(rl);
9180            DECODE_PRINTF(",1\n");
9181            TRACE_AND_STEP();
9182            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9183            *destreg = destval;
9184        }
9185        break;
9186    }
9187    DECODE_CLEAR_SEGOVR();
9188    END_OF_INSTR();
9189}
9190
9191/****************************************************************************
9192REMARKS:
9193Handles opcode 0xd2
9194****************************************************************************/
9195static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9196{
9197    int mod, rl, rh;
9198    u8 *destreg;
9199    uint destoffset;
9200    u8 destval;
9201    u8 amt;
9202
9203    /*
9204     * Yet another weirdo special case instruction format.  Part of
9205     * the opcode held below in "RH".  Doubly nested case would
9206     * result, except that the decoded instruction
9207     */
9208    START_OF_INSTR();
9209    FETCH_DECODE_MODRM(mod, rh, rl);
9210#ifdef DEBUG
9211    if (DEBUG_DECODE()) {
9212        /* XXX DECODE_PRINTF may be changed to something more
9213           general, so that it is important to leave the strings
9214           in the same format, even though the result is that the
9215           above test is done twice. */
9216        switch (rh) {
9217        case 0:
9218            DECODE_PRINTF("ROL\t");
9219            break;
9220        case 1:
9221            DECODE_PRINTF("ROR\t");
9222            break;
9223        case 2:
9224            DECODE_PRINTF("RCL\t");
9225            break;
9226        case 3:
9227            DECODE_PRINTF("RCR\t");
9228            break;
9229        case 4:
9230            DECODE_PRINTF("SHL\t");
9231            break;
9232        case 5:
9233            DECODE_PRINTF("SHR\t");
9234            break;
9235        case 6:
9236            DECODE_PRINTF("SAL\t");
9237            break;
9238        case 7:
9239            DECODE_PRINTF("SAR\t");
9240            break;
9241        }
9242    }
9243#endif
9244    /* know operation, decode the mod byte to find the addressing
9245       mode. */
9246    amt = M.x86.R_CL;
9247    switch (mod) {
9248    case 0:
9249        DECODE_PRINTF("BYTE PTR ");
9250        destoffset = decode_rm00_address(rl);
9251        DECODE_PRINTF(",CL\n");
9252        destval = fetch_data_byte(destoffset);
9253        TRACE_AND_STEP();
9254        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9255        store_data_byte(destoffset, destval);
9256        break;
9257    case 1:
9258        DECODE_PRINTF("BYTE PTR ");
9259        destoffset = decode_rm01_address(rl);
9260        DECODE_PRINTF(",CL\n");
9261        destval = fetch_data_byte(destoffset);
9262        TRACE_AND_STEP();
9263        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9264        store_data_byte(destoffset, destval);
9265        break;
9266    case 2:
9267        DECODE_PRINTF("BYTE PTR ");
9268        destoffset = decode_rm10_address(rl);
9269        DECODE_PRINTF(",CL\n");
9270        destval = fetch_data_byte(destoffset);
9271        TRACE_AND_STEP();
9272        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9273        store_data_byte(destoffset, destval);
9274        break;
9275    case 3:                     /* register to register */
9276        destreg = DECODE_RM_BYTE_REGISTER(rl);
9277        DECODE_PRINTF(",CL\n");
9278        TRACE_AND_STEP();
9279        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9280        *destreg = destval;
9281        break;
9282    }
9283    DECODE_CLEAR_SEGOVR();
9284    END_OF_INSTR();
9285}
9286
9287/****************************************************************************
9288REMARKS:
9289Handles opcode 0xd3
9290****************************************************************************/
9291static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9292{
9293    int mod, rl, rh;
9294    uint destoffset;
9295    u8 amt;
9296
9297    /*
9298     * Yet another weirdo special case instruction format.  Part of
9299     * the opcode held below in "RH".  Doubly nested case would
9300     * result, except that the decoded instruction
9301     */
9302    START_OF_INSTR();
9303    FETCH_DECODE_MODRM(mod, rh, rl);
9304#ifdef DEBUG
9305    if (DEBUG_DECODE()) {
9306        /* XXX DECODE_PRINTF may be changed to something more
9307           general, so that it is important to leave the strings
9308           in the same format, even though the result is that the
9309           above test is done twice. */
9310        switch (rh) {
9311        case 0:
9312            DECODE_PRINTF("ROL\t");
9313            break;
9314        case 1:
9315            DECODE_PRINTF("ROR\t");
9316            break;
9317        case 2:
9318            DECODE_PRINTF("RCL\t");
9319            break;
9320        case 3:
9321            DECODE_PRINTF("RCR\t");
9322            break;
9323        case 4:
9324            DECODE_PRINTF("SHL\t");
9325            break;
9326        case 5:
9327            DECODE_PRINTF("SHR\t");
9328            break;
9329        case 6:
9330            DECODE_PRINTF("SAL\t");
9331            break;
9332        case 7:
9333            DECODE_PRINTF("SAR\t");
9334            break;
9335        }
9336    }
9337#endif
9338    /* know operation, decode the mod byte to find the addressing
9339       mode. */
9340    amt = M.x86.R_CL;
9341    switch (mod) {
9342    case 0:
9343        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9344            u32 destval;
9345
9346            DECODE_PRINTF("DWORD PTR ");
9347            destoffset = decode_rm00_address(rl);
9348            DECODE_PRINTF(",CL\n");
9349            destval = fetch_data_long(destoffset);
9350            TRACE_AND_STEP();
9351            destval = (*opcD1_long_operation[rh]) (destval, amt);
9352            store_data_long(destoffset, destval);
9353        } else {
9354            u16 destval;
9355
9356            DECODE_PRINTF("WORD PTR ");
9357            destoffset = decode_rm00_address(rl);
9358            DECODE_PRINTF(",CL\n");
9359            destval = fetch_data_word(destoffset);
9360            TRACE_AND_STEP();
9361            destval = (*opcD1_word_operation[rh]) (destval, amt);
9362            store_data_word(destoffset, destval);
9363        }
9364        break;
9365    case 1:
9366        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9367            u32 destval;
9368
9369            DECODE_PRINTF("DWORD PTR ");
9370            destoffset = decode_rm01_address(rl);
9371            DECODE_PRINTF(",CL\n");
9372            destval = fetch_data_long(destoffset);
9373            TRACE_AND_STEP();
9374            destval = (*opcD1_long_operation[rh]) (destval, amt);
9375            store_data_long(destoffset, destval);
9376        } else {
9377            u16 destval;
9378
9379            DECODE_PRINTF("WORD PTR ");
9380            destoffset = decode_rm01_address(rl);
9381            DECODE_PRINTF(",CL\n");
9382            destval = fetch_data_word(destoffset);
9383            TRACE_AND_STEP();
9384            destval = (*opcD1_word_operation[rh]) (destval, amt);
9385            store_data_word(destoffset, destval);
9386        }
9387        break;
9388    case 2:
9389        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9390            u32 destval;
9391
9392            DECODE_PRINTF("DWORD PTR ");
9393            destoffset = decode_rm10_address(rl);
9394            DECODE_PRINTF(",CL\n");
9395            destval = fetch_data_long(destoffset);
9396            TRACE_AND_STEP();
9397            destval = (*opcD1_long_operation[rh]) (destval, amt);
9398            store_data_long(destoffset, destval);
9399        } else {
9400            u16 destval;
9401
9402            DECODE_PRINTF("WORD PTR ");
9403            destoffset = decode_rm10_address(rl);
9404            DECODE_PRINTF(",CL\n");
9405            destval = fetch_data_word(destoffset);
9406            TRACE_AND_STEP();
9407            destval = (*opcD1_word_operation[rh]) (destval, amt);
9408            store_data_word(destoffset, destval);
9409        }
9410        break;
9411    case 3:                     /* register to register */
9412        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9413            u32 *destreg;
9414
9415            destreg = DECODE_RM_LONG_REGISTER(rl);
9416            DECODE_PRINTF(",CL\n");
9417            TRACE_AND_STEP();
9418            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9419        } else {
9420            u16 *destreg;
9421
9422            destreg = DECODE_RM_WORD_REGISTER(rl);
9423            DECODE_PRINTF(",CL\n");
9424            TRACE_AND_STEP();
9425            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9426        }
9427        break;
9428    }
9429    DECODE_CLEAR_SEGOVR();
9430    END_OF_INSTR();
9431}
9432
9433/****************************************************************************
9434REMARKS:
9435Handles opcode 0xd4
9436****************************************************************************/
9437static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9438{
9439    u8 a;
9440
9441    START_OF_INSTR();
9442    DECODE_PRINTF("AAM\n");
9443    a = fetch_byte_imm();      /* this is a stupid encoding. */
9444    if (a != 10) {
9445	/* fix: add base decoding
9446	   aam_word(u8 val, int base a) */
9447        DECODE_PRINTF("ERROR DECODING AAM\n");
9448        TRACE_REGS();
9449        HALT_SYS();
9450    }
9451    TRACE_AND_STEP();
9452    /* note the type change here --- returning AL and AH in AX. */
9453    M.x86.R_AX = aam_word(M.x86.R_AL);
9454    DECODE_CLEAR_SEGOVR();
9455    END_OF_INSTR();
9456}
9457
9458/****************************************************************************
9459REMARKS:
9460Handles opcode 0xd5
9461****************************************************************************/
9462static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9463{
9464    u8 a;
9465
9466    START_OF_INSTR();
9467    DECODE_PRINTF("AAD\n");
9468    a = fetch_byte_imm();
9469    if (a != 10) {
9470	/* fix: add base decoding
9471	   aad_word(u16 val, int base a) */
9472        DECODE_PRINTF("ERROR DECODING AAM\n");
9473        TRACE_REGS();
9474        HALT_SYS();
9475    }
9476    TRACE_AND_STEP();
9477    M.x86.R_AX = aad_word(M.x86.R_AX);
9478    DECODE_CLEAR_SEGOVR();
9479    END_OF_INSTR();
9480}
9481
9482/* opcode 0xd6 ILLEGAL OPCODE */
9483
9484/****************************************************************************
9485REMARKS:
9486Handles opcode 0xd7
9487****************************************************************************/
9488static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9489{
9490    u16 addr;
9491
9492    START_OF_INSTR();
9493    DECODE_PRINTF("XLAT\n");
9494    TRACE_AND_STEP();
9495	addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9496    M.x86.R_AL = fetch_data_byte(addr);
9497    DECODE_CLEAR_SEGOVR();
9498    END_OF_INSTR();
9499}
9500
9501/* instuctions  D8 .. DF are in i87_ops.c */
9502
9503/****************************************************************************
9504REMARKS:
9505Handles opcode 0xe0
9506****************************************************************************/
9507static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9508{
9509    s16 ip;
9510
9511    START_OF_INSTR();
9512    DECODE_PRINTF("LOOPNE\t");
9513    ip = (s8) fetch_byte_imm();
9514    ip += (s16) M.x86.R_IP;
9515    DECODE_PRINTF2("%04x\n", ip);
9516    TRACE_AND_STEP();
9517    M.x86.R_CX -= 1;
9518    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9519        M.x86.R_IP = ip;
9520    DECODE_CLEAR_SEGOVR();
9521    END_OF_INSTR();
9522}
9523
9524/****************************************************************************
9525REMARKS:
9526Handles opcode 0xe1
9527****************************************************************************/
9528static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9529{
9530    s16 ip;
9531
9532    START_OF_INSTR();
9533    DECODE_PRINTF("LOOPE\t");
9534    ip = (s8) fetch_byte_imm();
9535    ip += (s16) M.x86.R_IP;
9536    DECODE_PRINTF2("%04x\n", ip);
9537    TRACE_AND_STEP();
9538    M.x86.R_CX -= 1;
9539    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9540        M.x86.R_IP = ip;
9541    DECODE_CLEAR_SEGOVR();
9542    END_OF_INSTR();
9543}
9544
9545/****************************************************************************
9546REMARKS:
9547Handles opcode 0xe2
9548****************************************************************************/
9549static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9550{
9551    s16 ip;
9552
9553    START_OF_INSTR();
9554    DECODE_PRINTF("LOOP\t");
9555    ip = (s8) fetch_byte_imm();
9556    ip += (s16) M.x86.R_IP;
9557    DECODE_PRINTF2("%04x\n", ip);
9558    TRACE_AND_STEP();
9559    M.x86.R_CX -= 1;
9560    if (M.x86.R_CX != 0)
9561        M.x86.R_IP = ip;
9562    DECODE_CLEAR_SEGOVR();
9563    END_OF_INSTR();
9564}
9565
9566/****************************************************************************
9567REMARKS:
9568Handles opcode 0xe3
9569****************************************************************************/
9570static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9571{
9572    u16 target;
9573    s8  offset;
9574
9575    /* jump to byte offset if overflow flag is set */
9576    START_OF_INSTR();
9577    DECODE_PRINTF("JCXZ\t");
9578    offset = (s8)fetch_byte_imm();
9579    target = (u16)(M.x86.R_IP + offset);
9580    DECODE_PRINTF2("%x\n", target);
9581    TRACE_AND_STEP();
9582    if (M.x86.R_CX == 0)
9583        M.x86.R_IP = target;
9584    DECODE_CLEAR_SEGOVR();
9585    END_OF_INSTR();
9586}
9587
9588/****************************************************************************
9589REMARKS:
9590Handles opcode 0xe4
9591****************************************************************************/
9592static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9593{
9594    u8 port;
9595
9596    START_OF_INSTR();
9597    DECODE_PRINTF("IN\t");
9598	port = (u8) fetch_byte_imm();
9599    DECODE_PRINTF2("%x,AL\n", port);
9600    TRACE_AND_STEP();
9601    M.x86.R_AL = (*sys_inb)(port);
9602    DECODE_CLEAR_SEGOVR();
9603    END_OF_INSTR();
9604}
9605
9606/****************************************************************************
9607REMARKS:
9608Handles opcode 0xe5
9609****************************************************************************/
9610static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9611{
9612    u8 port;
9613
9614    START_OF_INSTR();
9615    DECODE_PRINTF("IN\t");
9616	port = (u8) fetch_byte_imm();
9617    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9618        DECODE_PRINTF2("EAX,%x\n", port);
9619    } else {
9620        DECODE_PRINTF2("AX,%x\n", port);
9621    }
9622    TRACE_AND_STEP();
9623    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9624        M.x86.R_EAX = (*sys_inl)(port);
9625    } else {
9626        M.x86.R_AX = (*sys_inw)(port);
9627    }
9628    DECODE_CLEAR_SEGOVR();
9629    END_OF_INSTR();
9630}
9631
9632/****************************************************************************
9633REMARKS:
9634Handles opcode 0xe6
9635****************************************************************************/
9636static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9637{
9638    u8 port;
9639
9640    START_OF_INSTR();
9641    DECODE_PRINTF("OUT\t");
9642	port = (u8) fetch_byte_imm();
9643    DECODE_PRINTF2("%x,AL\n", port);
9644    TRACE_AND_STEP();
9645    (*sys_outb)(port, M.x86.R_AL);
9646    DECODE_CLEAR_SEGOVR();
9647    END_OF_INSTR();
9648}
9649
9650/****************************************************************************
9651REMARKS:
9652Handles opcode 0xe7
9653****************************************************************************/
9654static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9655{
9656    u8 port;
9657
9658    START_OF_INSTR();
9659    DECODE_PRINTF("OUT\t");
9660	port = (u8) fetch_byte_imm();
9661    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9662        DECODE_PRINTF2("%x,EAX\n", port);
9663    } else {
9664        DECODE_PRINTF2("%x,AX\n", port);
9665    }
9666    TRACE_AND_STEP();
9667    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9668        (*sys_outl)(port, M.x86.R_EAX);
9669    } else {
9670        (*sys_outw)(port, M.x86.R_AX);
9671    }
9672    DECODE_CLEAR_SEGOVR();
9673    END_OF_INSTR();
9674}
9675
9676/****************************************************************************
9677REMARKS:
9678Handles opcode 0xe8
9679****************************************************************************/
9680static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9681{
9682    s16 ip16;
9683    s32 ip32;
9684
9685    START_OF_INSTR();
9686    DECODE_PRINTF("CALL\t");
9687    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9688	ip32 = (s32) fetch_long_imm();
9689	ip32 += (s16) M.x86.R_IP;    /* CHECK SIGN */
9690	DECODE_PRINTF2("%04x\n", (u16)ip32);
9691	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
9692    } else {
9693	ip16 = (s16) fetch_word_imm();
9694	ip16 += (s16) M.x86.R_IP;    /* CHECK SIGN */
9695	DECODE_PRINTF2("%04x\n", (u16)ip16);
9696	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
9697    }
9698    TRACE_AND_STEP();
9699    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9700	push_long(M.x86.R_EIP);
9701	M.x86.R_EIP = ip32 & 0xffff;
9702    } else {
9703	push_word(M.x86.R_IP);
9704	M.x86.R_EIP = ip16;
9705    }
9706    DECODE_CLEAR_SEGOVR();
9707    END_OF_INSTR();
9708}
9709
9710/****************************************************************************
9711REMARKS:
9712Handles opcode 0xe9
9713****************************************************************************/
9714static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9715{
9716    u32 ip;
9717
9718    START_OF_INSTR();
9719    DECODE_PRINTF("JMP\t");
9720    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9721	ip = (u32)fetch_long_imm();
9722	ip += (u32)M.x86.R_EIP;
9723	DECODE_PRINTF2("%08x\n", (u32)ip);
9724	TRACE_AND_STEP();
9725	M.x86.R_EIP = (u32)ip;
9726    } else {
9727	ip = (s16)fetch_word_imm();
9728	ip += (s16)M.x86.R_IP;
9729	DECODE_PRINTF2("%04x\n", (u16)ip);
9730	TRACE_AND_STEP();
9731	M.x86.R_IP = (u16)ip;
9732    }
9733    DECODE_CLEAR_SEGOVR();
9734    END_OF_INSTR();
9735}
9736
9737/****************************************************************************
9738REMARKS:
9739Handles opcode 0xea
9740****************************************************************************/
9741static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9742{
9743    u16 cs;
9744    u32 ip;
9745
9746    START_OF_INSTR();
9747    DECODE_PRINTF("JMP\tFAR ");
9748    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9749	ip = fetch_long_imm();
9750    } else {
9751	ip = fetch_word_imm();
9752    }
9753    cs = fetch_word_imm();
9754    DECODE_PRINTF2("%04x:", cs);
9755    DECODE_PRINTF2("%04x\n", ip);
9756    TRACE_AND_STEP();
9757    M.x86.R_EIP = ip & 0xffff;
9758    M.x86.R_CS = cs;
9759    DECODE_CLEAR_SEGOVR();
9760    END_OF_INSTR();
9761}
9762
9763/****************************************************************************
9764REMARKS:
9765Handles opcode 0xeb
9766****************************************************************************/
9767static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9768{
9769    u16 target;
9770    s8 offset;
9771
9772    START_OF_INSTR();
9773    DECODE_PRINTF("JMP\t");
9774    offset = (s8)fetch_byte_imm();
9775    target = (u16)(M.x86.R_IP + offset);
9776    DECODE_PRINTF2("%x\n", target);
9777    TRACE_AND_STEP();
9778    M.x86.R_IP = target;
9779    DECODE_CLEAR_SEGOVR();
9780    END_OF_INSTR();
9781}
9782
9783/****************************************************************************
9784REMARKS:
9785Handles opcode 0xec
9786****************************************************************************/
9787static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9788{
9789    START_OF_INSTR();
9790    DECODE_PRINTF("IN\tAL,DX\n");
9791    TRACE_AND_STEP();
9792    M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9793    DECODE_CLEAR_SEGOVR();
9794    END_OF_INSTR();
9795}
9796
9797/****************************************************************************
9798REMARKS:
9799Handles opcode 0xed
9800****************************************************************************/
9801static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9802{
9803    START_OF_INSTR();
9804    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9805        DECODE_PRINTF("IN\tEAX,DX\n");
9806    } else {
9807        DECODE_PRINTF("IN\tAX,DX\n");
9808    }
9809    TRACE_AND_STEP();
9810    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9811        M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9812    } else {
9813        M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9814    }
9815    DECODE_CLEAR_SEGOVR();
9816    END_OF_INSTR();
9817}
9818
9819/****************************************************************************
9820REMARKS:
9821Handles opcode 0xee
9822****************************************************************************/
9823static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9824{
9825    START_OF_INSTR();
9826    DECODE_PRINTF("OUT\tDX,AL\n");
9827    TRACE_AND_STEP();
9828    (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9829    DECODE_CLEAR_SEGOVR();
9830    END_OF_INSTR();
9831}
9832
9833/****************************************************************************
9834REMARKS:
9835Handles opcode 0xef
9836****************************************************************************/
9837static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9838{
9839    START_OF_INSTR();
9840    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9841        DECODE_PRINTF("OUT\tDX,EAX\n");
9842    } else {
9843        DECODE_PRINTF("OUT\tDX,AX\n");
9844    }
9845    TRACE_AND_STEP();
9846    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9847        (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9848    } else {
9849        (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9850    }
9851    DECODE_CLEAR_SEGOVR();
9852    END_OF_INSTR();
9853}
9854
9855/****************************************************************************
9856REMARKS:
9857Handles opcode 0xf0
9858****************************************************************************/
9859static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9860{
9861    START_OF_INSTR();
9862    DECODE_PRINTF("LOCK:\n");
9863    TRACE_AND_STEP();
9864    DECODE_CLEAR_SEGOVR();
9865    END_OF_INSTR();
9866}
9867
9868/*opcode 0xf1 ILLEGAL OPERATION */
9869
9870/****************************************************************************
9871REMARKS:
9872Handles opcode 0xf2
9873****************************************************************************/
9874static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9875{
9876    START_OF_INSTR();
9877    DECODE_PRINTF("REPNE\n");
9878    TRACE_AND_STEP();
9879    M.x86.mode |= SYSMODE_PREFIX_REPNE;
9880    DECODE_CLEAR_SEGOVR();
9881    END_OF_INSTR();
9882}
9883
9884/****************************************************************************
9885REMARKS:
9886Handles opcode 0xf3
9887****************************************************************************/
9888static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9889{
9890    START_OF_INSTR();
9891    DECODE_PRINTF("REPE\n");
9892    TRACE_AND_STEP();
9893    M.x86.mode |= SYSMODE_PREFIX_REPE;
9894    DECODE_CLEAR_SEGOVR();
9895    END_OF_INSTR();
9896}
9897
9898/****************************************************************************
9899REMARKS:
9900Handles opcode 0xf4
9901****************************************************************************/
9902static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9903{
9904    START_OF_INSTR();
9905    DECODE_PRINTF("HALT\n");
9906    TRACE_AND_STEP();
9907    HALT_SYS();
9908    DECODE_CLEAR_SEGOVR();
9909    END_OF_INSTR();
9910}
9911
9912/****************************************************************************
9913REMARKS:
9914Handles opcode 0xf5
9915****************************************************************************/
9916static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9917{
9918    /* complement the carry flag. */
9919    START_OF_INSTR();
9920    DECODE_PRINTF("CMC\n");
9921    TRACE_AND_STEP();
9922    TOGGLE_FLAG(F_CF);
9923    DECODE_CLEAR_SEGOVR();
9924    END_OF_INSTR();
9925}
9926
9927/****************************************************************************
9928REMARKS:
9929Handles opcode 0xf6
9930****************************************************************************/
9931static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9932{
9933    int mod, rl, rh;
9934    u8 *destreg;
9935    uint destoffset;
9936    u8 destval, srcval;
9937
9938    /* long, drawn out code follows.  Double switch for a total
9939       of 32 cases.  */
9940    START_OF_INSTR();
9941    FETCH_DECODE_MODRM(mod, rh, rl);
9942    switch (mod) {
9943    case 0:                     /* mod=00 */
9944        switch (rh) {
9945        case 0:         /* test byte imm */
9946            DECODE_PRINTF("TEST\tBYTE PTR ");
9947            destoffset = decode_rm00_address(rl);
9948            DECODE_PRINTF(",");
9949            srcval = fetch_byte_imm();
9950            DECODE_PRINTF2("%02x\n", srcval);
9951            destval = fetch_data_byte(destoffset);
9952            TRACE_AND_STEP();
9953            test_byte(destval, srcval);
9954            break;
9955        case 1:
9956            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9957            HALT_SYS();
9958            break;
9959        case 2:
9960            DECODE_PRINTF("NOT\tBYTE PTR ");
9961            destoffset = decode_rm00_address(rl);
9962            DECODE_PRINTF("\n");
9963            destval = fetch_data_byte(destoffset);
9964            TRACE_AND_STEP();
9965            destval = not_byte(destval);
9966            store_data_byte(destoffset, destval);
9967            break;
9968        case 3:
9969            DECODE_PRINTF("NEG\tBYTE PTR ");
9970            destoffset = decode_rm00_address(rl);
9971            DECODE_PRINTF("\n");
9972            destval = fetch_data_byte(destoffset);
9973            TRACE_AND_STEP();
9974            destval = neg_byte(destval);
9975            store_data_byte(destoffset, destval);
9976            break;
9977        case 4:
9978            DECODE_PRINTF("MUL\tBYTE PTR ");
9979            destoffset = decode_rm00_address(rl);
9980            DECODE_PRINTF("\n");
9981            destval = fetch_data_byte(destoffset);
9982            TRACE_AND_STEP();
9983            mul_byte(destval);
9984            break;
9985        case 5:
9986            DECODE_PRINTF("IMUL\tBYTE PTR ");
9987            destoffset = decode_rm00_address(rl);
9988            DECODE_PRINTF("\n");
9989            destval = fetch_data_byte(destoffset);
9990            TRACE_AND_STEP();
9991            imul_byte(destval);
9992            break;
9993        case 6:
9994            DECODE_PRINTF("DIV\tBYTE PTR ");
9995            destoffset = decode_rm00_address(rl);
9996            DECODE_PRINTF("\n");
9997            destval = fetch_data_byte(destoffset);
9998            TRACE_AND_STEP();
9999            div_byte(destval);
10000            break;
10001        case 7:
10002            DECODE_PRINTF("IDIV\tBYTE PTR ");
10003            destoffset = decode_rm00_address(rl);
10004            DECODE_PRINTF("\n");
10005            destval = fetch_data_byte(destoffset);
10006            TRACE_AND_STEP();
10007            idiv_byte(destval);
10008            break;
10009        }
10010        break;                  /* end mod==00 */
10011    case 1:                     /* mod=01 */
10012        switch (rh) {
10013        case 0:         /* test byte imm */
10014            DECODE_PRINTF("TEST\tBYTE PTR ");
10015            destoffset = decode_rm01_address(rl);
10016            DECODE_PRINTF(",");
10017            srcval = fetch_byte_imm();
10018            DECODE_PRINTF2("%02x\n", srcval);
10019            destval = fetch_data_byte(destoffset);
10020            TRACE_AND_STEP();
10021            test_byte(destval, srcval);
10022            break;
10023        case 1:
10024            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10025            HALT_SYS();
10026            break;
10027        case 2:
10028            DECODE_PRINTF("NOT\tBYTE PTR ");
10029            destoffset = decode_rm01_address(rl);
10030            DECODE_PRINTF("\n");
10031            destval = fetch_data_byte(destoffset);
10032            TRACE_AND_STEP();
10033            destval = not_byte(destval);
10034            store_data_byte(destoffset, destval);
10035            break;
10036        case 3:
10037            DECODE_PRINTF("NEG\tBYTE PTR ");
10038            destoffset = decode_rm01_address(rl);
10039            DECODE_PRINTF("\n");
10040            destval = fetch_data_byte(destoffset);
10041            TRACE_AND_STEP();
10042            destval = neg_byte(destval);
10043            store_data_byte(destoffset, destval);
10044            break;
10045        case 4:
10046            DECODE_PRINTF("MUL\tBYTE PTR ");
10047            destoffset = decode_rm01_address(rl);
10048            DECODE_PRINTF("\n");
10049            destval = fetch_data_byte(destoffset);
10050            TRACE_AND_STEP();
10051            mul_byte(destval);
10052            break;
10053        case 5:
10054            DECODE_PRINTF("IMUL\tBYTE PTR ");
10055            destoffset = decode_rm01_address(rl);
10056            DECODE_PRINTF("\n");
10057            destval = fetch_data_byte(destoffset);
10058            TRACE_AND_STEP();
10059            imul_byte(destval);
10060            break;
10061        case 6:
10062            DECODE_PRINTF("DIV\tBYTE PTR ");
10063            destoffset = decode_rm01_address(rl);
10064            DECODE_PRINTF("\n");
10065            destval = fetch_data_byte(destoffset);
10066            TRACE_AND_STEP();
10067            div_byte(destval);
10068            break;
10069        case 7:
10070            DECODE_PRINTF("IDIV\tBYTE PTR ");
10071            destoffset = decode_rm01_address(rl);
10072            DECODE_PRINTF("\n");
10073            destval = fetch_data_byte(destoffset);
10074            TRACE_AND_STEP();
10075            idiv_byte(destval);
10076            break;
10077        }
10078        break;                  /* end mod==01 */
10079    case 2:                     /* mod=10 */
10080        switch (rh) {
10081        case 0:         /* test byte imm */
10082            DECODE_PRINTF("TEST\tBYTE PTR ");
10083            destoffset = decode_rm10_address(rl);
10084            DECODE_PRINTF(",");
10085            srcval = fetch_byte_imm();
10086            DECODE_PRINTF2("%02x\n", srcval);
10087            destval = fetch_data_byte(destoffset);
10088            TRACE_AND_STEP();
10089            test_byte(destval, srcval);
10090            break;
10091        case 1:
10092            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10093            HALT_SYS();
10094            break;
10095        case 2:
10096            DECODE_PRINTF("NOT\tBYTE PTR ");
10097            destoffset = decode_rm10_address(rl);
10098            DECODE_PRINTF("\n");
10099            destval = fetch_data_byte(destoffset);
10100            TRACE_AND_STEP();
10101            destval = not_byte(destval);
10102            store_data_byte(destoffset, destval);
10103            break;
10104        case 3:
10105            DECODE_PRINTF("NEG\tBYTE PTR ");
10106            destoffset = decode_rm10_address(rl);
10107            DECODE_PRINTF("\n");
10108            destval = fetch_data_byte(destoffset);
10109            TRACE_AND_STEP();
10110            destval = neg_byte(destval);
10111            store_data_byte(destoffset, destval);
10112            break;
10113        case 4:
10114            DECODE_PRINTF("MUL\tBYTE PTR ");
10115            destoffset = decode_rm10_address(rl);
10116            DECODE_PRINTF("\n");
10117            destval = fetch_data_byte(destoffset);
10118            TRACE_AND_STEP();
10119            mul_byte(destval);
10120            break;
10121        case 5:
10122            DECODE_PRINTF("IMUL\tBYTE PTR ");
10123            destoffset = decode_rm10_address(rl);
10124            DECODE_PRINTF("\n");
10125            destval = fetch_data_byte(destoffset);
10126            TRACE_AND_STEP();
10127            imul_byte(destval);
10128            break;
10129        case 6:
10130            DECODE_PRINTF("DIV\tBYTE PTR ");
10131            destoffset = decode_rm10_address(rl);
10132            DECODE_PRINTF("\n");
10133            destval = fetch_data_byte(destoffset);
10134            TRACE_AND_STEP();
10135            div_byte(destval);
10136            break;
10137        case 7:
10138            DECODE_PRINTF("IDIV\tBYTE PTR ");
10139            destoffset = decode_rm10_address(rl);
10140            DECODE_PRINTF("\n");
10141            destval = fetch_data_byte(destoffset);
10142            TRACE_AND_STEP();
10143            idiv_byte(destval);
10144            break;
10145        }
10146        break;                  /* end mod==10 */
10147    case 3:                     /* mod=11 */
10148        switch (rh) {
10149        case 0:         /* test byte imm */
10150            DECODE_PRINTF("TEST\t");
10151            destreg = DECODE_RM_BYTE_REGISTER(rl);
10152            DECODE_PRINTF(",");
10153            srcval = fetch_byte_imm();
10154            DECODE_PRINTF2("%02x\n", srcval);
10155            TRACE_AND_STEP();
10156            test_byte(*destreg, srcval);
10157            break;
10158        case 1:
10159            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10160            HALT_SYS();
10161            break;
10162        case 2:
10163            DECODE_PRINTF("NOT\t");
10164            destreg = DECODE_RM_BYTE_REGISTER(rl);
10165            DECODE_PRINTF("\n");
10166            TRACE_AND_STEP();
10167            *destreg = not_byte(*destreg);
10168            break;
10169        case 3:
10170            DECODE_PRINTF("NEG\t");
10171            destreg = DECODE_RM_BYTE_REGISTER(rl);
10172            DECODE_PRINTF("\n");
10173            TRACE_AND_STEP();
10174            *destreg = neg_byte(*destreg);
10175            break;
10176        case 4:
10177            DECODE_PRINTF("MUL\t");
10178            destreg = DECODE_RM_BYTE_REGISTER(rl);
10179            DECODE_PRINTF("\n");
10180            TRACE_AND_STEP();
10181            mul_byte(*destreg);      /*!!!  */
10182            break;
10183        case 5:
10184            DECODE_PRINTF("IMUL\t");
10185            destreg = DECODE_RM_BYTE_REGISTER(rl);
10186            DECODE_PRINTF("\n");
10187            TRACE_AND_STEP();
10188            imul_byte(*destreg);
10189            break;
10190        case 6:
10191            DECODE_PRINTF("DIV\t");
10192            destreg = DECODE_RM_BYTE_REGISTER(rl);
10193            DECODE_PRINTF("\n");
10194            TRACE_AND_STEP();
10195            div_byte(*destreg);
10196            break;
10197        case 7:
10198            DECODE_PRINTF("IDIV\t");
10199            destreg = DECODE_RM_BYTE_REGISTER(rl);
10200            DECODE_PRINTF("\n");
10201            TRACE_AND_STEP();
10202            idiv_byte(*destreg);
10203            break;
10204        }
10205        break;                  /* end mod==11 */
10206    }
10207    DECODE_CLEAR_SEGOVR();
10208    END_OF_INSTR();
10209}
10210
10211/****************************************************************************
10212REMARKS:
10213Handles opcode 0xf7
10214****************************************************************************/
10215static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10216{
10217    int mod, rl, rh;
10218    uint destoffset;
10219
10220    /* long, drawn out code follows.  Double switch for a total
10221       of 32 cases.  */
10222    START_OF_INSTR();
10223    FETCH_DECODE_MODRM(mod, rh, rl);
10224    switch (mod) {
10225    case 0:                     /* mod=00 */
10226        switch (rh) {
10227        case 0:         /* test word imm */
10228            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10229                u32 destval,srcval;
10230
10231                DECODE_PRINTF("TEST\tDWORD PTR ");
10232                destoffset = decode_rm00_address(rl);
10233                DECODE_PRINTF(",");
10234                srcval = fetch_long_imm();
10235                DECODE_PRINTF2("%x\n", srcval);
10236                destval = fetch_data_long(destoffset);
10237                TRACE_AND_STEP();
10238                test_long(destval, srcval);
10239            } else {
10240                u16 destval,srcval;
10241
10242                DECODE_PRINTF("TEST\tWORD PTR ");
10243                destoffset = decode_rm00_address(rl);
10244                DECODE_PRINTF(",");
10245                srcval = fetch_word_imm();
10246                DECODE_PRINTF2("%x\n", srcval);
10247                destval = fetch_data_word(destoffset);
10248                TRACE_AND_STEP();
10249                test_word(destval, srcval);
10250            }
10251            break;
10252        case 1:
10253            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10254            HALT_SYS();
10255            break;
10256        case 2:
10257            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10258                u32 destval;
10259
10260                DECODE_PRINTF("NOT\tDWORD PTR ");
10261                destoffset = decode_rm00_address(rl);
10262                DECODE_PRINTF("\n");
10263                destval = fetch_data_long(destoffset);
10264                TRACE_AND_STEP();
10265                destval = not_long(destval);
10266                store_data_long(destoffset, destval);
10267            } else {
10268                u16 destval;
10269
10270                DECODE_PRINTF("NOT\tWORD PTR ");
10271                destoffset = decode_rm00_address(rl);
10272                DECODE_PRINTF("\n");
10273                destval = fetch_data_word(destoffset);
10274                TRACE_AND_STEP();
10275                destval = not_word(destval);
10276                store_data_word(destoffset, destval);
10277            }
10278            break;
10279        case 3:
10280            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10281                u32 destval;
10282
10283                DECODE_PRINTF("NEG\tDWORD PTR ");
10284                destoffset = decode_rm00_address(rl);
10285                DECODE_PRINTF("\n");
10286                destval = fetch_data_long(destoffset);
10287                TRACE_AND_STEP();
10288                destval = neg_long(destval);
10289                store_data_long(destoffset, destval);
10290            } else {
10291                u16 destval;
10292
10293                DECODE_PRINTF("NEG\tWORD PTR ");
10294                destoffset = decode_rm00_address(rl);
10295                DECODE_PRINTF("\n");
10296                destval = fetch_data_word(destoffset);
10297                TRACE_AND_STEP();
10298                destval = neg_word(destval);
10299                store_data_word(destoffset, destval);
10300            }
10301            break;
10302        case 4:
10303            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10304                u32 destval;
10305
10306                DECODE_PRINTF("MUL\tDWORD PTR ");
10307                destoffset = decode_rm00_address(rl);
10308                DECODE_PRINTF("\n");
10309                destval = fetch_data_long(destoffset);
10310                TRACE_AND_STEP();
10311                mul_long(destval);
10312            } else {
10313                u16 destval;
10314
10315                DECODE_PRINTF("MUL\tWORD PTR ");
10316                destoffset = decode_rm00_address(rl);
10317                DECODE_PRINTF("\n");
10318                destval = fetch_data_word(destoffset);
10319                TRACE_AND_STEP();
10320                mul_word(destval);
10321            }
10322            break;
10323        case 5:
10324            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10325                u32 destval;
10326
10327                DECODE_PRINTF("IMUL\tDWORD PTR ");
10328                destoffset = decode_rm00_address(rl);
10329                DECODE_PRINTF("\n");
10330                destval = fetch_data_long(destoffset);
10331                TRACE_AND_STEP();
10332                imul_long(destval);
10333            } else {
10334                u16 destval;
10335
10336                DECODE_PRINTF("IMUL\tWORD PTR ");
10337                destoffset = decode_rm00_address(rl);
10338                DECODE_PRINTF("\n");
10339                destval = fetch_data_word(destoffset);
10340                TRACE_AND_STEP();
10341                imul_word(destval);
10342            }
10343            break;
10344        case 6:
10345            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10346                u32 destval;
10347
10348                DECODE_PRINTF("DIV\tDWORD PTR ");
10349                destoffset = decode_rm00_address(rl);
10350                DECODE_PRINTF("\n");
10351                destval = fetch_data_long(destoffset);
10352                TRACE_AND_STEP();
10353                div_long(destval);
10354            } else {
10355                u16 destval;
10356
10357                DECODE_PRINTF("DIV\tWORD PTR ");
10358                destoffset = decode_rm00_address(rl);
10359                DECODE_PRINTF("\n");
10360                destval = fetch_data_word(destoffset);
10361                TRACE_AND_STEP();
10362                div_word(destval);
10363            }
10364            break;
10365        case 7:
10366            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10367                u32 destval;
10368
10369                DECODE_PRINTF("IDIV\tDWORD PTR ");
10370                destoffset = decode_rm00_address(rl);
10371                DECODE_PRINTF("\n");
10372                destval = fetch_data_long(destoffset);
10373                TRACE_AND_STEP();
10374                idiv_long(destval);
10375            } else {
10376                u16 destval;
10377
10378                DECODE_PRINTF("IDIV\tWORD PTR ");
10379                destoffset = decode_rm00_address(rl);
10380                DECODE_PRINTF("\n");
10381                destval = fetch_data_word(destoffset);
10382                TRACE_AND_STEP();
10383                idiv_word(destval);
10384            }
10385            break;
10386        }
10387        break;                  /* end mod==00 */
10388    case 1:                     /* mod=01 */
10389        switch (rh) {
10390        case 0:         /* test word imm */
10391            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10392                u32 destval,srcval;
10393
10394                DECODE_PRINTF("TEST\tDWORD PTR ");
10395                destoffset = decode_rm01_address(rl);
10396                DECODE_PRINTF(",");
10397                srcval = fetch_long_imm();
10398                DECODE_PRINTF2("%x\n", srcval);
10399                destval = fetch_data_long(destoffset);
10400                TRACE_AND_STEP();
10401                test_long(destval, srcval);
10402            } else {
10403                u16 destval,srcval;
10404
10405                DECODE_PRINTF("TEST\tWORD PTR ");
10406                destoffset = decode_rm01_address(rl);
10407                DECODE_PRINTF(",");
10408                srcval = fetch_word_imm();
10409                DECODE_PRINTF2("%x\n", srcval);
10410                destval = fetch_data_word(destoffset);
10411                TRACE_AND_STEP();
10412                test_word(destval, srcval);
10413            }
10414            break;
10415        case 1:
10416            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10417            HALT_SYS();
10418            break;
10419        case 2:
10420            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10421                u32 destval;
10422
10423                DECODE_PRINTF("NOT\tDWORD PTR ");
10424                destoffset = decode_rm01_address(rl);
10425                DECODE_PRINTF("\n");
10426                destval = fetch_data_long(destoffset);
10427                TRACE_AND_STEP();
10428                destval = not_long(destval);
10429                store_data_long(destoffset, destval);
10430            } else {
10431                u16 destval;
10432
10433                DECODE_PRINTF("NOT\tWORD PTR ");
10434                destoffset = decode_rm01_address(rl);
10435                DECODE_PRINTF("\n");
10436                destval = fetch_data_word(destoffset);
10437                TRACE_AND_STEP();
10438                destval = not_word(destval);
10439                store_data_word(destoffset, destval);
10440            }
10441            break;
10442        case 3:
10443            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10444                u32 destval;
10445
10446                DECODE_PRINTF("NEG\tDWORD PTR ");
10447                destoffset = decode_rm01_address(rl);
10448                DECODE_PRINTF("\n");
10449                destval = fetch_data_long(destoffset);
10450                TRACE_AND_STEP();
10451                destval = neg_long(destval);
10452                store_data_long(destoffset, destval);
10453            } else {
10454                u16 destval;
10455
10456                DECODE_PRINTF("NEG\tWORD PTR ");
10457                destoffset = decode_rm01_address(rl);
10458                DECODE_PRINTF("\n");
10459                destval = fetch_data_word(destoffset);
10460                TRACE_AND_STEP();
10461                destval = neg_word(destval);
10462                store_data_word(destoffset, destval);
10463            }
10464            break;
10465        case 4:
10466            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10467                u32 destval;
10468
10469                DECODE_PRINTF("MUL\tDWORD PTR ");
10470                destoffset = decode_rm01_address(rl);
10471                DECODE_PRINTF("\n");
10472                destval = fetch_data_long(destoffset);
10473                TRACE_AND_STEP();
10474                mul_long(destval);
10475            } else {
10476                u16 destval;
10477
10478                DECODE_PRINTF("MUL\tWORD PTR ");
10479                destoffset = decode_rm01_address(rl);
10480                DECODE_PRINTF("\n");
10481                destval = fetch_data_word(destoffset);
10482                TRACE_AND_STEP();
10483                mul_word(destval);
10484            }
10485            break;
10486        case 5:
10487            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10488                u32 destval;
10489
10490                DECODE_PRINTF("IMUL\tDWORD PTR ");
10491                destoffset = decode_rm01_address(rl);
10492                DECODE_PRINTF("\n");
10493                destval = fetch_data_long(destoffset);
10494                TRACE_AND_STEP();
10495                imul_long(destval);
10496            } else {
10497                u16 destval;
10498
10499                DECODE_PRINTF("IMUL\tWORD PTR ");
10500                destoffset = decode_rm01_address(rl);
10501                DECODE_PRINTF("\n");
10502                destval = fetch_data_word(destoffset);
10503                TRACE_AND_STEP();
10504                imul_word(destval);
10505            }
10506            break;
10507        case 6:
10508            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10509                u32 destval;
10510
10511                DECODE_PRINTF("DIV\tDWORD PTR ");
10512                destoffset = decode_rm01_address(rl);
10513                DECODE_PRINTF("\n");
10514                destval = fetch_data_long(destoffset);
10515                TRACE_AND_STEP();
10516                div_long(destval);
10517            } else {
10518                u16 destval;
10519
10520                DECODE_PRINTF("DIV\tWORD PTR ");
10521                destoffset = decode_rm01_address(rl);
10522                DECODE_PRINTF("\n");
10523                destval = fetch_data_word(destoffset);
10524                TRACE_AND_STEP();
10525                div_word(destval);
10526            }
10527            break;
10528        case 7:
10529            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10530                u32 destval;
10531
10532                DECODE_PRINTF("IDIV\tDWORD PTR ");
10533                destoffset = decode_rm01_address(rl);
10534                DECODE_PRINTF("\n");
10535                destval = fetch_data_long(destoffset);
10536                TRACE_AND_STEP();
10537                idiv_long(destval);
10538            } else {
10539                u16 destval;
10540
10541                DECODE_PRINTF("IDIV\tWORD PTR ");
10542                destoffset = decode_rm01_address(rl);
10543                DECODE_PRINTF("\n");
10544                destval = fetch_data_word(destoffset);
10545                TRACE_AND_STEP();
10546                idiv_word(destval);
10547            }
10548            break;
10549        }
10550        break;                  /* end mod==01 */
10551    case 2:                     /* mod=10 */
10552        switch (rh) {
10553        case 0:         /* test word imm */
10554            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10555                u32 destval,srcval;
10556
10557                DECODE_PRINTF("TEST\tDWORD PTR ");
10558                destoffset = decode_rm10_address(rl);
10559                DECODE_PRINTF(",");
10560                srcval = fetch_long_imm();
10561                DECODE_PRINTF2("%x\n", srcval);
10562                destval = fetch_data_long(destoffset);
10563                TRACE_AND_STEP();
10564                test_long(destval, srcval);
10565            } else {
10566                u16 destval,srcval;
10567
10568                DECODE_PRINTF("TEST\tWORD PTR ");
10569                destoffset = decode_rm10_address(rl);
10570                DECODE_PRINTF(",");
10571                srcval = fetch_word_imm();
10572                DECODE_PRINTF2("%x\n", srcval);
10573                destval = fetch_data_word(destoffset);
10574                TRACE_AND_STEP();
10575                test_word(destval, srcval);
10576            }
10577            break;
10578        case 1:
10579            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10580            HALT_SYS();
10581            break;
10582        case 2:
10583            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10584                u32 destval;
10585
10586                DECODE_PRINTF("NOT\tDWORD PTR ");
10587                destoffset = decode_rm10_address(rl);
10588                DECODE_PRINTF("\n");
10589                destval = fetch_data_long(destoffset);
10590                TRACE_AND_STEP();
10591                destval = not_long(destval);
10592                store_data_long(destoffset, destval);
10593            } else {
10594                u16 destval;
10595
10596                DECODE_PRINTF("NOT\tWORD PTR ");
10597                destoffset = decode_rm10_address(rl);
10598                DECODE_PRINTF("\n");
10599                destval = fetch_data_word(destoffset);
10600                TRACE_AND_STEP();
10601                destval = not_word(destval);
10602                store_data_word(destoffset, destval);
10603            }
10604            break;
10605        case 3:
10606            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10607                u32 destval;
10608
10609                DECODE_PRINTF("NEG\tDWORD PTR ");
10610                destoffset = decode_rm10_address(rl);
10611                DECODE_PRINTF("\n");
10612                destval = fetch_data_long(destoffset);
10613                TRACE_AND_STEP();
10614                destval = neg_long(destval);
10615                store_data_long(destoffset, destval);
10616            } else {
10617                u16 destval;
10618
10619                DECODE_PRINTF("NEG\tWORD PTR ");
10620                destoffset = decode_rm10_address(rl);
10621                DECODE_PRINTF("\n");
10622                destval = fetch_data_word(destoffset);
10623                TRACE_AND_STEP();
10624                destval = neg_word(destval);
10625                store_data_word(destoffset, destval);
10626            }
10627            break;
10628        case 4:
10629            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10630                u32 destval;
10631
10632                DECODE_PRINTF("MUL\tDWORD PTR ");
10633                destoffset = decode_rm10_address(rl);
10634                DECODE_PRINTF("\n");
10635                destval = fetch_data_long(destoffset);
10636                TRACE_AND_STEP();
10637                mul_long(destval);
10638            } else {
10639                u16 destval;
10640
10641                DECODE_PRINTF("MUL\tWORD PTR ");
10642                destoffset = decode_rm10_address(rl);
10643                DECODE_PRINTF("\n");
10644                destval = fetch_data_word(destoffset);
10645                TRACE_AND_STEP();
10646                mul_word(destval);
10647            }
10648            break;
10649        case 5:
10650            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10651                u32 destval;
10652
10653                DECODE_PRINTF("IMUL\tDWORD PTR ");
10654                destoffset = decode_rm10_address(rl);
10655                DECODE_PRINTF("\n");
10656                destval = fetch_data_long(destoffset);
10657                TRACE_AND_STEP();
10658                imul_long(destval);
10659            } else {
10660                u16 destval;
10661
10662                DECODE_PRINTF("IMUL\tWORD PTR ");
10663                destoffset = decode_rm10_address(rl);
10664                DECODE_PRINTF("\n");
10665                destval = fetch_data_word(destoffset);
10666                TRACE_AND_STEP();
10667                imul_word(destval);
10668            }
10669            break;
10670        case 6:
10671            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10672                u32 destval;
10673
10674                DECODE_PRINTF("DIV\tDWORD PTR ");
10675                destoffset = decode_rm10_address(rl);
10676                DECODE_PRINTF("\n");
10677                destval = fetch_data_long(destoffset);
10678                TRACE_AND_STEP();
10679                div_long(destval);
10680            } else {
10681                u16 destval;
10682
10683                DECODE_PRINTF("DIV\tWORD PTR ");
10684                destoffset = decode_rm10_address(rl);
10685                DECODE_PRINTF("\n");
10686                destval = fetch_data_word(destoffset);
10687                TRACE_AND_STEP();
10688                div_word(destval);
10689            }
10690            break;
10691        case 7:
10692            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10693                u32 destval;
10694
10695                DECODE_PRINTF("IDIV\tDWORD PTR ");
10696                destoffset = decode_rm10_address(rl);
10697                DECODE_PRINTF("\n");
10698                destval = fetch_data_long(destoffset);
10699                TRACE_AND_STEP();
10700                idiv_long(destval);
10701            } else {
10702                u16 destval;
10703
10704                DECODE_PRINTF("IDIV\tWORD PTR ");
10705                destoffset = decode_rm10_address(rl);
10706                DECODE_PRINTF("\n");
10707                destval = fetch_data_word(destoffset);
10708                TRACE_AND_STEP();
10709                idiv_word(destval);
10710            }
10711            break;
10712        }
10713        break;                  /* end mod==10 */
10714    case 3:                     /* mod=11 */
10715        switch (rh) {
10716        case 0:         /* test word imm */
10717            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10718                u32 *destreg;
10719                u32 srcval;
10720
10721                DECODE_PRINTF("TEST\t");
10722                destreg = DECODE_RM_LONG_REGISTER(rl);
10723                DECODE_PRINTF(",");
10724                srcval = fetch_long_imm();
10725                DECODE_PRINTF2("%x\n", srcval);
10726                TRACE_AND_STEP();
10727                test_long(*destreg, srcval);
10728            } else {
10729                u16 *destreg;
10730                u16 srcval;
10731
10732                DECODE_PRINTF("TEST\t");
10733                destreg = DECODE_RM_WORD_REGISTER(rl);
10734                DECODE_PRINTF(",");
10735                srcval = fetch_word_imm();
10736                DECODE_PRINTF2("%x\n", srcval);
10737                TRACE_AND_STEP();
10738                test_word(*destreg, srcval);
10739            }
10740            break;
10741        case 1:
10742            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10743            HALT_SYS();
10744            break;
10745        case 2:
10746            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10747                u32 *destreg;
10748
10749                DECODE_PRINTF("NOT\t");
10750                destreg = DECODE_RM_LONG_REGISTER(rl);
10751                DECODE_PRINTF("\n");
10752                TRACE_AND_STEP();
10753                *destreg = not_long(*destreg);
10754            } else {
10755                u16 *destreg;
10756
10757                DECODE_PRINTF("NOT\t");
10758                destreg = DECODE_RM_WORD_REGISTER(rl);
10759                DECODE_PRINTF("\n");
10760                TRACE_AND_STEP();
10761                *destreg = not_word(*destreg);
10762            }
10763            break;
10764        case 3:
10765            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10766                u32 *destreg;
10767
10768                DECODE_PRINTF("NEG\t");
10769                destreg = DECODE_RM_LONG_REGISTER(rl);
10770                DECODE_PRINTF("\n");
10771                TRACE_AND_STEP();
10772                *destreg = neg_long(*destreg);
10773            } else {
10774                u16 *destreg;
10775
10776                DECODE_PRINTF("NEG\t");
10777                destreg = DECODE_RM_WORD_REGISTER(rl);
10778                DECODE_PRINTF("\n");
10779                TRACE_AND_STEP();
10780                *destreg = neg_word(*destreg);
10781            }
10782            break;
10783        case 4:
10784            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10785                u32 *destreg;
10786
10787                DECODE_PRINTF("MUL\t");
10788                destreg = DECODE_RM_LONG_REGISTER(rl);
10789                DECODE_PRINTF("\n");
10790                TRACE_AND_STEP();
10791                mul_long(*destreg);      /*!!!  */
10792            } else {
10793                u16 *destreg;
10794
10795                DECODE_PRINTF("MUL\t");
10796                destreg = DECODE_RM_WORD_REGISTER(rl);
10797                DECODE_PRINTF("\n");
10798                TRACE_AND_STEP();
10799                mul_word(*destreg);      /*!!!  */
10800            }
10801            break;
10802        case 5:
10803            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10804                u32 *destreg;
10805
10806                DECODE_PRINTF("IMUL\t");
10807                destreg = DECODE_RM_LONG_REGISTER(rl);
10808                DECODE_PRINTF("\n");
10809                TRACE_AND_STEP();
10810                imul_long(*destreg);
10811            } else {
10812                u16 *destreg;
10813
10814                DECODE_PRINTF("IMUL\t");
10815                destreg = DECODE_RM_WORD_REGISTER(rl);
10816                DECODE_PRINTF("\n");
10817                TRACE_AND_STEP();
10818                imul_word(*destreg);
10819            }
10820            break;
10821        case 6:
10822            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10823                u32 *destreg;
10824
10825                DECODE_PRINTF("DIV\t");
10826                destreg = DECODE_RM_LONG_REGISTER(rl);
10827                DECODE_PRINTF("\n");
10828                TRACE_AND_STEP();
10829                div_long(*destreg);
10830            } else {
10831                u16 *destreg;
10832
10833                DECODE_PRINTF("DIV\t");
10834                destreg = DECODE_RM_WORD_REGISTER(rl);
10835                DECODE_PRINTF("\n");
10836                TRACE_AND_STEP();
10837                div_word(*destreg);
10838            }
10839            break;
10840        case 7:
10841            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10842                u32 *destreg;
10843
10844                DECODE_PRINTF("IDIV\t");
10845                destreg = DECODE_RM_LONG_REGISTER(rl);
10846                DECODE_PRINTF("\n");
10847                TRACE_AND_STEP();
10848                idiv_long(*destreg);
10849            } else {
10850                u16 *destreg;
10851
10852                DECODE_PRINTF("IDIV\t");
10853                destreg = DECODE_RM_WORD_REGISTER(rl);
10854                DECODE_PRINTF("\n");
10855                TRACE_AND_STEP();
10856                idiv_word(*destreg);
10857            }
10858            break;
10859        }
10860        break;                  /* end mod==11 */
10861    }
10862    DECODE_CLEAR_SEGOVR();
10863    END_OF_INSTR();
10864}
10865
10866/****************************************************************************
10867REMARKS:
10868Handles opcode 0xf8
10869****************************************************************************/
10870static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10871{
10872    /* clear the carry flag. */
10873    START_OF_INSTR();
10874    DECODE_PRINTF("CLC\n");
10875    TRACE_AND_STEP();
10876    CLEAR_FLAG(F_CF);
10877    DECODE_CLEAR_SEGOVR();
10878    END_OF_INSTR();
10879}
10880
10881/****************************************************************************
10882REMARKS:
10883Handles opcode 0xf9
10884****************************************************************************/
10885static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10886{
10887    /* set the carry flag. */
10888    START_OF_INSTR();
10889    DECODE_PRINTF("STC\n");
10890    TRACE_AND_STEP();
10891    SET_FLAG(F_CF);
10892    DECODE_CLEAR_SEGOVR();
10893    END_OF_INSTR();
10894}
10895
10896/****************************************************************************
10897REMARKS:
10898Handles opcode 0xfa
10899****************************************************************************/
10900static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10901{
10902    /* clear interrupts. */
10903    START_OF_INSTR();
10904    DECODE_PRINTF("CLI\n");
10905    TRACE_AND_STEP();
10906    CLEAR_FLAG(F_IF);
10907    DECODE_CLEAR_SEGOVR();
10908    END_OF_INSTR();
10909}
10910
10911/****************************************************************************
10912REMARKS:
10913Handles opcode 0xfb
10914****************************************************************************/
10915static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10916{
10917    /* enable  interrupts. */
10918    START_OF_INSTR();
10919    DECODE_PRINTF("STI\n");
10920    TRACE_AND_STEP();
10921    SET_FLAG(F_IF);
10922    DECODE_CLEAR_SEGOVR();
10923    END_OF_INSTR();
10924}
10925
10926/****************************************************************************
10927REMARKS:
10928Handles opcode 0xfc
10929****************************************************************************/
10930static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10931{
10932    /* clear interrupts. */
10933    START_OF_INSTR();
10934    DECODE_PRINTF("CLD\n");
10935    TRACE_AND_STEP();
10936    CLEAR_FLAG(F_DF);
10937    DECODE_CLEAR_SEGOVR();
10938    END_OF_INSTR();
10939}
10940
10941/****************************************************************************
10942REMARKS:
10943Handles opcode 0xfd
10944****************************************************************************/
10945static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10946{
10947    /* clear interrupts. */
10948    START_OF_INSTR();
10949    DECODE_PRINTF("STD\n");
10950    TRACE_AND_STEP();
10951    SET_FLAG(F_DF);
10952    DECODE_CLEAR_SEGOVR();
10953    END_OF_INSTR();
10954}
10955
10956/****************************************************************************
10957REMARKS:
10958Handles opcode 0xfe
10959****************************************************************************/
10960static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10961{
10962    int mod, rh, rl;
10963    u8 destval;
10964    uint destoffset;
10965    u8 *destreg;
10966
10967    /* Yet another special case instruction. */
10968    START_OF_INSTR();
10969    FETCH_DECODE_MODRM(mod, rh, rl);
10970#ifdef DEBUG
10971    if (DEBUG_DECODE()) {
10972        /* XXX DECODE_PRINTF may be changed to something more
10973           general, so that it is important to leave the strings
10974           in the same format, even though the result is that the
10975           above test is done twice. */
10976
10977        switch (rh) {
10978        case 0:
10979            DECODE_PRINTF("INC\t");
10980            break;
10981        case 1:
10982            DECODE_PRINTF("DEC\t");
10983            break;
10984        case 2:
10985        case 3:
10986        case 4:
10987        case 5:
10988        case 6:
10989        case 7:
10990            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10991            HALT_SYS();
10992            break;
10993        }
10994    }
10995#endif
10996    switch (mod) {
10997    case 0:
10998        DECODE_PRINTF("BYTE PTR ");
10999        destoffset = decode_rm00_address(rl);
11000        DECODE_PRINTF("\n");
11001        switch (rh) {
11002        case 0:         /* inc word ptr ... */
11003            destval = fetch_data_byte(destoffset);
11004            TRACE_AND_STEP();
11005            destval = inc_byte(destval);
11006            store_data_byte(destoffset, destval);
11007            break;
11008        case 1:         /* dec word ptr ... */
11009            destval = fetch_data_byte(destoffset);
11010            TRACE_AND_STEP();
11011            destval = dec_byte(destval);
11012            store_data_byte(destoffset, destval);
11013            break;
11014        }
11015        break;
11016    case 1:
11017        DECODE_PRINTF("BYTE PTR ");
11018        destoffset = decode_rm01_address(rl);
11019        DECODE_PRINTF("\n");
11020        switch (rh) {
11021        case 0:
11022            destval = fetch_data_byte(destoffset);
11023            TRACE_AND_STEP();
11024            destval = inc_byte(destval);
11025            store_data_byte(destoffset, destval);
11026            break;
11027        case 1:
11028            destval = fetch_data_byte(destoffset);
11029            TRACE_AND_STEP();
11030            destval = dec_byte(destval);
11031            store_data_byte(destoffset, destval);
11032            break;
11033        }
11034        break;
11035    case 2:
11036        DECODE_PRINTF("BYTE PTR ");
11037        destoffset = decode_rm10_address(rl);
11038        DECODE_PRINTF("\n");
11039        switch (rh) {
11040        case 0:
11041            destval = fetch_data_byte(destoffset);
11042            TRACE_AND_STEP();
11043            destval = inc_byte(destval);
11044            store_data_byte(destoffset, destval);
11045            break;
11046        case 1:
11047            destval = fetch_data_byte(destoffset);
11048            TRACE_AND_STEP();
11049            destval = dec_byte(destval);
11050            store_data_byte(destoffset, destval);
11051            break;
11052        }
11053        break;
11054    case 3:
11055        destreg = DECODE_RM_BYTE_REGISTER(rl);
11056        DECODE_PRINTF("\n");
11057        switch (rh) {
11058        case 0:
11059            TRACE_AND_STEP();
11060            *destreg = inc_byte(*destreg);
11061            break;
11062        case 1:
11063            TRACE_AND_STEP();
11064            *destreg = dec_byte(*destreg);
11065            break;
11066        }
11067        break;
11068    }
11069    DECODE_CLEAR_SEGOVR();
11070    END_OF_INSTR();
11071}
11072
11073/****************************************************************************
11074REMARKS:
11075Handles opcode 0xff
11076****************************************************************************/
11077static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11078{
11079    int mod, rh, rl;
11080    uint destoffset = 0;
11081	u16 *destreg;
11082	u16 destval,destval2;
11083
11084    /* Yet another special case instruction. */
11085    START_OF_INSTR();
11086    FETCH_DECODE_MODRM(mod, rh, rl);
11087#ifdef DEBUG
11088    if (DEBUG_DECODE()) {
11089        /* XXX DECODE_PRINTF may be changed to something more
11090           general, so that it is important to leave the strings
11091           in the same format, even though the result is that the
11092           above test is done twice. */
11093
11094        switch (rh) {
11095        case 0:
11096            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11097                DECODE_PRINTF("INC\tDWORD PTR ");
11098            } else {
11099                DECODE_PRINTF("INC\tWORD PTR ");
11100            }
11101            break;
11102        case 1:
11103            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11104                DECODE_PRINTF("DEC\tDWORD PTR ");
11105            } else {
11106                DECODE_PRINTF("DEC\tWORD PTR ");
11107            }
11108            break;
11109        case 2:
11110            DECODE_PRINTF("CALL\t");
11111            break;
11112        case 3:
11113            DECODE_PRINTF("CALL\tFAR ");
11114            break;
11115        case 4:
11116            DECODE_PRINTF("JMP\t");
11117            break;
11118        case 5:
11119            DECODE_PRINTF("JMP\tFAR ");
11120            break;
11121        case 6:
11122            DECODE_PRINTF("PUSH\t");
11123            break;
11124        case 7:
11125            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11126            HALT_SYS();
11127            break;
11128        }
11129    }
11130#endif
11131    switch (mod) {
11132    case 0:
11133        destoffset = decode_rm00_address(rl);
11134        DECODE_PRINTF("\n");
11135        switch (rh) {
11136        case 0:         /* inc word ptr ... */
11137            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11138                u32 destval;
11139
11140                destval = fetch_data_long(destoffset);
11141                TRACE_AND_STEP();
11142                destval = inc_long(destval);
11143                store_data_long(destoffset, destval);
11144            } else {
11145                u16 destval;
11146
11147                destval = fetch_data_word(destoffset);
11148                TRACE_AND_STEP();
11149                destval = inc_word(destval);
11150                store_data_word(destoffset, destval);
11151            }
11152            break;
11153        case 1:         /* dec word ptr ... */
11154            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11155                u32 destval;
11156
11157                destval = fetch_data_long(destoffset);
11158                TRACE_AND_STEP();
11159                destval = dec_long(destval);
11160                store_data_long(destoffset, destval);
11161            } else {
11162                u16 destval;
11163
11164                destval = fetch_data_word(destoffset);
11165                TRACE_AND_STEP();
11166                destval = dec_word(destval);
11167                store_data_word(destoffset, destval);
11168            }
11169            break;
11170        case 2:         /* call word ptr ... */
11171            destval = fetch_data_word(destoffset);
11172            TRACE_AND_STEP();
11173            push_word(M.x86.R_IP);
11174            M.x86.R_IP = destval;
11175            break;
11176        case 3:         /* call far ptr ... */
11177            destval = fetch_data_word(destoffset);
11178            destval2 = fetch_data_word(destoffset + 2);
11179            TRACE_AND_STEP();
11180            push_word(M.x86.R_CS);
11181            M.x86.R_CS = destval2;
11182            push_word(M.x86.R_IP);
11183            M.x86.R_IP = destval;
11184            break;
11185        case 4:         /* jmp word ptr ... */
11186            destval = fetch_data_word(destoffset);
11187            TRACE_AND_STEP();
11188            M.x86.R_IP = destval;
11189            break;
11190        case 5:         /* jmp far ptr ... */
11191            destval = fetch_data_word(destoffset);
11192            destval2 = fetch_data_word(destoffset + 2);
11193            TRACE_AND_STEP();
11194            M.x86.R_IP = destval;
11195            M.x86.R_CS = destval2;
11196            break;
11197        case 6:         /*  push word ptr ... */
11198            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11199                u32 destval;
11200
11201                destval = fetch_data_long(destoffset);
11202                TRACE_AND_STEP();
11203                push_long(destval);
11204            } else {
11205                u16 destval;
11206
11207                destval = fetch_data_word(destoffset);
11208                TRACE_AND_STEP();
11209                push_word(destval);
11210            }
11211            break;
11212        }
11213        break;
11214    case 1:
11215        destoffset = decode_rm01_address(rl);
11216        DECODE_PRINTF("\n");
11217        switch (rh) {
11218        case 0:
11219            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11220                u32 destval;
11221
11222                destval = fetch_data_long(destoffset);
11223                TRACE_AND_STEP();
11224                destval = inc_long(destval);
11225                store_data_long(destoffset, destval);
11226            } else {
11227                u16 destval;
11228
11229                destval = fetch_data_word(destoffset);
11230                TRACE_AND_STEP();
11231                destval = inc_word(destval);
11232                store_data_word(destoffset, destval);
11233            }
11234            break;
11235        case 1:
11236            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11237                u32 destval;
11238
11239                destval = fetch_data_long(destoffset);
11240                TRACE_AND_STEP();
11241                destval = dec_long(destval);
11242                store_data_long(destoffset, destval);
11243            } else {
11244                u16 destval;
11245
11246                destval = fetch_data_word(destoffset);
11247                TRACE_AND_STEP();
11248                destval = dec_word(destval);
11249                store_data_word(destoffset, destval);
11250            }
11251            break;
11252        case 2:         /* call word ptr ... */
11253            destval = fetch_data_word(destoffset);
11254            TRACE_AND_STEP();
11255            push_word(M.x86.R_IP);
11256            M.x86.R_IP = destval;
11257            break;
11258        case 3:         /* call far ptr ... */
11259            destval = fetch_data_word(destoffset);
11260            destval2 = fetch_data_word(destoffset + 2);
11261            TRACE_AND_STEP();
11262            push_word(M.x86.R_CS);
11263            M.x86.R_CS = destval2;
11264            push_word(M.x86.R_IP);
11265            M.x86.R_IP = destval;
11266            break;
11267        case 4:         /* jmp word ptr ... */
11268            destval = fetch_data_word(destoffset);
11269            TRACE_AND_STEP();
11270            M.x86.R_IP = destval;
11271            break;
11272        case 5:         /* jmp far ptr ... */
11273            destval = fetch_data_word(destoffset);
11274            destval2 = fetch_data_word(destoffset + 2);
11275            TRACE_AND_STEP();
11276            M.x86.R_IP = destval;
11277            M.x86.R_CS = destval2;
11278            break;
11279        case 6:         /*  push word ptr ... */
11280            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11281                u32 destval;
11282
11283                destval = fetch_data_long(destoffset);
11284                TRACE_AND_STEP();
11285                push_long(destval);
11286            } else {
11287                u16 destval;
11288
11289                destval = fetch_data_word(destoffset);
11290                TRACE_AND_STEP();
11291                push_word(destval);
11292            }
11293            break;
11294        }
11295        break;
11296    case 2:
11297        destoffset = decode_rm10_address(rl);
11298        DECODE_PRINTF("\n");
11299        switch (rh) {
11300        case 0:
11301            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11302                u32 destval;
11303
11304                destval = fetch_data_long(destoffset);
11305                TRACE_AND_STEP();
11306                destval = inc_long(destval);
11307                store_data_long(destoffset, destval);
11308            } else {
11309                u16 destval;
11310
11311                destval = fetch_data_word(destoffset);
11312                TRACE_AND_STEP();
11313                destval = inc_word(destval);
11314                store_data_word(destoffset, destval);
11315            }
11316            break;
11317        case 1:
11318            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11319                u32 destval;
11320
11321                destval = fetch_data_long(destoffset);
11322                TRACE_AND_STEP();
11323                destval = dec_long(destval);
11324                store_data_long(destoffset, destval);
11325            } else {
11326                u16 destval;
11327
11328                destval = fetch_data_word(destoffset);
11329                TRACE_AND_STEP();
11330                destval = dec_word(destval);
11331                store_data_word(destoffset, destval);
11332            }
11333            break;
11334        case 2:         /* call word ptr ... */
11335            destval = fetch_data_word(destoffset);
11336            TRACE_AND_STEP();
11337            push_word(M.x86.R_IP);
11338            M.x86.R_IP = destval;
11339            break;
11340        case 3:         /* call far ptr ... */
11341            destval = fetch_data_word(destoffset);
11342            destval2 = fetch_data_word(destoffset + 2);
11343            TRACE_AND_STEP();
11344            push_word(M.x86.R_CS);
11345            M.x86.R_CS = destval2;
11346            push_word(M.x86.R_IP);
11347            M.x86.R_IP = destval;
11348            break;
11349        case 4:         /* jmp word ptr ... */
11350            destval = fetch_data_word(destoffset);
11351            TRACE_AND_STEP();
11352            M.x86.R_IP = destval;
11353            break;
11354        case 5:         /* jmp far ptr ... */
11355            destval = fetch_data_word(destoffset);
11356            destval2 = fetch_data_word(destoffset + 2);
11357            TRACE_AND_STEP();
11358            M.x86.R_IP = destval;
11359            M.x86.R_CS = destval2;
11360            break;
11361        case 6:         /*  push word ptr ... */
11362            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11363                u32 destval;
11364
11365                destval = fetch_data_long(destoffset);
11366                TRACE_AND_STEP();
11367                push_long(destval);
11368            } else {
11369                u16 destval;
11370
11371                destval = fetch_data_word(destoffset);
11372                TRACE_AND_STEP();
11373                push_word(destval);
11374            }
11375            break;
11376        }
11377        break;
11378    case 3:
11379        switch (rh) {
11380        case 0:
11381            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11382                u32 *destreg;
11383
11384                destreg = DECODE_RM_LONG_REGISTER(rl);
11385                DECODE_PRINTF("\n");
11386                TRACE_AND_STEP();
11387                *destreg = inc_long(*destreg);
11388            } else {
11389                u16 *destreg;
11390
11391                destreg = DECODE_RM_WORD_REGISTER(rl);
11392                DECODE_PRINTF("\n");
11393                TRACE_AND_STEP();
11394                *destreg = inc_word(*destreg);
11395            }
11396            break;
11397        case 1:
11398            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11399                u32 *destreg;
11400
11401                destreg = DECODE_RM_LONG_REGISTER(rl);
11402                DECODE_PRINTF("\n");
11403                TRACE_AND_STEP();
11404                *destreg = dec_long(*destreg);
11405            } else {
11406                u16 *destreg;
11407
11408                destreg = DECODE_RM_WORD_REGISTER(rl);
11409                DECODE_PRINTF("\n");
11410                TRACE_AND_STEP();
11411                *destreg = dec_word(*destreg);
11412            }
11413            break;
11414        case 2:         /* call word ptr ... */
11415            destreg = DECODE_RM_WORD_REGISTER(rl);
11416            DECODE_PRINTF("\n");
11417            TRACE_AND_STEP();
11418            push_word(M.x86.R_IP);
11419            M.x86.R_IP = *destreg;
11420            break;
11421        case 3:         /* jmp far ptr ... */
11422            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11423            TRACE_AND_STEP();
11424            HALT_SYS();
11425            break;
11426
11427        case 4:         /* jmp  ... */
11428            destreg = DECODE_RM_WORD_REGISTER(rl);
11429            DECODE_PRINTF("\n");
11430            TRACE_AND_STEP();
11431            M.x86.R_IP = (u16) (*destreg);
11432            break;
11433        case 5:         /* jmp far ptr ... */
11434            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11435            TRACE_AND_STEP();
11436            HALT_SYS();
11437            break;
11438        case 6:
11439            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11440                u32 *destreg;
11441
11442                destreg = DECODE_RM_LONG_REGISTER(rl);
11443                DECODE_PRINTF("\n");
11444                TRACE_AND_STEP();
11445                push_long(*destreg);
11446            } else {
11447                u16 *destreg;
11448
11449                destreg = DECODE_RM_WORD_REGISTER(rl);
11450                DECODE_PRINTF("\n");
11451                TRACE_AND_STEP();
11452                push_word(*destreg);
11453            }
11454            break;
11455        }
11456        break;
11457    }
11458    DECODE_CLEAR_SEGOVR();
11459    END_OF_INSTR();
11460}
11461
11462/***************************************************************************
11463 * Single byte operation code table:
11464 **************************************************************************/
11465void (*x86emu_optab[256])(u8) =
11466{
11467/*  0x00 */ x86emuOp_add_byte_RM_R,
11468/*  0x01 */ x86emuOp_add_word_RM_R,
11469/*  0x02 */ x86emuOp_add_byte_R_RM,
11470/*  0x03 */ x86emuOp_add_word_R_RM,
11471/*  0x04 */ x86emuOp_add_byte_AL_IMM,
11472/*  0x05 */ x86emuOp_add_word_AX_IMM,
11473/*  0x06 */ x86emuOp_push_ES,
11474/*  0x07 */ x86emuOp_pop_ES,
11475
11476/*  0x08 */ x86emuOp_or_byte_RM_R,
11477/*  0x09 */ x86emuOp_or_word_RM_R,
11478/*  0x0a */ x86emuOp_or_byte_R_RM,
11479/*  0x0b */ x86emuOp_or_word_R_RM,
11480/*  0x0c */ x86emuOp_or_byte_AL_IMM,
11481/*  0x0d */ x86emuOp_or_word_AX_IMM,
11482/*  0x0e */ x86emuOp_push_CS,
11483/*  0x0f */ x86emuOp_two_byte,
11484
11485/*  0x10 */ x86emuOp_adc_byte_RM_R,
11486/*  0x11 */ x86emuOp_adc_word_RM_R,
11487/*  0x12 */ x86emuOp_adc_byte_R_RM,
11488/*  0x13 */ x86emuOp_adc_word_R_RM,
11489/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11490/*  0x15 */ x86emuOp_adc_word_AX_IMM,
11491/*  0x16 */ x86emuOp_push_SS,
11492/*  0x17 */ x86emuOp_pop_SS,
11493
11494/*  0x18 */ x86emuOp_sbb_byte_RM_R,
11495/*  0x19 */ x86emuOp_sbb_word_RM_R,
11496/*  0x1a */ x86emuOp_sbb_byte_R_RM,
11497/*  0x1b */ x86emuOp_sbb_word_R_RM,
11498/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11499/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11500/*  0x1e */ x86emuOp_push_DS,
11501/*  0x1f */ x86emuOp_pop_DS,
11502
11503/*  0x20 */ x86emuOp_and_byte_RM_R,
11504/*  0x21 */ x86emuOp_and_word_RM_R,
11505/*  0x22 */ x86emuOp_and_byte_R_RM,
11506/*  0x23 */ x86emuOp_and_word_R_RM,
11507/*  0x24 */ x86emuOp_and_byte_AL_IMM,
11508/*  0x25 */ x86emuOp_and_word_AX_IMM,
11509/*  0x26 */ x86emuOp_segovr_ES,
11510/*  0x27 */ x86emuOp_daa,
11511
11512/*  0x28 */ x86emuOp_sub_byte_RM_R,
11513/*  0x29 */ x86emuOp_sub_word_RM_R,
11514/*  0x2a */ x86emuOp_sub_byte_R_RM,
11515/*  0x2b */ x86emuOp_sub_word_R_RM,
11516/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11517/*  0x2d */ x86emuOp_sub_word_AX_IMM,
11518/*  0x2e */ x86emuOp_segovr_CS,
11519/*  0x2f */ x86emuOp_das,
11520
11521/*  0x30 */ x86emuOp_xor_byte_RM_R,
11522/*  0x31 */ x86emuOp_xor_word_RM_R,
11523/*  0x32 */ x86emuOp_xor_byte_R_RM,
11524/*  0x33 */ x86emuOp_xor_word_R_RM,
11525/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11526/*  0x35 */ x86emuOp_xor_word_AX_IMM,
11527/*  0x36 */ x86emuOp_segovr_SS,
11528/*  0x37 */ x86emuOp_aaa,
11529
11530/*  0x38 */ x86emuOp_cmp_byte_RM_R,
11531/*  0x39 */ x86emuOp_cmp_word_RM_R,
11532/*  0x3a */ x86emuOp_cmp_byte_R_RM,
11533/*  0x3b */ x86emuOp_cmp_word_R_RM,
11534/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11535/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11536/*  0x3e */ x86emuOp_segovr_DS,
11537/*  0x3f */ x86emuOp_aas,
11538
11539/*  0x40 */ x86emuOp_inc_AX,
11540/*  0x41 */ x86emuOp_inc_CX,
11541/*  0x42 */ x86emuOp_inc_DX,
11542/*  0x43 */ x86emuOp_inc_BX,
11543/*  0x44 */ x86emuOp_inc_SP,
11544/*  0x45 */ x86emuOp_inc_BP,
11545/*  0x46 */ x86emuOp_inc_SI,
11546/*  0x47 */ x86emuOp_inc_DI,
11547
11548/*  0x48 */ x86emuOp_dec_AX,
11549/*  0x49 */ x86emuOp_dec_CX,
11550/*  0x4a */ x86emuOp_dec_DX,
11551/*  0x4b */ x86emuOp_dec_BX,
11552/*  0x4c */ x86emuOp_dec_SP,
11553/*  0x4d */ x86emuOp_dec_BP,
11554/*  0x4e */ x86emuOp_dec_SI,
11555/*  0x4f */ x86emuOp_dec_DI,
11556
11557/*  0x50 */ x86emuOp_push_AX,
11558/*  0x51 */ x86emuOp_push_CX,
11559/*  0x52 */ x86emuOp_push_DX,
11560/*  0x53 */ x86emuOp_push_BX,
11561/*  0x54 */ x86emuOp_push_SP,
11562/*  0x55 */ x86emuOp_push_BP,
11563/*  0x56 */ x86emuOp_push_SI,
11564/*  0x57 */ x86emuOp_push_DI,
11565
11566/*  0x58 */ x86emuOp_pop_AX,
11567/*  0x59 */ x86emuOp_pop_CX,
11568/*  0x5a */ x86emuOp_pop_DX,
11569/*  0x5b */ x86emuOp_pop_BX,
11570/*  0x5c */ x86emuOp_pop_SP,
11571/*  0x5d */ x86emuOp_pop_BP,
11572/*  0x5e */ x86emuOp_pop_SI,
11573/*  0x5f */ x86emuOp_pop_DI,
11574
11575/*  0x60 */ x86emuOp_push_all,
11576/*  0x61 */ x86emuOp_pop_all,
11577/*  0x62 */ x86emuOp_illegal_op,   /* bound */
11578/*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11579/*  0x64 */ x86emuOp_segovr_FS,
11580/*  0x65 */ x86emuOp_segovr_GS,
11581/*  0x66 */ x86emuOp_prefix_data,
11582/*  0x67 */ x86emuOp_prefix_addr,
11583
11584/*  0x68 */ x86emuOp_push_word_IMM,
11585/*  0x69 */ x86emuOp_imul_word_IMM,
11586/*  0x6a */ x86emuOp_push_byte_IMM,
11587/*  0x6b */ x86emuOp_imul_byte_IMM,
11588/*  0x6c */ x86emuOp_ins_byte,
11589/*  0x6d */ x86emuOp_ins_word,
11590/*  0x6e */ x86emuOp_outs_byte,
11591/*  0x6f */ x86emuOp_outs_word,
11592
11593/*  0x70 */ x86emuOp_jump_near_O,
11594/*  0x71 */ x86emuOp_jump_near_NO,
11595/*  0x72 */ x86emuOp_jump_near_B,
11596/*  0x73 */ x86emuOp_jump_near_NB,
11597/*  0x74 */ x86emuOp_jump_near_Z,
11598/*  0x75 */ x86emuOp_jump_near_NZ,
11599/*  0x76 */ x86emuOp_jump_near_BE,
11600/*  0x77 */ x86emuOp_jump_near_NBE,
11601
11602/*  0x78 */ x86emuOp_jump_near_S,
11603/*  0x79 */ x86emuOp_jump_near_NS,
11604/*  0x7a */ x86emuOp_jump_near_P,
11605/*  0x7b */ x86emuOp_jump_near_NP,
11606/*  0x7c */ x86emuOp_jump_near_L,
11607/*  0x7d */ x86emuOp_jump_near_NL,
11608/*  0x7e */ x86emuOp_jump_near_LE,
11609/*  0x7f */ x86emuOp_jump_near_NLE,
11610
11611/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11612/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11613/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11614/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11615/*  0x84 */ x86emuOp_test_byte_RM_R,
11616/*  0x85 */ x86emuOp_test_word_RM_R,
11617/*  0x86 */ x86emuOp_xchg_byte_RM_R,
11618/*  0x87 */ x86emuOp_xchg_word_RM_R,
11619
11620/*  0x88 */ x86emuOp_mov_byte_RM_R,
11621/*  0x89 */ x86emuOp_mov_word_RM_R,
11622/*  0x8a */ x86emuOp_mov_byte_R_RM,
11623/*  0x8b */ x86emuOp_mov_word_R_RM,
11624/*  0x8c */ x86emuOp_mov_word_RM_SR,
11625/*  0x8d */ x86emuOp_lea_word_R_M,
11626/*  0x8e */ x86emuOp_mov_word_SR_RM,
11627/*  0x8f */ x86emuOp_pop_RM,
11628
11629/*  0x90 */ x86emuOp_nop,
11630/*  0x91 */ x86emuOp_xchg_word_AX_CX,
11631/*  0x92 */ x86emuOp_xchg_word_AX_DX,
11632/*  0x93 */ x86emuOp_xchg_word_AX_BX,
11633/*  0x94 */ x86emuOp_xchg_word_AX_SP,
11634/*  0x95 */ x86emuOp_xchg_word_AX_BP,
11635/*  0x96 */ x86emuOp_xchg_word_AX_SI,
11636/*  0x97 */ x86emuOp_xchg_word_AX_DI,
11637
11638/*  0x98 */ x86emuOp_cbw,
11639/*  0x99 */ x86emuOp_cwd,
11640/*  0x9a */ x86emuOp_call_far_IMM,
11641/*  0x9b */ x86emuOp_wait,
11642/*  0x9c */ x86emuOp_pushf_word,
11643/*  0x9d */ x86emuOp_popf_word,
11644/*  0x9e */ x86emuOp_sahf,
11645/*  0x9f */ x86emuOp_lahf,
11646
11647/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11648/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11649/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11650/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11651/*  0xa4 */ x86emuOp_movs_byte,
11652/*  0xa5 */ x86emuOp_movs_word,
11653/*  0xa6 */ x86emuOp_cmps_byte,
11654/*  0xa7 */ x86emuOp_cmps_word,
11655/*  0xa8 */ x86emuOp_test_AL_IMM,
11656/*  0xa9 */ x86emuOp_test_AX_IMM,
11657/*  0xaa */ x86emuOp_stos_byte,
11658/*  0xab */ x86emuOp_stos_word,
11659/*  0xac */ x86emuOp_lods_byte,
11660/*  0xad */ x86emuOp_lods_word,
11661/*  0xac */ x86emuOp_scas_byte,
11662/*  0xad */ x86emuOp_scas_word,
11663
11664
11665/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11666/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11667/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11668/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11669/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11670/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11671/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11672/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11673
11674/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11675/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11676/*  0xba */ x86emuOp_mov_word_DX_IMM,
11677/*  0xbb */ x86emuOp_mov_word_BX_IMM,
11678/*  0xbc */ x86emuOp_mov_word_SP_IMM,
11679/*  0xbd */ x86emuOp_mov_word_BP_IMM,
11680/*  0xbe */ x86emuOp_mov_word_SI_IMM,
11681/*  0xbf */ x86emuOp_mov_word_DI_IMM,
11682
11683/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11684/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11685/*  0xc2 */ x86emuOp_ret_near_IMM,
11686/*  0xc3 */ x86emuOp_ret_near,
11687/*  0xc4 */ x86emuOp_les_R_IMM,
11688/*  0xc5 */ x86emuOp_lds_R_IMM,
11689/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11690/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11691/*  0xc8 */ x86emuOp_enter,
11692/*  0xc9 */ x86emuOp_leave,
11693/*  0xca */ x86emuOp_ret_far_IMM,
11694/*  0xcb */ x86emuOp_ret_far,
11695/*  0xcc */ x86emuOp_int3,
11696/*  0xcd */ x86emuOp_int_IMM,
11697/*  0xce */ x86emuOp_into,
11698/*  0xcf */ x86emuOp_iret,
11699
11700/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11701/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11702/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11703/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11704/*  0xd4 */ x86emuOp_aam,
11705/*  0xd5 */ x86emuOp_aad,
11706/*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11707/*  0xd7 */ x86emuOp_xlat,
11708/*  0xd8 */ x86emuOp_esc_coprocess_d8,
11709/*  0xd9 */ x86emuOp_esc_coprocess_d9,
11710/*  0xda */ x86emuOp_esc_coprocess_da,
11711/*  0xdb */ x86emuOp_esc_coprocess_db,
11712/*  0xdc */ x86emuOp_esc_coprocess_dc,
11713/*  0xdd */ x86emuOp_esc_coprocess_dd,
11714/*  0xde */ x86emuOp_esc_coprocess_de,
11715/*  0xdf */ x86emuOp_esc_coprocess_df,
11716
11717/*  0xe0 */ x86emuOp_loopne,
11718/*  0xe1 */ x86emuOp_loope,
11719/*  0xe2 */ x86emuOp_loop,
11720/*  0xe3 */ x86emuOp_jcxz,
11721/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11722/*  0xe5 */ x86emuOp_in_word_AX_IMM,
11723/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11724/*  0xe7 */ x86emuOp_out_word_IMM_AX,
11725
11726/*  0xe8 */ x86emuOp_call_near_IMM,
11727/*  0xe9 */ x86emuOp_jump_near_IMM,
11728/*  0xea */ x86emuOp_jump_far_IMM,
11729/*  0xeb */ x86emuOp_jump_byte_IMM,
11730/*  0xec */ x86emuOp_in_byte_AL_DX,
11731/*  0xed */ x86emuOp_in_word_AX_DX,
11732/*  0xee */ x86emuOp_out_byte_DX_AL,
11733/*  0xef */ x86emuOp_out_word_DX_AX,
11734
11735/*  0xf0 */ x86emuOp_lock,
11736/*  0xf1 */ x86emuOp_illegal_op,
11737/*  0xf2 */ x86emuOp_repne,
11738/*  0xf3 */ x86emuOp_repe,
11739/*  0xf4 */ x86emuOp_halt,
11740/*  0xf5 */ x86emuOp_cmc,
11741/*  0xf6 */ x86emuOp_opcF6_byte_RM,
11742/*  0xf7 */ x86emuOp_opcF7_word_RM,
11743
11744/*  0xf8 */ x86emuOp_clc,
11745/*  0xf9 */ x86emuOp_stc,
11746/*  0xfa */ x86emuOp_cli,
11747/*  0xfb */ x86emuOp_sti,
11748/*  0xfc */ x86emuOp_cld,
11749/*  0xfd */ x86emuOp_std,
11750/*  0xfe */ x86emuOp_opcFE_byte_RM,
11751/*  0xff */ x86emuOp_opcFF_word_RM,
11752};
11753