ops.c revision 6747b715
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    u16 farseg, faroff;
7069
7070    START_OF_INSTR();
7071	DECODE_PRINTF("CALL\t");
7072	faroff = fetch_word_imm();
7073	farseg = fetch_word_imm();
7074	DECODE_PRINTF2("%04x:", farseg);
7075	DECODE_PRINTF2("%04x\n", faroff);
7076	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7077
7078    /* XXX
7079     *
7080     * Hooked interrupt vectors calling into our "BIOS" will cause
7081     * problems unless all intersegment stuff is checked for BIOS
7082     * access.  Check needed here.  For moment, let it alone.
7083     */
7084    TRACE_AND_STEP();
7085    push_word(M.x86.R_CS);
7086    M.x86.R_CS = farseg;
7087    push_word(M.x86.R_IP);
7088    M.x86.R_IP = faroff;
7089    DECODE_CLEAR_SEGOVR();
7090    END_OF_INSTR();
7091}
7092
7093/****************************************************************************
7094REMARKS:
7095Handles opcode 0x9b
7096****************************************************************************/
7097static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7098{
7099    START_OF_INSTR();
7100    DECODE_PRINTF("WAIT");
7101    TRACE_AND_STEP();
7102    /* NADA.  */
7103    DECODE_CLEAR_SEGOVR();
7104    END_OF_INSTR();
7105}
7106
7107/****************************************************************************
7108REMARKS:
7109Handles opcode 0x9c
7110****************************************************************************/
7111static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7112{
7113    u32 flags;
7114
7115    START_OF_INSTR();
7116    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7117        DECODE_PRINTF("PUSHFD\n");
7118    } else {
7119        DECODE_PRINTF("PUSHF\n");
7120    }
7121    TRACE_AND_STEP();
7122
7123    /* clear out *all* bits not representing flags, and turn on real bits */
7124    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7125    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7126        push_long(flags);
7127    } else {
7128        push_word((u16)flags);
7129    }
7130    DECODE_CLEAR_SEGOVR();
7131    END_OF_INSTR();
7132}
7133
7134/****************************************************************************
7135REMARKS:
7136Handles opcode 0x9d
7137****************************************************************************/
7138static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7139{
7140    START_OF_INSTR();
7141    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7142        DECODE_PRINTF("POPFD\n");
7143    } else {
7144        DECODE_PRINTF("POPF\n");
7145    }
7146    TRACE_AND_STEP();
7147    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7148        M.x86.R_EFLG = pop_long();
7149    } else {
7150        M.x86.R_FLG = pop_word();
7151    }
7152    DECODE_CLEAR_SEGOVR();
7153    END_OF_INSTR();
7154}
7155
7156/****************************************************************************
7157REMARKS:
7158Handles opcode 0x9e
7159****************************************************************************/
7160static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7161{
7162    START_OF_INSTR();
7163    DECODE_PRINTF("SAHF\n");
7164    TRACE_AND_STEP();
7165    /* clear the lower bits of the flag register */
7166    M.x86.R_FLG &= 0xffffff00;
7167    /* or in the AH register into the flags register */
7168    M.x86.R_FLG |= M.x86.R_AH;
7169    DECODE_CLEAR_SEGOVR();
7170    END_OF_INSTR();
7171}
7172
7173/****************************************************************************
7174REMARKS:
7175Handles opcode 0x9f
7176****************************************************************************/
7177static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7178{
7179    START_OF_INSTR();
7180    DECODE_PRINTF("LAHF\n");
7181    TRACE_AND_STEP();
7182	M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7183    /*undocumented TC++ behavior??? Nope.  It's documented, but
7184       you have too look real hard to notice it. */
7185    M.x86.R_AH |= 0x2;
7186    DECODE_CLEAR_SEGOVR();
7187    END_OF_INSTR();
7188}
7189
7190/****************************************************************************
7191REMARKS:
7192Handles opcode 0xa0
7193****************************************************************************/
7194static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7195{
7196    u16 offset;
7197
7198    START_OF_INSTR();
7199    DECODE_PRINTF("MOV\tAL,");
7200    offset = fetch_word_imm();
7201    DECODE_PRINTF2("[%04x]\n", offset);
7202    TRACE_AND_STEP();
7203    M.x86.R_AL = fetch_data_byte(offset);
7204    DECODE_CLEAR_SEGOVR();
7205    END_OF_INSTR();
7206}
7207
7208/****************************************************************************
7209REMARKS:
7210Handles opcode 0xa1
7211****************************************************************************/
7212static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7213{
7214    u16 offset;
7215
7216    START_OF_INSTR();
7217    offset = fetch_word_imm();
7218    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7219        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7220    } else {
7221        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7222    }
7223    TRACE_AND_STEP();
7224    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7225        M.x86.R_EAX = fetch_data_long(offset);
7226    } else {
7227        M.x86.R_AX = fetch_data_word(offset);
7228    }
7229    DECODE_CLEAR_SEGOVR();
7230    END_OF_INSTR();
7231}
7232
7233/****************************************************************************
7234REMARKS:
7235Handles opcode 0xa2
7236****************************************************************************/
7237static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7238{
7239    u16 offset;
7240
7241    START_OF_INSTR();
7242    DECODE_PRINTF("MOV\t");
7243    offset = fetch_word_imm();
7244    DECODE_PRINTF2("[%04x],AL\n", offset);
7245    TRACE_AND_STEP();
7246    store_data_byte(offset, M.x86.R_AL);
7247    DECODE_CLEAR_SEGOVR();
7248    END_OF_INSTR();
7249}
7250
7251/****************************************************************************
7252REMARKS:
7253Handles opcode 0xa3
7254****************************************************************************/
7255static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7256{
7257    u16 offset;
7258
7259    START_OF_INSTR();
7260    offset = fetch_word_imm();
7261    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7262        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7263    } else {
7264        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7265    }
7266    TRACE_AND_STEP();
7267    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7268        store_data_long(offset, M.x86.R_EAX);
7269    } else {
7270        store_data_word(offset, M.x86.R_AX);
7271    }
7272    DECODE_CLEAR_SEGOVR();
7273    END_OF_INSTR();
7274}
7275
7276/****************************************************************************
7277REMARKS:
7278Handles opcode 0xa4
7279****************************************************************************/
7280static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7281{
7282    u8  val;
7283    u32 count;
7284    int inc;
7285
7286    START_OF_INSTR();
7287    DECODE_PRINTF("MOVS\tBYTE\n");
7288    if (ACCESS_FLAG(F_DF))   /* down */
7289        inc = -1;
7290    else
7291        inc = 1;
7292    TRACE_AND_STEP();
7293    count = 1;
7294    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7295        /* dont care whether REPE or REPNE */
7296        /* move them until CX is ZERO. */
7297        count = M.x86.R_CX;
7298        M.x86.R_CX = 0;
7299        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7300    }
7301    while (count--) {
7302        val = fetch_data_byte(M.x86.R_SI);
7303        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7304        M.x86.R_SI += inc;
7305        M.x86.R_DI += inc;
7306    }
7307    DECODE_CLEAR_SEGOVR();
7308    END_OF_INSTR();
7309}
7310
7311/****************************************************************************
7312REMARKS:
7313Handles opcode 0xa5
7314****************************************************************************/
7315static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7316{
7317    u32 val;
7318    int inc;
7319    u32 count;
7320
7321    START_OF_INSTR();
7322    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7323        DECODE_PRINTF("MOVS\tDWORD\n");
7324        if (ACCESS_FLAG(F_DF))      /* down */
7325            inc = -4;
7326        else
7327            inc = 4;
7328    } else {
7329        DECODE_PRINTF("MOVS\tWORD\n");
7330        if (ACCESS_FLAG(F_DF))      /* down */
7331            inc = -2;
7332        else
7333            inc = 2;
7334    }
7335    TRACE_AND_STEP();
7336    count = 1;
7337    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7338        /* dont care whether REPE or REPNE */
7339        /* move them until CX is ZERO. */
7340        count = M.x86.R_CX;
7341        M.x86.R_CX = 0;
7342        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7343    }
7344    while (count--) {
7345        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7346            val = fetch_data_long(M.x86.R_SI);
7347            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7348        } else {
7349            val = fetch_data_word(M.x86.R_SI);
7350            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7351        }
7352        M.x86.R_SI += inc;
7353        M.x86.R_DI += inc;
7354    }
7355    DECODE_CLEAR_SEGOVR();
7356    END_OF_INSTR();
7357}
7358
7359/****************************************************************************
7360REMARKS:
7361Handles opcode 0xa6
7362****************************************************************************/
7363static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7364{
7365    s8 val1, val2;
7366    int inc;
7367
7368    START_OF_INSTR();
7369    DECODE_PRINTF("CMPS\tBYTE\n");
7370    TRACE_AND_STEP();
7371    if (ACCESS_FLAG(F_DF))   /* down */
7372        inc = -1;
7373    else
7374        inc = 1;
7375
7376    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7377        /* REPE  */
7378        /* move them until CX is ZERO. */
7379        while (M.x86.R_CX != 0) {
7380            val1 = fetch_data_byte(M.x86.R_SI);
7381            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7382                     cmp_byte(val1, val2);
7383            M.x86.R_CX -= 1;
7384            M.x86.R_SI += inc;
7385            M.x86.R_DI += inc;
7386            if (ACCESS_FLAG(F_ZF) == 0)
7387                break;
7388        }
7389        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7390    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7391        /* REPNE  */
7392        /* move them until CX is ZERO. */
7393        while (M.x86.R_CX != 0) {
7394            val1 = fetch_data_byte(M.x86.R_SI);
7395            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7396            cmp_byte(val1, val2);
7397            M.x86.R_CX -= 1;
7398            M.x86.R_SI += inc;
7399            M.x86.R_DI += inc;
7400            if (ACCESS_FLAG(F_ZF))
7401                break;          /* zero flag set means equal */
7402        }
7403        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7404    } else {
7405        val1 = fetch_data_byte(M.x86.R_SI);
7406        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7407        cmp_byte(val1, val2);
7408        M.x86.R_SI += inc;
7409        M.x86.R_DI += inc;
7410    }
7411    DECODE_CLEAR_SEGOVR();
7412    END_OF_INSTR();
7413}
7414
7415/****************************************************************************
7416REMARKS:
7417Handles opcode 0xa7
7418****************************************************************************/
7419static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7420{
7421    u32 val1,val2;
7422    int inc;
7423
7424    START_OF_INSTR();
7425    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7426        DECODE_PRINTF("CMPS\tDWORD\n");
7427        if (ACCESS_FLAG(F_DF))   /* down */
7428            inc = -4;
7429        else
7430            inc = 4;
7431    } else {
7432        DECODE_PRINTF("CMPS\tWORD\n");
7433        if (ACCESS_FLAG(F_DF))   /* down */
7434            inc = -2;
7435        else
7436            inc = 2;
7437    }
7438    TRACE_AND_STEP();
7439    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7440        /* REPE  */
7441        /* move them until CX is ZERO. */
7442        while (M.x86.R_CX != 0) {
7443            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7444                val1 = fetch_data_long(M.x86.R_SI);
7445                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7446                cmp_long(val1, val2);
7447            } else {
7448                val1 = fetch_data_word(M.x86.R_SI);
7449                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7450                cmp_word((u16)val1, (u16)val2);
7451            }
7452            M.x86.R_CX -= 1;
7453            M.x86.R_SI += inc;
7454            M.x86.R_DI += inc;
7455            if (ACCESS_FLAG(F_ZF) == 0)
7456                break;
7457        }
7458        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7459    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7460        /* REPNE  */
7461        /* move them until CX is ZERO. */
7462        while (M.x86.R_CX != 0) {
7463            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7464                val1 = fetch_data_long(M.x86.R_SI);
7465                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7466                cmp_long(val1, val2);
7467            } else {
7468                val1 = fetch_data_word(M.x86.R_SI);
7469                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7470                cmp_word((u16)val1, (u16)val2);
7471            }
7472            M.x86.R_CX -= 1;
7473            M.x86.R_SI += inc;
7474            M.x86.R_DI += inc;
7475            if (ACCESS_FLAG(F_ZF))
7476                break;          /* zero flag set means equal */
7477        }
7478        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7479    } else {
7480        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7481            val1 = fetch_data_long(M.x86.R_SI);
7482            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7483            cmp_long(val1, val2);
7484        } else {
7485            val1 = fetch_data_word(M.x86.R_SI);
7486            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7487            cmp_word((u16)val1, (u16)val2);
7488        }
7489        M.x86.R_SI += inc;
7490        M.x86.R_DI += inc;
7491    }
7492    DECODE_CLEAR_SEGOVR();
7493    END_OF_INSTR();
7494}
7495
7496/****************************************************************************
7497REMARKS:
7498Handles opcode 0xa8
7499****************************************************************************/
7500static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7501{
7502    int imm;
7503
7504    START_OF_INSTR();
7505    DECODE_PRINTF("TEST\tAL,");
7506    imm = fetch_byte_imm();
7507    DECODE_PRINTF2("%04x\n", imm);
7508    TRACE_AND_STEP();
7509	test_byte(M.x86.R_AL, (u8)imm);
7510    DECODE_CLEAR_SEGOVR();
7511    END_OF_INSTR();
7512}
7513
7514/****************************************************************************
7515REMARKS:
7516Handles opcode 0xa9
7517****************************************************************************/
7518static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7519{
7520    u32 srcval;
7521
7522    START_OF_INSTR();
7523    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7524        DECODE_PRINTF("TEST\tEAX,");
7525        srcval = fetch_long_imm();
7526    } else {
7527        DECODE_PRINTF("TEST\tAX,");
7528        srcval = fetch_word_imm();
7529    }
7530    DECODE_PRINTF2("%x\n", srcval);
7531    TRACE_AND_STEP();
7532    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7533        test_long(M.x86.R_EAX, srcval);
7534    } else {
7535        test_word(M.x86.R_AX, (u16)srcval);
7536    }
7537    DECODE_CLEAR_SEGOVR();
7538    END_OF_INSTR();
7539}
7540
7541/****************************************************************************
7542REMARKS:
7543Handles opcode 0xaa
7544****************************************************************************/
7545static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7546{
7547    int inc;
7548
7549    START_OF_INSTR();
7550    DECODE_PRINTF("STOS\tBYTE\n");
7551    if (ACCESS_FLAG(F_DF))   /* down */
7552        inc = -1;
7553    else
7554        inc = 1;
7555    TRACE_AND_STEP();
7556    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7557        /* dont care whether REPE or REPNE */
7558        /* move them until CX is ZERO. */
7559        while (M.x86.R_CX != 0) {
7560            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7561            M.x86.R_CX -= 1;
7562            M.x86.R_DI += inc;
7563        }
7564        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7565    } else {
7566        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7567        M.x86.R_DI += inc;
7568    }
7569    DECODE_CLEAR_SEGOVR();
7570    END_OF_INSTR();
7571}
7572
7573/****************************************************************************
7574REMARKS:
7575Handles opcode 0xab
7576****************************************************************************/
7577static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7578{
7579    int inc;
7580    u32 count;
7581
7582    START_OF_INSTR();
7583    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7584        DECODE_PRINTF("STOS\tDWORD\n");
7585        if (ACCESS_FLAG(F_DF))   /* down */
7586            inc = -4;
7587        else
7588            inc = 4;
7589    } else {
7590        DECODE_PRINTF("STOS\tWORD\n");
7591        if (ACCESS_FLAG(F_DF))   /* down */
7592            inc = -2;
7593        else
7594            inc = 2;
7595    }
7596    TRACE_AND_STEP();
7597    count = 1;
7598    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7599        /* dont care whether REPE or REPNE */
7600        /* move them until CX is ZERO. */
7601        count = M.x86.R_CX;
7602        M.x86.R_CX = 0;
7603        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7604    }
7605    while (count--) {
7606        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7607            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7608        } else {
7609            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7610        }
7611        M.x86.R_DI += inc;
7612    }
7613    DECODE_CLEAR_SEGOVR();
7614    END_OF_INSTR();
7615}
7616
7617/****************************************************************************
7618REMARKS:
7619Handles opcode 0xac
7620****************************************************************************/
7621static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7622{
7623    int inc;
7624
7625    START_OF_INSTR();
7626    DECODE_PRINTF("LODS\tBYTE\n");
7627    TRACE_AND_STEP();
7628    if (ACCESS_FLAG(F_DF))   /* down */
7629        inc = -1;
7630    else
7631        inc = 1;
7632    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7633        /* dont care whether REPE or REPNE */
7634        /* move them until CX is ZERO. */
7635        while (M.x86.R_CX != 0) {
7636            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7637            M.x86.R_CX -= 1;
7638            M.x86.R_SI += inc;
7639        }
7640        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7641    } else {
7642        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7643        M.x86.R_SI += inc;
7644    }
7645    DECODE_CLEAR_SEGOVR();
7646    END_OF_INSTR();
7647}
7648
7649/****************************************************************************
7650REMARKS:
7651Handles opcode 0xad
7652****************************************************************************/
7653static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7654{
7655    int inc;
7656    u32 count;
7657
7658    START_OF_INSTR();
7659    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7660        DECODE_PRINTF("LODS\tDWORD\n");
7661        if (ACCESS_FLAG(F_DF))   /* down */
7662            inc = -4;
7663        else
7664            inc = 4;
7665    } else {
7666        DECODE_PRINTF("LODS\tWORD\n");
7667        if (ACCESS_FLAG(F_DF))   /* down */
7668            inc = -2;
7669        else
7670            inc = 2;
7671    }
7672    TRACE_AND_STEP();
7673    count = 1;
7674    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7675        /* dont care whether REPE or REPNE */
7676        /* move them until CX is ZERO. */
7677        count = M.x86.R_CX;
7678        M.x86.R_CX = 0;
7679        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7680    }
7681    while (count--) {
7682        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7683            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7684        } else {
7685            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7686        }
7687        M.x86.R_SI += inc;
7688    }
7689    DECODE_CLEAR_SEGOVR();
7690    END_OF_INSTR();
7691}
7692
7693/****************************************************************************
7694REMARKS:
7695Handles opcode 0xae
7696****************************************************************************/
7697static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7698{
7699    s8 val2;
7700    int inc;
7701
7702    START_OF_INSTR();
7703    DECODE_PRINTF("SCAS\tBYTE\n");
7704    TRACE_AND_STEP();
7705    if (ACCESS_FLAG(F_DF))   /* down */
7706        inc = -1;
7707    else
7708        inc = 1;
7709    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7710        /* REPE  */
7711        /* move them until CX is ZERO. */
7712        while (M.x86.R_CX != 0) {
7713            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7714            cmp_byte(M.x86.R_AL, val2);
7715            M.x86.R_CX -= 1;
7716            M.x86.R_DI += inc;
7717            if (ACCESS_FLAG(F_ZF) == 0)
7718                break;
7719        }
7720        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7721    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7722        /* REPNE  */
7723        /* move them until CX is ZERO. */
7724        while (M.x86.R_CX != 0) {
7725            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7726            cmp_byte(M.x86.R_AL, val2);
7727            M.x86.R_CX -= 1;
7728            M.x86.R_DI += inc;
7729            if (ACCESS_FLAG(F_ZF))
7730                break;          /* zero flag set means equal */
7731        }
7732        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7733    } else {
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_DI += inc;
7737    }
7738    DECODE_CLEAR_SEGOVR();
7739    END_OF_INSTR();
7740}
7741
7742/****************************************************************************
7743REMARKS:
7744Handles opcode 0xaf
7745****************************************************************************/
7746static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7747{
7748    int inc;
7749    u32 val;
7750
7751    START_OF_INSTR();
7752    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7753        DECODE_PRINTF("SCAS\tDWORD\n");
7754        if (ACCESS_FLAG(F_DF))   /* down */
7755            inc = -4;
7756        else
7757            inc = 4;
7758    } else {
7759        DECODE_PRINTF("SCAS\tWORD\n");
7760        if (ACCESS_FLAG(F_DF))   /* down */
7761            inc = -2;
7762        else
7763            inc = 2;
7764    }
7765    TRACE_AND_STEP();
7766    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7767        /* REPE  */
7768        /* move them until CX is ZERO. */
7769        while (M.x86.R_CX != 0) {
7770            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7771                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7772                cmp_long(M.x86.R_EAX, val);
7773            } else {
7774                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7775                cmp_word(M.x86.R_AX, (u16)val);
7776            }
7777            M.x86.R_CX -= 1;
7778            M.x86.R_DI += inc;
7779            if (ACCESS_FLAG(F_ZF) == 0)
7780                break;
7781        }
7782        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7783    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7784        /* REPNE  */
7785        /* move them until CX is ZERO. */
7786        while (M.x86.R_CX != 0) {
7787            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7788                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7789                cmp_long(M.x86.R_EAX, val);
7790            } else {
7791                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7792                cmp_word(M.x86.R_AX, (u16)val);
7793            }
7794            M.x86.R_CX -= 1;
7795            M.x86.R_DI += inc;
7796            if (ACCESS_FLAG(F_ZF))
7797                break;          /* zero flag set means equal */
7798        }
7799        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7800    } else {
7801        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7802            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7803            cmp_long(M.x86.R_EAX, val);
7804        } else {
7805            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7806            cmp_word(M.x86.R_AX, (u16)val);
7807        }
7808        M.x86.R_DI += inc;
7809    }
7810    DECODE_CLEAR_SEGOVR();
7811    END_OF_INSTR();
7812}
7813
7814/****************************************************************************
7815REMARKS:
7816Handles opcode 0xb0
7817****************************************************************************/
7818static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7819{
7820    u8 imm;
7821
7822    START_OF_INSTR();
7823    DECODE_PRINTF("MOV\tAL,");
7824    imm = fetch_byte_imm();
7825    DECODE_PRINTF2("%x\n", imm);
7826    TRACE_AND_STEP();
7827    M.x86.R_AL = imm;
7828    DECODE_CLEAR_SEGOVR();
7829    END_OF_INSTR();
7830}
7831
7832/****************************************************************************
7833REMARKS:
7834Handles opcode 0xb1
7835****************************************************************************/
7836static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7837{
7838    u8 imm;
7839
7840    START_OF_INSTR();
7841    DECODE_PRINTF("MOV\tCL,");
7842    imm = fetch_byte_imm();
7843    DECODE_PRINTF2("%x\n", imm);
7844    TRACE_AND_STEP();
7845    M.x86.R_CL = imm;
7846    DECODE_CLEAR_SEGOVR();
7847    END_OF_INSTR();
7848}
7849
7850/****************************************************************************
7851REMARKS:
7852Handles opcode 0xb2
7853****************************************************************************/
7854static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7855{
7856    u8 imm;
7857
7858    START_OF_INSTR();
7859    DECODE_PRINTF("MOV\tDL,");
7860    imm = fetch_byte_imm();
7861    DECODE_PRINTF2("%x\n", imm);
7862    TRACE_AND_STEP();
7863    M.x86.R_DL = imm;
7864    DECODE_CLEAR_SEGOVR();
7865    END_OF_INSTR();
7866}
7867
7868/****************************************************************************
7869REMARKS:
7870Handles opcode 0xb3
7871****************************************************************************/
7872static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7873{
7874    u8 imm;
7875
7876    START_OF_INSTR();
7877    DECODE_PRINTF("MOV\tBL,");
7878    imm = fetch_byte_imm();
7879    DECODE_PRINTF2("%x\n", imm);
7880    TRACE_AND_STEP();
7881    M.x86.R_BL = imm;
7882    DECODE_CLEAR_SEGOVR();
7883    END_OF_INSTR();
7884}
7885
7886/****************************************************************************
7887REMARKS:
7888Handles opcode 0xb4
7889****************************************************************************/
7890static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7891{
7892    u8 imm;
7893
7894    START_OF_INSTR();
7895    DECODE_PRINTF("MOV\tAH,");
7896    imm = fetch_byte_imm();
7897    DECODE_PRINTF2("%x\n", imm);
7898    TRACE_AND_STEP();
7899    M.x86.R_AH = imm;
7900    DECODE_CLEAR_SEGOVR();
7901    END_OF_INSTR();
7902}
7903
7904/****************************************************************************
7905REMARKS:
7906Handles opcode 0xb5
7907****************************************************************************/
7908static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7909{
7910    u8 imm;
7911
7912    START_OF_INSTR();
7913    DECODE_PRINTF("MOV\tCH,");
7914    imm = fetch_byte_imm();
7915    DECODE_PRINTF2("%x\n", imm);
7916    TRACE_AND_STEP();
7917    M.x86.R_CH = imm;
7918    DECODE_CLEAR_SEGOVR();
7919    END_OF_INSTR();
7920}
7921
7922/****************************************************************************
7923REMARKS:
7924Handles opcode 0xb6
7925****************************************************************************/
7926static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7927{
7928    u8 imm;
7929
7930    START_OF_INSTR();
7931    DECODE_PRINTF("MOV\tDH,");
7932    imm = fetch_byte_imm();
7933    DECODE_PRINTF2("%x\n", imm);
7934    TRACE_AND_STEP();
7935    M.x86.R_DH = imm;
7936    DECODE_CLEAR_SEGOVR();
7937    END_OF_INSTR();
7938}
7939
7940/****************************************************************************
7941REMARKS:
7942Handles opcode 0xb7
7943****************************************************************************/
7944static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7945{
7946    u8 imm;
7947
7948    START_OF_INSTR();
7949    DECODE_PRINTF("MOV\tBH,");
7950    imm = fetch_byte_imm();
7951    DECODE_PRINTF2("%x\n", imm);
7952    TRACE_AND_STEP();
7953    M.x86.R_BH = imm;
7954    DECODE_CLEAR_SEGOVR();
7955    END_OF_INSTR();
7956}
7957
7958/****************************************************************************
7959REMARKS:
7960Handles opcode 0xb8
7961****************************************************************************/
7962static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7963{
7964    u32 srcval;
7965
7966    START_OF_INSTR();
7967    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7968        DECODE_PRINTF("MOV\tEAX,");
7969        srcval = fetch_long_imm();
7970    } else {
7971        DECODE_PRINTF("MOV\tAX,");
7972        srcval = fetch_word_imm();
7973    }
7974    DECODE_PRINTF2("%x\n", srcval);
7975    TRACE_AND_STEP();
7976    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7977        M.x86.R_EAX = srcval;
7978    } else {
7979        M.x86.R_AX = (u16)srcval;
7980    }
7981    DECODE_CLEAR_SEGOVR();
7982    END_OF_INSTR();
7983}
7984
7985/****************************************************************************
7986REMARKS:
7987Handles opcode 0xb9
7988****************************************************************************/
7989static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7990{
7991    u32 srcval;
7992
7993    START_OF_INSTR();
7994    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7995        DECODE_PRINTF("MOV\tECX,");
7996        srcval = fetch_long_imm();
7997    } else {
7998        DECODE_PRINTF("MOV\tCX,");
7999        srcval = fetch_word_imm();
8000    }
8001    DECODE_PRINTF2("%x\n", srcval);
8002    TRACE_AND_STEP();
8003    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8004        M.x86.R_ECX = srcval;
8005    } else {
8006        M.x86.R_CX = (u16)srcval;
8007    }
8008    DECODE_CLEAR_SEGOVR();
8009    END_OF_INSTR();
8010}
8011
8012/****************************************************************************
8013REMARKS:
8014Handles opcode 0xba
8015****************************************************************************/
8016static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8017{
8018    u32 srcval;
8019
8020    START_OF_INSTR();
8021    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8022        DECODE_PRINTF("MOV\tEDX,");
8023        srcval = fetch_long_imm();
8024    } else {
8025        DECODE_PRINTF("MOV\tDX,");
8026        srcval = fetch_word_imm();
8027    }
8028    DECODE_PRINTF2("%x\n", srcval);
8029    TRACE_AND_STEP();
8030    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8031        M.x86.R_EDX = srcval;
8032    } else {
8033        M.x86.R_DX = (u16)srcval;
8034    }
8035    DECODE_CLEAR_SEGOVR();
8036    END_OF_INSTR();
8037}
8038
8039/****************************************************************************
8040REMARKS:
8041Handles opcode 0xbb
8042****************************************************************************/
8043static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8044{
8045    u32 srcval;
8046
8047    START_OF_INSTR();
8048    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8049        DECODE_PRINTF("MOV\tEBX,");
8050        srcval = fetch_long_imm();
8051    } else {
8052        DECODE_PRINTF("MOV\tBX,");
8053        srcval = fetch_word_imm();
8054    }
8055    DECODE_PRINTF2("%x\n", srcval);
8056    TRACE_AND_STEP();
8057    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8058        M.x86.R_EBX = srcval;
8059    } else {
8060        M.x86.R_BX = (u16)srcval;
8061    }
8062    DECODE_CLEAR_SEGOVR();
8063    END_OF_INSTR();
8064}
8065
8066/****************************************************************************
8067REMARKS:
8068Handles opcode 0xbc
8069****************************************************************************/
8070static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8071{
8072    u32 srcval;
8073
8074    START_OF_INSTR();
8075    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8076        DECODE_PRINTF("MOV\tESP,");
8077        srcval = fetch_long_imm();
8078    } else {
8079        DECODE_PRINTF("MOV\tSP,");
8080        srcval = fetch_word_imm();
8081    }
8082    DECODE_PRINTF2("%x\n", srcval);
8083    TRACE_AND_STEP();
8084    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8085        M.x86.R_ESP = srcval;
8086    } else {
8087        M.x86.R_SP = (u16)srcval;
8088    }
8089    DECODE_CLEAR_SEGOVR();
8090    END_OF_INSTR();
8091}
8092
8093/****************************************************************************
8094REMARKS:
8095Handles opcode 0xbd
8096****************************************************************************/
8097static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8098{
8099    u32 srcval;
8100
8101    START_OF_INSTR();
8102    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8103        DECODE_PRINTF("MOV\tEBP,");
8104        srcval = fetch_long_imm();
8105    } else {
8106        DECODE_PRINTF("MOV\tBP,");
8107        srcval = fetch_word_imm();
8108    }
8109    DECODE_PRINTF2("%x\n", srcval);
8110    TRACE_AND_STEP();
8111    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8112        M.x86.R_EBP = srcval;
8113    } else {
8114        M.x86.R_BP = (u16)srcval;
8115    }
8116    DECODE_CLEAR_SEGOVR();
8117    END_OF_INSTR();
8118}
8119
8120/****************************************************************************
8121REMARKS:
8122Handles opcode 0xbe
8123****************************************************************************/
8124static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8125{
8126    u32 srcval;
8127
8128    START_OF_INSTR();
8129    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8130        DECODE_PRINTF("MOV\tESI,");
8131        srcval = fetch_long_imm();
8132    } else {
8133        DECODE_PRINTF("MOV\tSI,");
8134        srcval = fetch_word_imm();
8135    }
8136    DECODE_PRINTF2("%x\n", srcval);
8137    TRACE_AND_STEP();
8138    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8139        M.x86.R_ESI = srcval;
8140    } else {
8141        M.x86.R_SI = (u16)srcval;
8142    }
8143    DECODE_CLEAR_SEGOVR();
8144    END_OF_INSTR();
8145}
8146
8147/****************************************************************************
8148REMARKS:
8149Handles opcode 0xbf
8150****************************************************************************/
8151static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8152{
8153    u32 srcval;
8154
8155    START_OF_INSTR();
8156    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8157        DECODE_PRINTF("MOV\tEDI,");
8158        srcval = fetch_long_imm();
8159    } else {
8160        DECODE_PRINTF("MOV\tDI,");
8161        srcval = fetch_word_imm();
8162    }
8163    DECODE_PRINTF2("%x\n", srcval);
8164    TRACE_AND_STEP();
8165    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8166        M.x86.R_EDI = srcval;
8167    } else {
8168        M.x86.R_DI = (u16)srcval;
8169    }
8170    DECODE_CLEAR_SEGOVR();
8171    END_OF_INSTR();
8172}
8173
8174/* used by opcodes c0, d0, and d2. */
8175static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8176{
8177    rol_byte,
8178    ror_byte,
8179    rcl_byte,
8180    rcr_byte,
8181    shl_byte,
8182    shr_byte,
8183    shl_byte,           /* sal_byte === shl_byte  by definition */
8184    sar_byte,
8185};
8186
8187/****************************************************************************
8188REMARKS:
8189Handles opcode 0xc0
8190****************************************************************************/
8191static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8192{
8193    int mod, rl, rh;
8194    u8 *destreg;
8195    uint destoffset;
8196    u8 destval;
8197    u8 amt;
8198
8199    /*
8200     * Yet another weirdo special case instruction format.  Part of
8201     * the opcode held below in "RH".  Doubly nested case would
8202     * result, except that the decoded instruction
8203     */
8204    START_OF_INSTR();
8205    FETCH_DECODE_MODRM(mod, rh, rl);
8206#ifdef DEBUG
8207    if (DEBUG_DECODE()) {
8208        /* XXX DECODE_PRINTF may be changed to something more
8209           general, so that it is important to leave the strings
8210           in the same format, even though the result is that the
8211           above test is done twice. */
8212
8213        switch (rh) {
8214        case 0:
8215            DECODE_PRINTF("ROL\t");
8216            break;
8217        case 1:
8218            DECODE_PRINTF("ROR\t");
8219            break;
8220        case 2:
8221            DECODE_PRINTF("RCL\t");
8222            break;
8223        case 3:
8224            DECODE_PRINTF("RCR\t");
8225            break;
8226        case 4:
8227            DECODE_PRINTF("SHL\t");
8228            break;
8229        case 5:
8230            DECODE_PRINTF("SHR\t");
8231            break;
8232        case 6:
8233            DECODE_PRINTF("SAL\t");
8234            break;
8235        case 7:
8236            DECODE_PRINTF("SAR\t");
8237            break;
8238        }
8239    }
8240#endif
8241    /* know operation, decode the mod byte to find the addressing
8242       mode. */
8243    switch (mod) {
8244    case 0:
8245        DECODE_PRINTF("BYTE PTR ");
8246        destoffset = decode_rm00_address(rl);
8247        amt = fetch_byte_imm();
8248        DECODE_PRINTF2(",%x\n", amt);
8249        destval = fetch_data_byte(destoffset);
8250        TRACE_AND_STEP();
8251        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8252        store_data_byte(destoffset, destval);
8253        break;
8254    case 1:
8255        DECODE_PRINTF("BYTE PTR ");
8256        destoffset = decode_rm01_address(rl);
8257        amt = fetch_byte_imm();
8258        DECODE_PRINTF2(",%x\n", amt);
8259        destval = fetch_data_byte(destoffset);
8260        TRACE_AND_STEP();
8261        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8262        store_data_byte(destoffset, destval);
8263        break;
8264    case 2:
8265        DECODE_PRINTF("BYTE PTR ");
8266        destoffset = decode_rm10_address(rl);
8267        amt = fetch_byte_imm();
8268        DECODE_PRINTF2(",%x\n", amt);
8269        destval = fetch_data_byte(destoffset);
8270        TRACE_AND_STEP();
8271        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8272        store_data_byte(destoffset, destval);
8273        break;
8274    case 3:                     /* register to register */
8275        destreg = DECODE_RM_BYTE_REGISTER(rl);
8276        amt = fetch_byte_imm();
8277        DECODE_PRINTF2(",%x\n", amt);
8278        TRACE_AND_STEP();
8279        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8280        *destreg = destval;
8281        break;
8282    }
8283    DECODE_CLEAR_SEGOVR();
8284    END_OF_INSTR();
8285}
8286
8287/* used by opcodes c1, d1, and d3. */
8288static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8289{
8290    rol_word,
8291    ror_word,
8292    rcl_word,
8293    rcr_word,
8294    shl_word,
8295    shr_word,
8296    shl_word,           /* sal_byte === shl_byte  by definition */
8297    sar_word,
8298};
8299
8300/* used by opcodes c1, d1, and d3. */
8301static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8302{
8303    rol_long,
8304    ror_long,
8305    rcl_long,
8306    rcr_long,
8307    shl_long,
8308    shr_long,
8309    shl_long,           /* sal_byte === shl_byte  by definition */
8310    sar_long,
8311};
8312
8313/****************************************************************************
8314REMARKS:
8315Handles opcode 0xc1
8316****************************************************************************/
8317static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8318{
8319    int mod, rl, rh;
8320    uint destoffset;
8321    u8 amt;
8322
8323    /*
8324     * Yet another weirdo special case instruction format.  Part of
8325     * the opcode held below in "RH".  Doubly nested case would
8326     * result, except that the decoded instruction
8327     */
8328    START_OF_INSTR();
8329    FETCH_DECODE_MODRM(mod, rh, rl);
8330#ifdef DEBUG
8331    if (DEBUG_DECODE()) {
8332        /* XXX DECODE_PRINTF may be changed to something more
8333           general, so that it is important to leave the strings
8334           in the same format, even though the result is that the
8335           above test is done twice. */
8336
8337        switch (rh) {
8338        case 0:
8339            DECODE_PRINTF("ROL\t");
8340            break;
8341        case 1:
8342            DECODE_PRINTF("ROR\t");
8343            break;
8344        case 2:
8345            DECODE_PRINTF("RCL\t");
8346            break;
8347        case 3:
8348            DECODE_PRINTF("RCR\t");
8349            break;
8350        case 4:
8351            DECODE_PRINTF("SHL\t");
8352            break;
8353        case 5:
8354            DECODE_PRINTF("SHR\t");
8355            break;
8356        case 6:
8357            DECODE_PRINTF("SAL\t");
8358            break;
8359        case 7:
8360            DECODE_PRINTF("SAR\t");
8361            break;
8362        }
8363    }
8364#endif
8365    /* know operation, decode the mod byte to find the addressing
8366       mode. */
8367    switch (mod) {
8368    case 0:
8369        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8370            u32 destval;
8371
8372            DECODE_PRINTF("DWORD PTR ");
8373            destoffset = decode_rm00_address(rl);
8374            amt = fetch_byte_imm();
8375            DECODE_PRINTF2(",%x\n", amt);
8376            destval = fetch_data_long(destoffset);
8377            TRACE_AND_STEP();
8378            destval = (*opcD1_long_operation[rh]) (destval, amt);
8379            store_data_long(destoffset, destval);
8380        } else {
8381            u16 destval;
8382
8383            DECODE_PRINTF("WORD PTR ");
8384            destoffset = decode_rm00_address(rl);
8385            amt = fetch_byte_imm();
8386            DECODE_PRINTF2(",%x\n", amt);
8387            destval = fetch_data_word(destoffset);
8388            TRACE_AND_STEP();
8389            destval = (*opcD1_word_operation[rh]) (destval, amt);
8390            store_data_word(destoffset, destval);
8391        }
8392        break;
8393    case 1:
8394        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8395            u32 destval;
8396
8397            DECODE_PRINTF("DWORD PTR ");
8398            destoffset = decode_rm01_address(rl);
8399            amt = fetch_byte_imm();
8400            DECODE_PRINTF2(",%x\n", amt);
8401            destval = fetch_data_long(destoffset);
8402            TRACE_AND_STEP();
8403            destval = (*opcD1_long_operation[rh]) (destval, amt);
8404            store_data_long(destoffset, destval);
8405        } else {
8406            u16 destval;
8407
8408            DECODE_PRINTF("WORD PTR ");
8409            destoffset = decode_rm01_address(rl);
8410            amt = fetch_byte_imm();
8411            DECODE_PRINTF2(",%x\n", amt);
8412            destval = fetch_data_word(destoffset);
8413            TRACE_AND_STEP();
8414            destval = (*opcD1_word_operation[rh]) (destval, amt);
8415            store_data_word(destoffset, destval);
8416        }
8417        break;
8418    case 2:
8419        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8420            u32 destval;
8421
8422            DECODE_PRINTF("DWORD PTR ");
8423            destoffset = decode_rm10_address(rl);
8424            amt = fetch_byte_imm();
8425            DECODE_PRINTF2(",%x\n", amt);
8426            destval = fetch_data_long(destoffset);
8427            TRACE_AND_STEP();
8428            destval = (*opcD1_long_operation[rh]) (destval, amt);
8429            store_data_long(destoffset, destval);
8430        } else {
8431            u16 destval;
8432
8433            DECODE_PRINTF("WORD PTR ");
8434            destoffset = decode_rm10_address(rl);
8435            amt = fetch_byte_imm();
8436            DECODE_PRINTF2(",%x\n", amt);
8437            destval = fetch_data_word(destoffset);
8438            TRACE_AND_STEP();
8439            destval = (*opcD1_word_operation[rh]) (destval, amt);
8440            store_data_word(destoffset, destval);
8441        }
8442        break;
8443    case 3:                     /* register to register */
8444        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8445            u32 *destreg;
8446
8447            destreg = DECODE_RM_LONG_REGISTER(rl);
8448            amt = fetch_byte_imm();
8449            DECODE_PRINTF2(",%x\n", amt);
8450            TRACE_AND_STEP();
8451            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8452        } else {
8453            u16 *destreg;
8454
8455            destreg = DECODE_RM_WORD_REGISTER(rl);
8456            amt = fetch_byte_imm();
8457            DECODE_PRINTF2(",%x\n", amt);
8458            TRACE_AND_STEP();
8459            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8460        }
8461        break;
8462    }
8463    DECODE_CLEAR_SEGOVR();
8464    END_OF_INSTR();
8465}
8466
8467/****************************************************************************
8468REMARKS:
8469Handles opcode 0xc2
8470****************************************************************************/
8471static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8472{
8473    u16 imm;
8474
8475    START_OF_INSTR();
8476    DECODE_PRINTF("RET\t");
8477    imm = fetch_word_imm();
8478    DECODE_PRINTF2("%x\n", imm);
8479	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8480	TRACE_AND_STEP();
8481    M.x86.R_IP = pop_word();
8482    M.x86.R_SP += imm;
8483    DECODE_CLEAR_SEGOVR();
8484    END_OF_INSTR();
8485}
8486
8487/****************************************************************************
8488REMARKS:
8489Handles opcode 0xc3
8490****************************************************************************/
8491static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8492{
8493    START_OF_INSTR();
8494    DECODE_PRINTF("RET\n");
8495	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8496	TRACE_AND_STEP();
8497    M.x86.R_IP = pop_word();
8498    DECODE_CLEAR_SEGOVR();
8499    END_OF_INSTR();
8500}
8501
8502/****************************************************************************
8503REMARKS:
8504Handles opcode 0xc4
8505****************************************************************************/
8506static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8507{
8508    int mod, rh, rl;
8509    u16 *dstreg;
8510    uint srcoffset;
8511
8512    START_OF_INSTR();
8513    DECODE_PRINTF("LES\t");
8514    FETCH_DECODE_MODRM(mod, rh, rl);
8515    switch (mod) {
8516    case 0:
8517        dstreg = DECODE_RM_WORD_REGISTER(rh);
8518        DECODE_PRINTF(",");
8519        srcoffset = decode_rm00_address(rl);
8520        DECODE_PRINTF("\n");
8521        TRACE_AND_STEP();
8522        *dstreg = fetch_data_word(srcoffset);
8523        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8524        break;
8525    case 1:
8526        dstreg = DECODE_RM_WORD_REGISTER(rh);
8527        DECODE_PRINTF(",");
8528        srcoffset = decode_rm01_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 2:
8535        dstreg = DECODE_RM_WORD_REGISTER(rh);
8536        DECODE_PRINTF(",");
8537        srcoffset = decode_rm10_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 3:                     /* register to register */
8544        /* UNDEFINED! */
8545        TRACE_AND_STEP();
8546    }
8547    DECODE_CLEAR_SEGOVR();
8548    END_OF_INSTR();
8549}
8550
8551/****************************************************************************
8552REMARKS:
8553Handles opcode 0xc5
8554****************************************************************************/
8555static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8556{
8557    int mod, rh, rl;
8558    u16 *dstreg;
8559    uint srcoffset;
8560
8561    START_OF_INSTR();
8562    DECODE_PRINTF("LDS\t");
8563    FETCH_DECODE_MODRM(mod, rh, rl);
8564    switch (mod) {
8565    case 0:
8566        dstreg = DECODE_RM_WORD_REGISTER(rh);
8567        DECODE_PRINTF(",");
8568        srcoffset = decode_rm00_address(rl);
8569        DECODE_PRINTF("\n");
8570        TRACE_AND_STEP();
8571        *dstreg = fetch_data_word(srcoffset);
8572        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8573        break;
8574    case 1:
8575        dstreg = DECODE_RM_WORD_REGISTER(rh);
8576        DECODE_PRINTF(",");
8577        srcoffset = decode_rm01_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 2:
8584        dstreg = DECODE_RM_WORD_REGISTER(rh);
8585        DECODE_PRINTF(",");
8586        srcoffset = decode_rm10_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 3:                     /* register to register */
8593        /* UNDEFINED! */
8594        TRACE_AND_STEP();
8595    }
8596    DECODE_CLEAR_SEGOVR();
8597    END_OF_INSTR();
8598}
8599
8600/****************************************************************************
8601REMARKS:
8602Handles opcode 0xc6
8603****************************************************************************/
8604static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8605{
8606    int mod, rl, rh;
8607    u8 *destreg;
8608    uint destoffset;
8609    u8 imm;
8610
8611    START_OF_INSTR();
8612    DECODE_PRINTF("MOV\t");
8613    FETCH_DECODE_MODRM(mod, rh, rl);
8614    if (rh != 0) {
8615        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8616        HALT_SYS();
8617    }
8618    switch (mod) {
8619    case 0:
8620        DECODE_PRINTF("BYTE PTR ");
8621        destoffset = decode_rm00_address(rl);
8622        imm = fetch_byte_imm();
8623        DECODE_PRINTF2(",%2x\n", imm);
8624        TRACE_AND_STEP();
8625        store_data_byte(destoffset, imm);
8626        break;
8627    case 1:
8628        DECODE_PRINTF("BYTE PTR ");
8629        destoffset = decode_rm01_address(rl);
8630        imm = fetch_byte_imm();
8631        DECODE_PRINTF2(",%2x\n", imm);
8632        TRACE_AND_STEP();
8633        store_data_byte(destoffset, imm);
8634        break;
8635    case 2:
8636        DECODE_PRINTF("BYTE PTR ");
8637        destoffset = decode_rm10_address(rl);
8638        imm = fetch_byte_imm();
8639        DECODE_PRINTF2(",%2x\n", imm);
8640        TRACE_AND_STEP();
8641        store_data_byte(destoffset, imm);
8642        break;
8643    case 3:                     /* register to register */
8644        destreg = DECODE_RM_BYTE_REGISTER(rl);
8645        imm = fetch_byte_imm();
8646        DECODE_PRINTF2(",%2x\n", imm);
8647        TRACE_AND_STEP();
8648        *destreg = imm;
8649        break;
8650    }
8651    DECODE_CLEAR_SEGOVR();
8652    END_OF_INSTR();
8653}
8654
8655/****************************************************************************
8656REMARKS:
8657Handles opcode 0xc7
8658****************************************************************************/
8659static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8660{
8661    int mod, rl, rh;
8662    uint destoffset;
8663
8664    START_OF_INSTR();
8665    DECODE_PRINTF("MOV\t");
8666    FETCH_DECODE_MODRM(mod, rh, rl);
8667    if (rh != 0) {
8668        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8669        HALT_SYS();
8670    }
8671    switch (mod) {
8672    case 0:
8673        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8674            u32 imm;
8675
8676            DECODE_PRINTF("DWORD PTR ");
8677            destoffset = decode_rm00_address(rl);
8678            imm = fetch_long_imm();
8679            DECODE_PRINTF2(",%x\n", imm);
8680            TRACE_AND_STEP();
8681            store_data_long(destoffset, imm);
8682        } else {
8683            u16 imm;
8684
8685            DECODE_PRINTF("WORD PTR ");
8686            destoffset = decode_rm00_address(rl);
8687            imm = fetch_word_imm();
8688            DECODE_PRINTF2(",%x\n", imm);
8689            TRACE_AND_STEP();
8690            store_data_word(destoffset, imm);
8691        }
8692        break;
8693    case 1:
8694        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8695            u32 imm;
8696
8697            DECODE_PRINTF("DWORD PTR ");
8698            destoffset = decode_rm01_address(rl);
8699            imm = fetch_long_imm();
8700            DECODE_PRINTF2(",%x\n", imm);
8701            TRACE_AND_STEP();
8702            store_data_long(destoffset, imm);
8703        } else {
8704            u16 imm;
8705
8706            DECODE_PRINTF("WORD PTR ");
8707            destoffset = decode_rm01_address(rl);
8708            imm = fetch_word_imm();
8709            DECODE_PRINTF2(",%x\n", imm);
8710            TRACE_AND_STEP();
8711            store_data_word(destoffset, imm);
8712        }
8713        break;
8714    case 2:
8715        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8716            u32 imm;
8717
8718            DECODE_PRINTF("DWORD PTR ");
8719            destoffset = decode_rm10_address(rl);
8720            imm = fetch_long_imm();
8721            DECODE_PRINTF2(",%x\n", imm);
8722            TRACE_AND_STEP();
8723            store_data_long(destoffset, imm);
8724        } else {
8725            u16 imm;
8726
8727            DECODE_PRINTF("WORD PTR ");
8728            destoffset = decode_rm10_address(rl);
8729            imm = fetch_word_imm();
8730            DECODE_PRINTF2(",%x\n", imm);
8731            TRACE_AND_STEP();
8732            store_data_word(destoffset, imm);
8733        }
8734        break;
8735    case 3:                     /* register to register */
8736        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8737			u32 *destreg;
8738			u32 imm;
8739
8740            destreg = DECODE_RM_LONG_REGISTER(rl);
8741            imm = fetch_long_imm();
8742            DECODE_PRINTF2(",%x\n", imm);
8743            TRACE_AND_STEP();
8744            *destreg = imm;
8745        } else {
8746			u16 *destreg;
8747			u16 imm;
8748
8749            destreg = DECODE_RM_WORD_REGISTER(rl);
8750            imm = fetch_word_imm();
8751            DECODE_PRINTF2(",%x\n", imm);
8752            TRACE_AND_STEP();
8753            *destreg = imm;
8754        }
8755        break;
8756    }
8757    DECODE_CLEAR_SEGOVR();
8758    END_OF_INSTR();
8759}
8760
8761/****************************************************************************
8762REMARKS:
8763Handles opcode 0xc8
8764****************************************************************************/
8765static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8766{
8767    u16 local,frame_pointer;
8768    u8  nesting;
8769    int i;
8770
8771    START_OF_INSTR();
8772    local = fetch_word_imm();
8773    nesting = fetch_byte_imm();
8774    DECODE_PRINTF2("ENTER %x\n", local);
8775    DECODE_PRINTF2(",%x\n", nesting);
8776    TRACE_AND_STEP();
8777    push_word(M.x86.R_BP);
8778    frame_pointer = M.x86.R_SP;
8779    if (nesting > 0) {
8780        for (i = 1; i < nesting; i++) {
8781            M.x86.R_BP -= 2;
8782            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8783            }
8784        push_word(frame_pointer);
8785        }
8786    M.x86.R_BP = frame_pointer;
8787    M.x86.R_SP = (u16)(M.x86.R_SP - local);
8788    DECODE_CLEAR_SEGOVR();
8789    END_OF_INSTR();
8790}
8791
8792/****************************************************************************
8793REMARKS:
8794Handles opcode 0xc9
8795****************************************************************************/
8796static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8797{
8798    START_OF_INSTR();
8799    DECODE_PRINTF("LEAVE\n");
8800    TRACE_AND_STEP();
8801    M.x86.R_SP = M.x86.R_BP;
8802    M.x86.R_BP = pop_word();
8803    DECODE_CLEAR_SEGOVR();
8804    END_OF_INSTR();
8805}
8806
8807/****************************************************************************
8808REMARKS:
8809Handles opcode 0xca
8810****************************************************************************/
8811static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8812{
8813    u16 imm;
8814
8815    START_OF_INSTR();
8816    DECODE_PRINTF("RETF\t");
8817    imm = fetch_word_imm();
8818    DECODE_PRINTF2("%x\n", imm);
8819	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8820	TRACE_AND_STEP();
8821    M.x86.R_IP = pop_word();
8822    M.x86.R_CS = pop_word();
8823    M.x86.R_SP += imm;
8824    DECODE_CLEAR_SEGOVR();
8825    END_OF_INSTR();
8826}
8827
8828/****************************************************************************
8829REMARKS:
8830Handles opcode 0xcb
8831****************************************************************************/
8832static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8833{
8834    START_OF_INSTR();
8835    DECODE_PRINTF("RETF\n");
8836	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8837	TRACE_AND_STEP();
8838    M.x86.R_IP = pop_word();
8839    M.x86.R_CS = pop_word();
8840    DECODE_CLEAR_SEGOVR();
8841    END_OF_INSTR();
8842}
8843
8844/****************************************************************************
8845REMARKS:
8846Handles opcode 0xcc
8847****************************************************************************/
8848static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8849{
8850    START_OF_INSTR();
8851    DECODE_PRINTF("INT 3\n");
8852    TRACE_AND_STEP();
8853    if (_X86EMU_intrTab[3]) {
8854	(*_X86EMU_intrTab[3])(3);
8855    } else {
8856        push_word((u16)M.x86.R_FLG);
8857        CLEAR_FLAG(F_IF);
8858        CLEAR_FLAG(F_TF);
8859        push_word(M.x86.R_CS);
8860        M.x86.R_CS = mem_access_word(3 * 4 + 2);
8861        push_word(M.x86.R_IP);
8862        M.x86.R_IP = mem_access_word(3 * 4);
8863    }
8864    DECODE_CLEAR_SEGOVR();
8865    END_OF_INSTR();
8866}
8867
8868/****************************************************************************
8869REMARKS:
8870Handles opcode 0xcd
8871****************************************************************************/
8872static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8873{
8874    u8 intnum;
8875
8876    START_OF_INSTR();
8877    DECODE_PRINTF("INT\t");
8878    intnum = fetch_byte_imm();
8879    DECODE_PRINTF2("%x\n", intnum);
8880    TRACE_AND_STEP();
8881    if (_X86EMU_intrTab[intnum]) {
8882	(*_X86EMU_intrTab[intnum])(intnum);
8883    } else {
8884        push_word((u16)M.x86.R_FLG);
8885        CLEAR_FLAG(F_IF);
8886        CLEAR_FLAG(F_TF);
8887        push_word(M.x86.R_CS);
8888        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8889        push_word(M.x86.R_IP);
8890        M.x86.R_IP = mem_access_word(intnum * 4);
8891    }
8892    DECODE_CLEAR_SEGOVR();
8893    END_OF_INSTR();
8894}
8895
8896/****************************************************************************
8897REMARKS:
8898Handles opcode 0xce
8899****************************************************************************/
8900static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8901{
8902    START_OF_INSTR();
8903    DECODE_PRINTF("INTO\n");
8904    TRACE_AND_STEP();
8905    if (ACCESS_FLAG(F_OF)) {
8906	if (_X86EMU_intrTab[4]) {
8907	    (*_X86EMU_intrTab[4])(4);
8908        } else {
8909            push_word((u16)M.x86.R_FLG);
8910            CLEAR_FLAG(F_IF);
8911            CLEAR_FLAG(F_TF);
8912            push_word(M.x86.R_CS);
8913            M.x86.R_CS = mem_access_word(4 * 4 + 2);
8914            push_word(M.x86.R_IP);
8915            M.x86.R_IP = mem_access_word(4 * 4);
8916        }
8917    }
8918    DECODE_CLEAR_SEGOVR();
8919    END_OF_INSTR();
8920}
8921
8922/****************************************************************************
8923REMARKS:
8924Handles opcode 0xcf
8925****************************************************************************/
8926static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8927{
8928    START_OF_INSTR();
8929    DECODE_PRINTF("IRET\n");
8930
8931    TRACE_AND_STEP();
8932
8933    M.x86.R_IP = pop_word();
8934    M.x86.R_CS = pop_word();
8935    M.x86.R_FLG = pop_word();
8936    DECODE_CLEAR_SEGOVR();
8937    END_OF_INSTR();
8938}
8939
8940/****************************************************************************
8941REMARKS:
8942Handles opcode 0xd0
8943****************************************************************************/
8944static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8945{
8946    int mod, rl, rh;
8947    u8 *destreg;
8948    uint destoffset;
8949    u8 destval;
8950
8951    /*
8952     * Yet another weirdo special case instruction format.  Part of
8953     * the opcode held below in "RH".  Doubly nested case would
8954     * result, except that the decoded instruction
8955     */
8956    START_OF_INSTR();
8957    FETCH_DECODE_MODRM(mod, rh, rl);
8958#ifdef DEBUG
8959    if (DEBUG_DECODE()) {
8960        /* XXX DECODE_PRINTF may be changed to something more
8961           general, so that it is important to leave the strings
8962           in the same format, even though the result is that the
8963           above test is done twice. */
8964        switch (rh) {
8965        case 0:
8966            DECODE_PRINTF("ROL\t");
8967            break;
8968        case 1:
8969            DECODE_PRINTF("ROR\t");
8970            break;
8971        case 2:
8972            DECODE_PRINTF("RCL\t");
8973            break;
8974        case 3:
8975            DECODE_PRINTF("RCR\t");
8976            break;
8977        case 4:
8978            DECODE_PRINTF("SHL\t");
8979            break;
8980        case 5:
8981            DECODE_PRINTF("SHR\t");
8982            break;
8983        case 6:
8984            DECODE_PRINTF("SAL\t");
8985            break;
8986        case 7:
8987            DECODE_PRINTF("SAR\t");
8988            break;
8989        }
8990    }
8991#endif
8992    /* know operation, decode the mod byte to find the addressing
8993       mode. */
8994    switch (mod) {
8995    case 0:
8996        DECODE_PRINTF("BYTE PTR ");
8997        destoffset = decode_rm00_address(rl);
8998        DECODE_PRINTF(",1\n");
8999        destval = fetch_data_byte(destoffset);
9000        TRACE_AND_STEP();
9001        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9002        store_data_byte(destoffset, destval);
9003        break;
9004    case 1:
9005        DECODE_PRINTF("BYTE PTR ");
9006        destoffset = decode_rm01_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 2:
9014        DECODE_PRINTF("BYTE PTR ");
9015        destoffset = decode_rm10_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 3:                     /* register to register */
9023        destreg = DECODE_RM_BYTE_REGISTER(rl);
9024        DECODE_PRINTF(",1\n");
9025        TRACE_AND_STEP();
9026        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9027        *destreg = destval;
9028        break;
9029    }
9030    DECODE_CLEAR_SEGOVR();
9031    END_OF_INSTR();
9032}
9033
9034/****************************************************************************
9035REMARKS:
9036Handles opcode 0xd1
9037****************************************************************************/
9038static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9039{
9040    int mod, rl, rh;
9041    uint destoffset;
9042
9043    /*
9044     * Yet another weirdo special case instruction format.  Part of
9045     * the opcode held below in "RH".  Doubly nested case would
9046     * result, except that the decoded instruction
9047     */
9048    START_OF_INSTR();
9049    FETCH_DECODE_MODRM(mod, rh, rl);
9050#ifdef DEBUG
9051    if (DEBUG_DECODE()) {
9052        /* XXX DECODE_PRINTF may be changed to something more
9053           general, so that it is important to leave the strings
9054           in the same format, even though the result is that the
9055           above test is done twice. */
9056        switch (rh) {
9057        case 0:
9058            DECODE_PRINTF("ROL\t");
9059            break;
9060        case 1:
9061            DECODE_PRINTF("ROR\t");
9062            break;
9063        case 2:
9064            DECODE_PRINTF("RCL\t");
9065            break;
9066        case 3:
9067            DECODE_PRINTF("RCR\t");
9068            break;
9069        case 4:
9070            DECODE_PRINTF("SHL\t");
9071            break;
9072        case 5:
9073            DECODE_PRINTF("SHR\t");
9074            break;
9075        case 6:
9076            DECODE_PRINTF("SAL\t");
9077            break;
9078        case 7:
9079            DECODE_PRINTF("SAR\t");
9080            break;
9081        }
9082    }
9083#endif
9084    /* know operation, decode the mod byte to find the addressing
9085       mode. */
9086    switch (mod) {
9087    case 0:
9088        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9089            u32 destval;
9090
9091            DECODE_PRINTF("DWORD PTR ");
9092            destoffset = decode_rm00_address(rl);
9093            DECODE_PRINTF(",1\n");
9094            destval = fetch_data_long(destoffset);
9095            TRACE_AND_STEP();
9096            destval = (*opcD1_long_operation[rh]) (destval, 1);
9097            store_data_long(destoffset, destval);
9098        } else {
9099            u16 destval;
9100
9101            DECODE_PRINTF("WORD PTR ");
9102            destoffset = decode_rm00_address(rl);
9103            DECODE_PRINTF(",1\n");
9104            destval = fetch_data_word(destoffset);
9105            TRACE_AND_STEP();
9106            destval = (*opcD1_word_operation[rh]) (destval, 1);
9107            store_data_word(destoffset, destval);
9108        }
9109        break;
9110    case 1:
9111        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9112            u32 destval;
9113
9114            DECODE_PRINTF("DWORD PTR ");
9115            destoffset = decode_rm01_address(rl);
9116            DECODE_PRINTF(",1\n");
9117            destval = fetch_data_long(destoffset);
9118            TRACE_AND_STEP();
9119            destval = (*opcD1_long_operation[rh]) (destval, 1);
9120            store_data_long(destoffset, destval);
9121        } else {
9122            u16 destval;
9123
9124            DECODE_PRINTF("WORD PTR ");
9125            destoffset = decode_rm01_address(rl);
9126            DECODE_PRINTF(",1\n");
9127            destval = fetch_data_word(destoffset);
9128            TRACE_AND_STEP();
9129            destval = (*opcD1_word_operation[rh]) (destval, 1);
9130            store_data_word(destoffset, destval);
9131        }
9132        break;
9133    case 2:
9134        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9135            u32 destval;
9136
9137            DECODE_PRINTF("DWORD PTR ");
9138            destoffset = decode_rm10_address(rl);
9139            DECODE_PRINTF(",1\n");
9140            destval = fetch_data_long(destoffset);
9141            TRACE_AND_STEP();
9142            destval = (*opcD1_long_operation[rh]) (destval, 1);
9143            store_data_long(destoffset, destval);
9144        } else {
9145            u16 destval;
9146
9147            DECODE_PRINTF("BYTE PTR ");
9148            destoffset = decode_rm10_address(rl);
9149            DECODE_PRINTF(",1\n");
9150            destval = fetch_data_word(destoffset);
9151            TRACE_AND_STEP();
9152            destval = (*opcD1_word_operation[rh]) (destval, 1);
9153            store_data_word(destoffset, destval);
9154        }
9155        break;
9156    case 3:                     /* register to register */
9157        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9158			u32 destval;
9159			u32 *destreg;
9160
9161            destreg = DECODE_RM_LONG_REGISTER(rl);
9162            DECODE_PRINTF(",1\n");
9163            TRACE_AND_STEP();
9164            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9165            *destreg = destval;
9166        } else {
9167			u16 destval;
9168			u16 *destreg;
9169
9170            destreg = DECODE_RM_WORD_REGISTER(rl);
9171            DECODE_PRINTF(",1\n");
9172            TRACE_AND_STEP();
9173            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9174            *destreg = destval;
9175        }
9176        break;
9177    }
9178    DECODE_CLEAR_SEGOVR();
9179    END_OF_INSTR();
9180}
9181
9182/****************************************************************************
9183REMARKS:
9184Handles opcode 0xd2
9185****************************************************************************/
9186static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9187{
9188    int mod, rl, rh;
9189    u8 *destreg;
9190    uint destoffset;
9191    u8 destval;
9192    u8 amt;
9193
9194    /*
9195     * Yet another weirdo special case instruction format.  Part of
9196     * the opcode held below in "RH".  Doubly nested case would
9197     * result, except that the decoded instruction
9198     */
9199    START_OF_INSTR();
9200    FETCH_DECODE_MODRM(mod, rh, rl);
9201#ifdef DEBUG
9202    if (DEBUG_DECODE()) {
9203        /* XXX DECODE_PRINTF may be changed to something more
9204           general, so that it is important to leave the strings
9205           in the same format, even though the result is that the
9206           above test is done twice. */
9207        switch (rh) {
9208        case 0:
9209            DECODE_PRINTF("ROL\t");
9210            break;
9211        case 1:
9212            DECODE_PRINTF("ROR\t");
9213            break;
9214        case 2:
9215            DECODE_PRINTF("RCL\t");
9216            break;
9217        case 3:
9218            DECODE_PRINTF("RCR\t");
9219            break;
9220        case 4:
9221            DECODE_PRINTF("SHL\t");
9222            break;
9223        case 5:
9224            DECODE_PRINTF("SHR\t");
9225            break;
9226        case 6:
9227            DECODE_PRINTF("SAL\t");
9228            break;
9229        case 7:
9230            DECODE_PRINTF("SAR\t");
9231            break;
9232        }
9233    }
9234#endif
9235    /* know operation, decode the mod byte to find the addressing
9236       mode. */
9237    amt = M.x86.R_CL;
9238    switch (mod) {
9239    case 0:
9240        DECODE_PRINTF("BYTE PTR ");
9241        destoffset = decode_rm00_address(rl);
9242        DECODE_PRINTF(",CL\n");
9243        destval = fetch_data_byte(destoffset);
9244        TRACE_AND_STEP();
9245        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9246        store_data_byte(destoffset, destval);
9247        break;
9248    case 1:
9249        DECODE_PRINTF("BYTE PTR ");
9250        destoffset = decode_rm01_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 2:
9258        DECODE_PRINTF("BYTE PTR ");
9259        destoffset = decode_rm10_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 3:                     /* register to register */
9267        destreg = DECODE_RM_BYTE_REGISTER(rl);
9268        DECODE_PRINTF(",CL\n");
9269        TRACE_AND_STEP();
9270        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9271        *destreg = destval;
9272        break;
9273    }
9274    DECODE_CLEAR_SEGOVR();
9275    END_OF_INSTR();
9276}
9277
9278/****************************************************************************
9279REMARKS:
9280Handles opcode 0xd3
9281****************************************************************************/
9282static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9283{
9284    int mod, rl, rh;
9285    uint destoffset;
9286    u8 amt;
9287
9288    /*
9289     * Yet another weirdo special case instruction format.  Part of
9290     * the opcode held below in "RH".  Doubly nested case would
9291     * result, except that the decoded instruction
9292     */
9293    START_OF_INSTR();
9294    FETCH_DECODE_MODRM(mod, rh, rl);
9295#ifdef DEBUG
9296    if (DEBUG_DECODE()) {
9297        /* XXX DECODE_PRINTF may be changed to something more
9298           general, so that it is important to leave the strings
9299           in the same format, even though the result is that the
9300           above test is done twice. */
9301        switch (rh) {
9302        case 0:
9303            DECODE_PRINTF("ROL\t");
9304            break;
9305        case 1:
9306            DECODE_PRINTF("ROR\t");
9307            break;
9308        case 2:
9309            DECODE_PRINTF("RCL\t");
9310            break;
9311        case 3:
9312            DECODE_PRINTF("RCR\t");
9313            break;
9314        case 4:
9315            DECODE_PRINTF("SHL\t");
9316            break;
9317        case 5:
9318            DECODE_PRINTF("SHR\t");
9319            break;
9320        case 6:
9321            DECODE_PRINTF("SAL\t");
9322            break;
9323        case 7:
9324            DECODE_PRINTF("SAR\t");
9325            break;
9326        }
9327    }
9328#endif
9329    /* know operation, decode the mod byte to find the addressing
9330       mode. */
9331    amt = M.x86.R_CL;
9332    switch (mod) {
9333    case 0:
9334        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9335            u32 destval;
9336
9337            DECODE_PRINTF("DWORD PTR ");
9338            destoffset = decode_rm00_address(rl);
9339            DECODE_PRINTF(",CL\n");
9340            destval = fetch_data_long(destoffset);
9341            TRACE_AND_STEP();
9342            destval = (*opcD1_long_operation[rh]) (destval, amt);
9343            store_data_long(destoffset, destval);
9344        } else {
9345            u16 destval;
9346
9347            DECODE_PRINTF("WORD PTR ");
9348            destoffset = decode_rm00_address(rl);
9349            DECODE_PRINTF(",CL\n");
9350            destval = fetch_data_word(destoffset);
9351            TRACE_AND_STEP();
9352            destval = (*opcD1_word_operation[rh]) (destval, amt);
9353            store_data_word(destoffset, destval);
9354        }
9355        break;
9356    case 1:
9357        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9358            u32 destval;
9359
9360            DECODE_PRINTF("DWORD PTR ");
9361            destoffset = decode_rm01_address(rl);
9362            DECODE_PRINTF(",CL\n");
9363            destval = fetch_data_long(destoffset);
9364            TRACE_AND_STEP();
9365            destval = (*opcD1_long_operation[rh]) (destval, amt);
9366            store_data_long(destoffset, destval);
9367        } else {
9368            u16 destval;
9369
9370            DECODE_PRINTF("WORD PTR ");
9371            destoffset = decode_rm01_address(rl);
9372            DECODE_PRINTF(",CL\n");
9373            destval = fetch_data_word(destoffset);
9374            TRACE_AND_STEP();
9375            destval = (*opcD1_word_operation[rh]) (destval, amt);
9376            store_data_word(destoffset, destval);
9377        }
9378        break;
9379    case 2:
9380        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9381            u32 destval;
9382
9383            DECODE_PRINTF("DWORD PTR ");
9384            destoffset = decode_rm10_address(rl);
9385            DECODE_PRINTF(",CL\n");
9386            destval = fetch_data_long(destoffset);
9387            TRACE_AND_STEP();
9388            destval = (*opcD1_long_operation[rh]) (destval, amt);
9389            store_data_long(destoffset, destval);
9390        } else {
9391            u16 destval;
9392
9393            DECODE_PRINTF("WORD PTR ");
9394            destoffset = decode_rm10_address(rl);
9395            DECODE_PRINTF(",CL\n");
9396            destval = fetch_data_word(destoffset);
9397            TRACE_AND_STEP();
9398            destval = (*opcD1_word_operation[rh]) (destval, amt);
9399            store_data_word(destoffset, destval);
9400        }
9401        break;
9402    case 3:                     /* register to register */
9403        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9404            u32 *destreg;
9405
9406            destreg = DECODE_RM_LONG_REGISTER(rl);
9407            DECODE_PRINTF(",CL\n");
9408            TRACE_AND_STEP();
9409            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9410        } else {
9411            u16 *destreg;
9412
9413            destreg = DECODE_RM_WORD_REGISTER(rl);
9414            DECODE_PRINTF(",CL\n");
9415            TRACE_AND_STEP();
9416            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9417        }
9418        break;
9419    }
9420    DECODE_CLEAR_SEGOVR();
9421    END_OF_INSTR();
9422}
9423
9424/****************************************************************************
9425REMARKS:
9426Handles opcode 0xd4
9427****************************************************************************/
9428static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9429{
9430    u8 a;
9431
9432    START_OF_INSTR();
9433    DECODE_PRINTF("AAM\n");
9434    a = fetch_byte_imm();      /* this is a stupid encoding. */
9435    if (a != 10) {
9436	/* fix: add base decoding
9437	   aam_word(u8 val, int base a) */
9438        DECODE_PRINTF("ERROR DECODING AAM\n");
9439        TRACE_REGS();
9440        HALT_SYS();
9441    }
9442    TRACE_AND_STEP();
9443    /* note the type change here --- returning AL and AH in AX. */
9444    M.x86.R_AX = aam_word(M.x86.R_AL);
9445    DECODE_CLEAR_SEGOVR();
9446    END_OF_INSTR();
9447}
9448
9449/****************************************************************************
9450REMARKS:
9451Handles opcode 0xd5
9452****************************************************************************/
9453static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9454{
9455    u8 a;
9456
9457    START_OF_INSTR();
9458    DECODE_PRINTF("AAD\n");
9459    a = fetch_byte_imm();
9460    if (a != 10) {
9461	/* fix: add base decoding
9462	   aad_word(u16 val, int base a) */
9463        DECODE_PRINTF("ERROR DECODING AAM\n");
9464        TRACE_REGS();
9465        HALT_SYS();
9466    }
9467    TRACE_AND_STEP();
9468    M.x86.R_AX = aad_word(M.x86.R_AX);
9469    DECODE_CLEAR_SEGOVR();
9470    END_OF_INSTR();
9471}
9472
9473/* opcode 0xd6 ILLEGAL OPCODE */
9474
9475/****************************************************************************
9476REMARKS:
9477Handles opcode 0xd7
9478****************************************************************************/
9479static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9480{
9481    u16 addr;
9482
9483    START_OF_INSTR();
9484    DECODE_PRINTF("XLAT\n");
9485    TRACE_AND_STEP();
9486	addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9487    M.x86.R_AL = fetch_data_byte(addr);
9488    DECODE_CLEAR_SEGOVR();
9489    END_OF_INSTR();
9490}
9491
9492/* instuctions  D8 .. DF are in i87_ops.c */
9493
9494/****************************************************************************
9495REMARKS:
9496Handles opcode 0xe0
9497****************************************************************************/
9498static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9499{
9500    s16 ip;
9501
9502    START_OF_INSTR();
9503    DECODE_PRINTF("LOOPNE\t");
9504    ip = (s8) fetch_byte_imm();
9505    ip += (s16) M.x86.R_IP;
9506    DECODE_PRINTF2("%04x\n", ip);
9507    TRACE_AND_STEP();
9508    M.x86.R_CX -= 1;
9509    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9510        M.x86.R_IP = ip;
9511    DECODE_CLEAR_SEGOVR();
9512    END_OF_INSTR();
9513}
9514
9515/****************************************************************************
9516REMARKS:
9517Handles opcode 0xe1
9518****************************************************************************/
9519static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9520{
9521    s16 ip;
9522
9523    START_OF_INSTR();
9524    DECODE_PRINTF("LOOPE\t");
9525    ip = (s8) fetch_byte_imm();
9526    ip += (s16) M.x86.R_IP;
9527    DECODE_PRINTF2("%04x\n", ip);
9528    TRACE_AND_STEP();
9529    M.x86.R_CX -= 1;
9530    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9531        M.x86.R_IP = ip;
9532    DECODE_CLEAR_SEGOVR();
9533    END_OF_INSTR();
9534}
9535
9536/****************************************************************************
9537REMARKS:
9538Handles opcode 0xe2
9539****************************************************************************/
9540static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9541{
9542    s16 ip;
9543
9544    START_OF_INSTR();
9545    DECODE_PRINTF("LOOP\t");
9546    ip = (s8) fetch_byte_imm();
9547    ip += (s16) M.x86.R_IP;
9548    DECODE_PRINTF2("%04x\n", ip);
9549    TRACE_AND_STEP();
9550    M.x86.R_CX -= 1;
9551    if (M.x86.R_CX != 0)
9552        M.x86.R_IP = ip;
9553    DECODE_CLEAR_SEGOVR();
9554    END_OF_INSTR();
9555}
9556
9557/****************************************************************************
9558REMARKS:
9559Handles opcode 0xe3
9560****************************************************************************/
9561static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9562{
9563    u16 target;
9564    s8  offset;
9565
9566    /* jump to byte offset if overflow flag is set */
9567    START_OF_INSTR();
9568    DECODE_PRINTF("JCXZ\t");
9569    offset = (s8)fetch_byte_imm();
9570    target = (u16)(M.x86.R_IP + offset);
9571    DECODE_PRINTF2("%x\n", target);
9572    TRACE_AND_STEP();
9573    if (M.x86.R_CX == 0)
9574        M.x86.R_IP = target;
9575    DECODE_CLEAR_SEGOVR();
9576    END_OF_INSTR();
9577}
9578
9579/****************************************************************************
9580REMARKS:
9581Handles opcode 0xe4
9582****************************************************************************/
9583static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9584{
9585    u8 port;
9586
9587    START_OF_INSTR();
9588    DECODE_PRINTF("IN\t");
9589	port = (u8) fetch_byte_imm();
9590    DECODE_PRINTF2("%x,AL\n", port);
9591    TRACE_AND_STEP();
9592    M.x86.R_AL = (*sys_inb)(port);
9593    DECODE_CLEAR_SEGOVR();
9594    END_OF_INSTR();
9595}
9596
9597/****************************************************************************
9598REMARKS:
9599Handles opcode 0xe5
9600****************************************************************************/
9601static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9602{
9603    u8 port;
9604
9605    START_OF_INSTR();
9606    DECODE_PRINTF("IN\t");
9607	port = (u8) fetch_byte_imm();
9608    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9609        DECODE_PRINTF2("EAX,%x\n", port);
9610    } else {
9611        DECODE_PRINTF2("AX,%x\n", port);
9612    }
9613    TRACE_AND_STEP();
9614    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9615        M.x86.R_EAX = (*sys_inl)(port);
9616    } else {
9617        M.x86.R_AX = (*sys_inw)(port);
9618    }
9619    DECODE_CLEAR_SEGOVR();
9620    END_OF_INSTR();
9621}
9622
9623/****************************************************************************
9624REMARKS:
9625Handles opcode 0xe6
9626****************************************************************************/
9627static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9628{
9629    u8 port;
9630
9631    START_OF_INSTR();
9632    DECODE_PRINTF("OUT\t");
9633	port = (u8) fetch_byte_imm();
9634    DECODE_PRINTF2("%x,AL\n", port);
9635    TRACE_AND_STEP();
9636    (*sys_outb)(port, M.x86.R_AL);
9637    DECODE_CLEAR_SEGOVR();
9638    END_OF_INSTR();
9639}
9640
9641/****************************************************************************
9642REMARKS:
9643Handles opcode 0xe7
9644****************************************************************************/
9645static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9646{
9647    u8 port;
9648
9649    START_OF_INSTR();
9650    DECODE_PRINTF("OUT\t");
9651	port = (u8) fetch_byte_imm();
9652    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9653        DECODE_PRINTF2("%x,EAX\n", port);
9654    } else {
9655        DECODE_PRINTF2("%x,AX\n", port);
9656    }
9657    TRACE_AND_STEP();
9658    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9659        (*sys_outl)(port, M.x86.R_EAX);
9660    } else {
9661        (*sys_outw)(port, M.x86.R_AX);
9662    }
9663    DECODE_CLEAR_SEGOVR();
9664    END_OF_INSTR();
9665}
9666
9667/****************************************************************************
9668REMARKS:
9669Handles opcode 0xe8
9670****************************************************************************/
9671static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9672{
9673    s16 ip;
9674
9675    START_OF_INSTR();
9676	DECODE_PRINTF("CALL\t");
9677	ip = (s16) fetch_word_imm();
9678	ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
9679	DECODE_PRINTF2("%04x\n", (u16)ip);
9680	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9681    TRACE_AND_STEP();
9682    push_word(M.x86.R_IP);
9683    M.x86.R_IP = ip;
9684    DECODE_CLEAR_SEGOVR();
9685    END_OF_INSTR();
9686}
9687
9688/****************************************************************************
9689REMARKS:
9690Handles opcode 0xe9
9691****************************************************************************/
9692static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9693{
9694    int ip;
9695
9696    START_OF_INSTR();
9697    DECODE_PRINTF("JMP\t");
9698    ip = (s16)fetch_word_imm();
9699    ip += (s16)M.x86.R_IP;
9700    DECODE_PRINTF2("%04x\n", (u16)ip);
9701    TRACE_AND_STEP();
9702    M.x86.R_IP = (u16)ip;
9703    DECODE_CLEAR_SEGOVR();
9704    END_OF_INSTR();
9705}
9706
9707/****************************************************************************
9708REMARKS:
9709Handles opcode 0xea
9710****************************************************************************/
9711static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9712{
9713    u16 cs, ip;
9714
9715    START_OF_INSTR();
9716    DECODE_PRINTF("JMP\tFAR ");
9717    ip = fetch_word_imm();
9718    cs = fetch_word_imm();
9719    DECODE_PRINTF2("%04x:", cs);
9720    DECODE_PRINTF2("%04x\n", ip);
9721    TRACE_AND_STEP();
9722    M.x86.R_IP = ip;
9723    M.x86.R_CS = cs;
9724    DECODE_CLEAR_SEGOVR();
9725    END_OF_INSTR();
9726}
9727
9728/****************************************************************************
9729REMARKS:
9730Handles opcode 0xeb
9731****************************************************************************/
9732static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9733{
9734    u16 target;
9735    s8 offset;
9736
9737    START_OF_INSTR();
9738    DECODE_PRINTF("JMP\t");
9739    offset = (s8)fetch_byte_imm();
9740    target = (u16)(M.x86.R_IP + offset);
9741    DECODE_PRINTF2("%x\n", target);
9742    TRACE_AND_STEP();
9743    M.x86.R_IP = target;
9744    DECODE_CLEAR_SEGOVR();
9745    END_OF_INSTR();
9746}
9747
9748/****************************************************************************
9749REMARKS:
9750Handles opcode 0xec
9751****************************************************************************/
9752static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9753{
9754    START_OF_INSTR();
9755    DECODE_PRINTF("IN\tAL,DX\n");
9756    TRACE_AND_STEP();
9757    M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9758    DECODE_CLEAR_SEGOVR();
9759    END_OF_INSTR();
9760}
9761
9762/****************************************************************************
9763REMARKS:
9764Handles opcode 0xed
9765****************************************************************************/
9766static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9767{
9768    START_OF_INSTR();
9769    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9770        DECODE_PRINTF("IN\tEAX,DX\n");
9771    } else {
9772        DECODE_PRINTF("IN\tAX,DX\n");
9773    }
9774    TRACE_AND_STEP();
9775    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9776        M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9777    } else {
9778        M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9779    }
9780    DECODE_CLEAR_SEGOVR();
9781    END_OF_INSTR();
9782}
9783
9784/****************************************************************************
9785REMARKS:
9786Handles opcode 0xee
9787****************************************************************************/
9788static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9789{
9790    START_OF_INSTR();
9791    DECODE_PRINTF("OUT\tDX,AL\n");
9792    TRACE_AND_STEP();
9793    (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9794    DECODE_CLEAR_SEGOVR();
9795    END_OF_INSTR();
9796}
9797
9798/****************************************************************************
9799REMARKS:
9800Handles opcode 0xef
9801****************************************************************************/
9802static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9803{
9804    START_OF_INSTR();
9805    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9806        DECODE_PRINTF("OUT\tDX,EAX\n");
9807    } else {
9808        DECODE_PRINTF("OUT\tDX,AX\n");
9809    }
9810    TRACE_AND_STEP();
9811    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9812        (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9813    } else {
9814        (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9815    }
9816    DECODE_CLEAR_SEGOVR();
9817    END_OF_INSTR();
9818}
9819
9820/****************************************************************************
9821REMARKS:
9822Handles opcode 0xf0
9823****************************************************************************/
9824static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9825{
9826    START_OF_INSTR();
9827    DECODE_PRINTF("LOCK:\n");
9828    TRACE_AND_STEP();
9829    DECODE_CLEAR_SEGOVR();
9830    END_OF_INSTR();
9831}
9832
9833/*opcode 0xf1 ILLEGAL OPERATION */
9834
9835/****************************************************************************
9836REMARKS:
9837Handles opcode 0xf2
9838****************************************************************************/
9839static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9840{
9841    START_OF_INSTR();
9842    DECODE_PRINTF("REPNE\n");
9843    TRACE_AND_STEP();
9844    M.x86.mode |= SYSMODE_PREFIX_REPNE;
9845    DECODE_CLEAR_SEGOVR();
9846    END_OF_INSTR();
9847}
9848
9849/****************************************************************************
9850REMARKS:
9851Handles opcode 0xf3
9852****************************************************************************/
9853static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9854{
9855    START_OF_INSTR();
9856    DECODE_PRINTF("REPE\n");
9857    TRACE_AND_STEP();
9858    M.x86.mode |= SYSMODE_PREFIX_REPE;
9859    DECODE_CLEAR_SEGOVR();
9860    END_OF_INSTR();
9861}
9862
9863/****************************************************************************
9864REMARKS:
9865Handles opcode 0xf4
9866****************************************************************************/
9867static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9868{
9869    START_OF_INSTR();
9870    DECODE_PRINTF("HALT\n");
9871    TRACE_AND_STEP();
9872    HALT_SYS();
9873    DECODE_CLEAR_SEGOVR();
9874    END_OF_INSTR();
9875}
9876
9877/****************************************************************************
9878REMARKS:
9879Handles opcode 0xf5
9880****************************************************************************/
9881static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9882{
9883    /* complement the carry flag. */
9884    START_OF_INSTR();
9885    DECODE_PRINTF("CMC\n");
9886    TRACE_AND_STEP();
9887    TOGGLE_FLAG(F_CF);
9888    DECODE_CLEAR_SEGOVR();
9889    END_OF_INSTR();
9890}
9891
9892/****************************************************************************
9893REMARKS:
9894Handles opcode 0xf6
9895****************************************************************************/
9896static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9897{
9898    int mod, rl, rh;
9899    u8 *destreg;
9900    uint destoffset;
9901    u8 destval, srcval;
9902
9903    /* long, drawn out code follows.  Double switch for a total
9904       of 32 cases.  */
9905    START_OF_INSTR();
9906    FETCH_DECODE_MODRM(mod, rh, rl);
9907    switch (mod) {
9908    case 0:                     /* mod=00 */
9909        switch (rh) {
9910        case 0:         /* test byte imm */
9911            DECODE_PRINTF("TEST\tBYTE PTR ");
9912            destoffset = decode_rm00_address(rl);
9913            DECODE_PRINTF(",");
9914            srcval = fetch_byte_imm();
9915            DECODE_PRINTF2("%02x\n", srcval);
9916            destval = fetch_data_byte(destoffset);
9917            TRACE_AND_STEP();
9918            test_byte(destval, srcval);
9919            break;
9920        case 1:
9921            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9922            HALT_SYS();
9923            break;
9924        case 2:
9925            DECODE_PRINTF("NOT\tBYTE PTR ");
9926            destoffset = decode_rm00_address(rl);
9927            DECODE_PRINTF("\n");
9928            destval = fetch_data_byte(destoffset);
9929            TRACE_AND_STEP();
9930            destval = not_byte(destval);
9931            store_data_byte(destoffset, destval);
9932            break;
9933        case 3:
9934            DECODE_PRINTF("NEG\tBYTE PTR ");
9935            destoffset = decode_rm00_address(rl);
9936            DECODE_PRINTF("\n");
9937            destval = fetch_data_byte(destoffset);
9938            TRACE_AND_STEP();
9939            destval = neg_byte(destval);
9940            store_data_byte(destoffset, destval);
9941            break;
9942        case 4:
9943            DECODE_PRINTF("MUL\tBYTE PTR ");
9944            destoffset = decode_rm00_address(rl);
9945            DECODE_PRINTF("\n");
9946            destval = fetch_data_byte(destoffset);
9947            TRACE_AND_STEP();
9948            mul_byte(destval);
9949            break;
9950        case 5:
9951            DECODE_PRINTF("IMUL\tBYTE PTR ");
9952            destoffset = decode_rm00_address(rl);
9953            DECODE_PRINTF("\n");
9954            destval = fetch_data_byte(destoffset);
9955            TRACE_AND_STEP();
9956            imul_byte(destval);
9957            break;
9958        case 6:
9959            DECODE_PRINTF("DIV\tBYTE PTR ");
9960            destoffset = decode_rm00_address(rl);
9961            DECODE_PRINTF("\n");
9962            destval = fetch_data_byte(destoffset);
9963            TRACE_AND_STEP();
9964            div_byte(destval);
9965            break;
9966        case 7:
9967            DECODE_PRINTF("IDIV\tBYTE PTR ");
9968            destoffset = decode_rm00_address(rl);
9969            DECODE_PRINTF("\n");
9970            destval = fetch_data_byte(destoffset);
9971            TRACE_AND_STEP();
9972            idiv_byte(destval);
9973            break;
9974        }
9975        break;                  /* end mod==00 */
9976    case 1:                     /* mod=01 */
9977        switch (rh) {
9978        case 0:         /* test byte imm */
9979            DECODE_PRINTF("TEST\tBYTE PTR ");
9980            destoffset = decode_rm01_address(rl);
9981            DECODE_PRINTF(",");
9982            srcval = fetch_byte_imm();
9983            DECODE_PRINTF2("%02x\n", srcval);
9984            destval = fetch_data_byte(destoffset);
9985            TRACE_AND_STEP();
9986            test_byte(destval, srcval);
9987            break;
9988        case 1:
9989            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9990            HALT_SYS();
9991            break;
9992        case 2:
9993            DECODE_PRINTF("NOT\tBYTE PTR ");
9994            destoffset = decode_rm01_address(rl);
9995            DECODE_PRINTF("\n");
9996            destval = fetch_data_byte(destoffset);
9997            TRACE_AND_STEP();
9998            destval = not_byte(destval);
9999            store_data_byte(destoffset, destval);
10000            break;
10001        case 3:
10002            DECODE_PRINTF("NEG\tBYTE PTR ");
10003            destoffset = decode_rm01_address(rl);
10004            DECODE_PRINTF("\n");
10005            destval = fetch_data_byte(destoffset);
10006            TRACE_AND_STEP();
10007            destval = neg_byte(destval);
10008            store_data_byte(destoffset, destval);
10009            break;
10010        case 4:
10011            DECODE_PRINTF("MUL\tBYTE PTR ");
10012            destoffset = decode_rm01_address(rl);
10013            DECODE_PRINTF("\n");
10014            destval = fetch_data_byte(destoffset);
10015            TRACE_AND_STEP();
10016            mul_byte(destval);
10017            break;
10018        case 5:
10019            DECODE_PRINTF("IMUL\tBYTE PTR ");
10020            destoffset = decode_rm01_address(rl);
10021            DECODE_PRINTF("\n");
10022            destval = fetch_data_byte(destoffset);
10023            TRACE_AND_STEP();
10024            imul_byte(destval);
10025            break;
10026        case 6:
10027            DECODE_PRINTF("DIV\tBYTE PTR ");
10028            destoffset = decode_rm01_address(rl);
10029            DECODE_PRINTF("\n");
10030            destval = fetch_data_byte(destoffset);
10031            TRACE_AND_STEP();
10032            div_byte(destval);
10033            break;
10034        case 7:
10035            DECODE_PRINTF("IDIV\tBYTE PTR ");
10036            destoffset = decode_rm01_address(rl);
10037            DECODE_PRINTF("\n");
10038            destval = fetch_data_byte(destoffset);
10039            TRACE_AND_STEP();
10040            idiv_byte(destval);
10041            break;
10042        }
10043        break;                  /* end mod==01 */
10044    case 2:                     /* mod=10 */
10045        switch (rh) {
10046        case 0:         /* test byte imm */
10047            DECODE_PRINTF("TEST\tBYTE PTR ");
10048            destoffset = decode_rm10_address(rl);
10049            DECODE_PRINTF(",");
10050            srcval = fetch_byte_imm();
10051            DECODE_PRINTF2("%02x\n", srcval);
10052            destval = fetch_data_byte(destoffset);
10053            TRACE_AND_STEP();
10054            test_byte(destval, srcval);
10055            break;
10056        case 1:
10057            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10058            HALT_SYS();
10059            break;
10060        case 2:
10061            DECODE_PRINTF("NOT\tBYTE PTR ");
10062            destoffset = decode_rm10_address(rl);
10063            DECODE_PRINTF("\n");
10064            destval = fetch_data_byte(destoffset);
10065            TRACE_AND_STEP();
10066            destval = not_byte(destval);
10067            store_data_byte(destoffset, destval);
10068            break;
10069        case 3:
10070            DECODE_PRINTF("NEG\tBYTE PTR ");
10071            destoffset = decode_rm10_address(rl);
10072            DECODE_PRINTF("\n");
10073            destval = fetch_data_byte(destoffset);
10074            TRACE_AND_STEP();
10075            destval = neg_byte(destval);
10076            store_data_byte(destoffset, destval);
10077            break;
10078        case 4:
10079            DECODE_PRINTF("MUL\tBYTE PTR ");
10080            destoffset = decode_rm10_address(rl);
10081            DECODE_PRINTF("\n");
10082            destval = fetch_data_byte(destoffset);
10083            TRACE_AND_STEP();
10084            mul_byte(destval);
10085            break;
10086        case 5:
10087            DECODE_PRINTF("IMUL\tBYTE PTR ");
10088            destoffset = decode_rm10_address(rl);
10089            DECODE_PRINTF("\n");
10090            destval = fetch_data_byte(destoffset);
10091            TRACE_AND_STEP();
10092            imul_byte(destval);
10093            break;
10094        case 6:
10095            DECODE_PRINTF("DIV\tBYTE PTR ");
10096            destoffset = decode_rm10_address(rl);
10097            DECODE_PRINTF("\n");
10098            destval = fetch_data_byte(destoffset);
10099            TRACE_AND_STEP();
10100            div_byte(destval);
10101            break;
10102        case 7:
10103            DECODE_PRINTF("IDIV\tBYTE PTR ");
10104            destoffset = decode_rm10_address(rl);
10105            DECODE_PRINTF("\n");
10106            destval = fetch_data_byte(destoffset);
10107            TRACE_AND_STEP();
10108            idiv_byte(destval);
10109            break;
10110        }
10111        break;                  /* end mod==10 */
10112    case 3:                     /* mod=11 */
10113        switch (rh) {
10114        case 0:         /* test byte imm */
10115            DECODE_PRINTF("TEST\t");
10116            destreg = DECODE_RM_BYTE_REGISTER(rl);
10117            DECODE_PRINTF(",");
10118            srcval = fetch_byte_imm();
10119            DECODE_PRINTF2("%02x\n", srcval);
10120            TRACE_AND_STEP();
10121            test_byte(*destreg, srcval);
10122            break;
10123        case 1:
10124            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10125            HALT_SYS();
10126            break;
10127        case 2:
10128            DECODE_PRINTF("NOT\t");
10129            destreg = DECODE_RM_BYTE_REGISTER(rl);
10130            DECODE_PRINTF("\n");
10131            TRACE_AND_STEP();
10132            *destreg = not_byte(*destreg);
10133            break;
10134        case 3:
10135            DECODE_PRINTF("NEG\t");
10136            destreg = DECODE_RM_BYTE_REGISTER(rl);
10137            DECODE_PRINTF("\n");
10138            TRACE_AND_STEP();
10139            *destreg = neg_byte(*destreg);
10140            break;
10141        case 4:
10142            DECODE_PRINTF("MUL\t");
10143            destreg = DECODE_RM_BYTE_REGISTER(rl);
10144            DECODE_PRINTF("\n");
10145            TRACE_AND_STEP();
10146            mul_byte(*destreg);      /*!!!  */
10147            break;
10148        case 5:
10149            DECODE_PRINTF("IMUL\t");
10150            destreg = DECODE_RM_BYTE_REGISTER(rl);
10151            DECODE_PRINTF("\n");
10152            TRACE_AND_STEP();
10153            imul_byte(*destreg);
10154            break;
10155        case 6:
10156            DECODE_PRINTF("DIV\t");
10157            destreg = DECODE_RM_BYTE_REGISTER(rl);
10158            DECODE_PRINTF("\n");
10159            TRACE_AND_STEP();
10160            div_byte(*destreg);
10161            break;
10162        case 7:
10163            DECODE_PRINTF("IDIV\t");
10164            destreg = DECODE_RM_BYTE_REGISTER(rl);
10165            DECODE_PRINTF("\n");
10166            TRACE_AND_STEP();
10167            idiv_byte(*destreg);
10168            break;
10169        }
10170        break;                  /* end mod==11 */
10171    }
10172    DECODE_CLEAR_SEGOVR();
10173    END_OF_INSTR();
10174}
10175
10176/****************************************************************************
10177REMARKS:
10178Handles opcode 0xf7
10179****************************************************************************/
10180static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10181{
10182    int mod, rl, rh;
10183    uint destoffset;
10184
10185    /* long, drawn out code follows.  Double switch for a total
10186       of 32 cases.  */
10187    START_OF_INSTR();
10188    FETCH_DECODE_MODRM(mod, rh, rl);
10189    switch (mod) {
10190    case 0:                     /* mod=00 */
10191        switch (rh) {
10192        case 0:         /* test word imm */
10193            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10194                u32 destval,srcval;
10195
10196                DECODE_PRINTF("TEST\tDWORD PTR ");
10197                destoffset = decode_rm00_address(rl);
10198                DECODE_PRINTF(",");
10199                srcval = fetch_long_imm();
10200                DECODE_PRINTF2("%x\n", srcval);
10201                destval = fetch_data_long(destoffset);
10202                TRACE_AND_STEP();
10203                test_long(destval, srcval);
10204            } else {
10205                u16 destval,srcval;
10206
10207                DECODE_PRINTF("TEST\tWORD PTR ");
10208                destoffset = decode_rm00_address(rl);
10209                DECODE_PRINTF(",");
10210                srcval = fetch_word_imm();
10211                DECODE_PRINTF2("%x\n", srcval);
10212                destval = fetch_data_word(destoffset);
10213                TRACE_AND_STEP();
10214                test_word(destval, srcval);
10215            }
10216            break;
10217        case 1:
10218            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10219            HALT_SYS();
10220            break;
10221        case 2:
10222            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10223                u32 destval;
10224
10225                DECODE_PRINTF("NOT\tDWORD PTR ");
10226                destoffset = decode_rm00_address(rl);
10227                DECODE_PRINTF("\n");
10228                destval = fetch_data_long(destoffset);
10229                TRACE_AND_STEP();
10230                destval = not_long(destval);
10231                store_data_long(destoffset, destval);
10232            } else {
10233                u16 destval;
10234
10235                DECODE_PRINTF("NOT\tWORD PTR ");
10236                destoffset = decode_rm00_address(rl);
10237                DECODE_PRINTF("\n");
10238                destval = fetch_data_word(destoffset);
10239                TRACE_AND_STEP();
10240                destval = not_word(destval);
10241                store_data_word(destoffset, destval);
10242            }
10243            break;
10244        case 3:
10245            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10246                u32 destval;
10247
10248                DECODE_PRINTF("NEG\tDWORD PTR ");
10249                destoffset = decode_rm00_address(rl);
10250                DECODE_PRINTF("\n");
10251                destval = fetch_data_long(destoffset);
10252                TRACE_AND_STEP();
10253                destval = neg_long(destval);
10254                store_data_long(destoffset, destval);
10255            } else {
10256                u16 destval;
10257
10258                DECODE_PRINTF("NEG\tWORD PTR ");
10259                destoffset = decode_rm00_address(rl);
10260                DECODE_PRINTF("\n");
10261                destval = fetch_data_word(destoffset);
10262                TRACE_AND_STEP();
10263                destval = neg_word(destval);
10264                store_data_word(destoffset, destval);
10265            }
10266            break;
10267        case 4:
10268            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10269                u32 destval;
10270
10271                DECODE_PRINTF("MUL\tDWORD PTR ");
10272                destoffset = decode_rm00_address(rl);
10273                DECODE_PRINTF("\n");
10274                destval = fetch_data_long(destoffset);
10275                TRACE_AND_STEP();
10276                mul_long(destval);
10277            } else {
10278                u16 destval;
10279
10280                DECODE_PRINTF("MUL\tWORD PTR ");
10281                destoffset = decode_rm00_address(rl);
10282                DECODE_PRINTF("\n");
10283                destval = fetch_data_word(destoffset);
10284                TRACE_AND_STEP();
10285                mul_word(destval);
10286            }
10287            break;
10288        case 5:
10289            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10290                u32 destval;
10291
10292                DECODE_PRINTF("IMUL\tDWORD PTR ");
10293                destoffset = decode_rm00_address(rl);
10294                DECODE_PRINTF("\n");
10295                destval = fetch_data_long(destoffset);
10296                TRACE_AND_STEP();
10297                imul_long(destval);
10298            } else {
10299                u16 destval;
10300
10301                DECODE_PRINTF("IMUL\tWORD PTR ");
10302                destoffset = decode_rm00_address(rl);
10303                DECODE_PRINTF("\n");
10304                destval = fetch_data_word(destoffset);
10305                TRACE_AND_STEP();
10306                imul_word(destval);
10307            }
10308            break;
10309        case 6:
10310            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10311                u32 destval;
10312
10313                DECODE_PRINTF("DIV\tDWORD PTR ");
10314                destoffset = decode_rm00_address(rl);
10315                DECODE_PRINTF("\n");
10316                destval = fetch_data_long(destoffset);
10317                TRACE_AND_STEP();
10318                div_long(destval);
10319            } else {
10320                u16 destval;
10321
10322                DECODE_PRINTF("DIV\tWORD PTR ");
10323                destoffset = decode_rm00_address(rl);
10324                DECODE_PRINTF("\n");
10325                destval = fetch_data_word(destoffset);
10326                TRACE_AND_STEP();
10327                div_word(destval);
10328            }
10329            break;
10330        case 7:
10331            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10332                u32 destval;
10333
10334                DECODE_PRINTF("IDIV\tDWORD PTR ");
10335                destoffset = decode_rm00_address(rl);
10336                DECODE_PRINTF("\n");
10337                destval = fetch_data_long(destoffset);
10338                TRACE_AND_STEP();
10339                idiv_long(destval);
10340            } else {
10341                u16 destval;
10342
10343                DECODE_PRINTF("IDIV\tWORD PTR ");
10344                destoffset = decode_rm00_address(rl);
10345                DECODE_PRINTF("\n");
10346                destval = fetch_data_word(destoffset);
10347                TRACE_AND_STEP();
10348                idiv_word(destval);
10349            }
10350            break;
10351        }
10352        break;                  /* end mod==00 */
10353    case 1:                     /* mod=01 */
10354        switch (rh) {
10355        case 0:         /* test word imm */
10356            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10357                u32 destval,srcval;
10358
10359                DECODE_PRINTF("TEST\tDWORD PTR ");
10360                destoffset = decode_rm01_address(rl);
10361                DECODE_PRINTF(",");
10362                srcval = fetch_long_imm();
10363                DECODE_PRINTF2("%x\n", srcval);
10364                destval = fetch_data_long(destoffset);
10365                TRACE_AND_STEP();
10366                test_long(destval, srcval);
10367            } else {
10368                u16 destval,srcval;
10369
10370                DECODE_PRINTF("TEST\tWORD PTR ");
10371                destoffset = decode_rm01_address(rl);
10372                DECODE_PRINTF(",");
10373                srcval = fetch_word_imm();
10374                DECODE_PRINTF2("%x\n", srcval);
10375                destval = fetch_data_word(destoffset);
10376                TRACE_AND_STEP();
10377                test_word(destval, srcval);
10378            }
10379            break;
10380        case 1:
10381            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10382            HALT_SYS();
10383            break;
10384        case 2:
10385            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10386                u32 destval;
10387
10388                DECODE_PRINTF("NOT\tDWORD PTR ");
10389                destoffset = decode_rm01_address(rl);
10390                DECODE_PRINTF("\n");
10391                destval = fetch_data_long(destoffset);
10392                TRACE_AND_STEP();
10393                destval = not_long(destval);
10394                store_data_long(destoffset, destval);
10395            } else {
10396                u16 destval;
10397
10398                DECODE_PRINTF("NOT\tWORD PTR ");
10399                destoffset = decode_rm01_address(rl);
10400                DECODE_PRINTF("\n");
10401                destval = fetch_data_word(destoffset);
10402                TRACE_AND_STEP();
10403                destval = not_word(destval);
10404                store_data_word(destoffset, destval);
10405            }
10406            break;
10407        case 3:
10408            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10409                u32 destval;
10410
10411                DECODE_PRINTF("NEG\tDWORD PTR ");
10412                destoffset = decode_rm01_address(rl);
10413                DECODE_PRINTF("\n");
10414                destval = fetch_data_long(destoffset);
10415                TRACE_AND_STEP();
10416                destval = neg_long(destval);
10417                store_data_long(destoffset, destval);
10418            } else {
10419                u16 destval;
10420
10421                DECODE_PRINTF("NEG\tWORD PTR ");
10422                destoffset = decode_rm01_address(rl);
10423                DECODE_PRINTF("\n");
10424                destval = fetch_data_word(destoffset);
10425                TRACE_AND_STEP();
10426                destval = neg_word(destval);
10427                store_data_word(destoffset, destval);
10428            }
10429            break;
10430        case 4:
10431            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10432                u32 destval;
10433
10434                DECODE_PRINTF("MUL\tDWORD PTR ");
10435                destoffset = decode_rm01_address(rl);
10436                DECODE_PRINTF("\n");
10437                destval = fetch_data_long(destoffset);
10438                TRACE_AND_STEP();
10439                mul_long(destval);
10440            } else {
10441                u16 destval;
10442
10443                DECODE_PRINTF("MUL\tWORD PTR ");
10444                destoffset = decode_rm01_address(rl);
10445                DECODE_PRINTF("\n");
10446                destval = fetch_data_word(destoffset);
10447                TRACE_AND_STEP();
10448                mul_word(destval);
10449            }
10450            break;
10451        case 5:
10452            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10453                u32 destval;
10454
10455                DECODE_PRINTF("IMUL\tDWORD PTR ");
10456                destoffset = decode_rm01_address(rl);
10457                DECODE_PRINTF("\n");
10458                destval = fetch_data_long(destoffset);
10459                TRACE_AND_STEP();
10460                imul_long(destval);
10461            } else {
10462                u16 destval;
10463
10464                DECODE_PRINTF("IMUL\tWORD PTR ");
10465                destoffset = decode_rm01_address(rl);
10466                DECODE_PRINTF("\n");
10467                destval = fetch_data_word(destoffset);
10468                TRACE_AND_STEP();
10469                imul_word(destval);
10470            }
10471            break;
10472        case 6:
10473            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10474                u32 destval;
10475
10476                DECODE_PRINTF("DIV\tDWORD PTR ");
10477                destoffset = decode_rm01_address(rl);
10478                DECODE_PRINTF("\n");
10479                destval = fetch_data_long(destoffset);
10480                TRACE_AND_STEP();
10481                div_long(destval);
10482            } else {
10483                u16 destval;
10484
10485                DECODE_PRINTF("DIV\tWORD PTR ");
10486                destoffset = decode_rm01_address(rl);
10487                DECODE_PRINTF("\n");
10488                destval = fetch_data_word(destoffset);
10489                TRACE_AND_STEP();
10490                div_word(destval);
10491            }
10492            break;
10493        case 7:
10494            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10495                u32 destval;
10496
10497                DECODE_PRINTF("IDIV\tDWORD PTR ");
10498                destoffset = decode_rm01_address(rl);
10499                DECODE_PRINTF("\n");
10500                destval = fetch_data_long(destoffset);
10501                TRACE_AND_STEP();
10502                idiv_long(destval);
10503            } else {
10504                u16 destval;
10505
10506                DECODE_PRINTF("IDIV\tWORD PTR ");
10507                destoffset = decode_rm01_address(rl);
10508                DECODE_PRINTF("\n");
10509                destval = fetch_data_word(destoffset);
10510                TRACE_AND_STEP();
10511                idiv_word(destval);
10512            }
10513            break;
10514        }
10515        break;                  /* end mod==01 */
10516    case 2:                     /* mod=10 */
10517        switch (rh) {
10518        case 0:         /* test word imm */
10519            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10520                u32 destval,srcval;
10521
10522                DECODE_PRINTF("TEST\tDWORD PTR ");
10523                destoffset = decode_rm10_address(rl);
10524                DECODE_PRINTF(",");
10525                srcval = fetch_long_imm();
10526                DECODE_PRINTF2("%x\n", srcval);
10527                destval = fetch_data_long(destoffset);
10528                TRACE_AND_STEP();
10529                test_long(destval, srcval);
10530            } else {
10531                u16 destval,srcval;
10532
10533                DECODE_PRINTF("TEST\tWORD PTR ");
10534                destoffset = decode_rm10_address(rl);
10535                DECODE_PRINTF(",");
10536                srcval = fetch_word_imm();
10537                DECODE_PRINTF2("%x\n", srcval);
10538                destval = fetch_data_word(destoffset);
10539                TRACE_AND_STEP();
10540                test_word(destval, srcval);
10541            }
10542            break;
10543        case 1:
10544            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10545            HALT_SYS();
10546            break;
10547        case 2:
10548            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10549                u32 destval;
10550
10551                DECODE_PRINTF("NOT\tDWORD PTR ");
10552                destoffset = decode_rm10_address(rl);
10553                DECODE_PRINTF("\n");
10554                destval = fetch_data_long(destoffset);
10555                TRACE_AND_STEP();
10556                destval = not_long(destval);
10557                store_data_long(destoffset, destval);
10558            } else {
10559                u16 destval;
10560
10561                DECODE_PRINTF("NOT\tWORD PTR ");
10562                destoffset = decode_rm10_address(rl);
10563                DECODE_PRINTF("\n");
10564                destval = fetch_data_word(destoffset);
10565                TRACE_AND_STEP();
10566                destval = not_word(destval);
10567                store_data_word(destoffset, destval);
10568            }
10569            break;
10570        case 3:
10571            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10572                u32 destval;
10573
10574                DECODE_PRINTF("NEG\tDWORD PTR ");
10575                destoffset = decode_rm10_address(rl);
10576                DECODE_PRINTF("\n");
10577                destval = fetch_data_long(destoffset);
10578                TRACE_AND_STEP();
10579                destval = neg_long(destval);
10580                store_data_long(destoffset, destval);
10581            } else {
10582                u16 destval;
10583
10584                DECODE_PRINTF("NEG\tWORD PTR ");
10585                destoffset = decode_rm10_address(rl);
10586                DECODE_PRINTF("\n");
10587                destval = fetch_data_word(destoffset);
10588                TRACE_AND_STEP();
10589                destval = neg_word(destval);
10590                store_data_word(destoffset, destval);
10591            }
10592            break;
10593        case 4:
10594            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10595                u32 destval;
10596
10597                DECODE_PRINTF("MUL\tDWORD PTR ");
10598                destoffset = decode_rm10_address(rl);
10599                DECODE_PRINTF("\n");
10600                destval = fetch_data_long(destoffset);
10601                TRACE_AND_STEP();
10602                mul_long(destval);
10603            } else {
10604                u16 destval;
10605
10606                DECODE_PRINTF("MUL\tWORD PTR ");
10607                destoffset = decode_rm10_address(rl);
10608                DECODE_PRINTF("\n");
10609                destval = fetch_data_word(destoffset);
10610                TRACE_AND_STEP();
10611                mul_word(destval);
10612            }
10613            break;
10614        case 5:
10615            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10616                u32 destval;
10617
10618                DECODE_PRINTF("IMUL\tDWORD PTR ");
10619                destoffset = decode_rm10_address(rl);
10620                DECODE_PRINTF("\n");
10621                destval = fetch_data_long(destoffset);
10622                TRACE_AND_STEP();
10623                imul_long(destval);
10624            } else {
10625                u16 destval;
10626
10627                DECODE_PRINTF("IMUL\tWORD PTR ");
10628                destoffset = decode_rm10_address(rl);
10629                DECODE_PRINTF("\n");
10630                destval = fetch_data_word(destoffset);
10631                TRACE_AND_STEP();
10632                imul_word(destval);
10633            }
10634            break;
10635        case 6:
10636            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10637                u32 destval;
10638
10639                DECODE_PRINTF("DIV\tDWORD PTR ");
10640                destoffset = decode_rm10_address(rl);
10641                DECODE_PRINTF("\n");
10642                destval = fetch_data_long(destoffset);
10643                TRACE_AND_STEP();
10644                div_long(destval);
10645            } else {
10646                u16 destval;
10647
10648                DECODE_PRINTF("DIV\tWORD PTR ");
10649                destoffset = decode_rm10_address(rl);
10650                DECODE_PRINTF("\n");
10651                destval = fetch_data_word(destoffset);
10652                TRACE_AND_STEP();
10653                div_word(destval);
10654            }
10655            break;
10656        case 7:
10657            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10658                u32 destval;
10659
10660                DECODE_PRINTF("IDIV\tDWORD PTR ");
10661                destoffset = decode_rm10_address(rl);
10662                DECODE_PRINTF("\n");
10663                destval = fetch_data_long(destoffset);
10664                TRACE_AND_STEP();
10665                idiv_long(destval);
10666            } else {
10667                u16 destval;
10668
10669                DECODE_PRINTF("IDIV\tWORD PTR ");
10670                destoffset = decode_rm10_address(rl);
10671                DECODE_PRINTF("\n");
10672                destval = fetch_data_word(destoffset);
10673                TRACE_AND_STEP();
10674                idiv_word(destval);
10675            }
10676            break;
10677        }
10678        break;                  /* end mod==10 */
10679    case 3:                     /* mod=11 */
10680        switch (rh) {
10681        case 0:         /* test word imm */
10682            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10683                u32 *destreg;
10684                u32 srcval;
10685
10686                DECODE_PRINTF("TEST\t");
10687                destreg = DECODE_RM_LONG_REGISTER(rl);
10688                DECODE_PRINTF(",");
10689                srcval = fetch_long_imm();
10690                DECODE_PRINTF2("%x\n", srcval);
10691                TRACE_AND_STEP();
10692                test_long(*destreg, srcval);
10693            } else {
10694                u16 *destreg;
10695                u16 srcval;
10696
10697                DECODE_PRINTF("TEST\t");
10698                destreg = DECODE_RM_WORD_REGISTER(rl);
10699                DECODE_PRINTF(",");
10700                srcval = fetch_word_imm();
10701                DECODE_PRINTF2("%x\n", srcval);
10702                TRACE_AND_STEP();
10703                test_word(*destreg, srcval);
10704            }
10705            break;
10706        case 1:
10707            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10708            HALT_SYS();
10709            break;
10710        case 2:
10711            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10712                u32 *destreg;
10713
10714                DECODE_PRINTF("NOT\t");
10715                destreg = DECODE_RM_LONG_REGISTER(rl);
10716                DECODE_PRINTF("\n");
10717                TRACE_AND_STEP();
10718                *destreg = not_long(*destreg);
10719            } else {
10720                u16 *destreg;
10721
10722                DECODE_PRINTF("NOT\t");
10723                destreg = DECODE_RM_WORD_REGISTER(rl);
10724                DECODE_PRINTF("\n");
10725                TRACE_AND_STEP();
10726                *destreg = not_word(*destreg);
10727            }
10728            break;
10729        case 3:
10730            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10731                u32 *destreg;
10732
10733                DECODE_PRINTF("NEG\t");
10734                destreg = DECODE_RM_LONG_REGISTER(rl);
10735                DECODE_PRINTF("\n");
10736                TRACE_AND_STEP();
10737                *destreg = neg_long(*destreg);
10738            } else {
10739                u16 *destreg;
10740
10741                DECODE_PRINTF("NEG\t");
10742                destreg = DECODE_RM_WORD_REGISTER(rl);
10743                DECODE_PRINTF("\n");
10744                TRACE_AND_STEP();
10745                *destreg = neg_word(*destreg);
10746            }
10747            break;
10748        case 4:
10749            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10750                u32 *destreg;
10751
10752                DECODE_PRINTF("MUL\t");
10753                destreg = DECODE_RM_LONG_REGISTER(rl);
10754                DECODE_PRINTF("\n");
10755                TRACE_AND_STEP();
10756                mul_long(*destreg);      /*!!!  */
10757            } else {
10758                u16 *destreg;
10759
10760                DECODE_PRINTF("MUL\t");
10761                destreg = DECODE_RM_WORD_REGISTER(rl);
10762                DECODE_PRINTF("\n");
10763                TRACE_AND_STEP();
10764                mul_word(*destreg);      /*!!!  */
10765            }
10766            break;
10767        case 5:
10768            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10769                u32 *destreg;
10770
10771                DECODE_PRINTF("IMUL\t");
10772                destreg = DECODE_RM_LONG_REGISTER(rl);
10773                DECODE_PRINTF("\n");
10774                TRACE_AND_STEP();
10775                imul_long(*destreg);
10776            } else {
10777                u16 *destreg;
10778
10779                DECODE_PRINTF("IMUL\t");
10780                destreg = DECODE_RM_WORD_REGISTER(rl);
10781                DECODE_PRINTF("\n");
10782                TRACE_AND_STEP();
10783                imul_word(*destreg);
10784            }
10785            break;
10786        case 6:
10787            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10788                u32 *destreg;
10789
10790                DECODE_PRINTF("DIV\t");
10791                destreg = DECODE_RM_LONG_REGISTER(rl);
10792                DECODE_PRINTF("\n");
10793                TRACE_AND_STEP();
10794                div_long(*destreg);
10795            } else {
10796                u16 *destreg;
10797
10798                DECODE_PRINTF("DIV\t");
10799                destreg = DECODE_RM_WORD_REGISTER(rl);
10800                DECODE_PRINTF("\n");
10801                TRACE_AND_STEP();
10802                div_word(*destreg);
10803            }
10804            break;
10805        case 7:
10806            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10807                u32 *destreg;
10808
10809                DECODE_PRINTF("IDIV\t");
10810                destreg = DECODE_RM_LONG_REGISTER(rl);
10811                DECODE_PRINTF("\n");
10812                TRACE_AND_STEP();
10813                idiv_long(*destreg);
10814            } else {
10815                u16 *destreg;
10816
10817                DECODE_PRINTF("IDIV\t");
10818                destreg = DECODE_RM_WORD_REGISTER(rl);
10819                DECODE_PRINTF("\n");
10820                TRACE_AND_STEP();
10821                idiv_word(*destreg);
10822            }
10823            break;
10824        }
10825        break;                  /* end mod==11 */
10826    }
10827    DECODE_CLEAR_SEGOVR();
10828    END_OF_INSTR();
10829}
10830
10831/****************************************************************************
10832REMARKS:
10833Handles opcode 0xf8
10834****************************************************************************/
10835static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10836{
10837    /* clear the carry flag. */
10838    START_OF_INSTR();
10839    DECODE_PRINTF("CLC\n");
10840    TRACE_AND_STEP();
10841    CLEAR_FLAG(F_CF);
10842    DECODE_CLEAR_SEGOVR();
10843    END_OF_INSTR();
10844}
10845
10846/****************************************************************************
10847REMARKS:
10848Handles opcode 0xf9
10849****************************************************************************/
10850static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10851{
10852    /* set the carry flag. */
10853    START_OF_INSTR();
10854    DECODE_PRINTF("STC\n");
10855    TRACE_AND_STEP();
10856    SET_FLAG(F_CF);
10857    DECODE_CLEAR_SEGOVR();
10858    END_OF_INSTR();
10859}
10860
10861/****************************************************************************
10862REMARKS:
10863Handles opcode 0xfa
10864****************************************************************************/
10865static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10866{
10867    /* clear interrupts. */
10868    START_OF_INSTR();
10869    DECODE_PRINTF("CLI\n");
10870    TRACE_AND_STEP();
10871    CLEAR_FLAG(F_IF);
10872    DECODE_CLEAR_SEGOVR();
10873    END_OF_INSTR();
10874}
10875
10876/****************************************************************************
10877REMARKS:
10878Handles opcode 0xfb
10879****************************************************************************/
10880static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10881{
10882    /* enable  interrupts. */
10883    START_OF_INSTR();
10884    DECODE_PRINTF("STI\n");
10885    TRACE_AND_STEP();
10886    SET_FLAG(F_IF);
10887    DECODE_CLEAR_SEGOVR();
10888    END_OF_INSTR();
10889}
10890
10891/****************************************************************************
10892REMARKS:
10893Handles opcode 0xfc
10894****************************************************************************/
10895static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10896{
10897    /* clear interrupts. */
10898    START_OF_INSTR();
10899    DECODE_PRINTF("CLD\n");
10900    TRACE_AND_STEP();
10901    CLEAR_FLAG(F_DF);
10902    DECODE_CLEAR_SEGOVR();
10903    END_OF_INSTR();
10904}
10905
10906/****************************************************************************
10907REMARKS:
10908Handles opcode 0xfd
10909****************************************************************************/
10910static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10911{
10912    /* clear interrupts. */
10913    START_OF_INSTR();
10914    DECODE_PRINTF("STD\n");
10915    TRACE_AND_STEP();
10916    SET_FLAG(F_DF);
10917    DECODE_CLEAR_SEGOVR();
10918    END_OF_INSTR();
10919}
10920
10921/****************************************************************************
10922REMARKS:
10923Handles opcode 0xfe
10924****************************************************************************/
10925static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10926{
10927    int mod, rh, rl;
10928    u8 destval;
10929    uint destoffset;
10930    u8 *destreg;
10931
10932    /* Yet another special case instruction. */
10933    START_OF_INSTR();
10934    FETCH_DECODE_MODRM(mod, rh, rl);
10935#ifdef DEBUG
10936    if (DEBUG_DECODE()) {
10937        /* XXX DECODE_PRINTF may be changed to something more
10938           general, so that it is important to leave the strings
10939           in the same format, even though the result is that the
10940           above test is done twice. */
10941
10942        switch (rh) {
10943        case 0:
10944            DECODE_PRINTF("INC\t");
10945            break;
10946        case 1:
10947            DECODE_PRINTF("DEC\t");
10948            break;
10949        case 2:
10950        case 3:
10951        case 4:
10952        case 5:
10953        case 6:
10954        case 7:
10955            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10956            HALT_SYS();
10957            break;
10958        }
10959    }
10960#endif
10961    switch (mod) {
10962    case 0:
10963        DECODE_PRINTF("BYTE PTR ");
10964        destoffset = decode_rm00_address(rl);
10965        DECODE_PRINTF("\n");
10966        switch (rh) {
10967        case 0:         /* inc word ptr ... */
10968            destval = fetch_data_byte(destoffset);
10969            TRACE_AND_STEP();
10970            destval = inc_byte(destval);
10971            store_data_byte(destoffset, destval);
10972            break;
10973        case 1:         /* dec word ptr ... */
10974            destval = fetch_data_byte(destoffset);
10975            TRACE_AND_STEP();
10976            destval = dec_byte(destval);
10977            store_data_byte(destoffset, destval);
10978            break;
10979        }
10980        break;
10981    case 1:
10982        DECODE_PRINTF("BYTE PTR ");
10983        destoffset = decode_rm01_address(rl);
10984        DECODE_PRINTF("\n");
10985        switch (rh) {
10986        case 0:
10987            destval = fetch_data_byte(destoffset);
10988            TRACE_AND_STEP();
10989            destval = inc_byte(destval);
10990            store_data_byte(destoffset, destval);
10991            break;
10992        case 1:
10993            destval = fetch_data_byte(destoffset);
10994            TRACE_AND_STEP();
10995            destval = dec_byte(destval);
10996            store_data_byte(destoffset, destval);
10997            break;
10998        }
10999        break;
11000    case 2:
11001        DECODE_PRINTF("BYTE PTR ");
11002        destoffset = decode_rm10_address(rl);
11003        DECODE_PRINTF("\n");
11004        switch (rh) {
11005        case 0:
11006            destval = fetch_data_byte(destoffset);
11007            TRACE_AND_STEP();
11008            destval = inc_byte(destval);
11009            store_data_byte(destoffset, destval);
11010            break;
11011        case 1:
11012            destval = fetch_data_byte(destoffset);
11013            TRACE_AND_STEP();
11014            destval = dec_byte(destval);
11015            store_data_byte(destoffset, destval);
11016            break;
11017        }
11018        break;
11019    case 3:
11020        destreg = DECODE_RM_BYTE_REGISTER(rl);
11021        DECODE_PRINTF("\n");
11022        switch (rh) {
11023        case 0:
11024            TRACE_AND_STEP();
11025            *destreg = inc_byte(*destreg);
11026            break;
11027        case 1:
11028            TRACE_AND_STEP();
11029            *destreg = dec_byte(*destreg);
11030            break;
11031        }
11032        break;
11033    }
11034    DECODE_CLEAR_SEGOVR();
11035    END_OF_INSTR();
11036}
11037
11038/****************************************************************************
11039REMARKS:
11040Handles opcode 0xff
11041****************************************************************************/
11042static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11043{
11044    int mod, rh, rl;
11045    uint destoffset = 0;
11046	u16 *destreg;
11047	u16 destval,destval2;
11048
11049    /* Yet another special case instruction. */
11050    START_OF_INSTR();
11051    FETCH_DECODE_MODRM(mod, rh, rl);
11052#ifdef DEBUG
11053    if (DEBUG_DECODE()) {
11054        /* XXX DECODE_PRINTF may be changed to something more
11055           general, so that it is important to leave the strings
11056           in the same format, even though the result is that the
11057           above test is done twice. */
11058
11059        switch (rh) {
11060        case 0:
11061            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11062                DECODE_PRINTF("INC\tDWORD PTR ");
11063            } else {
11064                DECODE_PRINTF("INC\tWORD PTR ");
11065            }
11066            break;
11067        case 1:
11068            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11069                DECODE_PRINTF("DEC\tDWORD PTR ");
11070            } else {
11071                DECODE_PRINTF("DEC\tWORD PTR ");
11072            }
11073            break;
11074        case 2:
11075            DECODE_PRINTF("CALL\t");
11076            break;
11077        case 3:
11078            DECODE_PRINTF("CALL\tFAR ");
11079            break;
11080        case 4:
11081            DECODE_PRINTF("JMP\t");
11082            break;
11083        case 5:
11084            DECODE_PRINTF("JMP\tFAR ");
11085            break;
11086        case 6:
11087            DECODE_PRINTF("PUSH\t");
11088            break;
11089        case 7:
11090            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11091            HALT_SYS();
11092            break;
11093        }
11094    }
11095#endif
11096    switch (mod) {
11097    case 0:
11098        destoffset = decode_rm00_address(rl);
11099        DECODE_PRINTF("\n");
11100        switch (rh) {
11101        case 0:         /* inc word ptr ... */
11102            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11103                u32 destval;
11104
11105                destval = fetch_data_long(destoffset);
11106                TRACE_AND_STEP();
11107                destval = inc_long(destval);
11108                store_data_long(destoffset, destval);
11109            } else {
11110                u16 destval;
11111
11112                destval = fetch_data_word(destoffset);
11113                TRACE_AND_STEP();
11114                destval = inc_word(destval);
11115                store_data_word(destoffset, destval);
11116            }
11117            break;
11118        case 1:         /* dec word ptr ... */
11119            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11120                u32 destval;
11121
11122                destval = fetch_data_long(destoffset);
11123                TRACE_AND_STEP();
11124                destval = dec_long(destval);
11125                store_data_long(destoffset, destval);
11126            } else {
11127                u16 destval;
11128
11129                destval = fetch_data_word(destoffset);
11130                TRACE_AND_STEP();
11131                destval = dec_word(destval);
11132                store_data_word(destoffset, destval);
11133            }
11134            break;
11135        case 2:         /* call word ptr ... */
11136            destval = fetch_data_word(destoffset);
11137            TRACE_AND_STEP();
11138            push_word(M.x86.R_IP);
11139            M.x86.R_IP = destval;
11140            break;
11141        case 3:         /* call far ptr ... */
11142            destval = fetch_data_word(destoffset);
11143            destval2 = fetch_data_word(destoffset + 2);
11144            TRACE_AND_STEP();
11145            push_word(M.x86.R_CS);
11146            M.x86.R_CS = destval2;
11147            push_word(M.x86.R_IP);
11148            M.x86.R_IP = destval;
11149            break;
11150        case 4:         /* jmp word ptr ... */
11151            destval = fetch_data_word(destoffset);
11152            TRACE_AND_STEP();
11153            M.x86.R_IP = destval;
11154            break;
11155        case 5:         /* jmp far ptr ... */
11156            destval = fetch_data_word(destoffset);
11157            destval2 = fetch_data_word(destoffset + 2);
11158            TRACE_AND_STEP();
11159            M.x86.R_IP = destval;
11160            M.x86.R_CS = destval2;
11161            break;
11162        case 6:         /*  push word ptr ... */
11163            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11164                u32 destval;
11165
11166                destval = fetch_data_long(destoffset);
11167                TRACE_AND_STEP();
11168                push_long(destval);
11169            } else {
11170                u16 destval;
11171
11172                destval = fetch_data_word(destoffset);
11173                TRACE_AND_STEP();
11174                push_word(destval);
11175            }
11176            break;
11177        }
11178        break;
11179    case 1:
11180        destoffset = decode_rm01_address(rl);
11181        DECODE_PRINTF("\n");
11182        switch (rh) {
11183        case 0:
11184            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11185                u32 destval;
11186
11187                destval = fetch_data_long(destoffset);
11188                TRACE_AND_STEP();
11189                destval = inc_long(destval);
11190                store_data_long(destoffset, destval);
11191            } else {
11192                u16 destval;
11193
11194                destval = fetch_data_word(destoffset);
11195                TRACE_AND_STEP();
11196                destval = inc_word(destval);
11197                store_data_word(destoffset, destval);
11198            }
11199            break;
11200        case 1:
11201            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11202                u32 destval;
11203
11204                destval = fetch_data_long(destoffset);
11205                TRACE_AND_STEP();
11206                destval = dec_long(destval);
11207                store_data_long(destoffset, destval);
11208            } else {
11209                u16 destval;
11210
11211                destval = fetch_data_word(destoffset);
11212                TRACE_AND_STEP();
11213                destval = dec_word(destval);
11214                store_data_word(destoffset, destval);
11215            }
11216            break;
11217        case 2:         /* call word ptr ... */
11218            destval = fetch_data_word(destoffset);
11219            TRACE_AND_STEP();
11220            push_word(M.x86.R_IP);
11221            M.x86.R_IP = destval;
11222            break;
11223        case 3:         /* call far ptr ... */
11224            destval = fetch_data_word(destoffset);
11225            destval2 = fetch_data_word(destoffset + 2);
11226            TRACE_AND_STEP();
11227            push_word(M.x86.R_CS);
11228            M.x86.R_CS = destval2;
11229            push_word(M.x86.R_IP);
11230            M.x86.R_IP = destval;
11231            break;
11232        case 4:         /* jmp word ptr ... */
11233            destval = fetch_data_word(destoffset);
11234            TRACE_AND_STEP();
11235            M.x86.R_IP = destval;
11236            break;
11237        case 5:         /* jmp far ptr ... */
11238            destval = fetch_data_word(destoffset);
11239            destval2 = fetch_data_word(destoffset + 2);
11240            TRACE_AND_STEP();
11241            M.x86.R_IP = destval;
11242            M.x86.R_CS = destval2;
11243            break;
11244        case 6:         /*  push word ptr ... */
11245            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11246                u32 destval;
11247
11248                destval = fetch_data_long(destoffset);
11249                TRACE_AND_STEP();
11250                push_long(destval);
11251            } else {
11252                u16 destval;
11253
11254                destval = fetch_data_word(destoffset);
11255                TRACE_AND_STEP();
11256                push_word(destval);
11257            }
11258            break;
11259        }
11260        break;
11261    case 2:
11262        destoffset = decode_rm10_address(rl);
11263        DECODE_PRINTF("\n");
11264        switch (rh) {
11265        case 0:
11266            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11267                u32 destval;
11268
11269                destval = fetch_data_long(destoffset);
11270                TRACE_AND_STEP();
11271                destval = inc_long(destval);
11272                store_data_long(destoffset, destval);
11273            } else {
11274                u16 destval;
11275
11276                destval = fetch_data_word(destoffset);
11277                TRACE_AND_STEP();
11278                destval = inc_word(destval);
11279                store_data_word(destoffset, destval);
11280            }
11281            break;
11282        case 1:
11283            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11284                u32 destval;
11285
11286                destval = fetch_data_long(destoffset);
11287                TRACE_AND_STEP();
11288                destval = dec_long(destval);
11289                store_data_long(destoffset, destval);
11290            } else {
11291                u16 destval;
11292
11293                destval = fetch_data_word(destoffset);
11294                TRACE_AND_STEP();
11295                destval = dec_word(destval);
11296                store_data_word(destoffset, destval);
11297            }
11298            break;
11299        case 2:         /* call word ptr ... */
11300            destval = fetch_data_word(destoffset);
11301            TRACE_AND_STEP();
11302            push_word(M.x86.R_IP);
11303            M.x86.R_IP = destval;
11304            break;
11305        case 3:         /* call far ptr ... */
11306            destval = fetch_data_word(destoffset);
11307            destval2 = fetch_data_word(destoffset + 2);
11308            TRACE_AND_STEP();
11309            push_word(M.x86.R_CS);
11310            M.x86.R_CS = destval2;
11311            push_word(M.x86.R_IP);
11312            M.x86.R_IP = destval;
11313            break;
11314        case 4:         /* jmp word ptr ... */
11315            destval = fetch_data_word(destoffset);
11316            TRACE_AND_STEP();
11317            M.x86.R_IP = destval;
11318            break;
11319        case 5:         /* jmp far ptr ... */
11320            destval = fetch_data_word(destoffset);
11321            destval2 = fetch_data_word(destoffset + 2);
11322            TRACE_AND_STEP();
11323            M.x86.R_IP = destval;
11324            M.x86.R_CS = destval2;
11325            break;
11326        case 6:         /*  push word ptr ... */
11327            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11328                u32 destval;
11329
11330                destval = fetch_data_long(destoffset);
11331                TRACE_AND_STEP();
11332                push_long(destval);
11333            } else {
11334                u16 destval;
11335
11336                destval = fetch_data_word(destoffset);
11337                TRACE_AND_STEP();
11338                push_word(destval);
11339            }
11340            break;
11341        }
11342        break;
11343    case 3:
11344        switch (rh) {
11345        case 0:
11346            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11347                u32 *destreg;
11348
11349                destreg = DECODE_RM_LONG_REGISTER(rl);
11350                DECODE_PRINTF("\n");
11351                TRACE_AND_STEP();
11352                *destreg = inc_long(*destreg);
11353            } else {
11354                u16 *destreg;
11355
11356                destreg = DECODE_RM_WORD_REGISTER(rl);
11357                DECODE_PRINTF("\n");
11358                TRACE_AND_STEP();
11359                *destreg = inc_word(*destreg);
11360            }
11361            break;
11362        case 1:
11363            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11364                u32 *destreg;
11365
11366                destreg = DECODE_RM_LONG_REGISTER(rl);
11367                DECODE_PRINTF("\n");
11368                TRACE_AND_STEP();
11369                *destreg = dec_long(*destreg);
11370            } else {
11371                u16 *destreg;
11372
11373                destreg = DECODE_RM_WORD_REGISTER(rl);
11374                DECODE_PRINTF("\n");
11375                TRACE_AND_STEP();
11376                *destreg = dec_word(*destreg);
11377            }
11378            break;
11379        case 2:         /* call word ptr ... */
11380            destreg = DECODE_RM_WORD_REGISTER(rl);
11381            DECODE_PRINTF("\n");
11382            TRACE_AND_STEP();
11383            push_word(M.x86.R_IP);
11384            M.x86.R_IP = *destreg;
11385            break;
11386        case 3:         /* jmp far ptr ... */
11387            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11388            TRACE_AND_STEP();
11389            HALT_SYS();
11390            break;
11391
11392        case 4:         /* jmp  ... */
11393            destreg = DECODE_RM_WORD_REGISTER(rl);
11394            DECODE_PRINTF("\n");
11395            TRACE_AND_STEP();
11396            M.x86.R_IP = (u16) (*destreg);
11397            break;
11398        case 5:         /* jmp far ptr ... */
11399            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11400            TRACE_AND_STEP();
11401            HALT_SYS();
11402            break;
11403        case 6:
11404            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11405                u32 *destreg;
11406
11407                destreg = DECODE_RM_LONG_REGISTER(rl);
11408                DECODE_PRINTF("\n");
11409                TRACE_AND_STEP();
11410                push_long(*destreg);
11411            } else {
11412                u16 *destreg;
11413
11414                destreg = DECODE_RM_WORD_REGISTER(rl);
11415                DECODE_PRINTF("\n");
11416                TRACE_AND_STEP();
11417                push_word(*destreg);
11418            }
11419            break;
11420        }
11421        break;
11422    }
11423    DECODE_CLEAR_SEGOVR();
11424    END_OF_INSTR();
11425}
11426
11427/***************************************************************************
11428 * Single byte operation code table:
11429 **************************************************************************/
11430void (*x86emu_optab[256])(u8) =
11431{
11432/*  0x00 */ x86emuOp_add_byte_RM_R,
11433/*  0x01 */ x86emuOp_add_word_RM_R,
11434/*  0x02 */ x86emuOp_add_byte_R_RM,
11435/*  0x03 */ x86emuOp_add_word_R_RM,
11436/*  0x04 */ x86emuOp_add_byte_AL_IMM,
11437/*  0x05 */ x86emuOp_add_word_AX_IMM,
11438/*  0x06 */ x86emuOp_push_ES,
11439/*  0x07 */ x86emuOp_pop_ES,
11440
11441/*  0x08 */ x86emuOp_or_byte_RM_R,
11442/*  0x09 */ x86emuOp_or_word_RM_R,
11443/*  0x0a */ x86emuOp_or_byte_R_RM,
11444/*  0x0b */ x86emuOp_or_word_R_RM,
11445/*  0x0c */ x86emuOp_or_byte_AL_IMM,
11446/*  0x0d */ x86emuOp_or_word_AX_IMM,
11447/*  0x0e */ x86emuOp_push_CS,
11448/*  0x0f */ x86emuOp_two_byte,
11449
11450/*  0x10 */ x86emuOp_adc_byte_RM_R,
11451/*  0x11 */ x86emuOp_adc_word_RM_R,
11452/*  0x12 */ x86emuOp_adc_byte_R_RM,
11453/*  0x13 */ x86emuOp_adc_word_R_RM,
11454/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11455/*  0x15 */ x86emuOp_adc_word_AX_IMM,
11456/*  0x16 */ x86emuOp_push_SS,
11457/*  0x17 */ x86emuOp_pop_SS,
11458
11459/*  0x18 */ x86emuOp_sbb_byte_RM_R,
11460/*  0x19 */ x86emuOp_sbb_word_RM_R,
11461/*  0x1a */ x86emuOp_sbb_byte_R_RM,
11462/*  0x1b */ x86emuOp_sbb_word_R_RM,
11463/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11464/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11465/*  0x1e */ x86emuOp_push_DS,
11466/*  0x1f */ x86emuOp_pop_DS,
11467
11468/*  0x20 */ x86emuOp_and_byte_RM_R,
11469/*  0x21 */ x86emuOp_and_word_RM_R,
11470/*  0x22 */ x86emuOp_and_byte_R_RM,
11471/*  0x23 */ x86emuOp_and_word_R_RM,
11472/*  0x24 */ x86emuOp_and_byte_AL_IMM,
11473/*  0x25 */ x86emuOp_and_word_AX_IMM,
11474/*  0x26 */ x86emuOp_segovr_ES,
11475/*  0x27 */ x86emuOp_daa,
11476
11477/*  0x28 */ x86emuOp_sub_byte_RM_R,
11478/*  0x29 */ x86emuOp_sub_word_RM_R,
11479/*  0x2a */ x86emuOp_sub_byte_R_RM,
11480/*  0x2b */ x86emuOp_sub_word_R_RM,
11481/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11482/*  0x2d */ x86emuOp_sub_word_AX_IMM,
11483/*  0x2e */ x86emuOp_segovr_CS,
11484/*  0x2f */ x86emuOp_das,
11485
11486/*  0x30 */ x86emuOp_xor_byte_RM_R,
11487/*  0x31 */ x86emuOp_xor_word_RM_R,
11488/*  0x32 */ x86emuOp_xor_byte_R_RM,
11489/*  0x33 */ x86emuOp_xor_word_R_RM,
11490/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11491/*  0x35 */ x86emuOp_xor_word_AX_IMM,
11492/*  0x36 */ x86emuOp_segovr_SS,
11493/*  0x37 */ x86emuOp_aaa,
11494
11495/*  0x38 */ x86emuOp_cmp_byte_RM_R,
11496/*  0x39 */ x86emuOp_cmp_word_RM_R,
11497/*  0x3a */ x86emuOp_cmp_byte_R_RM,
11498/*  0x3b */ x86emuOp_cmp_word_R_RM,
11499/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11500/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11501/*  0x3e */ x86emuOp_segovr_DS,
11502/*  0x3f */ x86emuOp_aas,
11503
11504/*  0x40 */ x86emuOp_inc_AX,
11505/*  0x41 */ x86emuOp_inc_CX,
11506/*  0x42 */ x86emuOp_inc_DX,
11507/*  0x43 */ x86emuOp_inc_BX,
11508/*  0x44 */ x86emuOp_inc_SP,
11509/*  0x45 */ x86emuOp_inc_BP,
11510/*  0x46 */ x86emuOp_inc_SI,
11511/*  0x47 */ x86emuOp_inc_DI,
11512
11513/*  0x48 */ x86emuOp_dec_AX,
11514/*  0x49 */ x86emuOp_dec_CX,
11515/*  0x4a */ x86emuOp_dec_DX,
11516/*  0x4b */ x86emuOp_dec_BX,
11517/*  0x4c */ x86emuOp_dec_SP,
11518/*  0x4d */ x86emuOp_dec_BP,
11519/*  0x4e */ x86emuOp_dec_SI,
11520/*  0x4f */ x86emuOp_dec_DI,
11521
11522/*  0x50 */ x86emuOp_push_AX,
11523/*  0x51 */ x86emuOp_push_CX,
11524/*  0x52 */ x86emuOp_push_DX,
11525/*  0x53 */ x86emuOp_push_BX,
11526/*  0x54 */ x86emuOp_push_SP,
11527/*  0x55 */ x86emuOp_push_BP,
11528/*  0x56 */ x86emuOp_push_SI,
11529/*  0x57 */ x86emuOp_push_DI,
11530
11531/*  0x58 */ x86emuOp_pop_AX,
11532/*  0x59 */ x86emuOp_pop_CX,
11533/*  0x5a */ x86emuOp_pop_DX,
11534/*  0x5b */ x86emuOp_pop_BX,
11535/*  0x5c */ x86emuOp_pop_SP,
11536/*  0x5d */ x86emuOp_pop_BP,
11537/*  0x5e */ x86emuOp_pop_SI,
11538/*  0x5f */ x86emuOp_pop_DI,
11539
11540/*  0x60 */ x86emuOp_push_all,
11541/*  0x61 */ x86emuOp_pop_all,
11542/*  0x62 */ x86emuOp_illegal_op,   /* bound */
11543/*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11544/*  0x64 */ x86emuOp_segovr_FS,
11545/*  0x65 */ x86emuOp_segovr_GS,
11546/*  0x66 */ x86emuOp_prefix_data,
11547/*  0x67 */ x86emuOp_prefix_addr,
11548
11549/*  0x68 */ x86emuOp_push_word_IMM,
11550/*  0x69 */ x86emuOp_imul_word_IMM,
11551/*  0x6a */ x86emuOp_push_byte_IMM,
11552/*  0x6b */ x86emuOp_imul_byte_IMM,
11553/*  0x6c */ x86emuOp_ins_byte,
11554/*  0x6d */ x86emuOp_ins_word,
11555/*  0x6e */ x86emuOp_outs_byte,
11556/*  0x6f */ x86emuOp_outs_word,
11557
11558/*  0x70 */ x86emuOp_jump_near_O,
11559/*  0x71 */ x86emuOp_jump_near_NO,
11560/*  0x72 */ x86emuOp_jump_near_B,
11561/*  0x73 */ x86emuOp_jump_near_NB,
11562/*  0x74 */ x86emuOp_jump_near_Z,
11563/*  0x75 */ x86emuOp_jump_near_NZ,
11564/*  0x76 */ x86emuOp_jump_near_BE,
11565/*  0x77 */ x86emuOp_jump_near_NBE,
11566
11567/*  0x78 */ x86emuOp_jump_near_S,
11568/*  0x79 */ x86emuOp_jump_near_NS,
11569/*  0x7a */ x86emuOp_jump_near_P,
11570/*  0x7b */ x86emuOp_jump_near_NP,
11571/*  0x7c */ x86emuOp_jump_near_L,
11572/*  0x7d */ x86emuOp_jump_near_NL,
11573/*  0x7e */ x86emuOp_jump_near_LE,
11574/*  0x7f */ x86emuOp_jump_near_NLE,
11575
11576/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11577/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11578/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11579/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11580/*  0x84 */ x86emuOp_test_byte_RM_R,
11581/*  0x85 */ x86emuOp_test_word_RM_R,
11582/*  0x86 */ x86emuOp_xchg_byte_RM_R,
11583/*  0x87 */ x86emuOp_xchg_word_RM_R,
11584
11585/*  0x88 */ x86emuOp_mov_byte_RM_R,
11586/*  0x89 */ x86emuOp_mov_word_RM_R,
11587/*  0x8a */ x86emuOp_mov_byte_R_RM,
11588/*  0x8b */ x86emuOp_mov_word_R_RM,
11589/*  0x8c */ x86emuOp_mov_word_RM_SR,
11590/*  0x8d */ x86emuOp_lea_word_R_M,
11591/*  0x8e */ x86emuOp_mov_word_SR_RM,
11592/*  0x8f */ x86emuOp_pop_RM,
11593
11594/*  0x90 */ x86emuOp_nop,
11595/*  0x91 */ x86emuOp_xchg_word_AX_CX,
11596/*  0x92 */ x86emuOp_xchg_word_AX_DX,
11597/*  0x93 */ x86emuOp_xchg_word_AX_BX,
11598/*  0x94 */ x86emuOp_xchg_word_AX_SP,
11599/*  0x95 */ x86emuOp_xchg_word_AX_BP,
11600/*  0x96 */ x86emuOp_xchg_word_AX_SI,
11601/*  0x97 */ x86emuOp_xchg_word_AX_DI,
11602
11603/*  0x98 */ x86emuOp_cbw,
11604/*  0x99 */ x86emuOp_cwd,
11605/*  0x9a */ x86emuOp_call_far_IMM,
11606/*  0x9b */ x86emuOp_wait,
11607/*  0x9c */ x86emuOp_pushf_word,
11608/*  0x9d */ x86emuOp_popf_word,
11609/*  0x9e */ x86emuOp_sahf,
11610/*  0x9f */ x86emuOp_lahf,
11611
11612/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11613/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11614/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11615/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11616/*  0xa4 */ x86emuOp_movs_byte,
11617/*  0xa5 */ x86emuOp_movs_word,
11618/*  0xa6 */ x86emuOp_cmps_byte,
11619/*  0xa7 */ x86emuOp_cmps_word,
11620/*  0xa8 */ x86emuOp_test_AL_IMM,
11621/*  0xa9 */ x86emuOp_test_AX_IMM,
11622/*  0xaa */ x86emuOp_stos_byte,
11623/*  0xab */ x86emuOp_stos_word,
11624/*  0xac */ x86emuOp_lods_byte,
11625/*  0xad */ x86emuOp_lods_word,
11626/*  0xac */ x86emuOp_scas_byte,
11627/*  0xad */ x86emuOp_scas_word,
11628
11629
11630/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11631/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11632/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11633/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11634/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11635/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11636/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11637/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11638
11639/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11640/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11641/*  0xba */ x86emuOp_mov_word_DX_IMM,
11642/*  0xbb */ x86emuOp_mov_word_BX_IMM,
11643/*  0xbc */ x86emuOp_mov_word_SP_IMM,
11644/*  0xbd */ x86emuOp_mov_word_BP_IMM,
11645/*  0xbe */ x86emuOp_mov_word_SI_IMM,
11646/*  0xbf */ x86emuOp_mov_word_DI_IMM,
11647
11648/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11649/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11650/*  0xc2 */ x86emuOp_ret_near_IMM,
11651/*  0xc3 */ x86emuOp_ret_near,
11652/*  0xc4 */ x86emuOp_les_R_IMM,
11653/*  0xc5 */ x86emuOp_lds_R_IMM,
11654/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11655/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11656/*  0xc8 */ x86emuOp_enter,
11657/*  0xc9 */ x86emuOp_leave,
11658/*  0xca */ x86emuOp_ret_far_IMM,
11659/*  0xcb */ x86emuOp_ret_far,
11660/*  0xcc */ x86emuOp_int3,
11661/*  0xcd */ x86emuOp_int_IMM,
11662/*  0xce */ x86emuOp_into,
11663/*  0xcf */ x86emuOp_iret,
11664
11665/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11666/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11667/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11668/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11669/*  0xd4 */ x86emuOp_aam,
11670/*  0xd5 */ x86emuOp_aad,
11671/*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11672/*  0xd7 */ x86emuOp_xlat,
11673/*  0xd8 */ x86emuOp_esc_coprocess_d8,
11674/*  0xd9 */ x86emuOp_esc_coprocess_d9,
11675/*  0xda */ x86emuOp_esc_coprocess_da,
11676/*  0xdb */ x86emuOp_esc_coprocess_db,
11677/*  0xdc */ x86emuOp_esc_coprocess_dc,
11678/*  0xdd */ x86emuOp_esc_coprocess_dd,
11679/*  0xde */ x86emuOp_esc_coprocess_de,
11680/*  0xdf */ x86emuOp_esc_coprocess_df,
11681
11682/*  0xe0 */ x86emuOp_loopne,
11683/*  0xe1 */ x86emuOp_loope,
11684/*  0xe2 */ x86emuOp_loop,
11685/*  0xe3 */ x86emuOp_jcxz,
11686/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11687/*  0xe5 */ x86emuOp_in_word_AX_IMM,
11688/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11689/*  0xe7 */ x86emuOp_out_word_IMM_AX,
11690
11691/*  0xe8 */ x86emuOp_call_near_IMM,
11692/*  0xe9 */ x86emuOp_jump_near_IMM,
11693/*  0xea */ x86emuOp_jump_far_IMM,
11694/*  0xeb */ x86emuOp_jump_byte_IMM,
11695/*  0xec */ x86emuOp_in_byte_AL_DX,
11696/*  0xed */ x86emuOp_in_word_AX_DX,
11697/*  0xee */ x86emuOp_out_byte_DX_AL,
11698/*  0xef */ x86emuOp_out_word_DX_AX,
11699
11700/*  0xf0 */ x86emuOp_lock,
11701/*  0xf1 */ x86emuOp_illegal_op,
11702/*  0xf2 */ x86emuOp_repne,
11703/*  0xf3 */ x86emuOp_repe,
11704/*  0xf4 */ x86emuOp_halt,
11705/*  0xf5 */ x86emuOp_cmc,
11706/*  0xf6 */ x86emuOp_opcF6_byte_RM,
11707/*  0xf7 */ x86emuOp_opcF7_word_RM,
11708
11709/*  0xf8 */ x86emuOp_clc,
11710/*  0xf9 */ x86emuOp_stc,
11711/*  0xfa */ x86emuOp_cli,
11712/*  0xfb */ x86emuOp_sti,
11713/*  0xfc */ x86emuOp_cld,
11714/*  0xfd */ x86emuOp_std,
11715/*  0xfe */ x86emuOp_opcFE_byte_RM,
11716/*  0xff */ x86emuOp_opcFF_word_RM,
11717};
11718