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    DECODE_CLEAR_SEGOVR();
105    END_OF_INSTR();
106}
107
108/****************************************************************************
109REMARKS:
110Handles opcode 0x00
111****************************************************************************/
112static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113{
114    int mod, rl, rh;
115    uint destoffset;
116    u8 *destreg, *srcreg;
117    u8 destval;
118
119    START_OF_INSTR();
120    DECODE_PRINTF("ADD\t");
121    FETCH_DECODE_MODRM(mod, rh, rl);
122    switch (mod) {
123    case 0:
124        destoffset = decode_rm00_address(rl);
125        DECODE_PRINTF(",");
126        destval = fetch_data_byte(destoffset);
127        srcreg = DECODE_RM_BYTE_REGISTER(rh);
128        DECODE_PRINTF("\n");
129        TRACE_AND_STEP();
130        destval = add_byte(destval, *srcreg);
131        store_data_byte(destoffset, destval);
132        break;
133    case 1:
134        destoffset = decode_rm01_address(rl);
135        DECODE_PRINTF(",");
136        destval = fetch_data_byte(destoffset);
137        srcreg = DECODE_RM_BYTE_REGISTER(rh);
138        DECODE_PRINTF("\n");
139        TRACE_AND_STEP();
140        destval = add_byte(destval, *srcreg);
141        store_data_byte(destoffset, destval);
142        break;
143    case 2:
144        destoffset = decode_rm10_address(rl);
145        DECODE_PRINTF(",");
146        destval = fetch_data_byte(destoffset);
147        srcreg = DECODE_RM_BYTE_REGISTER(rh);
148        DECODE_PRINTF("\n");
149        TRACE_AND_STEP();
150        destval = add_byte(destval, *srcreg);
151        store_data_byte(destoffset, destval);
152        break;
153    case 3:                     /* register to register */
154        destreg = DECODE_RM_BYTE_REGISTER(rl);
155        DECODE_PRINTF(",");
156        srcreg = DECODE_RM_BYTE_REGISTER(rh);
157        DECODE_PRINTF("\n");
158        TRACE_AND_STEP();
159        *destreg = add_byte(*destreg, *srcreg);
160        break;
161    }
162    DECODE_CLEAR_SEGOVR();
163    END_OF_INSTR();
164}
165
166/****************************************************************************
167REMARKS:
168Handles opcode 0x01
169****************************************************************************/
170static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
171{
172    int mod, rl, rh;
173    uint destoffset;
174
175    START_OF_INSTR();
176    DECODE_PRINTF("ADD\t");
177    FETCH_DECODE_MODRM(mod, rh, rl);
178    switch (mod) {
179    case 0:
180        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
181            u32 destval;
182            u32 *srcreg;
183
184            destoffset = decode_rm00_address(rl);
185            DECODE_PRINTF(",");
186            destval = fetch_data_long(destoffset);
187            srcreg = DECODE_RM_LONG_REGISTER(rh);
188            DECODE_PRINTF("\n");
189            TRACE_AND_STEP();
190            destval = add_long(destval, *srcreg);
191            store_data_long(destoffset, destval);
192        } else {
193            u16 destval;
194            u16 *srcreg;
195
196            destoffset = decode_rm00_address(rl);
197            DECODE_PRINTF(",");
198            destval = fetch_data_word(destoffset);
199            srcreg = DECODE_RM_WORD_REGISTER(rh);
200            DECODE_PRINTF("\n");
201            TRACE_AND_STEP();
202            destval = add_word(destval, *srcreg);
203            store_data_word(destoffset, destval);
204        }
205        break;
206    case 1:
207        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
208            u32 destval;
209            u32 *srcreg;
210
211            destoffset = decode_rm01_address(rl);
212            DECODE_PRINTF(",");
213            destval = fetch_data_long(destoffset);
214            srcreg = DECODE_RM_LONG_REGISTER(rh);
215            DECODE_PRINTF("\n");
216            TRACE_AND_STEP();
217            destval = add_long(destval, *srcreg);
218            store_data_long(destoffset, destval);
219        } else {
220            u16 destval;
221            u16 *srcreg;
222
223            destoffset = decode_rm01_address(rl);
224            DECODE_PRINTF(",");
225            destval = fetch_data_word(destoffset);
226            srcreg = DECODE_RM_WORD_REGISTER(rh);
227            DECODE_PRINTF("\n");
228            TRACE_AND_STEP();
229            destval = add_word(destval, *srcreg);
230            store_data_word(destoffset, destval);
231        }
232        break;
233    case 2:
234        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
235            u32 destval;
236            u32 *srcreg;
237
238            destoffset = decode_rm10_address(rl);
239            DECODE_PRINTF(",");
240            destval = fetch_data_long(destoffset);
241            srcreg = DECODE_RM_LONG_REGISTER(rh);
242            DECODE_PRINTF("\n");
243            TRACE_AND_STEP();
244            destval = add_long(destval, *srcreg);
245            store_data_long(destoffset, destval);
246        } else {
247            u16 destval;
248            u16 *srcreg;
249
250            destoffset = decode_rm10_address(rl);
251            DECODE_PRINTF(",");
252            destval = fetch_data_word(destoffset);
253            srcreg = DECODE_RM_WORD_REGISTER(rh);
254            DECODE_PRINTF("\n");
255            TRACE_AND_STEP();
256            destval = add_word(destval, *srcreg);
257            store_data_word(destoffset, destval);
258        }
259        break;
260    case 3:                     /* register to register */
261        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
262            u32 *destreg,*srcreg;
263
264            destreg = DECODE_RM_LONG_REGISTER(rl);
265            DECODE_PRINTF(",");
266            srcreg = DECODE_RM_LONG_REGISTER(rh);
267            DECODE_PRINTF("\n");
268            TRACE_AND_STEP();
269            *destreg = add_long(*destreg, *srcreg);
270        } else {
271            u16 *destreg,*srcreg;
272
273            destreg = DECODE_RM_WORD_REGISTER(rl);
274            DECODE_PRINTF(",");
275            srcreg = DECODE_RM_WORD_REGISTER(rh);
276            DECODE_PRINTF("\n");
277            TRACE_AND_STEP();
278            *destreg = add_word(*destreg, *srcreg);
279        }
280        break;
281    }
282    DECODE_CLEAR_SEGOVR();
283    END_OF_INSTR();
284}
285
286/****************************************************************************
287REMARKS:
288Handles opcode 0x02
289****************************************************************************/
290static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
291{
292    int mod, rl, rh;
293    u8 *destreg, *srcreg;
294    uint srcoffset;
295    u8 srcval;
296
297    START_OF_INSTR();
298    DECODE_PRINTF("ADD\t");
299    FETCH_DECODE_MODRM(mod, rh, rl);
300    switch (mod) {
301    case 0:
302        destreg = DECODE_RM_BYTE_REGISTER(rh);
303        DECODE_PRINTF(",");
304        srcoffset = decode_rm00_address(rl);
305        srcval = fetch_data_byte(srcoffset);
306        DECODE_PRINTF("\n");
307        TRACE_AND_STEP();
308        *destreg = add_byte(*destreg, srcval);
309        break;
310    case 1:
311        destreg = DECODE_RM_BYTE_REGISTER(rh);
312        DECODE_PRINTF(",");
313        srcoffset = decode_rm01_address(rl);
314        srcval = fetch_data_byte(srcoffset);
315        DECODE_PRINTF("\n");
316        TRACE_AND_STEP();
317        *destreg = add_byte(*destreg, srcval);
318        break;
319    case 2:
320        destreg = DECODE_RM_BYTE_REGISTER(rh);
321        DECODE_PRINTF(",");
322        srcoffset = decode_rm10_address(rl);
323        srcval = fetch_data_byte(srcoffset);
324        DECODE_PRINTF("\n");
325        TRACE_AND_STEP();
326        *destreg = add_byte(*destreg, srcval);
327        break;
328    case 3:                     /* register to register */
329        destreg = DECODE_RM_BYTE_REGISTER(rh);
330        DECODE_PRINTF(",");
331        srcreg = DECODE_RM_BYTE_REGISTER(rl);
332        DECODE_PRINTF("\n");
333        TRACE_AND_STEP();
334        *destreg = add_byte(*destreg, *srcreg);
335        break;
336    }
337    DECODE_CLEAR_SEGOVR();
338    END_OF_INSTR();
339}
340
341/****************************************************************************
342REMARKS:
343Handles opcode 0x03
344****************************************************************************/
345static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
346{
347    int mod, rl, rh;
348    uint srcoffset;
349
350    START_OF_INSTR();
351    DECODE_PRINTF("ADD\t");
352    FETCH_DECODE_MODRM(mod, rh, rl);
353    switch (mod) {
354    case 0:
355        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
356            u32 *destreg;
357            u32 srcval;
358
359            destreg = DECODE_RM_LONG_REGISTER(rh);
360            DECODE_PRINTF(",");
361            srcoffset = decode_rm00_address(rl);
362            srcval = fetch_data_long(srcoffset);
363            DECODE_PRINTF("\n");
364            TRACE_AND_STEP();
365            *destreg = add_long(*destreg, srcval);
366        } else {
367            u16 *destreg;
368            u16 srcval;
369
370            destreg = DECODE_RM_WORD_REGISTER(rh);
371            DECODE_PRINTF(",");
372            srcoffset = decode_rm00_address(rl);
373            srcval = fetch_data_word(srcoffset);
374            DECODE_PRINTF("\n");
375            TRACE_AND_STEP();
376            *destreg = add_word(*destreg, srcval);
377        }
378        break;
379    case 1:
380        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
381            u32 *destreg;
382            u32 srcval;
383
384            destreg = DECODE_RM_LONG_REGISTER(rh);
385            DECODE_PRINTF(",");
386            srcoffset = decode_rm01_address(rl);
387            srcval = fetch_data_long(srcoffset);
388            DECODE_PRINTF("\n");
389            TRACE_AND_STEP();
390            *destreg = add_long(*destreg, srcval);
391        } else {
392            u16 *destreg;
393            u16 srcval;
394
395            destreg = DECODE_RM_WORD_REGISTER(rh);
396            DECODE_PRINTF(",");
397            srcoffset = decode_rm01_address(rl);
398            srcval = fetch_data_word(srcoffset);
399            DECODE_PRINTF("\n");
400            TRACE_AND_STEP();
401            *destreg = add_word(*destreg, srcval);
402        }
403        break;
404    case 2:
405        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
406            u32 *destreg;
407            u32 srcval;
408
409            destreg = DECODE_RM_LONG_REGISTER(rh);
410            DECODE_PRINTF(",");
411            srcoffset = decode_rm10_address(rl);
412            srcval = fetch_data_long(srcoffset);
413            DECODE_PRINTF("\n");
414            TRACE_AND_STEP();
415            *destreg = add_long(*destreg, srcval);
416        } else {
417            u16 *destreg;
418            u16 srcval;
419
420            destreg = DECODE_RM_WORD_REGISTER(rh);
421            DECODE_PRINTF(",");
422            srcoffset = decode_rm10_address(rl);
423            srcval = fetch_data_word(srcoffset);
424            DECODE_PRINTF("\n");
425            TRACE_AND_STEP();
426            *destreg = add_word(*destreg, srcval);
427        }
428        break;
429    case 3:                     /* register to register */
430        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
431            u32 *destreg,*srcreg;
432
433            destreg = DECODE_RM_LONG_REGISTER(rh);
434            DECODE_PRINTF(",");
435            srcreg = DECODE_RM_LONG_REGISTER(rl);
436            DECODE_PRINTF("\n");
437            TRACE_AND_STEP();
438            *destreg = add_long(*destreg, *srcreg);
439        } else {
440            u16 *destreg,*srcreg;
441
442            destreg = DECODE_RM_WORD_REGISTER(rh);
443            DECODE_PRINTF(",");
444            srcreg = DECODE_RM_WORD_REGISTER(rl);
445            DECODE_PRINTF("\n");
446            TRACE_AND_STEP();
447            *destreg = add_word(*destreg, *srcreg);
448        }
449        break;
450    }
451    DECODE_CLEAR_SEGOVR();
452    END_OF_INSTR();
453}
454
455/****************************************************************************
456REMARKS:
457Handles opcode 0x04
458****************************************************************************/
459static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
460{
461    u8 srcval;
462
463    START_OF_INSTR();
464    DECODE_PRINTF("ADD\tAL,");
465    srcval = fetch_byte_imm();
466    DECODE_PRINTF2("%x\n", srcval);
467    TRACE_AND_STEP();
468    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
469    DECODE_CLEAR_SEGOVR();
470    END_OF_INSTR();
471}
472
473/****************************************************************************
474REMARKS:
475Handles opcode 0x05
476****************************************************************************/
477static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
478{
479    u32 srcval;
480
481    START_OF_INSTR();
482    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
483        DECODE_PRINTF("ADD\tEAX,");
484        srcval = fetch_long_imm();
485    } else {
486        DECODE_PRINTF("ADD\tAX,");
487        srcval = fetch_word_imm();
488    }
489    DECODE_PRINTF2("%x\n", srcval);
490    TRACE_AND_STEP();
491    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
492        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
493    } else {
494        M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
495    }
496    DECODE_CLEAR_SEGOVR();
497    END_OF_INSTR();
498}
499
500/****************************************************************************
501REMARKS:
502Handles opcode 0x06
503****************************************************************************/
504static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
505{
506    START_OF_INSTR();
507    DECODE_PRINTF("PUSH\tES\n");
508    TRACE_AND_STEP();
509    push_word(M.x86.R_ES);
510    DECODE_CLEAR_SEGOVR();
511    END_OF_INSTR();
512}
513
514/****************************************************************************
515REMARKS:
516Handles opcode 0x07
517****************************************************************************/
518static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
519{
520    START_OF_INSTR();
521    DECODE_PRINTF("POP\tES\n");
522    TRACE_AND_STEP();
523    M.x86.R_ES = pop_word();
524    DECODE_CLEAR_SEGOVR();
525    END_OF_INSTR();
526}
527
528/****************************************************************************
529REMARKS:
530Handles opcode 0x08
531****************************************************************************/
532static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
533{
534    int mod, rl, rh;
535    u8 *destreg, *srcreg;
536    uint destoffset;
537    u8 destval;
538
539    START_OF_INSTR();
540    DECODE_PRINTF("OR\t");
541    FETCH_DECODE_MODRM(mod, rh, rl);
542    switch (mod) {
543    case 0:
544        destoffset = decode_rm00_address(rl);
545        DECODE_PRINTF(",");
546        destval = fetch_data_byte(destoffset);
547        srcreg = DECODE_RM_BYTE_REGISTER(rh);
548        DECODE_PRINTF("\n");
549        TRACE_AND_STEP();
550        destval = or_byte(destval, *srcreg);
551        store_data_byte(destoffset, destval);
552        break;
553    case 1:
554        destoffset = decode_rm01_address(rl);
555        DECODE_PRINTF(",");
556        destval = fetch_data_byte(destoffset);
557        srcreg = DECODE_RM_BYTE_REGISTER(rh);
558        DECODE_PRINTF("\n");
559        TRACE_AND_STEP();
560        destval = or_byte(destval, *srcreg);
561        store_data_byte(destoffset, destval);
562        break;
563    case 2:
564        destoffset = decode_rm10_address(rl);
565        DECODE_PRINTF(",");
566        destval = fetch_data_byte(destoffset);
567        srcreg = DECODE_RM_BYTE_REGISTER(rh);
568        DECODE_PRINTF("\n");
569        TRACE_AND_STEP();
570        destval = or_byte(destval, *srcreg);
571        store_data_byte(destoffset, destval);
572        break;
573    case 3:                     /* register to register */
574        destreg = DECODE_RM_BYTE_REGISTER(rl);
575        DECODE_PRINTF(",");
576        srcreg = DECODE_RM_BYTE_REGISTER(rh);
577        DECODE_PRINTF("\n");
578        TRACE_AND_STEP();
579        *destreg = or_byte(*destreg, *srcreg);
580        break;
581    }
582    DECODE_CLEAR_SEGOVR();
583    END_OF_INSTR();
584}
585
586/****************************************************************************
587REMARKS:
588Handles opcode 0x09
589****************************************************************************/
590static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
591{
592    int mod, rl, rh;
593    uint destoffset;
594
595    START_OF_INSTR();
596    DECODE_PRINTF("OR\t");
597    FETCH_DECODE_MODRM(mod, rh, rl);
598    switch (mod) {
599    case 0:
600        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
601            u32 destval;
602            u32 *srcreg;
603
604            destoffset = decode_rm00_address(rl);
605            DECODE_PRINTF(",");
606            destval = fetch_data_long(destoffset);
607            srcreg = DECODE_RM_LONG_REGISTER(rh);
608            DECODE_PRINTF("\n");
609            TRACE_AND_STEP();
610            destval = or_long(destval, *srcreg);
611            store_data_long(destoffset, destval);
612        } else {
613            u16 destval;
614            u16 *srcreg;
615
616            destoffset = decode_rm00_address(rl);
617            DECODE_PRINTF(",");
618            destval = fetch_data_word(destoffset);
619            srcreg = DECODE_RM_WORD_REGISTER(rh);
620            DECODE_PRINTF("\n");
621            TRACE_AND_STEP();
622            destval = or_word(destval, *srcreg);
623            store_data_word(destoffset, destval);
624        }
625        break;
626    case 1:
627        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
628            u32 destval;
629            u32 *srcreg;
630
631            destoffset = decode_rm01_address(rl);
632            DECODE_PRINTF(",");
633            destval = fetch_data_long(destoffset);
634            srcreg = DECODE_RM_LONG_REGISTER(rh);
635            DECODE_PRINTF("\n");
636            TRACE_AND_STEP();
637            destval = or_long(destval, *srcreg);
638            store_data_long(destoffset, destval);
639        } else {
640            u16 destval;
641            u16 *srcreg;
642
643            destoffset = decode_rm01_address(rl);
644            DECODE_PRINTF(",");
645            destval = fetch_data_word(destoffset);
646            srcreg = DECODE_RM_WORD_REGISTER(rh);
647            DECODE_PRINTF("\n");
648            TRACE_AND_STEP();
649            destval = or_word(destval, *srcreg);
650            store_data_word(destoffset, destval);
651        }
652        break;
653    case 2:
654        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
655            u32 destval;
656            u32 *srcreg;
657
658            destoffset = decode_rm10_address(rl);
659            DECODE_PRINTF(",");
660            destval = fetch_data_long(destoffset);
661            srcreg = DECODE_RM_LONG_REGISTER(rh);
662            DECODE_PRINTF("\n");
663            TRACE_AND_STEP();
664            destval = or_long(destval, *srcreg);
665            store_data_long(destoffset, destval);
666        } else {
667            u16 destval;
668            u16 *srcreg;
669
670            destoffset = decode_rm10_address(rl);
671            DECODE_PRINTF(",");
672            destval = fetch_data_word(destoffset);
673            srcreg = DECODE_RM_WORD_REGISTER(rh);
674            DECODE_PRINTF("\n");
675            TRACE_AND_STEP();
676            destval = or_word(destval, *srcreg);
677            store_data_word(destoffset, destval);
678        }
679        break;
680    case 3:                     /* register to register */
681        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
682            u32 *destreg,*srcreg;
683
684            destreg = DECODE_RM_LONG_REGISTER(rl);
685            DECODE_PRINTF(",");
686            srcreg = DECODE_RM_LONG_REGISTER(rh);
687            DECODE_PRINTF("\n");
688            TRACE_AND_STEP();
689            *destreg = or_long(*destreg, *srcreg);
690        } else {
691            u16 *destreg,*srcreg;
692
693            destreg = DECODE_RM_WORD_REGISTER(rl);
694            DECODE_PRINTF(",");
695            srcreg = DECODE_RM_WORD_REGISTER(rh);
696            DECODE_PRINTF("\n");
697            TRACE_AND_STEP();
698            *destreg = or_word(*destreg, *srcreg);
699        }
700        break;
701    }
702    DECODE_CLEAR_SEGOVR();
703    END_OF_INSTR();
704}
705
706/****************************************************************************
707REMARKS:
708Handles opcode 0x0a
709****************************************************************************/
710static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
711{
712    int mod, rl, rh;
713    u8 *destreg, *srcreg;
714    uint srcoffset;
715    u8 srcval;
716
717    START_OF_INSTR();
718    DECODE_PRINTF("OR\t");
719    FETCH_DECODE_MODRM(mod, rh, rl);
720    switch (mod) {
721    case 0:
722        destreg = DECODE_RM_BYTE_REGISTER(rh);
723        DECODE_PRINTF(",");
724        srcoffset = decode_rm00_address(rl);
725        srcval = fetch_data_byte(srcoffset);
726        DECODE_PRINTF("\n");
727        TRACE_AND_STEP();
728        *destreg = or_byte(*destreg, srcval);
729        break;
730    case 1:
731        destreg = DECODE_RM_BYTE_REGISTER(rh);
732        DECODE_PRINTF(",");
733        srcoffset = decode_rm01_address(rl);
734        srcval = fetch_data_byte(srcoffset);
735        DECODE_PRINTF("\n");
736        TRACE_AND_STEP();
737        *destreg = or_byte(*destreg, srcval);
738        break;
739    case 2:
740        destreg = DECODE_RM_BYTE_REGISTER(rh);
741        DECODE_PRINTF(",");
742        srcoffset = decode_rm10_address(rl);
743        srcval = fetch_data_byte(srcoffset);
744        DECODE_PRINTF("\n");
745        TRACE_AND_STEP();
746        *destreg = or_byte(*destreg, srcval);
747        break;
748    case 3:                     /* register to register */
749        destreg = DECODE_RM_BYTE_REGISTER(rh);
750        DECODE_PRINTF(",");
751        srcreg = DECODE_RM_BYTE_REGISTER(rl);
752        DECODE_PRINTF("\n");
753        TRACE_AND_STEP();
754        *destreg = or_byte(*destreg, *srcreg);
755        break;
756    }
757    DECODE_CLEAR_SEGOVR();
758    END_OF_INSTR();
759}
760
761/****************************************************************************
762REMARKS:
763Handles opcode 0x0b
764****************************************************************************/
765static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
766{
767    int mod, rl, rh;
768    uint srcoffset;
769
770    START_OF_INSTR();
771    DECODE_PRINTF("OR\t");
772    FETCH_DECODE_MODRM(mod, rh, rl);
773    switch (mod) {
774    case 0:
775        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
776            u32 *destreg;
777            u32 srcval;
778
779            destreg = DECODE_RM_LONG_REGISTER(rh);
780            DECODE_PRINTF(",");
781            srcoffset = decode_rm00_address(rl);
782            srcval = fetch_data_long(srcoffset);
783            DECODE_PRINTF("\n");
784            TRACE_AND_STEP();
785            *destreg = or_long(*destreg, srcval);
786        } else {
787            u16 *destreg;
788            u16 srcval;
789
790            destreg = DECODE_RM_WORD_REGISTER(rh);
791            DECODE_PRINTF(",");
792            srcoffset = decode_rm00_address(rl);
793            srcval = fetch_data_word(srcoffset);
794            DECODE_PRINTF("\n");
795            TRACE_AND_STEP();
796            *destreg = or_word(*destreg, srcval);
797        }
798        break;
799    case 1:
800        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801            u32 *destreg;
802            u32 srcval;
803
804            destreg = DECODE_RM_LONG_REGISTER(rh);
805            DECODE_PRINTF(",");
806            srcoffset = decode_rm01_address(rl);
807            srcval = fetch_data_long(srcoffset);
808            DECODE_PRINTF("\n");
809            TRACE_AND_STEP();
810            *destreg = or_long(*destreg, srcval);
811        } else {
812            u16 *destreg;
813            u16 srcval;
814
815            destreg = DECODE_RM_WORD_REGISTER(rh);
816            DECODE_PRINTF(",");
817            srcoffset = decode_rm01_address(rl);
818            srcval = fetch_data_word(srcoffset);
819            DECODE_PRINTF("\n");
820            TRACE_AND_STEP();
821            *destreg = or_word(*destreg, srcval);
822        }
823        break;
824    case 2:
825        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
826            u32 *destreg;
827            u32 srcval;
828
829            destreg = DECODE_RM_LONG_REGISTER(rh);
830            DECODE_PRINTF(",");
831            srcoffset = decode_rm10_address(rl);
832            srcval = fetch_data_long(srcoffset);
833            DECODE_PRINTF("\n");
834            TRACE_AND_STEP();
835            *destreg = or_long(*destreg, srcval);
836        } else {
837            u16 *destreg;
838            u16 srcval;
839
840            destreg = DECODE_RM_WORD_REGISTER(rh);
841            DECODE_PRINTF(",");
842            srcoffset = decode_rm10_address(rl);
843            srcval = fetch_data_word(srcoffset);
844            DECODE_PRINTF("\n");
845            TRACE_AND_STEP();
846            *destreg = or_word(*destreg, srcval);
847        }
848        break;
849    case 3:                     /* register to register */
850        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
851            u32 *destreg,*srcreg;
852
853            destreg = DECODE_RM_LONG_REGISTER(rh);
854            DECODE_PRINTF(",");
855            srcreg = DECODE_RM_LONG_REGISTER(rl);
856            DECODE_PRINTF("\n");
857            TRACE_AND_STEP();
858            *destreg = or_long(*destreg, *srcreg);
859        } else {
860            u16 *destreg,*srcreg;
861
862            destreg = DECODE_RM_WORD_REGISTER(rh);
863            DECODE_PRINTF(",");
864            srcreg = DECODE_RM_WORD_REGISTER(rl);
865            DECODE_PRINTF("\n");
866            TRACE_AND_STEP();
867            *destreg = or_word(*destreg, *srcreg);
868        }
869        break;
870    }
871    DECODE_CLEAR_SEGOVR();
872    END_OF_INSTR();
873}
874
875/****************************************************************************
876REMARKS:
877Handles opcode 0x0c
878****************************************************************************/
879static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
880{
881    u8 srcval;
882
883    START_OF_INSTR();
884    DECODE_PRINTF("OR\tAL,");
885    srcval = fetch_byte_imm();
886    DECODE_PRINTF2("%x\n", srcval);
887    TRACE_AND_STEP();
888    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
889    DECODE_CLEAR_SEGOVR();
890    END_OF_INSTR();
891}
892
893/****************************************************************************
894REMARKS:
895Handles opcode 0x0d
896****************************************************************************/
897static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
898{
899    u32 srcval;
900
901    START_OF_INSTR();
902    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
903        DECODE_PRINTF("OR\tEAX,");
904        srcval = fetch_long_imm();
905    } else {
906        DECODE_PRINTF("OR\tAX,");
907        srcval = fetch_word_imm();
908    }
909    DECODE_PRINTF2("%x\n", srcval);
910    TRACE_AND_STEP();
911    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
912        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
913    } else {
914        M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
915    }
916    DECODE_CLEAR_SEGOVR();
917    END_OF_INSTR();
918}
919
920/****************************************************************************
921REMARKS:
922Handles opcode 0x0e
923****************************************************************************/
924static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
925{
926    START_OF_INSTR();
927    DECODE_PRINTF("PUSH\tCS\n");
928    TRACE_AND_STEP();
929    push_word(M.x86.R_CS);
930    DECODE_CLEAR_SEGOVR();
931    END_OF_INSTR();
932}
933
934/****************************************************************************
935REMARKS:
936Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
937****************************************************************************/
938static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
939{
940    u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
941    INC_DECODED_INST_LEN(1);
942    (*x86emu_optab2[op2])(op2);
943}
944
945/****************************************************************************
946REMARKS:
947Handles opcode 0x10
948****************************************************************************/
949static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
950{
951    int mod, rl, rh;
952    u8 *destreg, *srcreg;
953    uint destoffset;
954    u8 destval;
955
956    START_OF_INSTR();
957    DECODE_PRINTF("ADC\t");
958    FETCH_DECODE_MODRM(mod, rh, rl);
959    switch (mod) {
960    case 0:
961        destoffset = decode_rm00_address(rl);
962        DECODE_PRINTF(",");
963        destval = fetch_data_byte(destoffset);
964        srcreg = DECODE_RM_BYTE_REGISTER(rh);
965        DECODE_PRINTF("\n");
966        TRACE_AND_STEP();
967        destval = adc_byte(destval, *srcreg);
968        store_data_byte(destoffset, destval);
969        break;
970    case 1:
971        destoffset = decode_rm01_address(rl);
972        DECODE_PRINTF(",");
973        destval = fetch_data_byte(destoffset);
974        srcreg = DECODE_RM_BYTE_REGISTER(rh);
975        DECODE_PRINTF("\n");
976        TRACE_AND_STEP();
977        destval = adc_byte(destval, *srcreg);
978        store_data_byte(destoffset, destval);
979        break;
980    case 2:
981        destoffset = decode_rm10_address(rl);
982        DECODE_PRINTF(",");
983        destval = fetch_data_byte(destoffset);
984        srcreg = DECODE_RM_BYTE_REGISTER(rh);
985        DECODE_PRINTF("\n");
986        TRACE_AND_STEP();
987        destval = adc_byte(destval, *srcreg);
988        store_data_byte(destoffset, destval);
989        break;
990    case 3:                     /* register to register */
991        destreg = DECODE_RM_BYTE_REGISTER(rl);
992        DECODE_PRINTF(",");
993        srcreg = DECODE_RM_BYTE_REGISTER(rh);
994        DECODE_PRINTF("\n");
995        TRACE_AND_STEP();
996        *destreg = adc_byte(*destreg, *srcreg);
997        break;
998    }
999    DECODE_CLEAR_SEGOVR();
1000    END_OF_INSTR();
1001}
1002
1003/****************************************************************************
1004REMARKS:
1005Handles opcode 0x11
1006****************************************************************************/
1007static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1008{
1009    int mod, rl, rh;
1010    uint destoffset;
1011
1012    START_OF_INSTR();
1013    DECODE_PRINTF("ADC\t");
1014    FETCH_DECODE_MODRM(mod, rh, rl);
1015    switch (mod) {
1016    case 0:
1017        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1018            u32 destval;
1019            u32 *srcreg;
1020
1021            destoffset = decode_rm00_address(rl);
1022            DECODE_PRINTF(",");
1023            destval = fetch_data_long(destoffset);
1024            srcreg = DECODE_RM_LONG_REGISTER(rh);
1025            DECODE_PRINTF("\n");
1026            TRACE_AND_STEP();
1027            destval = adc_long(destval, *srcreg);
1028            store_data_long(destoffset, destval);
1029        } else {
1030            u16 destval;
1031            u16 *srcreg;
1032
1033            destoffset = decode_rm00_address(rl);
1034            DECODE_PRINTF(",");
1035            destval = fetch_data_word(destoffset);
1036            srcreg = DECODE_RM_WORD_REGISTER(rh);
1037            DECODE_PRINTF("\n");
1038            TRACE_AND_STEP();
1039            destval = adc_word(destval, *srcreg);
1040            store_data_word(destoffset, destval);
1041        }
1042        break;
1043    case 1:
1044        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1045            u32 destval;
1046            u32 *srcreg;
1047
1048            destoffset = decode_rm01_address(rl);
1049            DECODE_PRINTF(",");
1050            destval = fetch_data_long(destoffset);
1051            srcreg = DECODE_RM_LONG_REGISTER(rh);
1052            DECODE_PRINTF("\n");
1053            TRACE_AND_STEP();
1054            destval = adc_long(destval, *srcreg);
1055            store_data_long(destoffset, destval);
1056        } else {
1057            u16 destval;
1058            u16 *srcreg;
1059
1060            destoffset = decode_rm01_address(rl);
1061            DECODE_PRINTF(",");
1062            destval = fetch_data_word(destoffset);
1063            srcreg = DECODE_RM_WORD_REGISTER(rh);
1064            DECODE_PRINTF("\n");
1065            TRACE_AND_STEP();
1066            destval = adc_word(destval, *srcreg);
1067            store_data_word(destoffset, destval);
1068        }
1069        break;
1070    case 2:
1071        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1072            u32 destval;
1073            u32 *srcreg;
1074
1075            destoffset = decode_rm10_address(rl);
1076            DECODE_PRINTF(",");
1077            destval = fetch_data_long(destoffset);
1078            srcreg = DECODE_RM_LONG_REGISTER(rh);
1079            DECODE_PRINTF("\n");
1080            TRACE_AND_STEP();
1081            destval = adc_long(destval, *srcreg);
1082            store_data_long(destoffset, destval);
1083        } else {
1084            u16 destval;
1085            u16 *srcreg;
1086
1087            destoffset = decode_rm10_address(rl);
1088            DECODE_PRINTF(",");
1089            destval = fetch_data_word(destoffset);
1090            srcreg = DECODE_RM_WORD_REGISTER(rh);
1091            DECODE_PRINTF("\n");
1092            TRACE_AND_STEP();
1093            destval = adc_word(destval, *srcreg);
1094            store_data_word(destoffset, destval);
1095        }
1096        break;
1097    case 3:                     /* register to register */
1098        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1099            u32 *destreg,*srcreg;
1100
1101            destreg = DECODE_RM_LONG_REGISTER(rl);
1102            DECODE_PRINTF(",");
1103            srcreg = DECODE_RM_LONG_REGISTER(rh);
1104            DECODE_PRINTF("\n");
1105            TRACE_AND_STEP();
1106            *destreg = adc_long(*destreg, *srcreg);
1107        } else {
1108            u16 *destreg,*srcreg;
1109
1110            destreg = DECODE_RM_WORD_REGISTER(rl);
1111            DECODE_PRINTF(",");
1112            srcreg = DECODE_RM_WORD_REGISTER(rh);
1113            DECODE_PRINTF("\n");
1114            TRACE_AND_STEP();
1115            *destreg = adc_word(*destreg, *srcreg);
1116        }
1117        break;
1118    }
1119    DECODE_CLEAR_SEGOVR();
1120    END_OF_INSTR();
1121}
1122
1123/****************************************************************************
1124REMARKS:
1125Handles opcode 0x12
1126****************************************************************************/
1127static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1128{
1129    int mod, rl, rh;
1130    u8 *destreg, *srcreg;
1131    uint srcoffset;
1132    u8 srcval;
1133
1134    START_OF_INSTR();
1135    DECODE_PRINTF("ADC\t");
1136    FETCH_DECODE_MODRM(mod, rh, rl);
1137    switch (mod) {
1138    case 0:
1139        destreg = DECODE_RM_BYTE_REGISTER(rh);
1140        DECODE_PRINTF(",");
1141        srcoffset = decode_rm00_address(rl);
1142        srcval = fetch_data_byte(srcoffset);
1143        DECODE_PRINTF("\n");
1144        TRACE_AND_STEP();
1145        *destreg = adc_byte(*destreg, srcval);
1146        break;
1147    case 1:
1148        destreg = DECODE_RM_BYTE_REGISTER(rh);
1149        DECODE_PRINTF(",");
1150        srcoffset = decode_rm01_address(rl);
1151        srcval = fetch_data_byte(srcoffset);
1152        DECODE_PRINTF("\n");
1153        TRACE_AND_STEP();
1154        *destreg = adc_byte(*destreg, srcval);
1155        break;
1156    case 2:
1157        destreg = DECODE_RM_BYTE_REGISTER(rh);
1158        DECODE_PRINTF(",");
1159        srcoffset = decode_rm10_address(rl);
1160        srcval = fetch_data_byte(srcoffset);
1161        DECODE_PRINTF("\n");
1162        TRACE_AND_STEP();
1163        *destreg = adc_byte(*destreg, srcval);
1164        break;
1165    case 3:                     /* register to register */
1166        destreg = DECODE_RM_BYTE_REGISTER(rh);
1167        DECODE_PRINTF(",");
1168        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1169        DECODE_PRINTF("\n");
1170        TRACE_AND_STEP();
1171        *destreg = adc_byte(*destreg, *srcreg);
1172        break;
1173    }
1174    DECODE_CLEAR_SEGOVR();
1175    END_OF_INSTR();
1176}
1177
1178/****************************************************************************
1179REMARKS:
1180Handles opcode 0x13
1181****************************************************************************/
1182static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1183{
1184    int mod, rl, rh;
1185    uint srcoffset;
1186
1187    START_OF_INSTR();
1188    DECODE_PRINTF("ADC\t");
1189    FETCH_DECODE_MODRM(mod, rh, rl);
1190    switch (mod) {
1191    case 0:
1192        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1193            u32 *destreg;
1194            u32 srcval;
1195
1196            destreg = DECODE_RM_LONG_REGISTER(rh);
1197            DECODE_PRINTF(",");
1198            srcoffset = decode_rm00_address(rl);
1199            srcval = fetch_data_long(srcoffset);
1200            DECODE_PRINTF("\n");
1201            TRACE_AND_STEP();
1202            *destreg = adc_long(*destreg, srcval);
1203        } else {
1204            u16 *destreg;
1205            u16 srcval;
1206
1207            destreg = DECODE_RM_WORD_REGISTER(rh);
1208            DECODE_PRINTF(",");
1209            srcoffset = decode_rm00_address(rl);
1210            srcval = fetch_data_word(srcoffset);
1211            DECODE_PRINTF("\n");
1212            TRACE_AND_STEP();
1213            *destreg = adc_word(*destreg, srcval);
1214        }
1215        break;
1216    case 1:
1217        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1218            u32 *destreg;
1219            u32 srcval;
1220
1221            destreg = DECODE_RM_LONG_REGISTER(rh);
1222            DECODE_PRINTF(",");
1223            srcoffset = decode_rm01_address(rl);
1224            srcval = fetch_data_long(srcoffset);
1225            DECODE_PRINTF("\n");
1226            TRACE_AND_STEP();
1227            *destreg = adc_long(*destreg, srcval);
1228        } else {
1229            u16 *destreg;
1230            u16 srcval;
1231
1232            destreg = DECODE_RM_WORD_REGISTER(rh);
1233            DECODE_PRINTF(",");
1234            srcoffset = decode_rm01_address(rl);
1235            srcval = fetch_data_word(srcoffset);
1236            DECODE_PRINTF("\n");
1237            TRACE_AND_STEP();
1238            *destreg = adc_word(*destreg, srcval);
1239        }
1240        break;
1241    case 2:
1242        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1243            u32 *destreg;
1244            u32 srcval;
1245
1246            destreg = DECODE_RM_LONG_REGISTER(rh);
1247            DECODE_PRINTF(",");
1248            srcoffset = decode_rm10_address(rl);
1249            srcval = fetch_data_long(srcoffset);
1250            DECODE_PRINTF("\n");
1251            TRACE_AND_STEP();
1252            *destreg = adc_long(*destreg, srcval);
1253        } else {
1254            u16 *destreg;
1255            u16 srcval;
1256
1257            destreg = DECODE_RM_WORD_REGISTER(rh);
1258            DECODE_PRINTF(",");
1259            srcoffset = decode_rm10_address(rl);
1260            srcval = fetch_data_word(srcoffset);
1261            DECODE_PRINTF("\n");
1262            TRACE_AND_STEP();
1263            *destreg = adc_word(*destreg, srcval);
1264        }
1265        break;
1266    case 3:                     /* register to register */
1267        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1268            u32 *destreg,*srcreg;
1269
1270            destreg = DECODE_RM_LONG_REGISTER(rh);
1271            DECODE_PRINTF(",");
1272            srcreg = DECODE_RM_LONG_REGISTER(rl);
1273            DECODE_PRINTF("\n");
1274            TRACE_AND_STEP();
1275            *destreg = adc_long(*destreg, *srcreg);
1276        } else {
1277            u16 *destreg,*srcreg;
1278
1279            destreg = DECODE_RM_WORD_REGISTER(rh);
1280            DECODE_PRINTF(",");
1281            srcreg = DECODE_RM_WORD_REGISTER(rl);
1282            DECODE_PRINTF("\n");
1283            TRACE_AND_STEP();
1284            *destreg = adc_word(*destreg, *srcreg);
1285        }
1286        break;
1287    }
1288    DECODE_CLEAR_SEGOVR();
1289    END_OF_INSTR();
1290}
1291
1292/****************************************************************************
1293REMARKS:
1294Handles opcode 0x14
1295****************************************************************************/
1296static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1297{
1298    u8 srcval;
1299
1300    START_OF_INSTR();
1301    DECODE_PRINTF("ADC\tAL,");
1302    srcval = fetch_byte_imm();
1303    DECODE_PRINTF2("%x\n", srcval);
1304    TRACE_AND_STEP();
1305    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1306    DECODE_CLEAR_SEGOVR();
1307    END_OF_INSTR();
1308}
1309
1310/****************************************************************************
1311REMARKS:
1312Handles opcode 0x15
1313****************************************************************************/
1314static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1315{
1316    u32 srcval;
1317
1318    START_OF_INSTR();
1319    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1320        DECODE_PRINTF("ADC\tEAX,");
1321        srcval = fetch_long_imm();
1322    } else {
1323        DECODE_PRINTF("ADC\tAX,");
1324        srcval = fetch_word_imm();
1325    }
1326    DECODE_PRINTF2("%x\n", srcval);
1327    TRACE_AND_STEP();
1328    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1329        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1330    } else {
1331        M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1332    }
1333    DECODE_CLEAR_SEGOVR();
1334    END_OF_INSTR();
1335}
1336
1337/****************************************************************************
1338REMARKS:
1339Handles opcode 0x16
1340****************************************************************************/
1341static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1342{
1343    START_OF_INSTR();
1344    DECODE_PRINTF("PUSH\tSS\n");
1345    TRACE_AND_STEP();
1346    push_word(M.x86.R_SS);
1347    DECODE_CLEAR_SEGOVR();
1348    END_OF_INSTR();
1349}
1350
1351/****************************************************************************
1352REMARKS:
1353Handles opcode 0x17
1354****************************************************************************/
1355static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1356{
1357    START_OF_INSTR();
1358    DECODE_PRINTF("POP\tSS\n");
1359    TRACE_AND_STEP();
1360    M.x86.R_SS = pop_word();
1361    DECODE_CLEAR_SEGOVR();
1362    END_OF_INSTR();
1363}
1364
1365/****************************************************************************
1366REMARKS:
1367Handles opcode 0x18
1368****************************************************************************/
1369static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1370{
1371    int mod, rl, rh;
1372    u8 *destreg, *srcreg;
1373    uint destoffset;
1374    u8 destval;
1375
1376    START_OF_INSTR();
1377    DECODE_PRINTF("SBB\t");
1378    FETCH_DECODE_MODRM(mod, rh, rl);
1379    switch (mod) {
1380    case 0:
1381        destoffset = decode_rm00_address(rl);
1382        DECODE_PRINTF(",");
1383        destval = fetch_data_byte(destoffset);
1384        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1385        DECODE_PRINTF("\n");
1386        TRACE_AND_STEP();
1387        destval = sbb_byte(destval, *srcreg);
1388        store_data_byte(destoffset, destval);
1389        break;
1390    case 1:
1391        destoffset = decode_rm01_address(rl);
1392        DECODE_PRINTF(",");
1393        destval = fetch_data_byte(destoffset);
1394        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1395        DECODE_PRINTF("\n");
1396        TRACE_AND_STEP();
1397        destval = sbb_byte(destval, *srcreg);
1398        store_data_byte(destoffset, destval);
1399        break;
1400    case 2:
1401        destoffset = decode_rm10_address(rl);
1402        DECODE_PRINTF(",");
1403        destval = fetch_data_byte(destoffset);
1404        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1405        DECODE_PRINTF("\n");
1406        TRACE_AND_STEP();
1407        destval = sbb_byte(destval, *srcreg);
1408        store_data_byte(destoffset, destval);
1409        break;
1410    case 3:                     /* register to register */
1411        destreg = DECODE_RM_BYTE_REGISTER(rl);
1412        DECODE_PRINTF(",");
1413        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1414        DECODE_PRINTF("\n");
1415        TRACE_AND_STEP();
1416        *destreg = sbb_byte(*destreg, *srcreg);
1417        break;
1418    }
1419    DECODE_CLEAR_SEGOVR();
1420    END_OF_INSTR();
1421}
1422
1423/****************************************************************************
1424REMARKS:
1425Handles opcode 0x19
1426****************************************************************************/
1427static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1428{
1429    int mod, rl, rh;
1430    uint destoffset;
1431
1432    START_OF_INSTR();
1433    DECODE_PRINTF("SBB\t");
1434    FETCH_DECODE_MODRM(mod, rh, rl);
1435    switch (mod) {
1436    case 0:
1437        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1438            u32 destval;
1439            u32 *srcreg;
1440
1441            destoffset = decode_rm00_address(rl);
1442            DECODE_PRINTF(",");
1443            destval = fetch_data_long(destoffset);
1444            srcreg = DECODE_RM_LONG_REGISTER(rh);
1445            DECODE_PRINTF("\n");
1446            TRACE_AND_STEP();
1447            destval = sbb_long(destval, *srcreg);
1448            store_data_long(destoffset, destval);
1449        } else {
1450            u16 destval;
1451            u16 *srcreg;
1452
1453            destoffset = decode_rm00_address(rl);
1454            DECODE_PRINTF(",");
1455            destval = fetch_data_word(destoffset);
1456            srcreg = DECODE_RM_WORD_REGISTER(rh);
1457            DECODE_PRINTF("\n");
1458            TRACE_AND_STEP();
1459            destval = sbb_word(destval, *srcreg);
1460            store_data_word(destoffset, destval);
1461        }
1462        break;
1463    case 1:
1464        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1465            u32 destval;
1466            u32 *srcreg;
1467
1468            destoffset = decode_rm01_address(rl);
1469            DECODE_PRINTF(",");
1470            destval = fetch_data_long(destoffset);
1471            srcreg = DECODE_RM_LONG_REGISTER(rh);
1472            DECODE_PRINTF("\n");
1473            TRACE_AND_STEP();
1474            destval = sbb_long(destval, *srcreg);
1475            store_data_long(destoffset, destval);
1476        } else {
1477            u16 destval;
1478            u16 *srcreg;
1479
1480            destoffset = decode_rm01_address(rl);
1481            DECODE_PRINTF(",");
1482            destval = fetch_data_word(destoffset);
1483            srcreg = DECODE_RM_WORD_REGISTER(rh);
1484            DECODE_PRINTF("\n");
1485            TRACE_AND_STEP();
1486            destval = sbb_word(destval, *srcreg);
1487            store_data_word(destoffset, destval);
1488        }
1489        break;
1490    case 2:
1491        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1492            u32 destval;
1493            u32 *srcreg;
1494
1495            destoffset = decode_rm10_address(rl);
1496            DECODE_PRINTF(",");
1497            destval = fetch_data_long(destoffset);
1498            srcreg = DECODE_RM_LONG_REGISTER(rh);
1499            DECODE_PRINTF("\n");
1500            TRACE_AND_STEP();
1501            destval = sbb_long(destval, *srcreg);
1502            store_data_long(destoffset, destval);
1503        } else {
1504            u16 destval;
1505            u16 *srcreg;
1506
1507            destoffset = decode_rm10_address(rl);
1508            DECODE_PRINTF(",");
1509            destval = fetch_data_word(destoffset);
1510            srcreg = DECODE_RM_WORD_REGISTER(rh);
1511            DECODE_PRINTF("\n");
1512            TRACE_AND_STEP();
1513            destval = sbb_word(destval, *srcreg);
1514            store_data_word(destoffset, destval);
1515        }
1516        break;
1517    case 3:                     /* register to register */
1518        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1519            u32 *destreg,*srcreg;
1520
1521            destreg = DECODE_RM_LONG_REGISTER(rl);
1522            DECODE_PRINTF(",");
1523            srcreg = DECODE_RM_LONG_REGISTER(rh);
1524            DECODE_PRINTF("\n");
1525            TRACE_AND_STEP();
1526            *destreg = sbb_long(*destreg, *srcreg);
1527        } else {
1528            u16 *destreg,*srcreg;
1529
1530            destreg = DECODE_RM_WORD_REGISTER(rl);
1531            DECODE_PRINTF(",");
1532            srcreg = DECODE_RM_WORD_REGISTER(rh);
1533            DECODE_PRINTF("\n");
1534            TRACE_AND_STEP();
1535            *destreg = sbb_word(*destreg, *srcreg);
1536        }
1537        break;
1538    }
1539    DECODE_CLEAR_SEGOVR();
1540    END_OF_INSTR();
1541}
1542
1543/****************************************************************************
1544REMARKS:
1545Handles opcode 0x1a
1546****************************************************************************/
1547static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1548{
1549    int mod, rl, rh;
1550    u8 *destreg, *srcreg;
1551    uint srcoffset;
1552    u8 srcval;
1553
1554    START_OF_INSTR();
1555    DECODE_PRINTF("SBB\t");
1556    FETCH_DECODE_MODRM(mod, rh, rl);
1557    switch (mod) {
1558    case 0:
1559        destreg = DECODE_RM_BYTE_REGISTER(rh);
1560        DECODE_PRINTF(",");
1561        srcoffset = decode_rm00_address(rl);
1562        srcval = fetch_data_byte(srcoffset);
1563        DECODE_PRINTF("\n");
1564        TRACE_AND_STEP();
1565        *destreg = sbb_byte(*destreg, srcval);
1566        break;
1567    case 1:
1568        destreg = DECODE_RM_BYTE_REGISTER(rh);
1569        DECODE_PRINTF(",");
1570        srcoffset = decode_rm01_address(rl);
1571        srcval = fetch_data_byte(srcoffset);
1572        DECODE_PRINTF("\n");
1573        TRACE_AND_STEP();
1574        *destreg = sbb_byte(*destreg, srcval);
1575        break;
1576    case 2:
1577        destreg = DECODE_RM_BYTE_REGISTER(rh);
1578        DECODE_PRINTF(",");
1579        srcoffset = decode_rm10_address(rl);
1580        srcval = fetch_data_byte(srcoffset);
1581        DECODE_PRINTF("\n");
1582        TRACE_AND_STEP();
1583        *destreg = sbb_byte(*destreg, srcval);
1584        break;
1585    case 3:                     /* register to register */
1586        destreg = DECODE_RM_BYTE_REGISTER(rh);
1587        DECODE_PRINTF(",");
1588        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1589        DECODE_PRINTF("\n");
1590        TRACE_AND_STEP();
1591        *destreg = sbb_byte(*destreg, *srcreg);
1592        break;
1593    }
1594    DECODE_CLEAR_SEGOVR();
1595    END_OF_INSTR();
1596}
1597
1598/****************************************************************************
1599REMARKS:
1600Handles opcode 0x1b
1601****************************************************************************/
1602static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1603{
1604    int mod, rl, rh;
1605    uint srcoffset;
1606
1607    START_OF_INSTR();
1608    DECODE_PRINTF("SBB\t");
1609    FETCH_DECODE_MODRM(mod, rh, rl);
1610    switch (mod) {
1611    case 0:
1612        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1613            u32 *destreg;
1614            u32 srcval;
1615
1616            destreg = DECODE_RM_LONG_REGISTER(rh);
1617            DECODE_PRINTF(",");
1618            srcoffset = decode_rm00_address(rl);
1619            srcval = fetch_data_long(srcoffset);
1620            DECODE_PRINTF("\n");
1621            TRACE_AND_STEP();
1622            *destreg = sbb_long(*destreg, srcval);
1623        } else {
1624            u16 *destreg;
1625            u16 srcval;
1626
1627            destreg = DECODE_RM_WORD_REGISTER(rh);
1628            DECODE_PRINTF(",");
1629            srcoffset = decode_rm00_address(rl);
1630            srcval = fetch_data_word(srcoffset);
1631            DECODE_PRINTF("\n");
1632            TRACE_AND_STEP();
1633            *destreg = sbb_word(*destreg, srcval);
1634        }
1635        break;
1636    case 1:
1637        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1638            u32 *destreg;
1639            u32 srcval;
1640
1641            destreg = DECODE_RM_LONG_REGISTER(rh);
1642            DECODE_PRINTF(",");
1643            srcoffset = decode_rm01_address(rl);
1644            srcval = fetch_data_long(srcoffset);
1645            DECODE_PRINTF("\n");
1646            TRACE_AND_STEP();
1647            *destreg = sbb_long(*destreg, srcval);
1648        } else {
1649            u16 *destreg;
1650            u16 srcval;
1651
1652            destreg = DECODE_RM_WORD_REGISTER(rh);
1653            DECODE_PRINTF(",");
1654            srcoffset = decode_rm01_address(rl);
1655            srcval = fetch_data_word(srcoffset);
1656            DECODE_PRINTF("\n");
1657            TRACE_AND_STEP();
1658            *destreg = sbb_word(*destreg, srcval);
1659        }
1660        break;
1661    case 2:
1662        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1663            u32 *destreg;
1664            u32 srcval;
1665
1666            destreg = DECODE_RM_LONG_REGISTER(rh);
1667            DECODE_PRINTF(",");
1668            srcoffset = decode_rm10_address(rl);
1669            srcval = fetch_data_long(srcoffset);
1670            DECODE_PRINTF("\n");
1671            TRACE_AND_STEP();
1672            *destreg = sbb_long(*destreg, srcval);
1673        } else {
1674            u16 *destreg;
1675            u16 srcval;
1676
1677            destreg = DECODE_RM_WORD_REGISTER(rh);
1678            DECODE_PRINTF(",");
1679            srcoffset = decode_rm10_address(rl);
1680            srcval = fetch_data_word(srcoffset);
1681            DECODE_PRINTF("\n");
1682            TRACE_AND_STEP();
1683            *destreg = sbb_word(*destreg, srcval);
1684        }
1685        break;
1686    case 3:                     /* register to register */
1687        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1688            u32 *destreg,*srcreg;
1689
1690            destreg = DECODE_RM_LONG_REGISTER(rh);
1691            DECODE_PRINTF(",");
1692            srcreg = DECODE_RM_LONG_REGISTER(rl);
1693            DECODE_PRINTF("\n");
1694            TRACE_AND_STEP();
1695            *destreg = sbb_long(*destreg, *srcreg);
1696        } else {
1697            u16 *destreg,*srcreg;
1698
1699            destreg = DECODE_RM_WORD_REGISTER(rh);
1700            DECODE_PRINTF(",");
1701            srcreg = DECODE_RM_WORD_REGISTER(rl);
1702            DECODE_PRINTF("\n");
1703            TRACE_AND_STEP();
1704            *destreg = sbb_word(*destreg, *srcreg);
1705        }
1706        break;
1707    }
1708    DECODE_CLEAR_SEGOVR();
1709    END_OF_INSTR();
1710}
1711
1712/****************************************************************************
1713REMARKS:
1714Handles opcode 0x1c
1715****************************************************************************/
1716static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1717{
1718    u8 srcval;
1719
1720    START_OF_INSTR();
1721    DECODE_PRINTF("SBB\tAL,");
1722    srcval = fetch_byte_imm();
1723    DECODE_PRINTF2("%x\n", srcval);
1724    TRACE_AND_STEP();
1725    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1726    DECODE_CLEAR_SEGOVR();
1727    END_OF_INSTR();
1728}
1729
1730/****************************************************************************
1731REMARKS:
1732Handles opcode 0x1d
1733****************************************************************************/
1734static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1735{
1736    u32 srcval;
1737
1738    START_OF_INSTR();
1739    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1740        DECODE_PRINTF("SBB\tEAX,");
1741        srcval = fetch_long_imm();
1742    } else {
1743        DECODE_PRINTF("SBB\tAX,");
1744        srcval = fetch_word_imm();
1745    }
1746    DECODE_PRINTF2("%x\n", srcval);
1747    TRACE_AND_STEP();
1748    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1749        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1750    } else {
1751        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1752    }
1753    DECODE_CLEAR_SEGOVR();
1754    END_OF_INSTR();
1755}
1756
1757/****************************************************************************
1758REMARKS:
1759Handles opcode 0x1e
1760****************************************************************************/
1761static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1762{
1763    START_OF_INSTR();
1764    DECODE_PRINTF("PUSH\tDS\n");
1765    TRACE_AND_STEP();
1766    push_word(M.x86.R_DS);
1767    DECODE_CLEAR_SEGOVR();
1768    END_OF_INSTR();
1769}
1770
1771/****************************************************************************
1772REMARKS:
1773Handles opcode 0x1f
1774****************************************************************************/
1775static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1776{
1777    START_OF_INSTR();
1778    DECODE_PRINTF("POP\tDS\n");
1779    TRACE_AND_STEP();
1780    M.x86.R_DS = pop_word();
1781    DECODE_CLEAR_SEGOVR();
1782    END_OF_INSTR();
1783}
1784
1785/****************************************************************************
1786REMARKS:
1787Handles opcode 0x20
1788****************************************************************************/
1789static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1790{
1791    int mod, rl, rh;
1792    u8 *destreg, *srcreg;
1793    uint destoffset;
1794    u8 destval;
1795
1796    START_OF_INSTR();
1797    DECODE_PRINTF("AND\t");
1798    FETCH_DECODE_MODRM(mod, rh, rl);
1799
1800    switch (mod) {
1801    case 0:
1802        destoffset = decode_rm00_address(rl);
1803        DECODE_PRINTF(",");
1804        destval = fetch_data_byte(destoffset);
1805        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1806        DECODE_PRINTF("\n");
1807        TRACE_AND_STEP();
1808        destval = and_byte(destval, *srcreg);
1809        store_data_byte(destoffset, destval);
1810        break;
1811
1812    case 1:
1813        destoffset = decode_rm01_address(rl);
1814        DECODE_PRINTF(",");
1815        destval = fetch_data_byte(destoffset);
1816        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1817        DECODE_PRINTF("\n");
1818        TRACE_AND_STEP();
1819        destval = and_byte(destval, *srcreg);
1820        store_data_byte(destoffset, destval);
1821        break;
1822
1823    case 2:
1824        destoffset = decode_rm10_address(rl);
1825        DECODE_PRINTF(",");
1826        destval = fetch_data_byte(destoffset);
1827        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1828        DECODE_PRINTF("\n");
1829        TRACE_AND_STEP();
1830        destval = and_byte(destval, *srcreg);
1831        store_data_byte(destoffset, destval);
1832        break;
1833
1834    case 3:                     /* register to register */
1835        destreg = DECODE_RM_BYTE_REGISTER(rl);
1836        DECODE_PRINTF(",");
1837        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1838        DECODE_PRINTF("\n");
1839        TRACE_AND_STEP();
1840        *destreg = and_byte(*destreg, *srcreg);
1841        break;
1842    }
1843    DECODE_CLEAR_SEGOVR();
1844    END_OF_INSTR();
1845}
1846
1847/****************************************************************************
1848REMARKS:
1849Handles opcode 0x21
1850****************************************************************************/
1851static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1852{
1853    int mod, rl, rh;
1854    uint destoffset;
1855
1856    START_OF_INSTR();
1857    DECODE_PRINTF("AND\t");
1858    FETCH_DECODE_MODRM(mod, rh, rl);
1859    switch (mod) {
1860    case 0:
1861        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1862            u32 destval;
1863            u32 *srcreg;
1864
1865            destoffset = decode_rm00_address(rl);
1866            DECODE_PRINTF(",");
1867            destval = fetch_data_long(destoffset);
1868            srcreg = DECODE_RM_LONG_REGISTER(rh);
1869            DECODE_PRINTF("\n");
1870            TRACE_AND_STEP();
1871            destval = and_long(destval, *srcreg);
1872            store_data_long(destoffset, destval);
1873        } else {
1874            u16 destval;
1875            u16 *srcreg;
1876
1877            destoffset = decode_rm00_address(rl);
1878            DECODE_PRINTF(",");
1879            destval = fetch_data_word(destoffset);
1880            srcreg = DECODE_RM_WORD_REGISTER(rh);
1881            DECODE_PRINTF("\n");
1882            TRACE_AND_STEP();
1883            destval = and_word(destval, *srcreg);
1884            store_data_word(destoffset, destval);
1885        }
1886        break;
1887    case 1:
1888        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1889            u32 destval;
1890            u32 *srcreg;
1891
1892            destoffset = decode_rm01_address(rl);
1893            DECODE_PRINTF(",");
1894            destval = fetch_data_long(destoffset);
1895            srcreg = DECODE_RM_LONG_REGISTER(rh);
1896            DECODE_PRINTF("\n");
1897            TRACE_AND_STEP();
1898            destval = and_long(destval, *srcreg);
1899            store_data_long(destoffset, destval);
1900        } else {
1901            u16 destval;
1902            u16 *srcreg;
1903
1904            destoffset = decode_rm01_address(rl);
1905            DECODE_PRINTF(",");
1906            destval = fetch_data_word(destoffset);
1907            srcreg = DECODE_RM_WORD_REGISTER(rh);
1908            DECODE_PRINTF("\n");
1909            TRACE_AND_STEP();
1910            destval = and_word(destval, *srcreg);
1911            store_data_word(destoffset, destval);
1912        }
1913        break;
1914    case 2:
1915        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1916            u32 destval;
1917            u32 *srcreg;
1918
1919            destoffset = decode_rm10_address(rl);
1920            DECODE_PRINTF(",");
1921            destval = fetch_data_long(destoffset);
1922            srcreg = DECODE_RM_LONG_REGISTER(rh);
1923            DECODE_PRINTF("\n");
1924            TRACE_AND_STEP();
1925            destval = and_long(destval, *srcreg);
1926            store_data_long(destoffset, destval);
1927        } else {
1928            u16 destval;
1929            u16 *srcreg;
1930
1931            destoffset = decode_rm10_address(rl);
1932            DECODE_PRINTF(",");
1933            destval = fetch_data_word(destoffset);
1934            srcreg = DECODE_RM_WORD_REGISTER(rh);
1935            DECODE_PRINTF("\n");
1936            TRACE_AND_STEP();
1937            destval = and_word(destval, *srcreg);
1938            store_data_word(destoffset, destval);
1939        }
1940        break;
1941    case 3:                     /* register to register */
1942        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1943            u32 *destreg,*srcreg;
1944
1945            destreg = DECODE_RM_LONG_REGISTER(rl);
1946            DECODE_PRINTF(",");
1947            srcreg = DECODE_RM_LONG_REGISTER(rh);
1948            DECODE_PRINTF("\n");
1949            TRACE_AND_STEP();
1950            *destreg = and_long(*destreg, *srcreg);
1951        } else {
1952            u16 *destreg,*srcreg;
1953
1954            destreg = DECODE_RM_WORD_REGISTER(rl);
1955            DECODE_PRINTF(",");
1956            srcreg = DECODE_RM_WORD_REGISTER(rh);
1957            DECODE_PRINTF("\n");
1958            TRACE_AND_STEP();
1959            *destreg = and_word(*destreg, *srcreg);
1960        }
1961        break;
1962    }
1963    DECODE_CLEAR_SEGOVR();
1964    END_OF_INSTR();
1965}
1966
1967/****************************************************************************
1968REMARKS:
1969Handles opcode 0x22
1970****************************************************************************/
1971static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1972{
1973    int mod, rl, rh;
1974    u8 *destreg, *srcreg;
1975    uint srcoffset;
1976    u8 srcval;
1977
1978    START_OF_INSTR();
1979    DECODE_PRINTF("AND\t");
1980    FETCH_DECODE_MODRM(mod, rh, rl);
1981    switch (mod) {
1982    case 0:
1983        destreg = DECODE_RM_BYTE_REGISTER(rh);
1984        DECODE_PRINTF(",");
1985        srcoffset = decode_rm00_address(rl);
1986        srcval = fetch_data_byte(srcoffset);
1987        DECODE_PRINTF("\n");
1988        TRACE_AND_STEP();
1989        *destreg = and_byte(*destreg, srcval);
1990        break;
1991    case 1:
1992        destreg = DECODE_RM_BYTE_REGISTER(rh);
1993        DECODE_PRINTF(",");
1994        srcoffset = decode_rm01_address(rl);
1995        srcval = fetch_data_byte(srcoffset);
1996        DECODE_PRINTF("\n");
1997        TRACE_AND_STEP();
1998        *destreg = and_byte(*destreg, srcval);
1999        break;
2000    case 2:
2001        destreg = DECODE_RM_BYTE_REGISTER(rh);
2002        DECODE_PRINTF(",");
2003        srcoffset = decode_rm10_address(rl);
2004        srcval = fetch_data_byte(srcoffset);
2005        DECODE_PRINTF("\n");
2006        TRACE_AND_STEP();
2007        *destreg = and_byte(*destreg, srcval);
2008        break;
2009    case 3:                     /* register to register */
2010        destreg = DECODE_RM_BYTE_REGISTER(rh);
2011        DECODE_PRINTF(",");
2012        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2013        DECODE_PRINTF("\n");
2014        TRACE_AND_STEP();
2015        *destreg = and_byte(*destreg, *srcreg);
2016        break;
2017    }
2018    DECODE_CLEAR_SEGOVR();
2019    END_OF_INSTR();
2020}
2021
2022/****************************************************************************
2023REMARKS:
2024Handles opcode 0x23
2025****************************************************************************/
2026static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2027{
2028    int mod, rl, rh;
2029    uint srcoffset;
2030
2031    START_OF_INSTR();
2032    DECODE_PRINTF("AND\t");
2033    FETCH_DECODE_MODRM(mod, rh, rl);
2034    switch (mod) {
2035    case 0:
2036        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2037            u32 *destreg;
2038            u32 srcval;
2039
2040            destreg = DECODE_RM_LONG_REGISTER(rh);
2041            DECODE_PRINTF(",");
2042            srcoffset = decode_rm00_address(rl);
2043            srcval = fetch_data_long(srcoffset);
2044            DECODE_PRINTF("\n");
2045            TRACE_AND_STEP();
2046            *destreg = and_long(*destreg, srcval);
2047        } else {
2048            u16 *destreg;
2049            u16 srcval;
2050
2051            destreg = DECODE_RM_WORD_REGISTER(rh);
2052            DECODE_PRINTF(",");
2053            srcoffset = decode_rm00_address(rl);
2054            srcval = fetch_data_word(srcoffset);
2055            DECODE_PRINTF("\n");
2056            TRACE_AND_STEP();
2057            *destreg = and_word(*destreg, srcval);
2058        }
2059        break;
2060    case 1:
2061        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2062            u32 *destreg;
2063            u32 srcval;
2064
2065            destreg = DECODE_RM_LONG_REGISTER(rh);
2066            DECODE_PRINTF(",");
2067            srcoffset = decode_rm01_address(rl);
2068            srcval = fetch_data_long(srcoffset);
2069            DECODE_PRINTF("\n");
2070            TRACE_AND_STEP();
2071            *destreg = and_long(*destreg, srcval);
2072            break;
2073        } else {
2074            u16 *destreg;
2075            u16 srcval;
2076
2077            destreg = DECODE_RM_WORD_REGISTER(rh);
2078            DECODE_PRINTF(",");
2079            srcoffset = decode_rm01_address(rl);
2080            srcval = fetch_data_word(srcoffset);
2081            DECODE_PRINTF("\n");
2082            TRACE_AND_STEP();
2083            *destreg = and_word(*destreg, srcval);
2084            break;
2085        }
2086    case 2:
2087        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2088            u32 *destreg;
2089            u32 srcval;
2090
2091            destreg = DECODE_RM_LONG_REGISTER(rh);
2092            DECODE_PRINTF(",");
2093            srcoffset = decode_rm10_address(rl);
2094            srcval = fetch_data_long(srcoffset);
2095            DECODE_PRINTF("\n");
2096            TRACE_AND_STEP();
2097            *destreg = and_long(*destreg, srcval);
2098        } else {
2099            u16 *destreg;
2100            u16 srcval;
2101
2102            destreg = DECODE_RM_WORD_REGISTER(rh);
2103            DECODE_PRINTF(",");
2104            srcoffset = decode_rm10_address(rl);
2105            srcval = fetch_data_word(srcoffset);
2106            DECODE_PRINTF("\n");
2107            TRACE_AND_STEP();
2108            *destreg = and_word(*destreg, srcval);
2109        }
2110        break;
2111    case 3:                     /* register to register */
2112        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2113            u32 *destreg,*srcreg;
2114
2115            destreg = DECODE_RM_LONG_REGISTER(rh);
2116            DECODE_PRINTF(",");
2117            srcreg = DECODE_RM_LONG_REGISTER(rl);
2118            DECODE_PRINTF("\n");
2119            TRACE_AND_STEP();
2120            *destreg = and_long(*destreg, *srcreg);
2121        } else {
2122            u16 *destreg,*srcreg;
2123
2124            destreg = DECODE_RM_WORD_REGISTER(rh);
2125            DECODE_PRINTF(",");
2126            srcreg = DECODE_RM_WORD_REGISTER(rl);
2127            DECODE_PRINTF("\n");
2128            TRACE_AND_STEP();
2129            *destreg = and_word(*destreg, *srcreg);
2130        }
2131        break;
2132    }
2133    DECODE_CLEAR_SEGOVR();
2134    END_OF_INSTR();
2135}
2136
2137/****************************************************************************
2138REMARKS:
2139Handles opcode 0x24
2140****************************************************************************/
2141static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2142{
2143    u8 srcval;
2144
2145    START_OF_INSTR();
2146    DECODE_PRINTF("AND\tAL,");
2147    srcval = fetch_byte_imm();
2148    DECODE_PRINTF2("%x\n", srcval);
2149    TRACE_AND_STEP();
2150    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2151    DECODE_CLEAR_SEGOVR();
2152    END_OF_INSTR();
2153}
2154
2155/****************************************************************************
2156REMARKS:
2157Handles opcode 0x25
2158****************************************************************************/
2159static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2160{
2161    u32 srcval;
2162
2163    START_OF_INSTR();
2164    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2165        DECODE_PRINTF("AND\tEAX,");
2166        srcval = fetch_long_imm();
2167    } else {
2168        DECODE_PRINTF("AND\tAX,");
2169        srcval = fetch_word_imm();
2170    }
2171    DECODE_PRINTF2("%x\n", srcval);
2172    TRACE_AND_STEP();
2173    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2174        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2175    } else {
2176        M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2177    }
2178    DECODE_CLEAR_SEGOVR();
2179    END_OF_INSTR();
2180}
2181
2182/****************************************************************************
2183REMARKS:
2184Handles opcode 0x26
2185****************************************************************************/
2186static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2187{
2188    START_OF_INSTR();
2189    DECODE_PRINTF("ES:\n");
2190    TRACE_AND_STEP();
2191    M.x86.mode |= SYSMODE_SEGOVR_ES;
2192    /*
2193     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2194     * opcode subroutines we do not want to do this.
2195     */
2196    END_OF_INSTR();
2197}
2198
2199/****************************************************************************
2200REMARKS:
2201Handles opcode 0x27
2202****************************************************************************/
2203static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2204{
2205    START_OF_INSTR();
2206    DECODE_PRINTF("DAA\n");
2207    TRACE_AND_STEP();
2208    M.x86.R_AL = daa_byte(M.x86.R_AL);
2209    DECODE_CLEAR_SEGOVR();
2210    END_OF_INSTR();
2211}
2212
2213/****************************************************************************
2214REMARKS:
2215Handles opcode 0x28
2216****************************************************************************/
2217static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2218{
2219    int mod, rl, rh;
2220    u8 *destreg, *srcreg;
2221    uint destoffset;
2222    u8 destval;
2223
2224    START_OF_INSTR();
2225    DECODE_PRINTF("SUB\t");
2226    FETCH_DECODE_MODRM(mod, rh, rl);
2227    switch (mod) {
2228    case 0:
2229        destoffset = decode_rm00_address(rl);
2230        DECODE_PRINTF(",");
2231        destval = fetch_data_byte(destoffset);
2232        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2233        DECODE_PRINTF("\n");
2234        TRACE_AND_STEP();
2235        destval = sub_byte(destval, *srcreg);
2236        store_data_byte(destoffset, destval);
2237        break;
2238    case 1:
2239        destoffset = decode_rm01_address(rl);
2240        DECODE_PRINTF(",");
2241        destval = fetch_data_byte(destoffset);
2242        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2243        DECODE_PRINTF("\n");
2244        TRACE_AND_STEP();
2245        destval = sub_byte(destval, *srcreg);
2246        store_data_byte(destoffset, destval);
2247        break;
2248    case 2:
2249        destoffset = decode_rm10_address(rl);
2250        DECODE_PRINTF(",");
2251        destval = fetch_data_byte(destoffset);
2252        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2253        DECODE_PRINTF("\n");
2254        TRACE_AND_STEP();
2255        destval = sub_byte(destval, *srcreg);
2256        store_data_byte(destoffset, destval);
2257        break;
2258    case 3:                     /* register to register */
2259        destreg = DECODE_RM_BYTE_REGISTER(rl);
2260        DECODE_PRINTF(",");
2261        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2262        DECODE_PRINTF("\n");
2263        TRACE_AND_STEP();
2264        *destreg = sub_byte(*destreg, *srcreg);
2265        break;
2266    }
2267    DECODE_CLEAR_SEGOVR();
2268    END_OF_INSTR();
2269}
2270
2271/****************************************************************************
2272REMARKS:
2273Handles opcode 0x29
2274****************************************************************************/
2275static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2276{
2277    int mod, rl, rh;
2278    uint destoffset;
2279
2280    START_OF_INSTR();
2281    DECODE_PRINTF("SUB\t");
2282    FETCH_DECODE_MODRM(mod, rh, rl);
2283    switch (mod) {
2284    case 0:
2285        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2286            u32 destval;
2287            u32 *srcreg;
2288
2289            destoffset = decode_rm00_address(rl);
2290            DECODE_PRINTF(",");
2291            destval = fetch_data_long(destoffset);
2292            srcreg = DECODE_RM_LONG_REGISTER(rh);
2293            DECODE_PRINTF("\n");
2294            TRACE_AND_STEP();
2295            destval = sub_long(destval, *srcreg);
2296            store_data_long(destoffset, destval);
2297        } else {
2298            u16 destval;
2299            u16 *srcreg;
2300
2301            destoffset = decode_rm00_address(rl);
2302            DECODE_PRINTF(",");
2303            destval = fetch_data_word(destoffset);
2304            srcreg = DECODE_RM_WORD_REGISTER(rh);
2305            DECODE_PRINTF("\n");
2306            TRACE_AND_STEP();
2307            destval = sub_word(destval, *srcreg);
2308            store_data_word(destoffset, destval);
2309        }
2310        break;
2311    case 1:
2312        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2313            u32 destval;
2314            u32 *srcreg;
2315
2316            destoffset = decode_rm01_address(rl);
2317            DECODE_PRINTF(",");
2318            destval = fetch_data_long(destoffset);
2319            srcreg = DECODE_RM_LONG_REGISTER(rh);
2320            DECODE_PRINTF("\n");
2321            TRACE_AND_STEP();
2322            destval = sub_long(destval, *srcreg);
2323            store_data_long(destoffset, destval);
2324        } else {
2325            u16 destval;
2326            u16 *srcreg;
2327
2328            destoffset = decode_rm01_address(rl);
2329            DECODE_PRINTF(",");
2330            destval = fetch_data_word(destoffset);
2331            srcreg = DECODE_RM_WORD_REGISTER(rh);
2332            DECODE_PRINTF("\n");
2333            TRACE_AND_STEP();
2334            destval = sub_word(destval, *srcreg);
2335            store_data_word(destoffset, destval);
2336        }
2337        break;
2338    case 2:
2339        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2340            u32 destval;
2341            u32 *srcreg;
2342
2343            destoffset = decode_rm10_address(rl);
2344            DECODE_PRINTF(",");
2345            destval = fetch_data_long(destoffset);
2346            srcreg = DECODE_RM_LONG_REGISTER(rh);
2347            DECODE_PRINTF("\n");
2348            TRACE_AND_STEP();
2349            destval = sub_long(destval, *srcreg);
2350            store_data_long(destoffset, destval);
2351        } else {
2352            u16 destval;
2353            u16 *srcreg;
2354
2355            destoffset = decode_rm10_address(rl);
2356            DECODE_PRINTF(",");
2357            destval = fetch_data_word(destoffset);
2358            srcreg = DECODE_RM_WORD_REGISTER(rh);
2359            DECODE_PRINTF("\n");
2360            TRACE_AND_STEP();
2361            destval = sub_word(destval, *srcreg);
2362            store_data_word(destoffset, destval);
2363        }
2364        break;
2365    case 3:                     /* register to register */
2366        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2367            u32 *destreg,*srcreg;
2368
2369            destreg = DECODE_RM_LONG_REGISTER(rl);
2370            DECODE_PRINTF(",");
2371            srcreg = DECODE_RM_LONG_REGISTER(rh);
2372            DECODE_PRINTF("\n");
2373            TRACE_AND_STEP();
2374            *destreg = sub_long(*destreg, *srcreg);
2375        } else {
2376            u16 *destreg,*srcreg;
2377
2378            destreg = DECODE_RM_WORD_REGISTER(rl);
2379            DECODE_PRINTF(",");
2380            srcreg = DECODE_RM_WORD_REGISTER(rh);
2381            DECODE_PRINTF("\n");
2382            TRACE_AND_STEP();
2383            *destreg = sub_word(*destreg, *srcreg);
2384        }
2385        break;
2386    }
2387    DECODE_CLEAR_SEGOVR();
2388    END_OF_INSTR();
2389}
2390
2391/****************************************************************************
2392REMARKS:
2393Handles opcode 0x2a
2394****************************************************************************/
2395static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2396{
2397    int mod, rl, rh;
2398    u8 *destreg, *srcreg;
2399    uint srcoffset;
2400    u8 srcval;
2401
2402    START_OF_INSTR();
2403    DECODE_PRINTF("SUB\t");
2404    FETCH_DECODE_MODRM(mod, rh, rl);
2405    switch (mod) {
2406    case 0:
2407        destreg = DECODE_RM_BYTE_REGISTER(rh);
2408        DECODE_PRINTF(",");
2409        srcoffset = decode_rm00_address(rl);
2410        srcval = fetch_data_byte(srcoffset);
2411        DECODE_PRINTF("\n");
2412        TRACE_AND_STEP();
2413        *destreg = sub_byte(*destreg, srcval);
2414        break;
2415    case 1:
2416        destreg = DECODE_RM_BYTE_REGISTER(rh);
2417        DECODE_PRINTF(",");
2418        srcoffset = decode_rm01_address(rl);
2419        srcval = fetch_data_byte(srcoffset);
2420        DECODE_PRINTF("\n");
2421        TRACE_AND_STEP();
2422        *destreg = sub_byte(*destreg, srcval);
2423        break;
2424    case 2:
2425        destreg = DECODE_RM_BYTE_REGISTER(rh);
2426        DECODE_PRINTF(",");
2427        srcoffset = decode_rm10_address(rl);
2428        srcval = fetch_data_byte(srcoffset);
2429        DECODE_PRINTF("\n");
2430        TRACE_AND_STEP();
2431        *destreg = sub_byte(*destreg, srcval);
2432        break;
2433    case 3:                     /* register to register */
2434        destreg = DECODE_RM_BYTE_REGISTER(rh);
2435        DECODE_PRINTF(",");
2436        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2437        DECODE_PRINTF("\n");
2438        TRACE_AND_STEP();
2439        *destreg = sub_byte(*destreg, *srcreg);
2440        break;
2441    }
2442    DECODE_CLEAR_SEGOVR();
2443    END_OF_INSTR();
2444}
2445
2446/****************************************************************************
2447REMARKS:
2448Handles opcode 0x2b
2449****************************************************************************/
2450static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2451{
2452    int mod, rl, rh;
2453    uint srcoffset;
2454
2455    START_OF_INSTR();
2456    DECODE_PRINTF("SUB\t");
2457    FETCH_DECODE_MODRM(mod, rh, rl);
2458    switch (mod) {
2459    case 0:
2460        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2461            u32 *destreg;
2462            u32 srcval;
2463
2464            destreg = DECODE_RM_LONG_REGISTER(rh);
2465            DECODE_PRINTF(",");
2466            srcoffset = decode_rm00_address(rl);
2467            srcval = fetch_data_long(srcoffset);
2468            DECODE_PRINTF("\n");
2469            TRACE_AND_STEP();
2470            *destreg = sub_long(*destreg, srcval);
2471        } else {
2472            u16 *destreg;
2473            u16 srcval;
2474
2475            destreg = DECODE_RM_WORD_REGISTER(rh);
2476            DECODE_PRINTF(",");
2477            srcoffset = decode_rm00_address(rl);
2478            srcval = fetch_data_word(srcoffset);
2479            DECODE_PRINTF("\n");
2480            TRACE_AND_STEP();
2481            *destreg = sub_word(*destreg, srcval);
2482        }
2483        break;
2484    case 1:
2485        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2486            u32 *destreg;
2487            u32 srcval;
2488
2489            destreg = DECODE_RM_LONG_REGISTER(rh);
2490            DECODE_PRINTF(",");
2491            srcoffset = decode_rm01_address(rl);
2492            srcval = fetch_data_long(srcoffset);
2493            DECODE_PRINTF("\n");
2494            TRACE_AND_STEP();
2495            *destreg = sub_long(*destreg, srcval);
2496        } else {
2497            u16 *destreg;
2498            u16 srcval;
2499
2500            destreg = DECODE_RM_WORD_REGISTER(rh);
2501            DECODE_PRINTF(",");
2502            srcoffset = decode_rm01_address(rl);
2503            srcval = fetch_data_word(srcoffset);
2504            DECODE_PRINTF("\n");
2505            TRACE_AND_STEP();
2506            *destreg = sub_word(*destreg, srcval);
2507        }
2508        break;
2509    case 2:
2510        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2511            u32 *destreg;
2512            u32 srcval;
2513
2514            destreg = DECODE_RM_LONG_REGISTER(rh);
2515            DECODE_PRINTF(",");
2516            srcoffset = decode_rm10_address(rl);
2517            srcval = fetch_data_long(srcoffset);
2518            DECODE_PRINTF("\n");
2519            TRACE_AND_STEP();
2520            *destreg = sub_long(*destreg, srcval);
2521        } else {
2522            u16 *destreg;
2523            u16 srcval;
2524
2525            destreg = DECODE_RM_WORD_REGISTER(rh);
2526            DECODE_PRINTF(",");
2527            srcoffset = decode_rm10_address(rl);
2528            srcval = fetch_data_word(srcoffset);
2529            DECODE_PRINTF("\n");
2530            TRACE_AND_STEP();
2531            *destreg = sub_word(*destreg, srcval);
2532        }
2533        break;
2534    case 3:                     /* register to register */
2535        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2536            u32 *destreg,*srcreg;
2537
2538            destreg = DECODE_RM_LONG_REGISTER(rh);
2539            DECODE_PRINTF(",");
2540            srcreg = DECODE_RM_LONG_REGISTER(rl);
2541            DECODE_PRINTF("\n");
2542            TRACE_AND_STEP();
2543            *destreg = sub_long(*destreg, *srcreg);
2544        } else {
2545            u16 *destreg,*srcreg;
2546
2547            destreg = DECODE_RM_WORD_REGISTER(rh);
2548            DECODE_PRINTF(",");
2549            srcreg = DECODE_RM_WORD_REGISTER(rl);
2550            DECODE_PRINTF("\n");
2551            TRACE_AND_STEP();
2552            *destreg = sub_word(*destreg, *srcreg);
2553        }
2554        break;
2555    }
2556    DECODE_CLEAR_SEGOVR();
2557    END_OF_INSTR();
2558}
2559
2560/****************************************************************************
2561REMARKS:
2562Handles opcode 0x2c
2563****************************************************************************/
2564static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2565{
2566    u8 srcval;
2567
2568    START_OF_INSTR();
2569    DECODE_PRINTF("SUB\tAL,");
2570    srcval = fetch_byte_imm();
2571    DECODE_PRINTF2("%x\n", srcval);
2572    TRACE_AND_STEP();
2573    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2574    DECODE_CLEAR_SEGOVR();
2575    END_OF_INSTR();
2576}
2577
2578/****************************************************************************
2579REMARKS:
2580Handles opcode 0x2d
2581****************************************************************************/
2582static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2583{
2584    u32 srcval;
2585
2586    START_OF_INSTR();
2587    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2588        DECODE_PRINTF("SUB\tEAX,");
2589        srcval = fetch_long_imm();
2590    } else {
2591        DECODE_PRINTF("SUB\tAX,");
2592        srcval = fetch_word_imm();
2593    }
2594    DECODE_PRINTF2("%x\n", srcval);
2595    TRACE_AND_STEP();
2596    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2597        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2598    } else {
2599        M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2600    }
2601    DECODE_CLEAR_SEGOVR();
2602    END_OF_INSTR();
2603}
2604
2605/****************************************************************************
2606REMARKS:
2607Handles opcode 0x2e
2608****************************************************************************/
2609static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2610{
2611    START_OF_INSTR();
2612    DECODE_PRINTF("CS:\n");
2613    TRACE_AND_STEP();
2614    M.x86.mode |= SYSMODE_SEGOVR_CS;
2615    /* note no DECODE_CLEAR_SEGOVR here. */
2616    END_OF_INSTR();
2617}
2618
2619/****************************************************************************
2620REMARKS:
2621Handles opcode 0x2f
2622****************************************************************************/
2623static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2624{
2625    START_OF_INSTR();
2626    DECODE_PRINTF("DAS\n");
2627    TRACE_AND_STEP();
2628    M.x86.R_AL = das_byte(M.x86.R_AL);
2629    DECODE_CLEAR_SEGOVR();
2630    END_OF_INSTR();
2631}
2632
2633/****************************************************************************
2634REMARKS:
2635Handles opcode 0x30
2636****************************************************************************/
2637static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2638{
2639    int mod, rl, rh;
2640    u8 *destreg, *srcreg;
2641    uint destoffset;
2642    u8 destval;
2643
2644    START_OF_INSTR();
2645    DECODE_PRINTF("XOR\t");
2646    FETCH_DECODE_MODRM(mod, rh, rl);
2647    switch (mod) {
2648    case 0:
2649        destoffset = decode_rm00_address(rl);
2650        DECODE_PRINTF(",");
2651        destval = fetch_data_byte(destoffset);
2652        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2653        DECODE_PRINTF("\n");
2654        TRACE_AND_STEP();
2655        destval = xor_byte(destval, *srcreg);
2656        store_data_byte(destoffset, destval);
2657        break;
2658    case 1:
2659        destoffset = decode_rm01_address(rl);
2660        DECODE_PRINTF(",");
2661        destval = fetch_data_byte(destoffset);
2662        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2663        DECODE_PRINTF("\n");
2664        TRACE_AND_STEP();
2665        destval = xor_byte(destval, *srcreg);
2666        store_data_byte(destoffset, destval);
2667        break;
2668    case 2:
2669        destoffset = decode_rm10_address(rl);
2670        DECODE_PRINTF(",");
2671        destval = fetch_data_byte(destoffset);
2672        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2673        DECODE_PRINTF("\n");
2674        TRACE_AND_STEP();
2675        destval = xor_byte(destval, *srcreg);
2676        store_data_byte(destoffset, destval);
2677        break;
2678    case 3:                     /* register to register */
2679        destreg = DECODE_RM_BYTE_REGISTER(rl);
2680        DECODE_PRINTF(",");
2681        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2682        DECODE_PRINTF("\n");
2683        TRACE_AND_STEP();
2684        *destreg = xor_byte(*destreg, *srcreg);
2685        break;
2686    }
2687    DECODE_CLEAR_SEGOVR();
2688    END_OF_INSTR();
2689}
2690
2691/****************************************************************************
2692REMARKS:
2693Handles opcode 0x31
2694****************************************************************************/
2695static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2696{
2697    int mod, rl, rh;
2698    uint destoffset;
2699
2700    START_OF_INSTR();
2701    DECODE_PRINTF("XOR\t");
2702    FETCH_DECODE_MODRM(mod, rh, rl);
2703    switch (mod) {
2704    case 0:
2705        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2706            u32 destval;
2707            u32 *srcreg;
2708
2709            destoffset = decode_rm00_address(rl);
2710            DECODE_PRINTF(",");
2711            destval = fetch_data_long(destoffset);
2712            srcreg = DECODE_RM_LONG_REGISTER(rh);
2713            DECODE_PRINTF("\n");
2714            TRACE_AND_STEP();
2715            destval = xor_long(destval, *srcreg);
2716            store_data_long(destoffset, destval);
2717        } else {
2718            u16 destval;
2719            u16 *srcreg;
2720
2721            destoffset = decode_rm00_address(rl);
2722            DECODE_PRINTF(",");
2723            destval = fetch_data_word(destoffset);
2724            srcreg = DECODE_RM_WORD_REGISTER(rh);
2725            DECODE_PRINTF("\n");
2726            TRACE_AND_STEP();
2727            destval = xor_word(destval, *srcreg);
2728            store_data_word(destoffset, destval);
2729        }
2730        break;
2731    case 1:
2732        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2733            u32 destval;
2734            u32 *srcreg;
2735
2736            destoffset = decode_rm01_address(rl);
2737            DECODE_PRINTF(",");
2738            destval = fetch_data_long(destoffset);
2739            srcreg = DECODE_RM_LONG_REGISTER(rh);
2740            DECODE_PRINTF("\n");
2741            TRACE_AND_STEP();
2742            destval = xor_long(destval, *srcreg);
2743            store_data_long(destoffset, destval);
2744        } else {
2745            u16 destval;
2746            u16 *srcreg;
2747
2748            destoffset = decode_rm01_address(rl);
2749            DECODE_PRINTF(",");
2750            destval = fetch_data_word(destoffset);
2751            srcreg = DECODE_RM_WORD_REGISTER(rh);
2752            DECODE_PRINTF("\n");
2753            TRACE_AND_STEP();
2754            destval = xor_word(destval, *srcreg);
2755            store_data_word(destoffset, destval);
2756        }
2757        break;
2758    case 2:
2759        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2760            u32 destval;
2761            u32 *srcreg;
2762
2763            destoffset = decode_rm10_address(rl);
2764            DECODE_PRINTF(",");
2765            destval = fetch_data_long(destoffset);
2766            srcreg = DECODE_RM_LONG_REGISTER(rh);
2767            DECODE_PRINTF("\n");
2768            TRACE_AND_STEP();
2769            destval = xor_long(destval, *srcreg);
2770            store_data_long(destoffset, destval);
2771        } else {
2772            u16 destval;
2773            u16 *srcreg;
2774
2775            destoffset = decode_rm10_address(rl);
2776            DECODE_PRINTF(",");
2777            destval = fetch_data_word(destoffset);
2778            srcreg = DECODE_RM_WORD_REGISTER(rh);
2779            DECODE_PRINTF("\n");
2780            TRACE_AND_STEP();
2781            destval = xor_word(destval, *srcreg);
2782            store_data_word(destoffset, destval);
2783        }
2784        break;
2785    case 3:                     /* register to register */
2786        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2787            u32 *destreg,*srcreg;
2788
2789            destreg = DECODE_RM_LONG_REGISTER(rl);
2790            DECODE_PRINTF(",");
2791            srcreg = DECODE_RM_LONG_REGISTER(rh);
2792            DECODE_PRINTF("\n");
2793            TRACE_AND_STEP();
2794            *destreg = xor_long(*destreg, *srcreg);
2795        } else {
2796            u16 *destreg,*srcreg;
2797
2798            destreg = DECODE_RM_WORD_REGISTER(rl);
2799            DECODE_PRINTF(",");
2800            srcreg = DECODE_RM_WORD_REGISTER(rh);
2801            DECODE_PRINTF("\n");
2802            TRACE_AND_STEP();
2803            *destreg = xor_word(*destreg, *srcreg);
2804        }
2805        break;
2806    }
2807    DECODE_CLEAR_SEGOVR();
2808    END_OF_INSTR();
2809}
2810
2811/****************************************************************************
2812REMARKS:
2813Handles opcode 0x32
2814****************************************************************************/
2815static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2816{
2817    int mod, rl, rh;
2818    u8 *destreg, *srcreg;
2819    uint srcoffset;
2820    u8 srcval;
2821
2822    START_OF_INSTR();
2823    DECODE_PRINTF("XOR\t");
2824    FETCH_DECODE_MODRM(mod, rh, rl);
2825    switch (mod) {
2826    case 0:
2827        destreg = DECODE_RM_BYTE_REGISTER(rh);
2828        DECODE_PRINTF(",");
2829        srcoffset = decode_rm00_address(rl);
2830        srcval = fetch_data_byte(srcoffset);
2831        DECODE_PRINTF("\n");
2832        TRACE_AND_STEP();
2833        *destreg = xor_byte(*destreg, srcval);
2834        break;
2835    case 1:
2836        destreg = DECODE_RM_BYTE_REGISTER(rh);
2837        DECODE_PRINTF(",");
2838        srcoffset = decode_rm01_address(rl);
2839        srcval = fetch_data_byte(srcoffset);
2840        DECODE_PRINTF("\n");
2841        TRACE_AND_STEP();
2842        *destreg = xor_byte(*destreg, srcval);
2843        break;
2844    case 2:
2845        destreg = DECODE_RM_BYTE_REGISTER(rh);
2846        DECODE_PRINTF(",");
2847        srcoffset = decode_rm10_address(rl);
2848        srcval = fetch_data_byte(srcoffset);
2849        DECODE_PRINTF("\n");
2850        TRACE_AND_STEP();
2851        *destreg = xor_byte(*destreg, srcval);
2852        break;
2853    case 3:                     /* register to register */
2854        destreg = DECODE_RM_BYTE_REGISTER(rh);
2855        DECODE_PRINTF(",");
2856        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2857        DECODE_PRINTF("\n");
2858        TRACE_AND_STEP();
2859        *destreg = xor_byte(*destreg, *srcreg);
2860        break;
2861    }
2862    DECODE_CLEAR_SEGOVR();
2863    END_OF_INSTR();
2864}
2865
2866/****************************************************************************
2867REMARKS:
2868Handles opcode 0x33
2869****************************************************************************/
2870static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2871{
2872    int mod, rl, rh;
2873    uint srcoffset;
2874
2875    START_OF_INSTR();
2876    DECODE_PRINTF("XOR\t");
2877    FETCH_DECODE_MODRM(mod, rh, rl);
2878    switch (mod) {
2879    case 0:
2880        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2881            u32 *destreg;
2882            u32 srcval;
2883
2884            destreg = DECODE_RM_LONG_REGISTER(rh);
2885            DECODE_PRINTF(",");
2886            srcoffset = decode_rm00_address(rl);
2887            srcval = fetch_data_long(srcoffset);
2888            DECODE_PRINTF("\n");
2889            TRACE_AND_STEP();
2890            *destreg = xor_long(*destreg, srcval);
2891        } else {
2892            u16 *destreg;
2893            u16 srcval;
2894
2895            destreg = DECODE_RM_WORD_REGISTER(rh);
2896            DECODE_PRINTF(",");
2897            srcoffset = decode_rm00_address(rl);
2898            srcval = fetch_data_word(srcoffset);
2899            DECODE_PRINTF("\n");
2900            TRACE_AND_STEP();
2901            *destreg = xor_word(*destreg, srcval);
2902        }
2903        break;
2904    case 1:
2905        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2906            u32 *destreg;
2907            u32 srcval;
2908
2909            destreg = DECODE_RM_LONG_REGISTER(rh);
2910            DECODE_PRINTF(",");
2911            srcoffset = decode_rm01_address(rl);
2912            srcval = fetch_data_long(srcoffset);
2913            DECODE_PRINTF("\n");
2914            TRACE_AND_STEP();
2915            *destreg = xor_long(*destreg, srcval);
2916        } else {
2917            u16 *destreg;
2918            u16 srcval;
2919
2920            destreg = DECODE_RM_WORD_REGISTER(rh);
2921            DECODE_PRINTF(",");
2922            srcoffset = decode_rm01_address(rl);
2923            srcval = fetch_data_word(srcoffset);
2924            DECODE_PRINTF("\n");
2925            TRACE_AND_STEP();
2926            *destreg = xor_word(*destreg, srcval);
2927        }
2928        break;
2929    case 2:
2930        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2931            u32 *destreg;
2932            u32 srcval;
2933
2934            destreg = DECODE_RM_LONG_REGISTER(rh);
2935            DECODE_PRINTF(",");
2936            srcoffset = decode_rm10_address(rl);
2937            srcval = fetch_data_long(srcoffset);
2938            DECODE_PRINTF("\n");
2939            TRACE_AND_STEP();
2940            *destreg = xor_long(*destreg, srcval);
2941        } else {
2942            u16 *destreg;
2943            u16 srcval;
2944
2945            destreg = DECODE_RM_WORD_REGISTER(rh);
2946            DECODE_PRINTF(",");
2947            srcoffset = decode_rm10_address(rl);
2948            srcval = fetch_data_word(srcoffset);
2949            DECODE_PRINTF("\n");
2950            TRACE_AND_STEP();
2951            *destreg = xor_word(*destreg, srcval);
2952        }
2953        break;
2954    case 3:                     /* register to register */
2955        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2956            u32 *destreg,*srcreg;
2957
2958            destreg = DECODE_RM_LONG_REGISTER(rh);
2959            DECODE_PRINTF(",");
2960            srcreg = DECODE_RM_LONG_REGISTER(rl);
2961            DECODE_PRINTF("\n");
2962            TRACE_AND_STEP();
2963            *destreg = xor_long(*destreg, *srcreg);
2964        } else {
2965            u16 *destreg,*srcreg;
2966
2967            destreg = DECODE_RM_WORD_REGISTER(rh);
2968            DECODE_PRINTF(",");
2969            srcreg = DECODE_RM_WORD_REGISTER(rl);
2970            DECODE_PRINTF("\n");
2971            TRACE_AND_STEP();
2972            *destreg = xor_word(*destreg, *srcreg);
2973        }
2974        break;
2975    }
2976    DECODE_CLEAR_SEGOVR();
2977    END_OF_INSTR();
2978}
2979
2980/****************************************************************************
2981REMARKS:
2982Handles opcode 0x34
2983****************************************************************************/
2984static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2985{
2986    u8 srcval;
2987
2988    START_OF_INSTR();
2989    DECODE_PRINTF("XOR\tAL,");
2990    srcval = fetch_byte_imm();
2991    DECODE_PRINTF2("%x\n", srcval);
2992    TRACE_AND_STEP();
2993    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2994    DECODE_CLEAR_SEGOVR();
2995    END_OF_INSTR();
2996}
2997
2998/****************************************************************************
2999REMARKS:
3000Handles opcode 0x35
3001****************************************************************************/
3002static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3003{
3004    u32 srcval;
3005
3006    START_OF_INSTR();
3007    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3008        DECODE_PRINTF("XOR\tEAX,");
3009        srcval = fetch_long_imm();
3010    } else {
3011        DECODE_PRINTF("XOR\tAX,");
3012        srcval = fetch_word_imm();
3013    }
3014    DECODE_PRINTF2("%x\n", srcval);
3015    TRACE_AND_STEP();
3016    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3017        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3018    } else {
3019        M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3020    }
3021    DECODE_CLEAR_SEGOVR();
3022    END_OF_INSTR();
3023}
3024
3025/****************************************************************************
3026REMARKS:
3027Handles opcode 0x36
3028****************************************************************************/
3029static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3030{
3031    START_OF_INSTR();
3032    DECODE_PRINTF("SS:\n");
3033    TRACE_AND_STEP();
3034    M.x86.mode |= SYSMODE_SEGOVR_SS;
3035    /* no DECODE_CLEAR_SEGOVR ! */
3036    END_OF_INSTR();
3037}
3038
3039/****************************************************************************
3040REMARKS:
3041Handles opcode 0x37
3042****************************************************************************/
3043static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3044{
3045    START_OF_INSTR();
3046    DECODE_PRINTF("AAA\n");
3047    TRACE_AND_STEP();
3048    M.x86.R_AX = aaa_word(M.x86.R_AX);
3049    DECODE_CLEAR_SEGOVR();
3050    END_OF_INSTR();
3051}
3052
3053/****************************************************************************
3054REMARKS:
3055Handles opcode 0x38
3056****************************************************************************/
3057static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3058{
3059    int mod, rl, rh;
3060    uint destoffset;
3061    u8 *destreg, *srcreg;
3062    u8 destval;
3063
3064    START_OF_INSTR();
3065    DECODE_PRINTF("CMP\t");
3066    FETCH_DECODE_MODRM(mod, rh, rl);
3067    switch (mod) {
3068    case 0:
3069        destoffset = decode_rm00_address(rl);
3070        DECODE_PRINTF(",");
3071        destval = fetch_data_byte(destoffset);
3072        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3073        DECODE_PRINTF("\n");
3074        TRACE_AND_STEP();
3075        cmp_byte(destval, *srcreg);
3076        break;
3077    case 1:
3078        destoffset = decode_rm01_address(rl);
3079        DECODE_PRINTF(",");
3080        destval = fetch_data_byte(destoffset);
3081        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3082        DECODE_PRINTF("\n");
3083        TRACE_AND_STEP();
3084        cmp_byte(destval, *srcreg);
3085        break;
3086    case 2:
3087        destoffset = decode_rm10_address(rl);
3088        DECODE_PRINTF(",");
3089        destval = fetch_data_byte(destoffset);
3090        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3091        DECODE_PRINTF("\n");
3092        TRACE_AND_STEP();
3093        cmp_byte(destval, *srcreg);
3094        break;
3095    case 3:                     /* register to register */
3096        destreg = DECODE_RM_BYTE_REGISTER(rl);
3097        DECODE_PRINTF(",");
3098        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3099        DECODE_PRINTF("\n");
3100        TRACE_AND_STEP();
3101        cmp_byte(*destreg, *srcreg);
3102        break;
3103    }
3104    DECODE_CLEAR_SEGOVR();
3105    END_OF_INSTR();
3106}
3107
3108/****************************************************************************
3109REMARKS:
3110Handles opcode 0x39
3111****************************************************************************/
3112static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3113{
3114    int mod, rl, rh;
3115    uint destoffset;
3116
3117    START_OF_INSTR();
3118    DECODE_PRINTF("CMP\t");
3119    FETCH_DECODE_MODRM(mod, rh, rl);
3120    switch (mod) {
3121    case 0:
3122        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3123            u32 destval;
3124            u32 *srcreg;
3125
3126            destoffset = decode_rm00_address(rl);
3127            DECODE_PRINTF(",");
3128            destval = fetch_data_long(destoffset);
3129            srcreg = DECODE_RM_LONG_REGISTER(rh);
3130            DECODE_PRINTF("\n");
3131            TRACE_AND_STEP();
3132            cmp_long(destval, *srcreg);
3133        } else {
3134            u16 destval;
3135            u16 *srcreg;
3136
3137            destoffset = decode_rm00_address(rl);
3138            DECODE_PRINTF(",");
3139            destval = fetch_data_word(destoffset);
3140            srcreg = DECODE_RM_WORD_REGISTER(rh);
3141            DECODE_PRINTF("\n");
3142            TRACE_AND_STEP();
3143            cmp_word(destval, *srcreg);
3144        }
3145        break;
3146    case 1:
3147        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3148            u32 destval;
3149            u32 *srcreg;
3150
3151            destoffset = decode_rm01_address(rl);
3152            DECODE_PRINTF(",");
3153            destval = fetch_data_long(destoffset);
3154            srcreg = DECODE_RM_LONG_REGISTER(rh);
3155            DECODE_PRINTF("\n");
3156            TRACE_AND_STEP();
3157            cmp_long(destval, *srcreg);
3158        } else {
3159            u16 destval;
3160            u16 *srcreg;
3161
3162            destoffset = decode_rm01_address(rl);
3163            DECODE_PRINTF(",");
3164            destval = fetch_data_word(destoffset);
3165            srcreg = DECODE_RM_WORD_REGISTER(rh);
3166            DECODE_PRINTF("\n");
3167            TRACE_AND_STEP();
3168            cmp_word(destval, *srcreg);
3169        }
3170        break;
3171    case 2:
3172        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3173            u32 destval;
3174            u32 *srcreg;
3175
3176            destoffset = decode_rm10_address(rl);
3177            DECODE_PRINTF(",");
3178            destval = fetch_data_long(destoffset);
3179            srcreg = DECODE_RM_LONG_REGISTER(rh);
3180            DECODE_PRINTF("\n");
3181            TRACE_AND_STEP();
3182            cmp_long(destval, *srcreg);
3183        } else {
3184            u16 destval;
3185            u16 *srcreg;
3186
3187            destoffset = decode_rm10_address(rl);
3188            DECODE_PRINTF(",");
3189            destval = fetch_data_word(destoffset);
3190            srcreg = DECODE_RM_WORD_REGISTER(rh);
3191            DECODE_PRINTF("\n");
3192            TRACE_AND_STEP();
3193            cmp_word(destval, *srcreg);
3194        }
3195        break;
3196    case 3:                     /* register to register */
3197        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3198            u32 *destreg,*srcreg;
3199
3200            destreg = DECODE_RM_LONG_REGISTER(rl);
3201            DECODE_PRINTF(",");
3202            srcreg = DECODE_RM_LONG_REGISTER(rh);
3203            DECODE_PRINTF("\n");
3204            TRACE_AND_STEP();
3205            cmp_long(*destreg, *srcreg);
3206        } else {
3207            u16 *destreg,*srcreg;
3208
3209            destreg = DECODE_RM_WORD_REGISTER(rl);
3210            DECODE_PRINTF(",");
3211            srcreg = DECODE_RM_WORD_REGISTER(rh);
3212            DECODE_PRINTF("\n");
3213            TRACE_AND_STEP();
3214            cmp_word(*destreg, *srcreg);
3215        }
3216        break;
3217    }
3218    DECODE_CLEAR_SEGOVR();
3219    END_OF_INSTR();
3220}
3221
3222/****************************************************************************
3223REMARKS:
3224Handles opcode 0x3a
3225****************************************************************************/
3226static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3227{
3228    int mod, rl, rh;
3229    u8 *destreg, *srcreg;
3230    uint srcoffset;
3231    u8 srcval;
3232
3233    START_OF_INSTR();
3234    DECODE_PRINTF("CMP\t");
3235    FETCH_DECODE_MODRM(mod, rh, rl);
3236    switch (mod) {
3237    case 0:
3238        destreg = DECODE_RM_BYTE_REGISTER(rh);
3239        DECODE_PRINTF(",");
3240        srcoffset = decode_rm00_address(rl);
3241        srcval = fetch_data_byte(srcoffset);
3242        DECODE_PRINTF("\n");
3243        TRACE_AND_STEP();
3244        cmp_byte(*destreg, srcval);
3245        break;
3246    case 1:
3247        destreg = DECODE_RM_BYTE_REGISTER(rh);
3248        DECODE_PRINTF(",");
3249        srcoffset = decode_rm01_address(rl);
3250        srcval = fetch_data_byte(srcoffset);
3251        DECODE_PRINTF("\n");
3252        TRACE_AND_STEP();
3253        cmp_byte(*destreg, srcval);
3254        break;
3255    case 2:
3256        destreg = DECODE_RM_BYTE_REGISTER(rh);
3257        DECODE_PRINTF(",");
3258        srcoffset = decode_rm10_address(rl);
3259        srcval = fetch_data_byte(srcoffset);
3260        DECODE_PRINTF("\n");
3261        TRACE_AND_STEP();
3262        cmp_byte(*destreg, srcval);
3263        break;
3264    case 3:                     /* register to register */
3265        destreg = DECODE_RM_BYTE_REGISTER(rh);
3266        DECODE_PRINTF(",");
3267        srcreg = DECODE_RM_BYTE_REGISTER(rl);
3268        DECODE_PRINTF("\n");
3269        TRACE_AND_STEP();
3270        cmp_byte(*destreg, *srcreg);
3271        break;
3272    }
3273    DECODE_CLEAR_SEGOVR();
3274    END_OF_INSTR();
3275}
3276
3277/****************************************************************************
3278REMARKS:
3279Handles opcode 0x3b
3280****************************************************************************/
3281static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3282{
3283    int mod, rl, rh;
3284    uint srcoffset;
3285
3286    START_OF_INSTR();
3287    DECODE_PRINTF("CMP\t");
3288    FETCH_DECODE_MODRM(mod, rh, rl);
3289    switch (mod) {
3290    case 0:
3291        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3292            u32 *destreg;
3293            u32 srcval;
3294
3295            destreg = DECODE_RM_LONG_REGISTER(rh);
3296            DECODE_PRINTF(",");
3297            srcoffset = decode_rm00_address(rl);
3298            srcval = fetch_data_long(srcoffset);
3299            DECODE_PRINTF("\n");
3300            TRACE_AND_STEP();
3301            cmp_long(*destreg, srcval);
3302        } else {
3303            u16 *destreg;
3304            u16 srcval;
3305
3306            destreg = DECODE_RM_WORD_REGISTER(rh);
3307            DECODE_PRINTF(",");
3308            srcoffset = decode_rm00_address(rl);
3309            srcval = fetch_data_word(srcoffset);
3310            DECODE_PRINTF("\n");
3311            TRACE_AND_STEP();
3312            cmp_word(*destreg, srcval);
3313        }
3314        break;
3315    case 1:
3316        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3317            u32 *destreg;
3318            u32 srcval;
3319
3320            destreg = DECODE_RM_LONG_REGISTER(rh);
3321            DECODE_PRINTF(",");
3322            srcoffset = decode_rm01_address(rl);
3323            srcval = fetch_data_long(srcoffset);
3324            DECODE_PRINTF("\n");
3325            TRACE_AND_STEP();
3326            cmp_long(*destreg, srcval);
3327        } else {
3328            u16 *destreg;
3329            u16 srcval;
3330
3331            destreg = DECODE_RM_WORD_REGISTER(rh);
3332            DECODE_PRINTF(",");
3333            srcoffset = decode_rm01_address(rl);
3334            srcval = fetch_data_word(srcoffset);
3335            DECODE_PRINTF("\n");
3336            TRACE_AND_STEP();
3337            cmp_word(*destreg, srcval);
3338        }
3339        break;
3340    case 2:
3341        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3342            u32 *destreg;
3343            u32 srcval;
3344
3345            destreg = DECODE_RM_LONG_REGISTER(rh);
3346            DECODE_PRINTF(",");
3347            srcoffset = decode_rm10_address(rl);
3348            srcval = fetch_data_long(srcoffset);
3349            DECODE_PRINTF("\n");
3350            TRACE_AND_STEP();
3351            cmp_long(*destreg, srcval);
3352        } else {
3353            u16 *destreg;
3354            u16 srcval;
3355
3356            destreg = DECODE_RM_WORD_REGISTER(rh);
3357            DECODE_PRINTF(",");
3358            srcoffset = decode_rm10_address(rl);
3359            srcval = fetch_data_word(srcoffset);
3360            DECODE_PRINTF("\n");
3361            TRACE_AND_STEP();
3362            cmp_word(*destreg, srcval);
3363        }
3364        break;
3365    case 3:                     /* register to register */
3366        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3367            u32 *destreg,*srcreg;
3368
3369            destreg = DECODE_RM_LONG_REGISTER(rh);
3370            DECODE_PRINTF(",");
3371            srcreg = DECODE_RM_LONG_REGISTER(rl);
3372            DECODE_PRINTF("\n");
3373            TRACE_AND_STEP();
3374            cmp_long(*destreg, *srcreg);
3375        } else {
3376            u16 *destreg,*srcreg;
3377
3378            destreg = DECODE_RM_WORD_REGISTER(rh);
3379            DECODE_PRINTF(",");
3380            srcreg = DECODE_RM_WORD_REGISTER(rl);
3381            DECODE_PRINTF("\n");
3382            TRACE_AND_STEP();
3383            cmp_word(*destreg, *srcreg);
3384        }
3385        break;
3386    }
3387    DECODE_CLEAR_SEGOVR();
3388    END_OF_INSTR();
3389}
3390
3391/****************************************************************************
3392REMARKS:
3393Handles opcode 0x3c
3394****************************************************************************/
3395static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3396{
3397    u8 srcval;
3398
3399    START_OF_INSTR();
3400    DECODE_PRINTF("CMP\tAL,");
3401    srcval = fetch_byte_imm();
3402    DECODE_PRINTF2("%x\n", srcval);
3403    TRACE_AND_STEP();
3404    cmp_byte(M.x86.R_AL, srcval);
3405    DECODE_CLEAR_SEGOVR();
3406    END_OF_INSTR();
3407}
3408
3409/****************************************************************************
3410REMARKS:
3411Handles opcode 0x3d
3412****************************************************************************/
3413static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3414{
3415    u32 srcval;
3416
3417    START_OF_INSTR();
3418    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3419        DECODE_PRINTF("CMP\tEAX,");
3420        srcval = fetch_long_imm();
3421    } else {
3422        DECODE_PRINTF("CMP\tAX,");
3423        srcval = fetch_word_imm();
3424    }
3425    DECODE_PRINTF2("%x\n", srcval);
3426    TRACE_AND_STEP();
3427    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3428        cmp_long(M.x86.R_EAX, srcval);
3429    } else {
3430        cmp_word(M.x86.R_AX, (u16)srcval);
3431    }
3432    DECODE_CLEAR_SEGOVR();
3433    END_OF_INSTR();
3434}
3435
3436/****************************************************************************
3437REMARKS:
3438Handles opcode 0x3e
3439****************************************************************************/
3440static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3441{
3442    START_OF_INSTR();
3443    DECODE_PRINTF("DS:\n");
3444    TRACE_AND_STEP();
3445    M.x86.mode |= SYSMODE_SEGOVR_DS;
3446    /* NO DECODE_CLEAR_SEGOVR! */
3447    END_OF_INSTR();
3448}
3449
3450/****************************************************************************
3451REMARKS:
3452Handles opcode 0x3f
3453****************************************************************************/
3454static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3455{
3456    START_OF_INSTR();
3457    DECODE_PRINTF("AAS\n");
3458    TRACE_AND_STEP();
3459    M.x86.R_AX = aas_word(M.x86.R_AX);
3460    DECODE_CLEAR_SEGOVR();
3461    END_OF_INSTR();
3462}
3463
3464/****************************************************************************
3465REMARKS:
3466Handles opcode 0x40
3467****************************************************************************/
3468static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3469{
3470    START_OF_INSTR();
3471    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3472        DECODE_PRINTF("INC\tEAX\n");
3473    } else {
3474        DECODE_PRINTF("INC\tAX\n");
3475    }
3476    TRACE_AND_STEP();
3477    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478        M.x86.R_EAX = inc_long(M.x86.R_EAX);
3479    } else {
3480        M.x86.R_AX = inc_word(M.x86.R_AX);
3481    }
3482    DECODE_CLEAR_SEGOVR();
3483    END_OF_INSTR();
3484}
3485
3486/****************************************************************************
3487REMARKS:
3488Handles opcode 0x41
3489****************************************************************************/
3490static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3491{
3492    START_OF_INSTR();
3493    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3494        DECODE_PRINTF("INC\tECX\n");
3495    } else {
3496        DECODE_PRINTF("INC\tCX\n");
3497    }
3498    TRACE_AND_STEP();
3499    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3500        M.x86.R_ECX = inc_long(M.x86.R_ECX);
3501    } else {
3502        M.x86.R_CX = inc_word(M.x86.R_CX);
3503    }
3504    DECODE_CLEAR_SEGOVR();
3505    END_OF_INSTR();
3506}
3507
3508/****************************************************************************
3509REMARKS:
3510Handles opcode 0x42
3511****************************************************************************/
3512static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3513{
3514    START_OF_INSTR();
3515    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3516        DECODE_PRINTF("INC\tEDX\n");
3517    } else {
3518        DECODE_PRINTF("INC\tDX\n");
3519    }
3520    TRACE_AND_STEP();
3521    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3522        M.x86.R_EDX = inc_long(M.x86.R_EDX);
3523    } else {
3524        M.x86.R_DX = inc_word(M.x86.R_DX);
3525    }
3526    DECODE_CLEAR_SEGOVR();
3527    END_OF_INSTR();
3528}
3529
3530/****************************************************************************
3531REMARKS:
3532Handles opcode 0x43
3533****************************************************************************/
3534static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3535{
3536    START_OF_INSTR();
3537    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3538        DECODE_PRINTF("INC\tEBX\n");
3539    } else {
3540        DECODE_PRINTF("INC\tBX\n");
3541    }
3542    TRACE_AND_STEP();
3543    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3544        M.x86.R_EBX = inc_long(M.x86.R_EBX);
3545    } else {
3546        M.x86.R_BX = inc_word(M.x86.R_BX);
3547    }
3548    DECODE_CLEAR_SEGOVR();
3549    END_OF_INSTR();
3550}
3551
3552/****************************************************************************
3553REMARKS:
3554Handles opcode 0x44
3555****************************************************************************/
3556static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3557{
3558    START_OF_INSTR();
3559    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3560        DECODE_PRINTF("INC\tESP\n");
3561    } else {
3562        DECODE_PRINTF("INC\tSP\n");
3563    }
3564    TRACE_AND_STEP();
3565    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3566        M.x86.R_ESP = inc_long(M.x86.R_ESP);
3567    } else {
3568        M.x86.R_SP = inc_word(M.x86.R_SP);
3569    }
3570    DECODE_CLEAR_SEGOVR();
3571    END_OF_INSTR();
3572}
3573
3574/****************************************************************************
3575REMARKS:
3576Handles opcode 0x45
3577****************************************************************************/
3578static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3579{
3580    START_OF_INSTR();
3581    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3582        DECODE_PRINTF("INC\tEBP\n");
3583    } else {
3584        DECODE_PRINTF("INC\tBP\n");
3585    }
3586    TRACE_AND_STEP();
3587    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3588        M.x86.R_EBP = inc_long(M.x86.R_EBP);
3589    } else {
3590        M.x86.R_BP = inc_word(M.x86.R_BP);
3591    }
3592    DECODE_CLEAR_SEGOVR();
3593    END_OF_INSTR();
3594}
3595
3596/****************************************************************************
3597REMARKS:
3598Handles opcode 0x46
3599****************************************************************************/
3600static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3601{
3602    START_OF_INSTR();
3603    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3604        DECODE_PRINTF("INC\tESI\n");
3605    } else {
3606        DECODE_PRINTF("INC\tSI\n");
3607    }
3608    TRACE_AND_STEP();
3609    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3610        M.x86.R_ESI = inc_long(M.x86.R_ESI);
3611    } else {
3612        M.x86.R_SI = inc_word(M.x86.R_SI);
3613    }
3614    DECODE_CLEAR_SEGOVR();
3615    END_OF_INSTR();
3616}
3617
3618/****************************************************************************
3619REMARKS:
3620Handles opcode 0x47
3621****************************************************************************/
3622static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3623{
3624    START_OF_INSTR();
3625    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3626        DECODE_PRINTF("INC\tEDI\n");
3627    } else {
3628        DECODE_PRINTF("INC\tDI\n");
3629    }
3630    TRACE_AND_STEP();
3631    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3632        M.x86.R_EDI = inc_long(M.x86.R_EDI);
3633    } else {
3634        M.x86.R_DI = inc_word(M.x86.R_DI);
3635    }
3636    DECODE_CLEAR_SEGOVR();
3637    END_OF_INSTR();
3638}
3639
3640/****************************************************************************
3641REMARKS:
3642Handles opcode 0x48
3643****************************************************************************/
3644static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3645{
3646    START_OF_INSTR();
3647    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3648        DECODE_PRINTF("DEC\tEAX\n");
3649    } else {
3650        DECODE_PRINTF("DEC\tAX\n");
3651    }
3652    TRACE_AND_STEP();
3653    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3654        M.x86.R_EAX = dec_long(M.x86.R_EAX);
3655    } else {
3656        M.x86.R_AX = dec_word(M.x86.R_AX);
3657    }
3658    DECODE_CLEAR_SEGOVR();
3659    END_OF_INSTR();
3660}
3661
3662/****************************************************************************
3663REMARKS:
3664Handles opcode 0x49
3665****************************************************************************/
3666static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3667{
3668    START_OF_INSTR();
3669    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3670        DECODE_PRINTF("DEC\tECX\n");
3671    } else {
3672        DECODE_PRINTF("DEC\tCX\n");
3673    }
3674    TRACE_AND_STEP();
3675    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3676        M.x86.R_ECX = dec_long(M.x86.R_ECX);
3677    } else {
3678        M.x86.R_CX = dec_word(M.x86.R_CX);
3679    }
3680    DECODE_CLEAR_SEGOVR();
3681    END_OF_INSTR();
3682}
3683
3684/****************************************************************************
3685REMARKS:
3686Handles opcode 0x4a
3687****************************************************************************/
3688static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3689{
3690    START_OF_INSTR();
3691    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692        DECODE_PRINTF("DEC\tEDX\n");
3693    } else {
3694        DECODE_PRINTF("DEC\tDX\n");
3695    }
3696    TRACE_AND_STEP();
3697    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3698        M.x86.R_EDX = dec_long(M.x86.R_EDX);
3699    } else {
3700        M.x86.R_DX = dec_word(M.x86.R_DX);
3701    }
3702    DECODE_CLEAR_SEGOVR();
3703    END_OF_INSTR();
3704}
3705
3706/****************************************************************************
3707REMARKS:
3708Handles opcode 0x4b
3709****************************************************************************/
3710static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3711{
3712    START_OF_INSTR();
3713    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3714        DECODE_PRINTF("DEC\tEBX\n");
3715    } else {
3716        DECODE_PRINTF("DEC\tBX\n");
3717    }
3718    TRACE_AND_STEP();
3719    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3720        M.x86.R_EBX = dec_long(M.x86.R_EBX);
3721    } else {
3722        M.x86.R_BX = dec_word(M.x86.R_BX);
3723    }
3724    DECODE_CLEAR_SEGOVR();
3725    END_OF_INSTR();
3726}
3727
3728/****************************************************************************
3729REMARKS:
3730Handles opcode 0x4c
3731****************************************************************************/
3732static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3733{
3734    START_OF_INSTR();
3735    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3736        DECODE_PRINTF("DEC\tESP\n");
3737    } else {
3738        DECODE_PRINTF("DEC\tSP\n");
3739    }
3740    TRACE_AND_STEP();
3741    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742        M.x86.R_ESP = dec_long(M.x86.R_ESP);
3743    } else {
3744        M.x86.R_SP = dec_word(M.x86.R_SP);
3745    }
3746    DECODE_CLEAR_SEGOVR();
3747    END_OF_INSTR();
3748}
3749
3750/****************************************************************************
3751REMARKS:
3752Handles opcode 0x4d
3753****************************************************************************/
3754static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3755{
3756    START_OF_INSTR();
3757    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3758        DECODE_PRINTF("DEC\tEBP\n");
3759    } else {
3760        DECODE_PRINTF("DEC\tBP\n");
3761    }
3762    TRACE_AND_STEP();
3763    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3764        M.x86.R_EBP = dec_long(M.x86.R_EBP);
3765    } else {
3766        M.x86.R_BP = dec_word(M.x86.R_BP);
3767    }
3768    DECODE_CLEAR_SEGOVR();
3769    END_OF_INSTR();
3770}
3771
3772/****************************************************************************
3773REMARKS:
3774Handles opcode 0x4e
3775****************************************************************************/
3776static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3777{
3778    START_OF_INSTR();
3779    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3780        DECODE_PRINTF("DEC\tESI\n");
3781    } else {
3782        DECODE_PRINTF("DEC\tSI\n");
3783    }
3784    TRACE_AND_STEP();
3785    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3786        M.x86.R_ESI = dec_long(M.x86.R_ESI);
3787    } else {
3788        M.x86.R_SI = dec_word(M.x86.R_SI);
3789    }
3790    DECODE_CLEAR_SEGOVR();
3791    END_OF_INSTR();
3792}
3793
3794/****************************************************************************
3795REMARKS:
3796Handles opcode 0x4f
3797****************************************************************************/
3798static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3799{
3800    START_OF_INSTR();
3801    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3802        DECODE_PRINTF("DEC\tEDI\n");
3803    } else {
3804        DECODE_PRINTF("DEC\tDI\n");
3805    }
3806    TRACE_AND_STEP();
3807    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3808        M.x86.R_EDI = dec_long(M.x86.R_EDI);
3809    } else {
3810        M.x86.R_DI = dec_word(M.x86.R_DI);
3811    }
3812    DECODE_CLEAR_SEGOVR();
3813    END_OF_INSTR();
3814}
3815
3816/****************************************************************************
3817REMARKS:
3818Handles opcode 0x50
3819****************************************************************************/
3820static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3821{
3822    START_OF_INSTR();
3823    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824        DECODE_PRINTF("PUSH\tEAX\n");
3825    } else {
3826        DECODE_PRINTF("PUSH\tAX\n");
3827    }
3828    TRACE_AND_STEP();
3829    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3830        push_long(M.x86.R_EAX);
3831    } else {
3832        push_word(M.x86.R_AX);
3833    }
3834    DECODE_CLEAR_SEGOVR();
3835    END_OF_INSTR();
3836}
3837
3838/****************************************************************************
3839REMARKS:
3840Handles opcode 0x51
3841****************************************************************************/
3842static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3843{
3844    START_OF_INSTR();
3845    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3846        DECODE_PRINTF("PUSH\tECX\n");
3847    } else {
3848        DECODE_PRINTF("PUSH\tCX\n");
3849    }
3850    TRACE_AND_STEP();
3851    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3852        push_long(M.x86.R_ECX);
3853    } else {
3854        push_word(M.x86.R_CX);
3855    }
3856    DECODE_CLEAR_SEGOVR();
3857    END_OF_INSTR();
3858}
3859
3860/****************************************************************************
3861REMARKS:
3862Handles opcode 0x52
3863****************************************************************************/
3864static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3865{
3866    START_OF_INSTR();
3867    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3868        DECODE_PRINTF("PUSH\tEDX\n");
3869    } else {
3870        DECODE_PRINTF("PUSH\tDX\n");
3871    }
3872    TRACE_AND_STEP();
3873    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874        push_long(M.x86.R_EDX);
3875    } else {
3876        push_word(M.x86.R_DX);
3877    }
3878    DECODE_CLEAR_SEGOVR();
3879    END_OF_INSTR();
3880}
3881
3882/****************************************************************************
3883REMARKS:
3884Handles opcode 0x53
3885****************************************************************************/
3886static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3887{
3888    START_OF_INSTR();
3889    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3890        DECODE_PRINTF("PUSH\tEBX\n");
3891    } else {
3892        DECODE_PRINTF("PUSH\tBX\n");
3893    }
3894    TRACE_AND_STEP();
3895    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3896        push_long(M.x86.R_EBX);
3897    } else {
3898        push_word(M.x86.R_BX);
3899    }
3900    DECODE_CLEAR_SEGOVR();
3901    END_OF_INSTR();
3902}
3903
3904/****************************************************************************
3905REMARKS:
3906Handles opcode 0x54
3907****************************************************************************/
3908static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3909{
3910    START_OF_INSTR();
3911    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3912        DECODE_PRINTF("PUSH\tESP\n");
3913    } else {
3914        DECODE_PRINTF("PUSH\tSP\n");
3915    }
3916    TRACE_AND_STEP();
3917	/* Always push (E)SP, since we are emulating an i386 and above
3918	 * processor. This is necessary as some BIOS'es use this to check
3919	 * what type of processor is in the system.
3920	 */
3921	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3922		push_long(M.x86.R_ESP);
3923	} else {
3924		push_word((u16)(M.x86.R_SP));
3925    }
3926    DECODE_CLEAR_SEGOVR();
3927    END_OF_INSTR();
3928}
3929
3930/****************************************************************************
3931REMARKS:
3932Handles opcode 0x55
3933****************************************************************************/
3934static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3935{
3936    START_OF_INSTR();
3937    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3938        DECODE_PRINTF("PUSH\tEBP\n");
3939    } else {
3940        DECODE_PRINTF("PUSH\tBP\n");
3941    }
3942    TRACE_AND_STEP();
3943    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3944        push_long(M.x86.R_EBP);
3945    } else {
3946        push_word(M.x86.R_BP);
3947    }
3948    DECODE_CLEAR_SEGOVR();
3949    END_OF_INSTR();
3950}
3951
3952/****************************************************************************
3953REMARKS:
3954Handles opcode 0x56
3955****************************************************************************/
3956static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3957{
3958    START_OF_INSTR();
3959    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3960        DECODE_PRINTF("PUSH\tESI\n");
3961    } else {
3962        DECODE_PRINTF("PUSH\tSI\n");
3963    }
3964    TRACE_AND_STEP();
3965    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3966        push_long(M.x86.R_ESI);
3967    } else {
3968        push_word(M.x86.R_SI);
3969    }
3970    DECODE_CLEAR_SEGOVR();
3971    END_OF_INSTR();
3972}
3973
3974/****************************************************************************
3975REMARKS:
3976Handles opcode 0x57
3977****************************************************************************/
3978static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3979{
3980    START_OF_INSTR();
3981    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3982        DECODE_PRINTF("PUSH\tEDI\n");
3983    } else {
3984        DECODE_PRINTF("PUSH\tDI\n");
3985    }
3986    TRACE_AND_STEP();
3987    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3988        push_long(M.x86.R_EDI);
3989    } else {
3990        push_word(M.x86.R_DI);
3991    }
3992    DECODE_CLEAR_SEGOVR();
3993    END_OF_INSTR();
3994}
3995
3996/****************************************************************************
3997REMARKS:
3998Handles opcode 0x58
3999****************************************************************************/
4000static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4001{
4002    START_OF_INSTR();
4003    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4004        DECODE_PRINTF("POP\tEAX\n");
4005    } else {
4006        DECODE_PRINTF("POP\tAX\n");
4007    }
4008    TRACE_AND_STEP();
4009    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4010        M.x86.R_EAX = pop_long();
4011    } else {
4012        M.x86.R_AX = pop_word();
4013    }
4014    DECODE_CLEAR_SEGOVR();
4015    END_OF_INSTR();
4016}
4017
4018/****************************************************************************
4019REMARKS:
4020Handles opcode 0x59
4021****************************************************************************/
4022static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4023{
4024    START_OF_INSTR();
4025    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4026        DECODE_PRINTF("POP\tECX\n");
4027    } else {
4028        DECODE_PRINTF("POP\tCX\n");
4029    }
4030    TRACE_AND_STEP();
4031    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4032        M.x86.R_ECX = pop_long();
4033    } else {
4034        M.x86.R_CX = pop_word();
4035    }
4036    DECODE_CLEAR_SEGOVR();
4037    END_OF_INSTR();
4038}
4039
4040/****************************************************************************
4041REMARKS:
4042Handles opcode 0x5a
4043****************************************************************************/
4044static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4045{
4046    START_OF_INSTR();
4047    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4048        DECODE_PRINTF("POP\tEDX\n");
4049    } else {
4050        DECODE_PRINTF("POP\tDX\n");
4051    }
4052    TRACE_AND_STEP();
4053    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4054        M.x86.R_EDX = pop_long();
4055    } else {
4056        M.x86.R_DX = pop_word();
4057    }
4058    DECODE_CLEAR_SEGOVR();
4059    END_OF_INSTR();
4060}
4061
4062/****************************************************************************
4063REMARKS:
4064Handles opcode 0x5b
4065****************************************************************************/
4066static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4067{
4068    START_OF_INSTR();
4069    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4070        DECODE_PRINTF("POP\tEBX\n");
4071    } else {
4072        DECODE_PRINTF("POP\tBX\n");
4073    }
4074    TRACE_AND_STEP();
4075    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4076        M.x86.R_EBX = pop_long();
4077    } else {
4078        M.x86.R_BX = pop_word();
4079    }
4080    DECODE_CLEAR_SEGOVR();
4081    END_OF_INSTR();
4082}
4083
4084/****************************************************************************
4085REMARKS:
4086Handles opcode 0x5c
4087****************************************************************************/
4088static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4089{
4090    START_OF_INSTR();
4091    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092        DECODE_PRINTF("POP\tESP\n");
4093    } else {
4094        DECODE_PRINTF("POP\tSP\n");
4095    }
4096    TRACE_AND_STEP();
4097    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4098        M.x86.R_ESP = pop_long();
4099    } else {
4100        M.x86.R_SP = pop_word();
4101    }
4102    DECODE_CLEAR_SEGOVR();
4103    END_OF_INSTR();
4104}
4105
4106/****************************************************************************
4107REMARKS:
4108Handles opcode 0x5d
4109****************************************************************************/
4110static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4111{
4112    START_OF_INSTR();
4113    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4114        DECODE_PRINTF("POP\tEBP\n");
4115    } else {
4116        DECODE_PRINTF("POP\tBP\n");
4117    }
4118    TRACE_AND_STEP();
4119    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4120        M.x86.R_EBP = pop_long();
4121    } else {
4122        M.x86.R_BP = pop_word();
4123    }
4124    DECODE_CLEAR_SEGOVR();
4125    END_OF_INSTR();
4126}
4127
4128/****************************************************************************
4129REMARKS:
4130Handles opcode 0x5e
4131****************************************************************************/
4132static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4133{
4134    START_OF_INSTR();
4135    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4136        DECODE_PRINTF("POP\tESI\n");
4137    } else {
4138        DECODE_PRINTF("POP\tSI\n");
4139    }
4140    TRACE_AND_STEP();
4141    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4142        M.x86.R_ESI = pop_long();
4143    } else {
4144        M.x86.R_SI = pop_word();
4145    }
4146    DECODE_CLEAR_SEGOVR();
4147    END_OF_INSTR();
4148}
4149
4150/****************************************************************************
4151REMARKS:
4152Handles opcode 0x5f
4153****************************************************************************/
4154static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4155{
4156    START_OF_INSTR();
4157    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4158        DECODE_PRINTF("POP\tEDI\n");
4159    } else {
4160        DECODE_PRINTF("POP\tDI\n");
4161    }
4162    TRACE_AND_STEP();
4163    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4164        M.x86.R_EDI = pop_long();
4165    } else {
4166        M.x86.R_DI = pop_word();
4167    }
4168    DECODE_CLEAR_SEGOVR();
4169    END_OF_INSTR();
4170}
4171
4172/****************************************************************************
4173REMARKS:
4174Handles opcode 0x60
4175****************************************************************************/
4176static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4177{
4178    START_OF_INSTR();
4179    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4180        DECODE_PRINTF("PUSHAD\n");
4181    } else {
4182        DECODE_PRINTF("PUSHA\n");
4183    }
4184    TRACE_AND_STEP();
4185    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4186        u32 old_sp = M.x86.R_ESP;
4187
4188        push_long(M.x86.R_EAX);
4189        push_long(M.x86.R_ECX);
4190        push_long(M.x86.R_EDX);
4191        push_long(M.x86.R_EBX);
4192        push_long(old_sp);
4193        push_long(M.x86.R_EBP);
4194        push_long(M.x86.R_ESI);
4195        push_long(M.x86.R_EDI);
4196    } else {
4197        u16 old_sp = M.x86.R_SP;
4198
4199        push_word(M.x86.R_AX);
4200        push_word(M.x86.R_CX);
4201        push_word(M.x86.R_DX);
4202        push_word(M.x86.R_BX);
4203        push_word(old_sp);
4204        push_word(M.x86.R_BP);
4205        push_word(M.x86.R_SI);
4206        push_word(M.x86.R_DI);
4207    }
4208    DECODE_CLEAR_SEGOVR();
4209    END_OF_INSTR();
4210}
4211
4212/****************************************************************************
4213REMARKS:
4214Handles opcode 0x61
4215****************************************************************************/
4216static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4217{
4218    START_OF_INSTR();
4219    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4220        DECODE_PRINTF("POPAD\n");
4221    } else {
4222        DECODE_PRINTF("POPA\n");
4223    }
4224    TRACE_AND_STEP();
4225    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4226        M.x86.R_EDI = pop_long();
4227        M.x86.R_ESI = pop_long();
4228        M.x86.R_EBP = pop_long();
4229        M.x86.R_ESP += 4;              /* skip ESP */
4230        M.x86.R_EBX = pop_long();
4231        M.x86.R_EDX = pop_long();
4232        M.x86.R_ECX = pop_long();
4233        M.x86.R_EAX = pop_long();
4234    } else {
4235        M.x86.R_DI = pop_word();
4236        M.x86.R_SI = pop_word();
4237        M.x86.R_BP = pop_word();
4238        M.x86.R_SP += 2;               /* skip SP */
4239        M.x86.R_BX = pop_word();
4240        M.x86.R_DX = pop_word();
4241        M.x86.R_CX = pop_word();
4242        M.x86.R_AX = pop_word();
4243    }
4244    DECODE_CLEAR_SEGOVR();
4245    END_OF_INSTR();
4246}
4247
4248/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4249/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4250
4251/****************************************************************************
4252REMARKS:
4253Handles opcode 0x64
4254****************************************************************************/
4255static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4256{
4257    START_OF_INSTR();
4258    DECODE_PRINTF("FS:\n");
4259    TRACE_AND_STEP();
4260    M.x86.mode |= SYSMODE_SEGOVR_FS;
4261    /*
4262     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4263     * opcode subroutines we do not want to do this.
4264     */
4265    END_OF_INSTR();
4266}
4267
4268/****************************************************************************
4269REMARKS:
4270Handles opcode 0x65
4271****************************************************************************/
4272static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4273{
4274    START_OF_INSTR();
4275    DECODE_PRINTF("GS:\n");
4276    TRACE_AND_STEP();
4277    M.x86.mode |= SYSMODE_SEGOVR_GS;
4278    /*
4279     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4280     * opcode subroutines we do not want to do this.
4281     */
4282    END_OF_INSTR();
4283}
4284
4285/****************************************************************************
4286REMARKS:
4287Handles opcode 0x66 - prefix for 32-bit register
4288****************************************************************************/
4289static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4290{
4291    START_OF_INSTR();
4292    DECODE_PRINTF("DATA:\n");
4293    TRACE_AND_STEP();
4294    M.x86.mode |= SYSMODE_PREFIX_DATA;
4295    /* note no DECODE_CLEAR_SEGOVR here. */
4296    END_OF_INSTR();
4297}
4298
4299/****************************************************************************
4300REMARKS:
4301Handles opcode 0x67 - prefix for 32-bit address
4302****************************************************************************/
4303static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4304{
4305    START_OF_INSTR();
4306    DECODE_PRINTF("ADDR:\n");
4307    TRACE_AND_STEP();
4308    M.x86.mode |= SYSMODE_PREFIX_ADDR;
4309    /* note no DECODE_CLEAR_SEGOVR here. */
4310    END_OF_INSTR();
4311}
4312
4313/****************************************************************************
4314REMARKS:
4315Handles opcode 0x68
4316****************************************************************************/
4317static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4318{
4319    u32 imm;
4320
4321    START_OF_INSTR();
4322    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4323        imm = fetch_long_imm();
4324    } else {
4325        imm = fetch_word_imm();
4326    }
4327    DECODE_PRINTF2("PUSH\t%x\n", imm);
4328    TRACE_AND_STEP();
4329    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4330        push_long(imm);
4331    } else {
4332        push_word((u16)imm);
4333    }
4334    DECODE_CLEAR_SEGOVR();
4335    END_OF_INSTR();
4336}
4337
4338/****************************************************************************
4339REMARKS:
4340Handles opcode 0x69
4341****************************************************************************/
4342static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4343{
4344    int mod, rl, rh;
4345    uint srcoffset;
4346
4347    START_OF_INSTR();
4348    DECODE_PRINTF("IMUL\t");
4349    FETCH_DECODE_MODRM(mod, rh, rl);
4350    switch (mod) {
4351    case 0:
4352        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353            u32 *destreg;
4354            u32 srcval;
4355            u32 res_lo,res_hi;
4356            s32 imm;
4357
4358            destreg = DECODE_RM_LONG_REGISTER(rh);
4359            DECODE_PRINTF(",");
4360            srcoffset = decode_rm00_address(rl);
4361            srcval = fetch_data_long(srcoffset);
4362            imm = fetch_long_imm();
4363            DECODE_PRINTF2(",%d\n", (s32)imm);
4364            TRACE_AND_STEP();
4365            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4366            if (res_hi != 0) {
4367                SET_FLAG(F_CF);
4368                SET_FLAG(F_OF);
4369            } else {
4370                CLEAR_FLAG(F_CF);
4371                CLEAR_FLAG(F_OF);
4372            }
4373            *destreg = (u32)res_lo;
4374        } else {
4375            u16 *destreg;
4376            u16 srcval;
4377            u32 res;
4378            s16 imm;
4379
4380            destreg = DECODE_RM_WORD_REGISTER(rh);
4381            DECODE_PRINTF(",");
4382            srcoffset = decode_rm00_address(rl);
4383            srcval = fetch_data_word(srcoffset);
4384            imm = fetch_word_imm();
4385            DECODE_PRINTF2(",%d\n", (s32)imm);
4386            TRACE_AND_STEP();
4387            res = (s16)srcval * (s16)imm;
4388            if (res > 0xFFFF) {
4389                SET_FLAG(F_CF);
4390                SET_FLAG(F_OF);
4391            } else {
4392                CLEAR_FLAG(F_CF);
4393                CLEAR_FLAG(F_OF);
4394            }
4395            *destreg = (u16)res;
4396        }
4397        break;
4398    case 1:
4399        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4400            u32 *destreg;
4401            u32 srcval;
4402            u32 res_lo,res_hi;
4403            s32 imm;
4404
4405            destreg = DECODE_RM_LONG_REGISTER(rh);
4406            DECODE_PRINTF(",");
4407            srcoffset = decode_rm01_address(rl);
4408            srcval = fetch_data_long(srcoffset);
4409            imm = fetch_long_imm();
4410            DECODE_PRINTF2(",%d\n", (s32)imm);
4411            TRACE_AND_STEP();
4412            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4413            if (res_hi != 0) {
4414                SET_FLAG(F_CF);
4415                SET_FLAG(F_OF);
4416            } else {
4417                CLEAR_FLAG(F_CF);
4418                CLEAR_FLAG(F_OF);
4419            }
4420            *destreg = (u32)res_lo;
4421        } else {
4422            u16 *destreg;
4423            u16 srcval;
4424            u32 res;
4425            s16 imm;
4426
4427            destreg = DECODE_RM_WORD_REGISTER(rh);
4428            DECODE_PRINTF(",");
4429            srcoffset = decode_rm01_address(rl);
4430            srcval = fetch_data_word(srcoffset);
4431            imm = fetch_word_imm();
4432            DECODE_PRINTF2(",%d\n", (s32)imm);
4433            TRACE_AND_STEP();
4434            res = (s16)srcval * (s16)imm;
4435            if (res > 0xFFFF) {
4436                SET_FLAG(F_CF);
4437                SET_FLAG(F_OF);
4438            } else {
4439                CLEAR_FLAG(F_CF);
4440                CLEAR_FLAG(F_OF);
4441            }
4442            *destreg = (u16)res;
4443        }
4444        break;
4445    case 2:
4446        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4447            u32 *destreg;
4448            u32 srcval;
4449            u32 res_lo,res_hi;
4450            s32 imm;
4451
4452            destreg = DECODE_RM_LONG_REGISTER(rh);
4453            DECODE_PRINTF(",");
4454            srcoffset = decode_rm10_address(rl);
4455            srcval = fetch_data_long(srcoffset);
4456            imm = fetch_long_imm();
4457            DECODE_PRINTF2(",%d\n", (s32)imm);
4458            TRACE_AND_STEP();
4459            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4460            if (res_hi != 0) {
4461                SET_FLAG(F_CF);
4462                SET_FLAG(F_OF);
4463            } else {
4464                CLEAR_FLAG(F_CF);
4465                CLEAR_FLAG(F_OF);
4466            }
4467            *destreg = (u32)res_lo;
4468        } else {
4469            u16 *destreg;
4470            u16 srcval;
4471            u32 res;
4472            s16 imm;
4473
4474            destreg = DECODE_RM_WORD_REGISTER(rh);
4475            DECODE_PRINTF(",");
4476            srcoffset = decode_rm10_address(rl);
4477            srcval = fetch_data_word(srcoffset);
4478            imm = fetch_word_imm();
4479            DECODE_PRINTF2(",%d\n", (s32)imm);
4480            TRACE_AND_STEP();
4481            res = (s16)srcval * (s16)imm;
4482            if (res > 0xFFFF) {
4483                SET_FLAG(F_CF);
4484                SET_FLAG(F_OF);
4485            } else {
4486                CLEAR_FLAG(F_CF);
4487                CLEAR_FLAG(F_OF);
4488            }
4489            *destreg = (u16)res;
4490        }
4491        break;
4492    case 3:                     /* register to register */
4493        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4494            u32 *destreg,*srcreg;
4495            u32 res_lo,res_hi;
4496            s32 imm;
4497
4498            destreg = DECODE_RM_LONG_REGISTER(rh);
4499            DECODE_PRINTF(",");
4500            srcreg = DECODE_RM_LONG_REGISTER(rl);
4501            imm = fetch_long_imm();
4502            DECODE_PRINTF2(",%d\n", (s32)imm);
4503            TRACE_AND_STEP();
4504            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4505            if (res_hi != 0) {
4506                SET_FLAG(F_CF);
4507                SET_FLAG(F_OF);
4508            } else {
4509                CLEAR_FLAG(F_CF);
4510                CLEAR_FLAG(F_OF);
4511            }
4512            *destreg = (u32)res_lo;
4513        } else {
4514            u16 *destreg,*srcreg;
4515            u32 res;
4516            s16 imm;
4517
4518            destreg = DECODE_RM_WORD_REGISTER(rh);
4519            DECODE_PRINTF(",");
4520            srcreg = DECODE_RM_WORD_REGISTER(rl);
4521            imm = fetch_word_imm();
4522            DECODE_PRINTF2(",%d\n", (s32)imm);
4523            res = (s16)*srcreg * (s16)imm;
4524            if (res > 0xFFFF) {
4525                SET_FLAG(F_CF);
4526                SET_FLAG(F_OF);
4527            } else {
4528                CLEAR_FLAG(F_CF);
4529                CLEAR_FLAG(F_OF);
4530            }
4531            *destreg = (u16)res;
4532        }
4533        break;
4534    }
4535    DECODE_CLEAR_SEGOVR();
4536    END_OF_INSTR();
4537}
4538
4539/****************************************************************************
4540REMARKS:
4541Handles opcode 0x6a
4542****************************************************************************/
4543static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4544{
4545    s16 imm;
4546
4547    START_OF_INSTR();
4548    imm = (s8)fetch_byte_imm();
4549    DECODE_PRINTF2("PUSH\t%d\n", imm);
4550    TRACE_AND_STEP();
4551    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4552	push_long((s32)imm);
4553    } else {
4554	push_word(imm);
4555    }
4556    DECODE_CLEAR_SEGOVR();
4557    END_OF_INSTR();
4558}
4559
4560/****************************************************************************
4561REMARKS:
4562Handles opcode 0x6b
4563****************************************************************************/
4564static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4565{
4566    int mod, rl, rh;
4567    uint srcoffset;
4568    s8  imm;
4569
4570    START_OF_INSTR();
4571    DECODE_PRINTF("IMUL\t");
4572    FETCH_DECODE_MODRM(mod, rh, rl);
4573    switch (mod) {
4574    case 0:
4575        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4576            u32 *destreg;
4577            u32 srcval;
4578            u32 res_lo,res_hi;
4579
4580            destreg = DECODE_RM_LONG_REGISTER(rh);
4581            DECODE_PRINTF(",");
4582            srcoffset = decode_rm00_address(rl);
4583            srcval = fetch_data_long(srcoffset);
4584            imm = fetch_byte_imm();
4585            DECODE_PRINTF2(",%d\n", (s32)imm);
4586            TRACE_AND_STEP();
4587            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4588            if (res_hi != 0) {
4589                SET_FLAG(F_CF);
4590                SET_FLAG(F_OF);
4591            } else {
4592                CLEAR_FLAG(F_CF);
4593                CLEAR_FLAG(F_OF);
4594            }
4595            *destreg = (u32)res_lo;
4596        } else {
4597            u16 *destreg;
4598            u16 srcval;
4599            u32 res;
4600
4601            destreg = DECODE_RM_WORD_REGISTER(rh);
4602            DECODE_PRINTF(",");
4603            srcoffset = decode_rm00_address(rl);
4604            srcval = fetch_data_word(srcoffset);
4605            imm = fetch_byte_imm();
4606            DECODE_PRINTF2(",%d\n", (s32)imm);
4607            TRACE_AND_STEP();
4608            res = (s16)srcval * (s16)imm;
4609            if (res > 0xFFFF) {
4610                SET_FLAG(F_CF);
4611                SET_FLAG(F_OF);
4612            } else {
4613                CLEAR_FLAG(F_CF);
4614                CLEAR_FLAG(F_OF);
4615            }
4616            *destreg = (u16)res;
4617        }
4618        break;
4619    case 1:
4620        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4621            u32 *destreg;
4622            u32 srcval;
4623            u32 res_lo,res_hi;
4624
4625            destreg = DECODE_RM_LONG_REGISTER(rh);
4626            DECODE_PRINTF(",");
4627            srcoffset = decode_rm01_address(rl);
4628            srcval = fetch_data_long(srcoffset);
4629            imm = fetch_byte_imm();
4630            DECODE_PRINTF2(",%d\n", (s32)imm);
4631            TRACE_AND_STEP();
4632            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4633            if (res_hi != 0) {
4634                SET_FLAG(F_CF);
4635                SET_FLAG(F_OF);
4636            } else {
4637                CLEAR_FLAG(F_CF);
4638                CLEAR_FLAG(F_OF);
4639            }
4640            *destreg = (u32)res_lo;
4641        } else {
4642            u16 *destreg;
4643            u16 srcval;
4644            u32 res;
4645
4646            destreg = DECODE_RM_WORD_REGISTER(rh);
4647            DECODE_PRINTF(",");
4648            srcoffset = decode_rm01_address(rl);
4649            srcval = fetch_data_word(srcoffset);
4650            imm = fetch_byte_imm();
4651            DECODE_PRINTF2(",%d\n", (s32)imm);
4652            TRACE_AND_STEP();
4653            res = (s16)srcval * (s16)imm;
4654            if (res > 0xFFFF) {
4655                SET_FLAG(F_CF);
4656                SET_FLAG(F_OF);
4657            } else {
4658                CLEAR_FLAG(F_CF);
4659                CLEAR_FLAG(F_OF);
4660            }
4661            *destreg = (u16)res;
4662        }
4663        break;
4664    case 2:
4665        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4666            u32 *destreg;
4667            u32 srcval;
4668            u32 res_lo,res_hi;
4669
4670            destreg = DECODE_RM_LONG_REGISTER(rh);
4671            DECODE_PRINTF(",");
4672            srcoffset = decode_rm10_address(rl);
4673            srcval = fetch_data_long(srcoffset);
4674            imm = fetch_byte_imm();
4675            DECODE_PRINTF2(",%d\n", (s32)imm);
4676            TRACE_AND_STEP();
4677            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4678            if (res_hi != 0) {
4679                SET_FLAG(F_CF);
4680                SET_FLAG(F_OF);
4681            } else {
4682                CLEAR_FLAG(F_CF);
4683                CLEAR_FLAG(F_OF);
4684            }
4685            *destreg = (u32)res_lo;
4686        } else {
4687            u16 *destreg;
4688            u16 srcval;
4689            u32 res;
4690
4691            destreg = DECODE_RM_WORD_REGISTER(rh);
4692            DECODE_PRINTF(",");
4693            srcoffset = decode_rm10_address(rl);
4694            srcval = fetch_data_word(srcoffset);
4695            imm = fetch_byte_imm();
4696            DECODE_PRINTF2(",%d\n", (s32)imm);
4697            TRACE_AND_STEP();
4698            res = (s16)srcval * (s16)imm;
4699            if (res > 0xFFFF) {
4700                SET_FLAG(F_CF);
4701                SET_FLAG(F_OF);
4702            } else {
4703                CLEAR_FLAG(F_CF);
4704                CLEAR_FLAG(F_OF);
4705            }
4706            *destreg = (u16)res;
4707        }
4708        break;
4709    case 3:                     /* register to register */
4710        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4711            u32 *destreg,*srcreg;
4712            u32 res_lo,res_hi;
4713
4714            destreg = DECODE_RM_LONG_REGISTER(rh);
4715            DECODE_PRINTF(",");
4716            srcreg = DECODE_RM_LONG_REGISTER(rl);
4717            imm = fetch_byte_imm();
4718            DECODE_PRINTF2(",%d\n", (s32)imm);
4719            TRACE_AND_STEP();
4720            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4721            if (res_hi != 0) {
4722                SET_FLAG(F_CF);
4723                SET_FLAG(F_OF);
4724            } else {
4725                CLEAR_FLAG(F_CF);
4726                CLEAR_FLAG(F_OF);
4727            }
4728            *destreg = (u32)res_lo;
4729        } else {
4730            u16 *destreg,*srcreg;
4731            u32 res;
4732
4733            destreg = DECODE_RM_WORD_REGISTER(rh);
4734            DECODE_PRINTF(",");
4735            srcreg = DECODE_RM_WORD_REGISTER(rl);
4736            imm = fetch_byte_imm();
4737            DECODE_PRINTF2(",%d\n", (s32)imm);
4738            res = (s16)*srcreg * (s16)imm;
4739            if (res > 0xFFFF) {
4740                SET_FLAG(F_CF);
4741                SET_FLAG(F_OF);
4742            } else {
4743                CLEAR_FLAG(F_CF);
4744                CLEAR_FLAG(F_OF);
4745            }
4746            *destreg = (u16)res;
4747        }
4748        break;
4749    }
4750    DECODE_CLEAR_SEGOVR();
4751    END_OF_INSTR();
4752}
4753
4754/****************************************************************************
4755REMARKS:
4756Handles opcode 0x6c
4757****************************************************************************/
4758static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4759{
4760    START_OF_INSTR();
4761    DECODE_PRINTF("INSB\n");
4762    ins(1);
4763    TRACE_AND_STEP();
4764    DECODE_CLEAR_SEGOVR();
4765    END_OF_INSTR();
4766}
4767
4768/****************************************************************************
4769REMARKS:
4770Handles opcode 0x6d
4771****************************************************************************/
4772static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4773{
4774    START_OF_INSTR();
4775    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4776        DECODE_PRINTF("INSD\n");
4777        ins(4);
4778    } else {
4779        DECODE_PRINTF("INSW\n");
4780        ins(2);
4781    }
4782    TRACE_AND_STEP();
4783    DECODE_CLEAR_SEGOVR();
4784    END_OF_INSTR();
4785}
4786
4787/****************************************************************************
4788REMARKS:
4789Handles opcode 0x6e
4790****************************************************************************/
4791static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4792{
4793    START_OF_INSTR();
4794    DECODE_PRINTF("OUTSB\n");
4795    outs(1);
4796    TRACE_AND_STEP();
4797    DECODE_CLEAR_SEGOVR();
4798    END_OF_INSTR();
4799}
4800
4801/****************************************************************************
4802REMARKS:
4803Handles opcode 0x6f
4804****************************************************************************/
4805static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4806{
4807    START_OF_INSTR();
4808    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4809        DECODE_PRINTF("OUTSD\n");
4810        outs(4);
4811    } else {
4812        DECODE_PRINTF("OUTSW\n");
4813        outs(2);
4814    }
4815    TRACE_AND_STEP();
4816    DECODE_CLEAR_SEGOVR();
4817    END_OF_INSTR();
4818}
4819
4820/****************************************************************************
4821REMARKS:
4822Handles opcode 0x70
4823****************************************************************************/
4824static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4825{
4826    s8 offset;
4827    u16 target;
4828
4829    /* jump to byte offset if overflow flag is set */
4830    START_OF_INSTR();
4831    DECODE_PRINTF("JO\t");
4832    offset = (s8)fetch_byte_imm();
4833    target = (u16)(M.x86.R_IP + (s16)offset);
4834    DECODE_PRINTF2("%x\n", target);
4835    TRACE_AND_STEP();
4836    if (ACCESS_FLAG(F_OF))
4837        M.x86.R_IP = target;
4838    DECODE_CLEAR_SEGOVR();
4839    END_OF_INSTR();
4840}
4841
4842/****************************************************************************
4843REMARKS:
4844Handles opcode 0x71
4845****************************************************************************/
4846static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4847{
4848    s8 offset;
4849    u16 target;
4850
4851    /* jump to byte offset if overflow is not set */
4852    START_OF_INSTR();
4853    DECODE_PRINTF("JNO\t");
4854    offset = (s8)fetch_byte_imm();
4855    target = (u16)(M.x86.R_IP + (s16)offset);
4856    DECODE_PRINTF2("%x\n", target);
4857    TRACE_AND_STEP();
4858    if (!ACCESS_FLAG(F_OF))
4859        M.x86.R_IP = target;
4860    DECODE_CLEAR_SEGOVR();
4861    END_OF_INSTR();
4862}
4863
4864/****************************************************************************
4865REMARKS:
4866Handles opcode 0x72
4867****************************************************************************/
4868static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4869{
4870    s8 offset;
4871    u16 target;
4872
4873    /* jump to byte offset if carry flag is set. */
4874    START_OF_INSTR();
4875    DECODE_PRINTF("JB\t");
4876    offset = (s8)fetch_byte_imm();
4877    target = (u16)(M.x86.R_IP + (s16)offset);
4878    DECODE_PRINTF2("%x\n", target);
4879    TRACE_AND_STEP();
4880    if (ACCESS_FLAG(F_CF))
4881        M.x86.R_IP = target;
4882    DECODE_CLEAR_SEGOVR();
4883    END_OF_INSTR();
4884}
4885
4886/****************************************************************************
4887REMARKS:
4888Handles opcode 0x73
4889****************************************************************************/
4890static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4891{
4892    s8 offset;
4893    u16 target;
4894
4895    /* jump to byte offset if carry flag is clear. */
4896    START_OF_INSTR();
4897    DECODE_PRINTF("JNB\t");
4898    offset = (s8)fetch_byte_imm();
4899    target = (u16)(M.x86.R_IP + (s16)offset);
4900    DECODE_PRINTF2("%x\n", target);
4901    TRACE_AND_STEP();
4902    if (!ACCESS_FLAG(F_CF))
4903        M.x86.R_IP = target;
4904    DECODE_CLEAR_SEGOVR();
4905    END_OF_INSTR();
4906}
4907
4908/****************************************************************************
4909REMARKS:
4910Handles opcode 0x74
4911****************************************************************************/
4912static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4913{
4914    s8 offset;
4915    u16 target;
4916
4917    /* jump to byte offset if zero flag is set. */
4918    START_OF_INSTR();
4919    DECODE_PRINTF("JZ\t");
4920    offset = (s8)fetch_byte_imm();
4921    target = (u16)(M.x86.R_IP + (s16)offset);
4922    DECODE_PRINTF2("%x\n", target);
4923    TRACE_AND_STEP();
4924    if (ACCESS_FLAG(F_ZF))
4925        M.x86.R_IP = target;
4926    DECODE_CLEAR_SEGOVR();
4927    END_OF_INSTR();
4928}
4929
4930/****************************************************************************
4931REMARKS:
4932Handles opcode 0x75
4933****************************************************************************/
4934static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4935{
4936    s8 offset;
4937    u16 target;
4938
4939    /* jump to byte offset if zero flag is clear. */
4940    START_OF_INSTR();
4941    DECODE_PRINTF("JNZ\t");
4942    offset = (s8)fetch_byte_imm();
4943    target = (u16)(M.x86.R_IP + (s16)offset);
4944    DECODE_PRINTF2("%x\n", target);
4945    TRACE_AND_STEP();
4946    if (!ACCESS_FLAG(F_ZF))
4947        M.x86.R_IP = target;
4948    DECODE_CLEAR_SEGOVR();
4949    END_OF_INSTR();
4950}
4951
4952/****************************************************************************
4953REMARKS:
4954Handles opcode 0x76
4955****************************************************************************/
4956static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4957{
4958    s8 offset;
4959    u16 target;
4960
4961    /* jump to byte offset if carry flag is set or if the zero
4962       flag is set. */
4963    START_OF_INSTR();
4964    DECODE_PRINTF("JBE\t");
4965    offset = (s8)fetch_byte_imm();
4966    target = (u16)(M.x86.R_IP + (s16)offset);
4967    DECODE_PRINTF2("%x\n", target);
4968    TRACE_AND_STEP();
4969    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4970        M.x86.R_IP = target;
4971    DECODE_CLEAR_SEGOVR();
4972    END_OF_INSTR();
4973}
4974
4975/****************************************************************************
4976REMARKS:
4977Handles opcode 0x77
4978****************************************************************************/
4979static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4980{
4981    s8 offset;
4982    u16 target;
4983
4984    /* jump to byte offset if carry flag is clear and if the zero
4985       flag is clear */
4986    START_OF_INSTR();
4987    DECODE_PRINTF("JNBE\t");
4988    offset = (s8)fetch_byte_imm();
4989    target = (u16)(M.x86.R_IP + (s16)offset);
4990    DECODE_PRINTF2("%x\n", target);
4991    TRACE_AND_STEP();
4992    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4993        M.x86.R_IP = target;
4994    DECODE_CLEAR_SEGOVR();
4995    END_OF_INSTR();
4996}
4997
4998/****************************************************************************
4999REMARKS:
5000Handles opcode 0x78
5001****************************************************************************/
5002static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5003{
5004    s8 offset;
5005    u16 target;
5006
5007    /* jump to byte offset if sign flag is set */
5008    START_OF_INSTR();
5009    DECODE_PRINTF("JS\t");
5010    offset = (s8)fetch_byte_imm();
5011    target = (u16)(M.x86.R_IP + (s16)offset);
5012    DECODE_PRINTF2("%x\n", target);
5013    TRACE_AND_STEP();
5014    if (ACCESS_FLAG(F_SF))
5015        M.x86.R_IP = target;
5016    DECODE_CLEAR_SEGOVR();
5017    END_OF_INSTR();
5018}
5019
5020/****************************************************************************
5021REMARKS:
5022Handles opcode 0x79
5023****************************************************************************/
5024static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5025{
5026    s8 offset;
5027    u16 target;
5028
5029    /* jump to byte offset if sign flag is clear */
5030    START_OF_INSTR();
5031    DECODE_PRINTF("JNS\t");
5032    offset = (s8)fetch_byte_imm();
5033    target = (u16)(M.x86.R_IP + (s16)offset);
5034    DECODE_PRINTF2("%x\n", target);
5035    TRACE_AND_STEP();
5036    if (!ACCESS_FLAG(F_SF))
5037        M.x86.R_IP = target;
5038    DECODE_CLEAR_SEGOVR();
5039    END_OF_INSTR();
5040}
5041
5042/****************************************************************************
5043REMARKS:
5044Handles opcode 0x7a
5045****************************************************************************/
5046static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5047{
5048    s8 offset;
5049    u16 target;
5050
5051    /* jump to byte offset if parity flag is set (even parity) */
5052    START_OF_INSTR();
5053    DECODE_PRINTF("JP\t");
5054    offset = (s8)fetch_byte_imm();
5055    target = (u16)(M.x86.R_IP + (s16)offset);
5056    DECODE_PRINTF2("%x\n", target);
5057    TRACE_AND_STEP();
5058    if (ACCESS_FLAG(F_PF))
5059        M.x86.R_IP = target;
5060    DECODE_CLEAR_SEGOVR();
5061    END_OF_INSTR();
5062}
5063
5064/****************************************************************************
5065REMARKS:
5066Handles opcode 0x7b
5067****************************************************************************/
5068static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5069{
5070    s8 offset;
5071    u16 target;
5072
5073    /* jump to byte offset if parity flag is clear (odd parity) */
5074    START_OF_INSTR();
5075    DECODE_PRINTF("JNP\t");
5076    offset = (s8)fetch_byte_imm();
5077    target = (u16)(M.x86.R_IP + (s16)offset);
5078    DECODE_PRINTF2("%x\n", target);
5079    TRACE_AND_STEP();
5080    if (!ACCESS_FLAG(F_PF))
5081        M.x86.R_IP = target;
5082    DECODE_CLEAR_SEGOVR();
5083    END_OF_INSTR();
5084}
5085
5086/****************************************************************************
5087REMARKS:
5088Handles opcode 0x7c
5089****************************************************************************/
5090static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5091{
5092    s8 offset;
5093    u16 target;
5094    int sf, of;
5095
5096    /* jump to byte offset if sign flag not equal to overflow flag. */
5097    START_OF_INSTR();
5098    DECODE_PRINTF("JL\t");
5099    offset = (s8)fetch_byte_imm();
5100    target = (u16)(M.x86.R_IP + (s16)offset);
5101    DECODE_PRINTF2("%x\n", target);
5102    TRACE_AND_STEP();
5103    sf = ACCESS_FLAG(F_SF) != 0;
5104    of = ACCESS_FLAG(F_OF) != 0;
5105    if (sf ^ of)
5106        M.x86.R_IP = target;
5107    DECODE_CLEAR_SEGOVR();
5108    END_OF_INSTR();
5109}
5110
5111/****************************************************************************
5112REMARKS:
5113Handles opcode 0x7d
5114****************************************************************************/
5115static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5116{
5117    s8 offset;
5118    u16 target;
5119    int sf, of;
5120
5121    /* jump to byte offset if sign flag not equal to overflow flag. */
5122    START_OF_INSTR();
5123    DECODE_PRINTF("JNL\t");
5124    offset = (s8)fetch_byte_imm();
5125    target = (u16)(M.x86.R_IP + (s16)offset);
5126    DECODE_PRINTF2("%x\n", target);
5127    TRACE_AND_STEP();
5128    sf = ACCESS_FLAG(F_SF) != 0;
5129    of = ACCESS_FLAG(F_OF) != 0;
5130    /* note: inverse of above, but using == instead of xor. */
5131    if (sf == of)
5132        M.x86.R_IP = target;
5133    DECODE_CLEAR_SEGOVR();
5134    END_OF_INSTR();
5135}
5136
5137/****************************************************************************
5138REMARKS:
5139Handles opcode 0x7e
5140****************************************************************************/
5141static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5142{
5143    s8 offset;
5144    u16 target;
5145    int sf, of;
5146
5147    /* jump to byte offset if sign flag not equal to overflow flag
5148       or the zero flag is set */
5149    START_OF_INSTR();
5150    DECODE_PRINTF("JLE\t");
5151    offset = (s8)fetch_byte_imm();
5152    target = (u16)(M.x86.R_IP + (s16)offset);
5153    DECODE_PRINTF2("%x\n", target);
5154    TRACE_AND_STEP();
5155    sf = ACCESS_FLAG(F_SF) != 0;
5156    of = ACCESS_FLAG(F_OF) != 0;
5157    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5158        M.x86.R_IP = target;
5159    DECODE_CLEAR_SEGOVR();
5160    END_OF_INSTR();
5161}
5162
5163/****************************************************************************
5164REMARKS:
5165Handles opcode 0x7f
5166****************************************************************************/
5167static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5168{
5169    s8 offset;
5170    u16 target;
5171    int sf, of;
5172
5173    /* jump to byte offset if sign flag equal to overflow flag.
5174       and the zero flag is clear */
5175    START_OF_INSTR();
5176    DECODE_PRINTF("JNLE\t");
5177    offset = (s8)fetch_byte_imm();
5178    target = (u16)(M.x86.R_IP + (s16)offset);
5179    DECODE_PRINTF2("%x\n", target);
5180    TRACE_AND_STEP();
5181    sf = ACCESS_FLAG(F_SF) != 0;
5182    of = ACCESS_FLAG(F_OF) != 0;
5183    if ((sf == of) && !ACCESS_FLAG(F_ZF))
5184        M.x86.R_IP = target;
5185    DECODE_CLEAR_SEGOVR();
5186    END_OF_INSTR();
5187}
5188
5189static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5190{
5191    add_byte,           /* 00 */
5192    or_byte,            /* 01 */
5193    adc_byte,           /* 02 */
5194    sbb_byte,           /* 03 */
5195    and_byte,           /* 04 */
5196    sub_byte,           /* 05 */
5197    xor_byte,           /* 06 */
5198    cmp_byte,           /* 07 */
5199};
5200
5201/****************************************************************************
5202REMARKS:
5203Handles opcode 0x80
5204****************************************************************************/
5205static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5206{
5207    int mod, rl, rh;
5208    u8 *destreg;
5209    uint destoffset;
5210    u8 imm;
5211    u8 destval;
5212
5213    /*
5214     * Weirdo special case instruction format.  Part of the opcode
5215     * held below in "RH".  Doubly nested case would result, except
5216     * that the decoded instruction
5217     */
5218    START_OF_INSTR();
5219    FETCH_DECODE_MODRM(mod, rh, rl);
5220#ifdef DEBUG
5221    if (DEBUG_DECODE()) {
5222        /* XXX DECODE_PRINTF may be changed to something more
5223           general, so that it is important to leave the strings
5224           in the same format, even though the result is that the
5225           above test is done twice. */
5226
5227        switch (rh) {
5228        case 0:
5229            DECODE_PRINTF("ADD\t");
5230            break;
5231        case 1:
5232            DECODE_PRINTF("OR\t");
5233            break;
5234        case 2:
5235            DECODE_PRINTF("ADC\t");
5236            break;
5237        case 3:
5238            DECODE_PRINTF("SBB\t");
5239            break;
5240        case 4:
5241            DECODE_PRINTF("AND\t");
5242            break;
5243        case 5:
5244            DECODE_PRINTF("SUB\t");
5245            break;
5246        case 6:
5247            DECODE_PRINTF("XOR\t");
5248            break;
5249        case 7:
5250            DECODE_PRINTF("CMP\t");
5251            break;
5252        }
5253    }
5254#endif
5255    /* know operation, decode the mod byte to find the addressing
5256       mode. */
5257    switch (mod) {
5258    case 0:
5259        DECODE_PRINTF("BYTE PTR ");
5260        destoffset = decode_rm00_address(rl);
5261        DECODE_PRINTF(",");
5262        destval = fetch_data_byte(destoffset);
5263        imm = fetch_byte_imm();
5264        DECODE_PRINTF2("%x\n", imm);
5265        TRACE_AND_STEP();
5266        destval = (*opc80_byte_operation[rh]) (destval, imm);
5267        if (rh != 7)
5268            store_data_byte(destoffset, destval);
5269        break;
5270    case 1:
5271        DECODE_PRINTF("BYTE PTR ");
5272        destoffset = decode_rm01_address(rl);
5273        DECODE_PRINTF(",");
5274        destval = fetch_data_byte(destoffset);
5275        imm = fetch_byte_imm();
5276        DECODE_PRINTF2("%x\n", imm);
5277        TRACE_AND_STEP();
5278        destval = (*opc80_byte_operation[rh]) (destval, imm);
5279        if (rh != 7)
5280            store_data_byte(destoffset, destval);
5281        break;
5282    case 2:
5283        DECODE_PRINTF("BYTE PTR ");
5284        destoffset = decode_rm10_address(rl);
5285        DECODE_PRINTF(",");
5286        destval = fetch_data_byte(destoffset);
5287        imm = fetch_byte_imm();
5288        DECODE_PRINTF2("%x\n", imm);
5289        TRACE_AND_STEP();
5290        destval = (*opc80_byte_operation[rh]) (destval, imm);
5291        if (rh != 7)
5292            store_data_byte(destoffset, destval);
5293        break;
5294    case 3:                     /* register to register */
5295        destreg = DECODE_RM_BYTE_REGISTER(rl);
5296        DECODE_PRINTF(",");
5297        imm = fetch_byte_imm();
5298        DECODE_PRINTF2("%x\n", imm);
5299        TRACE_AND_STEP();
5300        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5301        if (rh != 7)
5302            *destreg = destval;
5303        break;
5304    }
5305    DECODE_CLEAR_SEGOVR();
5306    END_OF_INSTR();
5307}
5308
5309static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5310{
5311    add_word,           /*00 */
5312    or_word,            /*01 */
5313    adc_word,           /*02 */
5314    sbb_word,           /*03 */
5315    and_word,           /*04 */
5316    sub_word,           /*05 */
5317    xor_word,           /*06 */
5318    cmp_word,           /*07 */
5319};
5320
5321static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5322{
5323    add_long,           /*00 */
5324    or_long,            /*01 */
5325    adc_long,           /*02 */
5326    sbb_long,           /*03 */
5327    and_long,           /*04 */
5328    sub_long,           /*05 */
5329    xor_long,           /*06 */
5330    cmp_long,           /*07 */
5331};
5332
5333/****************************************************************************
5334REMARKS:
5335Handles opcode 0x81
5336****************************************************************************/
5337static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5338{
5339    int mod, rl, rh;
5340    uint destoffset;
5341
5342    /*
5343     * Weirdo special case instruction format.  Part of the opcode
5344     * held below in "RH".  Doubly nested case would result, except
5345     * that the decoded instruction
5346     */
5347    START_OF_INSTR();
5348    FETCH_DECODE_MODRM(mod, rh, rl);
5349#ifdef DEBUG
5350    if (DEBUG_DECODE()) {
5351        /* XXX DECODE_PRINTF may be changed to something more
5352           general, so that it is important to leave the strings
5353           in the same format, even though the result is that the
5354           above test is done twice. */
5355
5356        switch (rh) {
5357        case 0:
5358            DECODE_PRINTF("ADD\t");
5359            break;
5360        case 1:
5361            DECODE_PRINTF("OR\t");
5362            break;
5363        case 2:
5364            DECODE_PRINTF("ADC\t");
5365            break;
5366        case 3:
5367            DECODE_PRINTF("SBB\t");
5368            break;
5369        case 4:
5370            DECODE_PRINTF("AND\t");
5371            break;
5372        case 5:
5373            DECODE_PRINTF("SUB\t");
5374            break;
5375        case 6:
5376            DECODE_PRINTF("XOR\t");
5377            break;
5378        case 7:
5379            DECODE_PRINTF("CMP\t");
5380            break;
5381        }
5382    }
5383#endif
5384    /*
5385     * Know operation, decode the mod byte to find the addressing
5386     * mode.
5387     */
5388    switch (mod) {
5389    case 0:
5390        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5391            u32 destval,imm;
5392
5393            DECODE_PRINTF("DWORD PTR ");
5394            destoffset = decode_rm00_address(rl);
5395            DECODE_PRINTF(",");
5396            destval = fetch_data_long(destoffset);
5397            imm = fetch_long_imm();
5398            DECODE_PRINTF2("%x\n", imm);
5399            TRACE_AND_STEP();
5400            destval = (*opc81_long_operation[rh]) (destval, imm);
5401            if (rh != 7)
5402                store_data_long(destoffset, destval);
5403        } else {
5404            u16 destval,imm;
5405
5406            DECODE_PRINTF("WORD PTR ");
5407            destoffset = decode_rm00_address(rl);
5408            DECODE_PRINTF(",");
5409            destval = fetch_data_word(destoffset);
5410            imm = fetch_word_imm();
5411            DECODE_PRINTF2("%x\n", imm);
5412            TRACE_AND_STEP();
5413            destval = (*opc81_word_operation[rh]) (destval, imm);
5414            if (rh != 7)
5415                store_data_word(destoffset, destval);
5416        }
5417        break;
5418    case 1:
5419        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5420            u32 destval,imm;
5421
5422            DECODE_PRINTF("DWORD PTR ");
5423            destoffset = decode_rm01_address(rl);
5424            DECODE_PRINTF(",");
5425            destval = fetch_data_long(destoffset);
5426            imm = fetch_long_imm();
5427            DECODE_PRINTF2("%x\n", imm);
5428            TRACE_AND_STEP();
5429            destval = (*opc81_long_operation[rh]) (destval, imm);
5430            if (rh != 7)
5431                store_data_long(destoffset, destval);
5432        } else {
5433            u16 destval,imm;
5434
5435            DECODE_PRINTF("WORD PTR ");
5436            destoffset = decode_rm01_address(rl);
5437            DECODE_PRINTF(",");
5438            destval = fetch_data_word(destoffset);
5439            imm = fetch_word_imm();
5440            DECODE_PRINTF2("%x\n", imm);
5441            TRACE_AND_STEP();
5442            destval = (*opc81_word_operation[rh]) (destval, imm);
5443            if (rh != 7)
5444                store_data_word(destoffset, destval);
5445        }
5446        break;
5447    case 2:
5448        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5449            u32 destval,imm;
5450
5451            DECODE_PRINTF("DWORD PTR ");
5452            destoffset = decode_rm10_address(rl);
5453            DECODE_PRINTF(",");
5454            destval = fetch_data_long(destoffset);
5455            imm = fetch_long_imm();
5456            DECODE_PRINTF2("%x\n", imm);
5457            TRACE_AND_STEP();
5458            destval = (*opc81_long_operation[rh]) (destval, imm);
5459            if (rh != 7)
5460                store_data_long(destoffset, destval);
5461        } else {
5462            u16 destval,imm;
5463
5464            DECODE_PRINTF("WORD PTR ");
5465            destoffset = decode_rm10_address(rl);
5466            DECODE_PRINTF(",");
5467            destval = fetch_data_word(destoffset);
5468            imm = fetch_word_imm();
5469            DECODE_PRINTF2("%x\n", imm);
5470            TRACE_AND_STEP();
5471            destval = (*opc81_word_operation[rh]) (destval, imm);
5472            if (rh != 7)
5473                store_data_word(destoffset, destval);
5474        }
5475        break;
5476    case 3:                     /* register to register */
5477        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5478            u32 *destreg;
5479            u32 destval,imm;
5480
5481            destreg = DECODE_RM_LONG_REGISTER(rl);
5482            DECODE_PRINTF(",");
5483            imm = fetch_long_imm();
5484            DECODE_PRINTF2("%x\n", imm);
5485            TRACE_AND_STEP();
5486            destval = (*opc81_long_operation[rh]) (*destreg, imm);
5487            if (rh != 7)
5488                *destreg = destval;
5489        } else {
5490            u16 *destreg;
5491            u16 destval,imm;
5492
5493            destreg = DECODE_RM_WORD_REGISTER(rl);
5494            DECODE_PRINTF(",");
5495            imm = fetch_word_imm();
5496            DECODE_PRINTF2("%x\n", imm);
5497            TRACE_AND_STEP();
5498            destval = (*opc81_word_operation[rh]) (*destreg, imm);
5499            if (rh != 7)
5500                *destreg = destval;
5501        }
5502        break;
5503    }
5504    DECODE_CLEAR_SEGOVR();
5505    END_OF_INSTR();
5506}
5507
5508static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5509{
5510    add_byte,           /*00 */
5511    or_byte,            /*01 *//*YYY UNUSED ???? */
5512    adc_byte,           /*02 */
5513    sbb_byte,           /*03 */
5514    and_byte,           /*04 *//*YYY UNUSED ???? */
5515    sub_byte,           /*05 */
5516    xor_byte,           /*06 *//*YYY UNUSED ???? */
5517    cmp_byte,           /*07 */
5518};
5519
5520/****************************************************************************
5521REMARKS:
5522Handles opcode 0x82
5523****************************************************************************/
5524static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5525{
5526    int mod, rl, rh;
5527    u8 *destreg;
5528    uint destoffset;
5529    u8 imm;
5530    u8 destval;
5531
5532    /*
5533     * Weirdo special case instruction format.  Part of the opcode
5534     * held below in "RH".  Doubly nested case would result, except
5535     * that the decoded instruction Similar to opcode 81, except that
5536     * the immediate byte is sign extended to a word length.
5537     */
5538    START_OF_INSTR();
5539    FETCH_DECODE_MODRM(mod, rh, rl);
5540#ifdef DEBUG
5541    if (DEBUG_DECODE()) {
5542        /* XXX DECODE_PRINTF may be changed to something more
5543           general, so that it is important to leave the strings
5544           in the same format, even though the result is that the
5545           above test is done twice. */
5546        switch (rh) {
5547        case 0:
5548            DECODE_PRINTF("ADD\t");
5549            break;
5550        case 1:
5551            DECODE_PRINTF("OR\t");
5552            break;
5553        case 2:
5554            DECODE_PRINTF("ADC\t");
5555            break;
5556        case 3:
5557            DECODE_PRINTF("SBB\t");
5558            break;
5559        case 4:
5560            DECODE_PRINTF("AND\t");
5561            break;
5562        case 5:
5563            DECODE_PRINTF("SUB\t");
5564            break;
5565        case 6:
5566            DECODE_PRINTF("XOR\t");
5567            break;
5568        case 7:
5569            DECODE_PRINTF("CMP\t");
5570            break;
5571        }
5572    }
5573#endif
5574    /* know operation, decode the mod byte to find the addressing
5575       mode. */
5576    switch (mod) {
5577    case 0:
5578        DECODE_PRINTF("BYTE PTR ");
5579        destoffset = decode_rm00_address(rl);
5580        destval = fetch_data_byte(destoffset);
5581        imm = fetch_byte_imm();
5582        DECODE_PRINTF2(",%x\n", imm);
5583        TRACE_AND_STEP();
5584        destval = (*opc82_byte_operation[rh]) (destval, imm);
5585        if (rh != 7)
5586            store_data_byte(destoffset, destval);
5587        break;
5588    case 1:
5589        DECODE_PRINTF("BYTE PTR ");
5590        destoffset = decode_rm01_address(rl);
5591        destval = fetch_data_byte(destoffset);
5592        imm = fetch_byte_imm();
5593        DECODE_PRINTF2(",%x\n", imm);
5594        TRACE_AND_STEP();
5595        destval = (*opc82_byte_operation[rh]) (destval, imm);
5596        if (rh != 7)
5597            store_data_byte(destoffset, destval);
5598        break;
5599    case 2:
5600        DECODE_PRINTF("BYTE PTR ");
5601        destoffset = decode_rm10_address(rl);
5602        destval = fetch_data_byte(destoffset);
5603        imm = fetch_byte_imm();
5604        DECODE_PRINTF2(",%x\n", imm);
5605        TRACE_AND_STEP();
5606        destval = (*opc82_byte_operation[rh]) (destval, imm);
5607        if (rh != 7)
5608            store_data_byte(destoffset, destval);
5609        break;
5610    case 3:                     /* register to register */
5611        destreg = DECODE_RM_BYTE_REGISTER(rl);
5612        imm = fetch_byte_imm();
5613        DECODE_PRINTF2(",%x\n", imm);
5614        TRACE_AND_STEP();
5615        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5616        if (rh != 7)
5617            *destreg = destval;
5618        break;
5619    }
5620    DECODE_CLEAR_SEGOVR();
5621    END_OF_INSTR();
5622}
5623
5624static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5625{
5626    add_word,           /*00 */
5627    or_word,            /*01 *//*YYY UNUSED ???? */
5628    adc_word,           /*02 */
5629    sbb_word,           /*03 */
5630    and_word,           /*04 *//*YYY UNUSED ???? */
5631    sub_word,           /*05 */
5632    xor_word,           /*06 *//*YYY UNUSED ???? */
5633    cmp_word,           /*07 */
5634};
5635
5636static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5637{
5638    add_long,           /*00 */
5639    or_long,            /*01 *//*YYY UNUSED ???? */
5640    adc_long,           /*02 */
5641    sbb_long,           /*03 */
5642    and_long,           /*04 *//*YYY UNUSED ???? */
5643    sub_long,           /*05 */
5644    xor_long,           /*06 *//*YYY UNUSED ???? */
5645    cmp_long,           /*07 */
5646};
5647
5648/****************************************************************************
5649REMARKS:
5650Handles opcode 0x83
5651****************************************************************************/
5652static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5653{
5654    int mod, rl, rh;
5655    uint destoffset;
5656
5657    /*
5658     * Weirdo special case instruction format.  Part of the opcode
5659     * held below in "RH".  Doubly nested case would result, except
5660     * that the decoded instruction Similar to opcode 81, except that
5661     * the immediate byte is sign extended to a word length.
5662     */
5663    START_OF_INSTR();
5664    FETCH_DECODE_MODRM(mod, rh, rl);
5665#ifdef DEBUG
5666    if (DEBUG_DECODE()) {
5667        /* XXX DECODE_PRINTF may be changed to something more
5668           general, so that it is important to leave the strings
5669           in the same format, even though the result is that the
5670           above test is done twice. */
5671       switch (rh) {
5672        case 0:
5673            DECODE_PRINTF("ADD\t");
5674            break;
5675        case 1:
5676            DECODE_PRINTF("OR\t");
5677            break;
5678        case 2:
5679            DECODE_PRINTF("ADC\t");
5680            break;
5681        case 3:
5682            DECODE_PRINTF("SBB\t");
5683            break;
5684        case 4:
5685            DECODE_PRINTF("AND\t");
5686            break;
5687        case 5:
5688            DECODE_PRINTF("SUB\t");
5689            break;
5690        case 6:
5691            DECODE_PRINTF("XOR\t");
5692            break;
5693        case 7:
5694            DECODE_PRINTF("CMP\t");
5695            break;
5696        }
5697    }
5698#endif
5699    /* know operation, decode the mod byte to find the addressing
5700       mode. */
5701    switch (mod) {
5702    case 0:
5703        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5704            u32 destval,imm;
5705
5706            DECODE_PRINTF("DWORD PTR ");
5707            destoffset = decode_rm00_address(rl);
5708            destval = fetch_data_long(destoffset);
5709            imm = (s8) fetch_byte_imm();
5710            DECODE_PRINTF2(",%x\n", imm);
5711            TRACE_AND_STEP();
5712            destval = (*opc83_long_operation[rh]) (destval, imm);
5713            if (rh != 7)
5714                store_data_long(destoffset, destval);
5715        } else {
5716            u16 destval,imm;
5717
5718            DECODE_PRINTF("WORD PTR ");
5719            destoffset = decode_rm00_address(rl);
5720            destval = fetch_data_word(destoffset);
5721            imm = (s8) fetch_byte_imm();
5722            DECODE_PRINTF2(",%x\n", imm);
5723            TRACE_AND_STEP();
5724            destval = (*opc83_word_operation[rh]) (destval, imm);
5725            if (rh != 7)
5726                store_data_word(destoffset, destval);
5727        }
5728        break;
5729    case 1:
5730        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5731            u32 destval,imm;
5732
5733            DECODE_PRINTF("DWORD PTR ");
5734            destoffset = decode_rm01_address(rl);
5735            destval = fetch_data_long(destoffset);
5736            imm = (s8) fetch_byte_imm();
5737            DECODE_PRINTF2(",%x\n", imm);
5738            TRACE_AND_STEP();
5739            destval = (*opc83_long_operation[rh]) (destval, imm);
5740            if (rh != 7)
5741                store_data_long(destoffset, destval);
5742        } else {
5743            u16 destval,imm;
5744
5745            DECODE_PRINTF("WORD PTR ");
5746            destoffset = decode_rm01_address(rl);
5747            destval = fetch_data_word(destoffset);
5748            imm = (s8) fetch_byte_imm();
5749            DECODE_PRINTF2(",%x\n", imm);
5750            TRACE_AND_STEP();
5751            destval = (*opc83_word_operation[rh]) (destval, imm);
5752            if (rh != 7)
5753                store_data_word(destoffset, destval);
5754        }
5755        break;
5756    case 2:
5757        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5758            u32 destval,imm;
5759
5760            DECODE_PRINTF("DWORD PTR ");
5761            destoffset = decode_rm10_address(rl);
5762            destval = fetch_data_long(destoffset);
5763            imm = (s8) fetch_byte_imm();
5764            DECODE_PRINTF2(",%x\n", imm);
5765            TRACE_AND_STEP();
5766            destval = (*opc83_long_operation[rh]) (destval, imm);
5767            if (rh != 7)
5768                store_data_long(destoffset, destval);
5769        } else {
5770            u16 destval,imm;
5771
5772            DECODE_PRINTF("WORD PTR ");
5773            destoffset = decode_rm10_address(rl);
5774            destval = fetch_data_word(destoffset);
5775            imm = (s8) fetch_byte_imm();
5776            DECODE_PRINTF2(",%x\n", imm);
5777            TRACE_AND_STEP();
5778            destval = (*opc83_word_operation[rh]) (destval, imm);
5779            if (rh != 7)
5780                store_data_word(destoffset, destval);
5781        }
5782        break;
5783    case 3:                     /* register to register */
5784        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5785            u32 *destreg;
5786            u32 destval,imm;
5787
5788            destreg = DECODE_RM_LONG_REGISTER(rl);
5789            imm = (s8) fetch_byte_imm();
5790            DECODE_PRINTF2(",%x\n", imm);
5791            TRACE_AND_STEP();
5792            destval = (*opc83_long_operation[rh]) (*destreg, imm);
5793            if (rh != 7)
5794                *destreg = destval;
5795        } else {
5796            u16 *destreg;
5797            u16 destval,imm;
5798
5799            destreg = DECODE_RM_WORD_REGISTER(rl);
5800            imm = (s8) fetch_byte_imm();
5801            DECODE_PRINTF2(",%x\n", imm);
5802            TRACE_AND_STEP();
5803            destval = (*opc83_word_operation[rh]) (*destreg, imm);
5804            if (rh != 7)
5805                *destreg = destval;
5806        }
5807        break;
5808    }
5809    DECODE_CLEAR_SEGOVR();
5810    END_OF_INSTR();
5811}
5812
5813/****************************************************************************
5814REMARKS:
5815Handles opcode 0x84
5816****************************************************************************/
5817static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5818{
5819    int mod, rl, rh;
5820    u8 *destreg, *srcreg;
5821    uint destoffset;
5822    u8 destval;
5823
5824    START_OF_INSTR();
5825    DECODE_PRINTF("TEST\t");
5826    FETCH_DECODE_MODRM(mod, rh, rl);
5827    switch (mod) {
5828    case 0:
5829        destoffset = decode_rm00_address(rl);
5830        DECODE_PRINTF(",");
5831        destval = fetch_data_byte(destoffset);
5832        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5833        DECODE_PRINTF("\n");
5834        TRACE_AND_STEP();
5835        test_byte(destval, *srcreg);
5836        break;
5837    case 1:
5838        destoffset = decode_rm01_address(rl);
5839        DECODE_PRINTF(",");
5840        destval = fetch_data_byte(destoffset);
5841        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5842        DECODE_PRINTF("\n");
5843        TRACE_AND_STEP();
5844        test_byte(destval, *srcreg);
5845        break;
5846    case 2:
5847        destoffset = decode_rm10_address(rl);
5848        DECODE_PRINTF(",");
5849        destval = fetch_data_byte(destoffset);
5850        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5851        DECODE_PRINTF("\n");
5852        TRACE_AND_STEP();
5853        test_byte(destval, *srcreg);
5854        break;
5855    case 3:                     /* register to register */
5856        destreg = DECODE_RM_BYTE_REGISTER(rl);
5857        DECODE_PRINTF(",");
5858        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5859        DECODE_PRINTF("\n");
5860        TRACE_AND_STEP();
5861        test_byte(*destreg, *srcreg);
5862        break;
5863    }
5864    DECODE_CLEAR_SEGOVR();
5865    END_OF_INSTR();
5866}
5867
5868/****************************************************************************
5869REMARKS:
5870Handles opcode 0x85
5871****************************************************************************/
5872static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5873{
5874    int mod, rl, rh;
5875    uint destoffset;
5876
5877    START_OF_INSTR();
5878    DECODE_PRINTF("TEST\t");
5879    FETCH_DECODE_MODRM(mod, rh, rl);
5880    switch (mod) {
5881    case 0:
5882        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5883            u32 destval;
5884            u32 *srcreg;
5885
5886            destoffset = decode_rm00_address(rl);
5887            DECODE_PRINTF(",");
5888            destval = fetch_data_long(destoffset);
5889            srcreg = DECODE_RM_LONG_REGISTER(rh);
5890            DECODE_PRINTF("\n");
5891            TRACE_AND_STEP();
5892            test_long(destval, *srcreg);
5893        } else {
5894            u16 destval;
5895            u16 *srcreg;
5896
5897            destoffset = decode_rm00_address(rl);
5898            DECODE_PRINTF(",");
5899            destval = fetch_data_word(destoffset);
5900            srcreg = DECODE_RM_WORD_REGISTER(rh);
5901            DECODE_PRINTF("\n");
5902            TRACE_AND_STEP();
5903            test_word(destval, *srcreg);
5904        }
5905        break;
5906    case 1:
5907        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5908            u32 destval;
5909            u32 *srcreg;
5910
5911            destoffset = decode_rm01_address(rl);
5912            DECODE_PRINTF(",");
5913            destval = fetch_data_long(destoffset);
5914            srcreg = DECODE_RM_LONG_REGISTER(rh);
5915            DECODE_PRINTF("\n");
5916            TRACE_AND_STEP();
5917            test_long(destval, *srcreg);
5918        } else {
5919            u16 destval;
5920            u16 *srcreg;
5921
5922            destoffset = decode_rm01_address(rl);
5923            DECODE_PRINTF(",");
5924            destval = fetch_data_word(destoffset);
5925            srcreg = DECODE_RM_WORD_REGISTER(rh);
5926            DECODE_PRINTF("\n");
5927            TRACE_AND_STEP();
5928            test_word(destval, *srcreg);
5929        }
5930        break;
5931    case 2:
5932        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5933            u32 destval;
5934            u32 *srcreg;
5935
5936            destoffset = decode_rm10_address(rl);
5937            DECODE_PRINTF(",");
5938            destval = fetch_data_long(destoffset);
5939            srcreg = DECODE_RM_LONG_REGISTER(rh);
5940            DECODE_PRINTF("\n");
5941            TRACE_AND_STEP();
5942            test_long(destval, *srcreg);
5943        } else {
5944            u16 destval;
5945            u16 *srcreg;
5946
5947            destoffset = decode_rm10_address(rl);
5948            DECODE_PRINTF(",");
5949            destval = fetch_data_word(destoffset);
5950            srcreg = DECODE_RM_WORD_REGISTER(rh);
5951            DECODE_PRINTF("\n");
5952            TRACE_AND_STEP();
5953            test_word(destval, *srcreg);
5954        }
5955        break;
5956    case 3:                     /* register to register */
5957        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5958            u32 *destreg,*srcreg;
5959
5960            destreg = DECODE_RM_LONG_REGISTER(rl);
5961            DECODE_PRINTF(",");
5962            srcreg = DECODE_RM_LONG_REGISTER(rh);
5963            DECODE_PRINTF("\n");
5964            TRACE_AND_STEP();
5965            test_long(*destreg, *srcreg);
5966        } else {
5967            u16 *destreg,*srcreg;
5968
5969            destreg = DECODE_RM_WORD_REGISTER(rl);
5970            DECODE_PRINTF(",");
5971            srcreg = DECODE_RM_WORD_REGISTER(rh);
5972            DECODE_PRINTF("\n");
5973            TRACE_AND_STEP();
5974            test_word(*destreg, *srcreg);
5975        }
5976        break;
5977    }
5978    DECODE_CLEAR_SEGOVR();
5979    END_OF_INSTR();
5980}
5981
5982/****************************************************************************
5983REMARKS:
5984Handles opcode 0x86
5985****************************************************************************/
5986static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5987{
5988    int mod, rl, rh;
5989    u8 *destreg, *srcreg;
5990    uint destoffset;
5991    u8 destval;
5992    u8 tmp;
5993
5994    START_OF_INSTR();
5995    DECODE_PRINTF("XCHG\t");
5996    FETCH_DECODE_MODRM(mod, rh, rl);
5997    switch (mod) {
5998    case 0:
5999        destoffset = decode_rm00_address(rl);
6000        DECODE_PRINTF(",");
6001        destval = fetch_data_byte(destoffset);
6002        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6003        DECODE_PRINTF("\n");
6004        TRACE_AND_STEP();
6005        tmp = *srcreg;
6006        *srcreg = destval;
6007        destval = tmp;
6008        store_data_byte(destoffset, destval);
6009        break;
6010    case 1:
6011        destoffset = decode_rm01_address(rl);
6012        DECODE_PRINTF(",");
6013        destval = fetch_data_byte(destoffset);
6014        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6015        DECODE_PRINTF("\n");
6016        TRACE_AND_STEP();
6017        tmp = *srcreg;
6018        *srcreg = destval;
6019        destval = tmp;
6020        store_data_byte(destoffset, destval);
6021        break;
6022    case 2:
6023        destoffset = decode_rm10_address(rl);
6024        DECODE_PRINTF(",");
6025        destval = fetch_data_byte(destoffset);
6026        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6027        DECODE_PRINTF("\n");
6028        TRACE_AND_STEP();
6029        tmp = *srcreg;
6030        *srcreg = destval;
6031        destval = tmp;
6032        store_data_byte(destoffset, destval);
6033        break;
6034    case 3:                     /* register to register */
6035        destreg = DECODE_RM_BYTE_REGISTER(rl);
6036        DECODE_PRINTF(",");
6037        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6038        DECODE_PRINTF("\n");
6039        TRACE_AND_STEP();
6040        tmp = *srcreg;
6041        *srcreg = *destreg;
6042        *destreg = tmp;
6043        break;
6044    }
6045    DECODE_CLEAR_SEGOVR();
6046    END_OF_INSTR();
6047}
6048
6049/****************************************************************************
6050REMARKS:
6051Handles opcode 0x87
6052****************************************************************************/
6053static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6054{
6055    int mod, rl, rh;
6056    uint destoffset;
6057
6058    START_OF_INSTR();
6059    DECODE_PRINTF("XCHG\t");
6060    FETCH_DECODE_MODRM(mod, rh, rl);
6061    switch (mod) {
6062    case 0:
6063        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6064            u32 *srcreg;
6065            u32 destval,tmp;
6066
6067            destoffset = decode_rm00_address(rl);
6068            DECODE_PRINTF(",");
6069            destval = fetch_data_long(destoffset);
6070            srcreg = DECODE_RM_LONG_REGISTER(rh);
6071            DECODE_PRINTF("\n");
6072            TRACE_AND_STEP();
6073            tmp = *srcreg;
6074            *srcreg = destval;
6075            destval = tmp;
6076            store_data_long(destoffset, destval);
6077        } else {
6078            u16 *srcreg;
6079            u16 destval,tmp;
6080
6081            destoffset = decode_rm00_address(rl);
6082            DECODE_PRINTF(",");
6083            destval = fetch_data_word(destoffset);
6084            srcreg = DECODE_RM_WORD_REGISTER(rh);
6085            DECODE_PRINTF("\n");
6086            TRACE_AND_STEP();
6087            tmp = *srcreg;
6088            *srcreg = destval;
6089            destval = tmp;
6090            store_data_word(destoffset, destval);
6091        }
6092        break;
6093    case 1:
6094        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6095            u32 *srcreg;
6096            u32 destval,tmp;
6097
6098            destoffset = decode_rm01_address(rl);
6099            DECODE_PRINTF(",");
6100            destval = fetch_data_long(destoffset);
6101            srcreg = DECODE_RM_LONG_REGISTER(rh);
6102            DECODE_PRINTF("\n");
6103            TRACE_AND_STEP();
6104            tmp = *srcreg;
6105            *srcreg = destval;
6106            destval = tmp;
6107            store_data_long(destoffset, destval);
6108        } else {
6109            u16 *srcreg;
6110            u16 destval,tmp;
6111
6112            destoffset = decode_rm01_address(rl);
6113            DECODE_PRINTF(",");
6114            destval = fetch_data_word(destoffset);
6115            srcreg = DECODE_RM_WORD_REGISTER(rh);
6116            DECODE_PRINTF("\n");
6117            TRACE_AND_STEP();
6118            tmp = *srcreg;
6119            *srcreg = destval;
6120            destval = tmp;
6121            store_data_word(destoffset, destval);
6122        }
6123        break;
6124    case 2:
6125        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6126            u32 *srcreg;
6127            u32 destval,tmp;
6128
6129            destoffset = decode_rm10_address(rl);
6130            DECODE_PRINTF(",");
6131            destval = fetch_data_long(destoffset);
6132            srcreg = DECODE_RM_LONG_REGISTER(rh);
6133            DECODE_PRINTF("\n");
6134            TRACE_AND_STEP();
6135            tmp = *srcreg;
6136            *srcreg = destval;
6137            destval = tmp;
6138            store_data_long(destoffset, destval);
6139        } else {
6140            u16 *srcreg;
6141            u16 destval,tmp;
6142
6143            destoffset = decode_rm10_address(rl);
6144            DECODE_PRINTF(",");
6145            destval = fetch_data_word(destoffset);
6146            srcreg = DECODE_RM_WORD_REGISTER(rh);
6147            DECODE_PRINTF("\n");
6148            TRACE_AND_STEP();
6149            tmp = *srcreg;
6150            *srcreg = destval;
6151            destval = tmp;
6152            store_data_word(destoffset, destval);
6153        }
6154        break;
6155    case 3:                     /* register to register */
6156        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6157            u32 *destreg,*srcreg;
6158            u32 tmp;
6159
6160            destreg = DECODE_RM_LONG_REGISTER(rl);
6161            DECODE_PRINTF(",");
6162            srcreg = DECODE_RM_LONG_REGISTER(rh);
6163            DECODE_PRINTF("\n");
6164            TRACE_AND_STEP();
6165            tmp = *srcreg;
6166            *srcreg = *destreg;
6167            *destreg = tmp;
6168        } else {
6169            u16 *destreg,*srcreg;
6170            u16 tmp;
6171
6172            destreg = DECODE_RM_WORD_REGISTER(rl);
6173            DECODE_PRINTF(",");
6174            srcreg = DECODE_RM_WORD_REGISTER(rh);
6175            DECODE_PRINTF("\n");
6176            TRACE_AND_STEP();
6177            tmp = *srcreg;
6178            *srcreg = *destreg;
6179            *destreg = tmp;
6180        }
6181        break;
6182    }
6183    DECODE_CLEAR_SEGOVR();
6184    END_OF_INSTR();
6185}
6186
6187/****************************************************************************
6188REMARKS:
6189Handles opcode 0x88
6190****************************************************************************/
6191static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6192{
6193    int mod, rl, rh;
6194    u8 *destreg, *srcreg;
6195    uint destoffset;
6196
6197    START_OF_INSTR();
6198    DECODE_PRINTF("MOV\t");
6199    FETCH_DECODE_MODRM(mod, rh, rl);
6200    switch (mod) {
6201    case 0:
6202        destoffset = decode_rm00_address(rl);
6203        DECODE_PRINTF(",");
6204        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6205        DECODE_PRINTF("\n");
6206        TRACE_AND_STEP();
6207        store_data_byte(destoffset, *srcreg);
6208        break;
6209    case 1:
6210        destoffset = decode_rm01_address(rl);
6211        DECODE_PRINTF(",");
6212        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6213        DECODE_PRINTF("\n");
6214        TRACE_AND_STEP();
6215        store_data_byte(destoffset, *srcreg);
6216        break;
6217    case 2:
6218        destoffset = decode_rm10_address(rl);
6219        DECODE_PRINTF(",");
6220        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6221        DECODE_PRINTF("\n");
6222        TRACE_AND_STEP();
6223        store_data_byte(destoffset, *srcreg);
6224        break;
6225    case 3:                     /* register to register */
6226        destreg = DECODE_RM_BYTE_REGISTER(rl);
6227        DECODE_PRINTF(",");
6228        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6229        DECODE_PRINTF("\n");
6230        TRACE_AND_STEP();
6231        *destreg = *srcreg;
6232        break;
6233    }
6234    DECODE_CLEAR_SEGOVR();
6235    END_OF_INSTR();
6236}
6237
6238/****************************************************************************
6239REMARKS:
6240Handles opcode 0x89
6241****************************************************************************/
6242static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6243{
6244    int mod, rl, rh;
6245    u32 destoffset;
6246
6247    START_OF_INSTR();
6248    DECODE_PRINTF("MOV\t");
6249    FETCH_DECODE_MODRM(mod, rh, rl);
6250    switch (mod) {
6251    case 0:
6252        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6253            u32 *srcreg;
6254
6255            destoffset = decode_rm00_address(rl);
6256            DECODE_PRINTF(",");
6257            srcreg = DECODE_RM_LONG_REGISTER(rh);
6258            DECODE_PRINTF("\n");
6259            TRACE_AND_STEP();
6260            store_data_long(destoffset, *srcreg);
6261        } else {
6262            u16 *srcreg;
6263
6264            destoffset = decode_rm00_address(rl);
6265            DECODE_PRINTF(",");
6266            srcreg = DECODE_RM_WORD_REGISTER(rh);
6267            DECODE_PRINTF("\n");
6268            TRACE_AND_STEP();
6269            store_data_word(destoffset, *srcreg);
6270        }
6271        break;
6272    case 1:
6273        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6274            u32 *srcreg;
6275
6276            destoffset = decode_rm01_address(rl);
6277            DECODE_PRINTF(",");
6278            srcreg = DECODE_RM_LONG_REGISTER(rh);
6279            DECODE_PRINTF("\n");
6280            TRACE_AND_STEP();
6281            store_data_long(destoffset, *srcreg);
6282        } else {
6283            u16 *srcreg;
6284
6285            destoffset = decode_rm01_address(rl);
6286            DECODE_PRINTF(",");
6287            srcreg = DECODE_RM_WORD_REGISTER(rh);
6288            DECODE_PRINTF("\n");
6289            TRACE_AND_STEP();
6290            store_data_word(destoffset, *srcreg);
6291        }
6292        break;
6293    case 2:
6294        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6295            u32 *srcreg;
6296
6297            destoffset = decode_rm10_address(rl);
6298            DECODE_PRINTF(",");
6299            srcreg = DECODE_RM_LONG_REGISTER(rh);
6300            DECODE_PRINTF("\n");
6301            TRACE_AND_STEP();
6302            store_data_long(destoffset, *srcreg);
6303        } else {
6304            u16 *srcreg;
6305
6306            destoffset = decode_rm10_address(rl);
6307            DECODE_PRINTF(",");
6308            srcreg = DECODE_RM_WORD_REGISTER(rh);
6309            DECODE_PRINTF("\n");
6310            TRACE_AND_STEP();
6311            store_data_word(destoffset, *srcreg);
6312        }
6313        break;
6314    case 3:                     /* register to register */
6315        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6316            u32 *destreg,*srcreg;
6317
6318            destreg = DECODE_RM_LONG_REGISTER(rl);
6319            DECODE_PRINTF(",");
6320            srcreg = DECODE_RM_LONG_REGISTER(rh);
6321            DECODE_PRINTF("\n");
6322            TRACE_AND_STEP();
6323            *destreg = *srcreg;
6324        } else {
6325            u16 *destreg,*srcreg;
6326
6327            destreg = DECODE_RM_WORD_REGISTER(rl);
6328            DECODE_PRINTF(",");
6329            srcreg = DECODE_RM_WORD_REGISTER(rh);
6330            DECODE_PRINTF("\n");
6331            TRACE_AND_STEP();
6332            *destreg = *srcreg;
6333        }
6334        break;
6335    }
6336    DECODE_CLEAR_SEGOVR();
6337    END_OF_INSTR();
6338}
6339
6340/****************************************************************************
6341REMARKS:
6342Handles opcode 0x8a
6343****************************************************************************/
6344static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6345{
6346    int mod, rl, rh;
6347    u8 *destreg, *srcreg;
6348    uint srcoffset;
6349    u8 srcval;
6350
6351    START_OF_INSTR();
6352    DECODE_PRINTF("MOV\t");
6353    FETCH_DECODE_MODRM(mod, rh, rl);
6354    switch (mod) {
6355    case 0:
6356        destreg = DECODE_RM_BYTE_REGISTER(rh);
6357        DECODE_PRINTF(",");
6358        srcoffset = decode_rm00_address(rl);
6359        srcval = fetch_data_byte(srcoffset);
6360        DECODE_PRINTF("\n");
6361        TRACE_AND_STEP();
6362        *destreg = srcval;
6363        break;
6364    case 1:
6365        destreg = DECODE_RM_BYTE_REGISTER(rh);
6366        DECODE_PRINTF(",");
6367        srcoffset = decode_rm01_address(rl);
6368        srcval = fetch_data_byte(srcoffset);
6369        DECODE_PRINTF("\n");
6370        TRACE_AND_STEP();
6371        *destreg = srcval;
6372        break;
6373    case 2:
6374        destreg = DECODE_RM_BYTE_REGISTER(rh);
6375        DECODE_PRINTF(",");
6376        srcoffset = decode_rm10_address(rl);
6377        srcval = fetch_data_byte(srcoffset);
6378        DECODE_PRINTF("\n");
6379        TRACE_AND_STEP();
6380        *destreg = srcval;
6381        break;
6382    case 3:                     /* register to register */
6383        destreg = DECODE_RM_BYTE_REGISTER(rh);
6384        DECODE_PRINTF(",");
6385        srcreg = DECODE_RM_BYTE_REGISTER(rl);
6386        DECODE_PRINTF("\n");
6387        TRACE_AND_STEP();
6388        *destreg = *srcreg;
6389        break;
6390    }
6391    DECODE_CLEAR_SEGOVR();
6392    END_OF_INSTR();
6393}
6394
6395/****************************************************************************
6396REMARKS:
6397Handles opcode 0x8b
6398****************************************************************************/
6399static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6400{
6401    int mod, rl, rh;
6402    uint srcoffset;
6403
6404    START_OF_INSTR();
6405    DECODE_PRINTF("MOV\t");
6406    FETCH_DECODE_MODRM(mod, rh, rl);
6407    switch (mod) {
6408    case 0:
6409        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6410            u32 *destreg;
6411            u32 srcval;
6412
6413            destreg = DECODE_RM_LONG_REGISTER(rh);
6414            DECODE_PRINTF(",");
6415            srcoffset = decode_rm00_address(rl);
6416            srcval = fetch_data_long(srcoffset);
6417            DECODE_PRINTF("\n");
6418            TRACE_AND_STEP();
6419            *destreg = srcval;
6420        } else {
6421            u16 *destreg;
6422            u16 srcval;
6423
6424            destreg = DECODE_RM_WORD_REGISTER(rh);
6425            DECODE_PRINTF(",");
6426            srcoffset = decode_rm00_address(rl);
6427            srcval = fetch_data_word(srcoffset);
6428            DECODE_PRINTF("\n");
6429            TRACE_AND_STEP();
6430            *destreg = srcval;
6431        }
6432        break;
6433    case 1:
6434        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6435            u32 *destreg;
6436            u32 srcval;
6437
6438            destreg = DECODE_RM_LONG_REGISTER(rh);
6439            DECODE_PRINTF(",");
6440            srcoffset = decode_rm01_address(rl);
6441            srcval = fetch_data_long(srcoffset);
6442            DECODE_PRINTF("\n");
6443            TRACE_AND_STEP();
6444            *destreg = srcval;
6445        } else {
6446            u16 *destreg;
6447            u16 srcval;
6448
6449            destreg = DECODE_RM_WORD_REGISTER(rh);
6450            DECODE_PRINTF(",");
6451            srcoffset = decode_rm01_address(rl);
6452            srcval = fetch_data_word(srcoffset);
6453            DECODE_PRINTF("\n");
6454            TRACE_AND_STEP();
6455            *destreg = srcval;
6456        }
6457        break;
6458    case 2:
6459        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6460            u32 *destreg;
6461            u32 srcval;
6462
6463            destreg = DECODE_RM_LONG_REGISTER(rh);
6464            DECODE_PRINTF(",");
6465            srcoffset = decode_rm10_address(rl);
6466            srcval = fetch_data_long(srcoffset);
6467            DECODE_PRINTF("\n");
6468            TRACE_AND_STEP();
6469            *destreg = srcval;
6470        } else {
6471            u16 *destreg;
6472            u16 srcval;
6473
6474            destreg = DECODE_RM_WORD_REGISTER(rh);
6475            DECODE_PRINTF(",");
6476            srcoffset = decode_rm10_address(rl);
6477            srcval = fetch_data_word(srcoffset);
6478            DECODE_PRINTF("\n");
6479            TRACE_AND_STEP();
6480            *destreg = srcval;
6481        }
6482        break;
6483    case 3:                     /* register to register */
6484        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6485            u32 *destreg, *srcreg;
6486
6487            destreg = DECODE_RM_LONG_REGISTER(rh);
6488            DECODE_PRINTF(",");
6489            srcreg = DECODE_RM_LONG_REGISTER(rl);
6490            DECODE_PRINTF("\n");
6491            TRACE_AND_STEP();
6492            *destreg = *srcreg;
6493        } else {
6494            u16 *destreg, *srcreg;
6495
6496            destreg = DECODE_RM_WORD_REGISTER(rh);
6497            DECODE_PRINTF(",");
6498            srcreg = DECODE_RM_WORD_REGISTER(rl);
6499            DECODE_PRINTF("\n");
6500            TRACE_AND_STEP();
6501            *destreg = *srcreg;
6502        }
6503        break;
6504    }
6505    DECODE_CLEAR_SEGOVR();
6506    END_OF_INSTR();
6507}
6508
6509/****************************************************************************
6510REMARKS:
6511Handles opcode 0x8c
6512****************************************************************************/
6513static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6514{
6515    int mod, rl, rh;
6516    u16 *destreg, *srcreg;
6517    uint destoffset;
6518    u16 destval;
6519
6520    START_OF_INSTR();
6521    DECODE_PRINTF("MOV\t");
6522    FETCH_DECODE_MODRM(mod, rh, rl);
6523    switch (mod) {
6524    case 0:
6525        destoffset = decode_rm00_address(rl);
6526        DECODE_PRINTF(",");
6527        srcreg = decode_rm_seg_register(rh);
6528        DECODE_PRINTF("\n");
6529        TRACE_AND_STEP();
6530        destval = *srcreg;
6531        store_data_word(destoffset, destval);
6532        break;
6533    case 1:
6534        destoffset = decode_rm01_address(rl);
6535        DECODE_PRINTF(",");
6536        srcreg = decode_rm_seg_register(rh);
6537        DECODE_PRINTF("\n");
6538        TRACE_AND_STEP();
6539        destval = *srcreg;
6540        store_data_word(destoffset, destval);
6541        break;
6542    case 2:
6543        destoffset = decode_rm10_address(rl);
6544        DECODE_PRINTF(",");
6545        srcreg = decode_rm_seg_register(rh);
6546        DECODE_PRINTF("\n");
6547        TRACE_AND_STEP();
6548        destval = *srcreg;
6549        store_data_word(destoffset, destval);
6550        break;
6551    case 3:                     /* register to register */
6552        destreg = DECODE_RM_WORD_REGISTER(rl);
6553        DECODE_PRINTF(",");
6554        srcreg = decode_rm_seg_register(rh);
6555        DECODE_PRINTF("\n");
6556        TRACE_AND_STEP();
6557        *destreg = *srcreg;
6558        break;
6559    }
6560    DECODE_CLEAR_SEGOVR();
6561    END_OF_INSTR();
6562}
6563
6564/****************************************************************************
6565REMARKS:
6566Handles opcode 0x8d
6567****************************************************************************/
6568static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6569{
6570    int mod, rl, rh;
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_DATA) {
6578            u32 *srcreg;
6579            u32 destoffset;
6580
6581            srcreg = DECODE_RM_LONG_REGISTER(rh);
6582            DECODE_PRINTF(",");
6583            destoffset = decode_rm00_address(rl);
6584            DECODE_PRINTF("\n");
6585            TRACE_AND_STEP();
6586            *srcreg = destoffset;
6587        } else {
6588            u16 *srcreg;
6589            u16 destoffset;
6590
6591            srcreg = DECODE_RM_WORD_REGISTER(rh);
6592            DECODE_PRINTF(",");
6593            destoffset = decode_rm00_address(rl);
6594            DECODE_PRINTF("\n");
6595            TRACE_AND_STEP();
6596            *srcreg = destoffset;
6597        }
6598        break;
6599    case 1:
6600        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6601            u32 *srcreg;
6602            u32 destoffset;
6603
6604            srcreg = DECODE_RM_LONG_REGISTER(rh);
6605            DECODE_PRINTF(",");
6606            destoffset = decode_rm01_address(rl);
6607            DECODE_PRINTF("\n");
6608            TRACE_AND_STEP();
6609            *srcreg = destoffset;
6610        } else {
6611            u16 *srcreg;
6612            u16 destoffset;
6613
6614            srcreg = DECODE_RM_WORD_REGISTER(rh);
6615            DECODE_PRINTF(",");
6616            destoffset = decode_rm01_address(rl);
6617            DECODE_PRINTF("\n");
6618            TRACE_AND_STEP();
6619            *srcreg = destoffset;
6620        }
6621        break;
6622    case 2:
6623        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6624            u32 *srcreg;
6625            u32 destoffset;
6626
6627            srcreg = DECODE_RM_LONG_REGISTER(rh);
6628            DECODE_PRINTF(",");
6629            destoffset = decode_rm10_address(rl);
6630            DECODE_PRINTF("\n");
6631            TRACE_AND_STEP();
6632            *srcreg = destoffset;
6633        } else {
6634            u16 *srcreg;
6635            u16 destoffset;
6636
6637            srcreg = DECODE_RM_WORD_REGISTER(rh);
6638            DECODE_PRINTF(",");
6639            destoffset = decode_rm10_address(rl);
6640            DECODE_PRINTF("\n");
6641            TRACE_AND_STEP();
6642            *srcreg = destoffset;
6643        }
6644        break;
6645    case 3:                     /* register to register */
6646        /* undefined.  Do nothing. */
6647        break;
6648    }
6649    DECODE_CLEAR_SEGOVR();
6650    END_OF_INSTR();
6651}
6652
6653/****************************************************************************
6654REMARKS:
6655Handles opcode 0x8e
6656****************************************************************************/
6657static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6658{
6659    int mod, rl, rh;
6660    u16 *destreg, *srcreg;
6661    uint srcoffset;
6662    u16 srcval;
6663
6664    START_OF_INSTR();
6665    DECODE_PRINTF("MOV\t");
6666    FETCH_DECODE_MODRM(mod, rh, rl);
6667    switch (mod) {
6668    case 0:
6669        destreg = decode_rm_seg_register(rh);
6670        DECODE_PRINTF(",");
6671        srcoffset = decode_rm00_address(rl);
6672        srcval = fetch_data_word(srcoffset);
6673        DECODE_PRINTF("\n");
6674        TRACE_AND_STEP();
6675        *destreg = srcval;
6676        break;
6677    case 1:
6678        destreg = decode_rm_seg_register(rh);
6679        DECODE_PRINTF(",");
6680        srcoffset = decode_rm01_address(rl);
6681        srcval = fetch_data_word(srcoffset);
6682        DECODE_PRINTF("\n");
6683        TRACE_AND_STEP();
6684        *destreg = srcval;
6685        break;
6686    case 2:
6687        destreg = decode_rm_seg_register(rh);
6688        DECODE_PRINTF(",");
6689        srcoffset = decode_rm10_address(rl);
6690        srcval = fetch_data_word(srcoffset);
6691        DECODE_PRINTF("\n");
6692        TRACE_AND_STEP();
6693        *destreg = srcval;
6694        break;
6695    case 3:                     /* register to register */
6696        destreg = decode_rm_seg_register(rh);
6697        DECODE_PRINTF(",");
6698        srcreg = DECODE_RM_WORD_REGISTER(rl);
6699        DECODE_PRINTF("\n");
6700        TRACE_AND_STEP();
6701        *destreg = *srcreg;
6702        break;
6703    }
6704    /*
6705     * Clean up, and reset all the R_xSP pointers to the correct
6706     * locations.  This is about 3x too much overhead (doing all the
6707     * segreg ptrs when only one is needed, but this instruction
6708     * *cannot* be that common, and this isn't too much work anyway.
6709     */
6710    DECODE_CLEAR_SEGOVR();
6711    END_OF_INSTR();
6712}
6713
6714/****************************************************************************
6715REMARKS:
6716Handles opcode 0x8f
6717****************************************************************************/
6718static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6719{
6720    int mod, rl, rh;
6721    uint destoffset;
6722
6723    START_OF_INSTR();
6724    DECODE_PRINTF("POP\t");
6725    FETCH_DECODE_MODRM(mod, rh, rl);
6726    if (rh != 0) {
6727        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6728        HALT_SYS();
6729    }
6730    switch (mod) {
6731    case 0:
6732        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6733            u32 destval;
6734
6735            destoffset = decode_rm00_address(rl);
6736            DECODE_PRINTF("\n");
6737            TRACE_AND_STEP();
6738            destval = pop_long();
6739            store_data_long(destoffset, destval);
6740        } else {
6741            u16 destval;
6742
6743            destoffset = decode_rm00_address(rl);
6744            DECODE_PRINTF("\n");
6745            TRACE_AND_STEP();
6746            destval = pop_word();
6747            store_data_word(destoffset, destval);
6748        }
6749        break;
6750    case 1:
6751        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6752            u32 destval;
6753
6754            destoffset = decode_rm01_address(rl);
6755            DECODE_PRINTF("\n");
6756            TRACE_AND_STEP();
6757            destval = pop_long();
6758            store_data_long(destoffset, destval);
6759        } else {
6760            u16 destval;
6761
6762            destoffset = decode_rm01_address(rl);
6763            DECODE_PRINTF("\n");
6764            TRACE_AND_STEP();
6765            destval = pop_word();
6766            store_data_word(destoffset, destval);
6767        }
6768        break;
6769    case 2:
6770        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6771            u32 destval;
6772
6773            destoffset = decode_rm10_address(rl);
6774            DECODE_PRINTF("\n");
6775            TRACE_AND_STEP();
6776            destval = pop_long();
6777            store_data_long(destoffset, destval);
6778        } else {
6779            u16 destval;
6780
6781            destoffset = decode_rm10_address(rl);
6782            DECODE_PRINTF("\n");
6783            TRACE_AND_STEP();
6784            destval = pop_word();
6785            store_data_word(destoffset, destval);
6786        }
6787        break;
6788    case 3:                     /* register to register */
6789        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6790            u32 *destreg;
6791
6792            destreg = DECODE_RM_LONG_REGISTER(rl);
6793            DECODE_PRINTF("\n");
6794            TRACE_AND_STEP();
6795            *destreg = pop_long();
6796        } else {
6797            u16 *destreg;
6798
6799            destreg = DECODE_RM_WORD_REGISTER(rl);
6800            DECODE_PRINTF("\n");
6801            TRACE_AND_STEP();
6802            *destreg = pop_word();
6803        }
6804        break;
6805    }
6806    DECODE_CLEAR_SEGOVR();
6807    END_OF_INSTR();
6808}
6809
6810/****************************************************************************
6811REMARKS:
6812Handles opcode 0x90
6813****************************************************************************/
6814static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6815{
6816    START_OF_INSTR();
6817    DECODE_PRINTF("NOP\n");
6818    TRACE_AND_STEP();
6819    DECODE_CLEAR_SEGOVR();
6820    END_OF_INSTR();
6821}
6822
6823/****************************************************************************
6824REMARKS:
6825Handles opcode 0x91
6826****************************************************************************/
6827static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6828{
6829    u32 tmp;
6830
6831    START_OF_INSTR();
6832    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6833        DECODE_PRINTF("XCHG\tEAX,ECX\n");
6834    } else {
6835        DECODE_PRINTF("XCHG\tAX,CX\n");
6836    }
6837    TRACE_AND_STEP();
6838    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6839        tmp = M.x86.R_EAX;
6840        M.x86.R_EAX = M.x86.R_ECX;
6841        M.x86.R_ECX = tmp;
6842    } else {
6843        tmp = M.x86.R_AX;
6844        M.x86.R_AX = M.x86.R_CX;
6845        M.x86.R_CX = (u16)tmp;
6846    }
6847    DECODE_CLEAR_SEGOVR();
6848    END_OF_INSTR();
6849}
6850
6851/****************************************************************************
6852REMARKS:
6853Handles opcode 0x92
6854****************************************************************************/
6855static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6856{
6857    u32 tmp;
6858
6859    START_OF_INSTR();
6860    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6861        DECODE_PRINTF("XCHG\tEAX,EDX\n");
6862    } else {
6863        DECODE_PRINTF("XCHG\tAX,DX\n");
6864    }
6865    TRACE_AND_STEP();
6866    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6867        tmp = M.x86.R_EAX;
6868        M.x86.R_EAX = M.x86.R_EDX;
6869        M.x86.R_EDX = tmp;
6870    } else {
6871        tmp = M.x86.R_AX;
6872        M.x86.R_AX = M.x86.R_DX;
6873        M.x86.R_DX = (u16)tmp;
6874    }
6875    DECODE_CLEAR_SEGOVR();
6876    END_OF_INSTR();
6877}
6878
6879/****************************************************************************
6880REMARKS:
6881Handles opcode 0x93
6882****************************************************************************/
6883static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6884{
6885    u32 tmp;
6886
6887    START_OF_INSTR();
6888    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6889        DECODE_PRINTF("XCHG\tEAX,EBX\n");
6890    } else {
6891        DECODE_PRINTF("XCHG\tAX,BX\n");
6892    }
6893    TRACE_AND_STEP();
6894    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6895        tmp = M.x86.R_EAX;
6896        M.x86.R_EAX = M.x86.R_EBX;
6897        M.x86.R_EBX = tmp;
6898    } else {
6899        tmp = M.x86.R_AX;
6900        M.x86.R_AX = M.x86.R_BX;
6901        M.x86.R_BX = (u16)tmp;
6902    }
6903    DECODE_CLEAR_SEGOVR();
6904    END_OF_INSTR();
6905}
6906
6907/****************************************************************************
6908REMARKS:
6909Handles opcode 0x94
6910****************************************************************************/
6911static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6912{
6913    u32 tmp;
6914
6915    START_OF_INSTR();
6916    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6917        DECODE_PRINTF("XCHG\tEAX,ESP\n");
6918    } else {
6919        DECODE_PRINTF("XCHG\tAX,SP\n");
6920    }
6921    TRACE_AND_STEP();
6922    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6923        tmp = M.x86.R_EAX;
6924        M.x86.R_EAX = M.x86.R_ESP;
6925        M.x86.R_ESP = tmp;
6926    } else {
6927        tmp = M.x86.R_AX;
6928        M.x86.R_AX = M.x86.R_SP;
6929        M.x86.R_SP = (u16)tmp;
6930    }
6931    DECODE_CLEAR_SEGOVR();
6932    END_OF_INSTR();
6933}
6934
6935/****************************************************************************
6936REMARKS:
6937Handles opcode 0x95
6938****************************************************************************/
6939static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6940{
6941    u32 tmp;
6942
6943    START_OF_INSTR();
6944    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6945        DECODE_PRINTF("XCHG\tEAX,EBP\n");
6946    } else {
6947        DECODE_PRINTF("XCHG\tAX,BP\n");
6948    }
6949    TRACE_AND_STEP();
6950    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6951        tmp = M.x86.R_EAX;
6952        M.x86.R_EAX = M.x86.R_EBP;
6953        M.x86.R_EBP = tmp;
6954    } else {
6955        tmp = M.x86.R_AX;
6956        M.x86.R_AX = M.x86.R_BP;
6957        M.x86.R_BP = (u16)tmp;
6958    }
6959    DECODE_CLEAR_SEGOVR();
6960    END_OF_INSTR();
6961}
6962
6963/****************************************************************************
6964REMARKS:
6965Handles opcode 0x96
6966****************************************************************************/
6967static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6968{
6969    u32 tmp;
6970
6971    START_OF_INSTR();
6972    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6973        DECODE_PRINTF("XCHG\tEAX,ESI\n");
6974    } else {
6975        DECODE_PRINTF("XCHG\tAX,SI\n");
6976    }
6977    TRACE_AND_STEP();
6978    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6979        tmp = M.x86.R_EAX;
6980        M.x86.R_EAX = M.x86.R_ESI;
6981        M.x86.R_ESI = tmp;
6982    } else {
6983        tmp = M.x86.R_AX;
6984        M.x86.R_AX = M.x86.R_SI;
6985        M.x86.R_SI = (u16)tmp;
6986    }
6987    DECODE_CLEAR_SEGOVR();
6988    END_OF_INSTR();
6989}
6990
6991/****************************************************************************
6992REMARKS:
6993Handles opcode 0x97
6994****************************************************************************/
6995static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6996{
6997    u32 tmp;
6998
6999    START_OF_INSTR();
7000    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7001        DECODE_PRINTF("XCHG\tEAX,EDI\n");
7002    } else {
7003        DECODE_PRINTF("XCHG\tAX,DI\n");
7004    }
7005    TRACE_AND_STEP();
7006    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7007        tmp = M.x86.R_EAX;
7008        M.x86.R_EAX = M.x86.R_EDI;
7009        M.x86.R_EDI = tmp;
7010    } else {
7011        tmp = M.x86.R_AX;
7012        M.x86.R_AX = M.x86.R_DI;
7013        M.x86.R_DI = (u16)tmp;
7014    }
7015    DECODE_CLEAR_SEGOVR();
7016    END_OF_INSTR();
7017}
7018
7019/****************************************************************************
7020REMARKS:
7021Handles opcode 0x98
7022****************************************************************************/
7023static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7024{
7025    START_OF_INSTR();
7026    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7027        DECODE_PRINTF("CWDE\n");
7028    } else {
7029        DECODE_PRINTF("CBW\n");
7030    }
7031    TRACE_AND_STEP();
7032    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7033        if (M.x86.R_AX & 0x8000) {
7034            M.x86.R_EAX |= 0xffff0000;
7035        } else {
7036            M.x86.R_EAX &= 0x0000ffff;
7037        }
7038    } else {
7039        if (M.x86.R_AL & 0x80) {
7040            M.x86.R_AH = 0xff;
7041        } else {
7042            M.x86.R_AH = 0x0;
7043        }
7044    }
7045    DECODE_CLEAR_SEGOVR();
7046    END_OF_INSTR();
7047}
7048
7049/****************************************************************************
7050REMARKS:
7051Handles opcode 0x99
7052****************************************************************************/
7053static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7054{
7055    START_OF_INSTR();
7056    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7057        DECODE_PRINTF("CDQ\n");
7058    } else {
7059        DECODE_PRINTF("CWD\n");
7060    }
7061    DECODE_PRINTF("CWD\n");
7062    TRACE_AND_STEP();
7063    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7064        if (M.x86.R_EAX & 0x80000000) {
7065            M.x86.R_EDX = 0xffffffff;
7066        } else {
7067            M.x86.R_EDX = 0x0;
7068        }
7069    } else {
7070        if (M.x86.R_AX & 0x8000) {
7071            M.x86.R_DX = 0xffff;
7072        } else {
7073            M.x86.R_DX = 0x0;
7074        }
7075    }
7076    DECODE_CLEAR_SEGOVR();
7077    END_OF_INSTR();
7078}
7079
7080/****************************************************************************
7081REMARKS:
7082Handles opcode 0x9a
7083****************************************************************************/
7084static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7085{
7086    u16 farseg, faroff;
7087
7088    START_OF_INSTR();
7089	DECODE_PRINTF("CALL\t");
7090	faroff = fetch_word_imm();
7091	farseg = fetch_word_imm();
7092	DECODE_PRINTF2("%04x:", farseg);
7093	DECODE_PRINTF2("%04x\n", faroff);
7094	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7095
7096    /* XXX
7097     *
7098     * Hooked interrupt vectors calling into our "BIOS" will cause
7099     * problems unless all intersegment stuff is checked for BIOS
7100     * access.  Check needed here.  For moment, let it alone.
7101     */
7102    TRACE_AND_STEP();
7103    push_word(M.x86.R_CS);
7104    M.x86.R_CS = farseg;
7105    push_word(M.x86.R_IP);
7106    M.x86.R_IP = faroff;
7107    DECODE_CLEAR_SEGOVR();
7108    END_OF_INSTR();
7109}
7110
7111/****************************************************************************
7112REMARKS:
7113Handles opcode 0x9b
7114****************************************************************************/
7115static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7116{
7117    START_OF_INSTR();
7118    DECODE_PRINTF("WAIT");
7119    TRACE_AND_STEP();
7120    /* NADA.  */
7121    DECODE_CLEAR_SEGOVR();
7122    END_OF_INSTR();
7123}
7124
7125/****************************************************************************
7126REMARKS:
7127Handles opcode 0x9c
7128****************************************************************************/
7129static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7130{
7131    u32 flags;
7132
7133    START_OF_INSTR();
7134    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7135        DECODE_PRINTF("PUSHFD\n");
7136    } else {
7137        DECODE_PRINTF("PUSHF\n");
7138    }
7139    TRACE_AND_STEP();
7140
7141    /* clear out *all* bits not representing flags, and turn on real bits */
7142    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7143    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7144        push_long(flags);
7145    } else {
7146        push_word((u16)flags);
7147    }
7148    DECODE_CLEAR_SEGOVR();
7149    END_OF_INSTR();
7150}
7151
7152/****************************************************************************
7153REMARKS:
7154Handles opcode 0x9d
7155****************************************************************************/
7156static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7157{
7158    START_OF_INSTR();
7159    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7160        DECODE_PRINTF("POPFD\n");
7161    } else {
7162        DECODE_PRINTF("POPF\n");
7163    }
7164    TRACE_AND_STEP();
7165    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7166        M.x86.R_EFLG = pop_long();
7167    } else {
7168        M.x86.R_FLG = pop_word();
7169    }
7170    DECODE_CLEAR_SEGOVR();
7171    END_OF_INSTR();
7172}
7173
7174/****************************************************************************
7175REMARKS:
7176Handles opcode 0x9e
7177****************************************************************************/
7178static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7179{
7180    START_OF_INSTR();
7181    DECODE_PRINTF("SAHF\n");
7182    TRACE_AND_STEP();
7183    /* clear the lower bits of the flag register */
7184    M.x86.R_FLG &= 0xffffff00;
7185    /* or in the AH register into the flags register */
7186    M.x86.R_FLG |= M.x86.R_AH;
7187    DECODE_CLEAR_SEGOVR();
7188    END_OF_INSTR();
7189}
7190
7191/****************************************************************************
7192REMARKS:
7193Handles opcode 0x9f
7194****************************************************************************/
7195static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7196{
7197    START_OF_INSTR();
7198    DECODE_PRINTF("LAHF\n");
7199    TRACE_AND_STEP();
7200	M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7201    /*undocumented TC++ behavior??? Nope.  It's documented, but
7202       you have too look real hard to notice it. */
7203    M.x86.R_AH |= 0x2;
7204    DECODE_CLEAR_SEGOVR();
7205    END_OF_INSTR();
7206}
7207
7208/****************************************************************************
7209REMARKS:
7210Handles opcode 0xa0
7211****************************************************************************/
7212static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7213{
7214    u16 offset;
7215
7216    START_OF_INSTR();
7217    DECODE_PRINTF("MOV\tAL,");
7218    offset = fetch_word_imm();
7219    DECODE_PRINTF2("[%04x]\n", offset);
7220    TRACE_AND_STEP();
7221    M.x86.R_AL = fetch_data_byte(offset);
7222    DECODE_CLEAR_SEGOVR();
7223    END_OF_INSTR();
7224}
7225
7226/****************************************************************************
7227REMARKS:
7228Handles opcode 0xa1
7229****************************************************************************/
7230static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7231{
7232    u16 offset;
7233
7234    START_OF_INSTR();
7235    offset = fetch_word_imm();
7236    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7237        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7238    } else {
7239        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7240    }
7241    TRACE_AND_STEP();
7242    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7243        M.x86.R_EAX = fetch_data_long(offset);
7244    } else {
7245        M.x86.R_AX = fetch_data_word(offset);
7246    }
7247    DECODE_CLEAR_SEGOVR();
7248    END_OF_INSTR();
7249}
7250
7251/****************************************************************************
7252REMARKS:
7253Handles opcode 0xa2
7254****************************************************************************/
7255static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7256{
7257    u16 offset;
7258
7259    START_OF_INSTR();
7260    DECODE_PRINTF("MOV\t");
7261    offset = fetch_word_imm();
7262    DECODE_PRINTF2("[%04x],AL\n", offset);
7263    TRACE_AND_STEP();
7264    store_data_byte(offset, M.x86.R_AL);
7265    DECODE_CLEAR_SEGOVR();
7266    END_OF_INSTR();
7267}
7268
7269/****************************************************************************
7270REMARKS:
7271Handles opcode 0xa3
7272****************************************************************************/
7273static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7274{
7275    u16 offset;
7276
7277    START_OF_INSTR();
7278    offset = fetch_word_imm();
7279    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7280        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7281    } else {
7282        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7283    }
7284    TRACE_AND_STEP();
7285    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7286        store_data_long(offset, M.x86.R_EAX);
7287    } else {
7288        store_data_word(offset, M.x86.R_AX);
7289    }
7290    DECODE_CLEAR_SEGOVR();
7291    END_OF_INSTR();
7292}
7293
7294/****************************************************************************
7295REMARKS:
7296Handles opcode 0xa4
7297****************************************************************************/
7298static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7299{
7300    u8  val;
7301    u32 count;
7302    int inc;
7303
7304    START_OF_INSTR();
7305    DECODE_PRINTF("MOVS\tBYTE\n");
7306    if (ACCESS_FLAG(F_DF))   /* down */
7307        inc = -1;
7308    else
7309        inc = 1;
7310    TRACE_AND_STEP();
7311    count = 1;
7312    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7313        /* dont care whether REPE or REPNE */
7314        /* move them until CX is ZERO. */
7315        count = M.x86.R_CX;
7316        M.x86.R_CX = 0;
7317        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7318    }
7319    while (count--) {
7320        val = fetch_data_byte(M.x86.R_SI);
7321        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7322        M.x86.R_SI += inc;
7323        M.x86.R_DI += inc;
7324    }
7325    DECODE_CLEAR_SEGOVR();
7326    END_OF_INSTR();
7327}
7328
7329/****************************************************************************
7330REMARKS:
7331Handles opcode 0xa5
7332****************************************************************************/
7333static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7334{
7335    u32 val;
7336    int inc;
7337    u32 count;
7338
7339    START_OF_INSTR();
7340    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7341        DECODE_PRINTF("MOVS\tDWORD\n");
7342        if (ACCESS_FLAG(F_DF))      /* down */
7343            inc = -4;
7344        else
7345            inc = 4;
7346    } else {
7347        DECODE_PRINTF("MOVS\tWORD\n");
7348        if (ACCESS_FLAG(F_DF))      /* down */
7349            inc = -2;
7350        else
7351            inc = 2;
7352    }
7353    TRACE_AND_STEP();
7354    count = 1;
7355    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7356        /* dont care whether REPE or REPNE */
7357        /* move them until CX is ZERO. */
7358        count = M.x86.R_CX;
7359        M.x86.R_CX = 0;
7360        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7361    }
7362    while (count--) {
7363        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7364            val = fetch_data_long(M.x86.R_SI);
7365            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7366        } else {
7367            val = fetch_data_word(M.x86.R_SI);
7368            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7369        }
7370        M.x86.R_SI += inc;
7371        M.x86.R_DI += inc;
7372    }
7373    DECODE_CLEAR_SEGOVR();
7374    END_OF_INSTR();
7375}
7376
7377/****************************************************************************
7378REMARKS:
7379Handles opcode 0xa6
7380****************************************************************************/
7381static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7382{
7383    s8 val1, val2;
7384    int inc;
7385
7386    START_OF_INSTR();
7387    DECODE_PRINTF("CMPS\tBYTE\n");
7388    TRACE_AND_STEP();
7389    if (ACCESS_FLAG(F_DF))   /* down */
7390        inc = -1;
7391    else
7392        inc = 1;
7393
7394    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7395        /* REPE  */
7396        /* move them until CX is ZERO. */
7397        while (M.x86.R_CX != 0) {
7398            val1 = fetch_data_byte(M.x86.R_SI);
7399            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7400                     cmp_byte(val1, val2);
7401            M.x86.R_CX -= 1;
7402            M.x86.R_SI += inc;
7403            M.x86.R_DI += inc;
7404            if (ACCESS_FLAG(F_ZF) == 0)
7405                break;
7406        }
7407        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7408    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7409        /* REPNE  */
7410        /* move them until CX is ZERO. */
7411        while (M.x86.R_CX != 0) {
7412            val1 = fetch_data_byte(M.x86.R_SI);
7413            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7414            cmp_byte(val1, val2);
7415            M.x86.R_CX -= 1;
7416            M.x86.R_SI += inc;
7417            M.x86.R_DI += inc;
7418            if (ACCESS_FLAG(F_ZF))
7419                break;          /* zero flag set means equal */
7420        }
7421        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7422    } else {
7423        val1 = fetch_data_byte(M.x86.R_SI);
7424        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7425        cmp_byte(val1, val2);
7426        M.x86.R_SI += inc;
7427        M.x86.R_DI += inc;
7428    }
7429    DECODE_CLEAR_SEGOVR();
7430    END_OF_INSTR();
7431}
7432
7433/****************************************************************************
7434REMARKS:
7435Handles opcode 0xa7
7436****************************************************************************/
7437static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7438{
7439    u32 val1,val2;
7440    int inc;
7441
7442    START_OF_INSTR();
7443    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7444        DECODE_PRINTF("CMPS\tDWORD\n");
7445        if (ACCESS_FLAG(F_DF))   /* down */
7446            inc = -4;
7447        else
7448            inc = 4;
7449    } else {
7450        DECODE_PRINTF("CMPS\tWORD\n");
7451        if (ACCESS_FLAG(F_DF))   /* down */
7452            inc = -2;
7453        else
7454            inc = 2;
7455    }
7456    TRACE_AND_STEP();
7457    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7458        /* REPE  */
7459        /* move them until CX is ZERO. */
7460        while (M.x86.R_CX != 0) {
7461            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7462                val1 = fetch_data_long(M.x86.R_SI);
7463                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7464                cmp_long(val1, val2);
7465            } else {
7466                val1 = fetch_data_word(M.x86.R_SI);
7467                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7468                cmp_word((u16)val1, (u16)val2);
7469            }
7470            M.x86.R_CX -= 1;
7471            M.x86.R_SI += inc;
7472            M.x86.R_DI += inc;
7473            if (ACCESS_FLAG(F_ZF) == 0)
7474                break;
7475        }
7476        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7477    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7478        /* REPNE  */
7479        /* move them until CX is ZERO. */
7480        while (M.x86.R_CX != 0) {
7481            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7482                val1 = fetch_data_long(M.x86.R_SI);
7483                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7484                cmp_long(val1, val2);
7485            } else {
7486                val1 = fetch_data_word(M.x86.R_SI);
7487                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7488                cmp_word((u16)val1, (u16)val2);
7489            }
7490            M.x86.R_CX -= 1;
7491            M.x86.R_SI += inc;
7492            M.x86.R_DI += inc;
7493            if (ACCESS_FLAG(F_ZF))
7494                break;          /* zero flag set means equal */
7495        }
7496        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7497    } else {
7498        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7499            val1 = fetch_data_long(M.x86.R_SI);
7500            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7501            cmp_long(val1, val2);
7502        } else {
7503            val1 = fetch_data_word(M.x86.R_SI);
7504            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7505            cmp_word((u16)val1, (u16)val2);
7506        }
7507        M.x86.R_SI += inc;
7508        M.x86.R_DI += inc;
7509    }
7510    DECODE_CLEAR_SEGOVR();
7511    END_OF_INSTR();
7512}
7513
7514/****************************************************************************
7515REMARKS:
7516Handles opcode 0xa8
7517****************************************************************************/
7518static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7519{
7520    int imm;
7521
7522    START_OF_INSTR();
7523    DECODE_PRINTF("TEST\tAL,");
7524    imm = fetch_byte_imm();
7525    DECODE_PRINTF2("%04x\n", imm);
7526    TRACE_AND_STEP();
7527	test_byte(M.x86.R_AL, (u8)imm);
7528    DECODE_CLEAR_SEGOVR();
7529    END_OF_INSTR();
7530}
7531
7532/****************************************************************************
7533REMARKS:
7534Handles opcode 0xa9
7535****************************************************************************/
7536static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7537{
7538    u32 srcval;
7539
7540    START_OF_INSTR();
7541    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7542        DECODE_PRINTF("TEST\tEAX,");
7543        srcval = fetch_long_imm();
7544    } else {
7545        DECODE_PRINTF("TEST\tAX,");
7546        srcval = fetch_word_imm();
7547    }
7548    DECODE_PRINTF2("%x\n", srcval);
7549    TRACE_AND_STEP();
7550    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7551        test_long(M.x86.R_EAX, srcval);
7552    } else {
7553        test_word(M.x86.R_AX, (u16)srcval);
7554    }
7555    DECODE_CLEAR_SEGOVR();
7556    END_OF_INSTR();
7557}
7558
7559/****************************************************************************
7560REMARKS:
7561Handles opcode 0xaa
7562****************************************************************************/
7563static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7564{
7565    int inc;
7566
7567    START_OF_INSTR();
7568    DECODE_PRINTF("STOS\tBYTE\n");
7569    if (ACCESS_FLAG(F_DF))   /* down */
7570        inc = -1;
7571    else
7572        inc = 1;
7573    TRACE_AND_STEP();
7574    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7575        /* dont care whether REPE or REPNE */
7576        /* move them until CX is ZERO. */
7577        while (M.x86.R_CX != 0) {
7578            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7579            M.x86.R_CX -= 1;
7580            M.x86.R_DI += inc;
7581        }
7582        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7583    } else {
7584        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7585        M.x86.R_DI += inc;
7586    }
7587    DECODE_CLEAR_SEGOVR();
7588    END_OF_INSTR();
7589}
7590
7591/****************************************************************************
7592REMARKS:
7593Handles opcode 0xab
7594****************************************************************************/
7595static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7596{
7597    int inc;
7598    u32 count;
7599
7600    START_OF_INSTR();
7601    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7602        DECODE_PRINTF("STOS\tDWORD\n");
7603        if (ACCESS_FLAG(F_DF))   /* down */
7604            inc = -4;
7605        else
7606            inc = 4;
7607    } else {
7608        DECODE_PRINTF("STOS\tWORD\n");
7609        if (ACCESS_FLAG(F_DF))   /* down */
7610            inc = -2;
7611        else
7612            inc = 2;
7613    }
7614    TRACE_AND_STEP();
7615    count = 1;
7616    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7617        /* dont care whether REPE or REPNE */
7618        /* move them until CX is ZERO. */
7619        count = M.x86.R_CX;
7620        M.x86.R_CX = 0;
7621        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7622    }
7623    while (count--) {
7624        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7625            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7626        } else {
7627            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7628        }
7629        M.x86.R_DI += inc;
7630    }
7631    DECODE_CLEAR_SEGOVR();
7632    END_OF_INSTR();
7633}
7634
7635/****************************************************************************
7636REMARKS:
7637Handles opcode 0xac
7638****************************************************************************/
7639static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7640{
7641    int inc;
7642
7643    START_OF_INSTR();
7644    DECODE_PRINTF("LODS\tBYTE\n");
7645    TRACE_AND_STEP();
7646    if (ACCESS_FLAG(F_DF))   /* down */
7647        inc = -1;
7648    else
7649        inc = 1;
7650    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7651        /* dont care whether REPE or REPNE */
7652        /* move them until CX is ZERO. */
7653        while (M.x86.R_CX != 0) {
7654            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7655            M.x86.R_CX -= 1;
7656            M.x86.R_SI += inc;
7657        }
7658        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7659    } else {
7660        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7661        M.x86.R_SI += inc;
7662    }
7663    DECODE_CLEAR_SEGOVR();
7664    END_OF_INSTR();
7665}
7666
7667/****************************************************************************
7668REMARKS:
7669Handles opcode 0xad
7670****************************************************************************/
7671static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7672{
7673    int inc;
7674    u32 count;
7675
7676    START_OF_INSTR();
7677    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7678        DECODE_PRINTF("LODS\tDWORD\n");
7679        if (ACCESS_FLAG(F_DF))   /* down */
7680            inc = -4;
7681        else
7682            inc = 4;
7683    } else {
7684        DECODE_PRINTF("LODS\tWORD\n");
7685        if (ACCESS_FLAG(F_DF))   /* down */
7686            inc = -2;
7687        else
7688            inc = 2;
7689    }
7690    TRACE_AND_STEP();
7691    count = 1;
7692    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7693        /* dont care whether REPE or REPNE */
7694        /* move them until CX is ZERO. */
7695        count = M.x86.R_CX;
7696        M.x86.R_CX = 0;
7697        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7698    }
7699    while (count--) {
7700        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7701            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7702        } else {
7703            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7704        }
7705        M.x86.R_SI += inc;
7706    }
7707    DECODE_CLEAR_SEGOVR();
7708    END_OF_INSTR();
7709}
7710
7711/****************************************************************************
7712REMARKS:
7713Handles opcode 0xae
7714****************************************************************************/
7715static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7716{
7717    s8 val2;
7718    int inc;
7719
7720    START_OF_INSTR();
7721    DECODE_PRINTF("SCAS\tBYTE\n");
7722    TRACE_AND_STEP();
7723    if (ACCESS_FLAG(F_DF))   /* down */
7724        inc = -1;
7725    else
7726        inc = 1;
7727    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7728        /* REPE  */
7729        /* move them until CX is ZERO. */
7730        while (M.x86.R_CX != 0) {
7731            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7732            cmp_byte(M.x86.R_AL, val2);
7733            M.x86.R_CX -= 1;
7734            M.x86.R_DI += inc;
7735            if (ACCESS_FLAG(F_ZF) == 0)
7736                break;
7737        }
7738        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7739    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7740        /* REPNE  */
7741        /* move them until CX is ZERO. */
7742        while (M.x86.R_CX != 0) {
7743            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7744            cmp_byte(M.x86.R_AL, val2);
7745            M.x86.R_CX -= 1;
7746            M.x86.R_DI += inc;
7747            if (ACCESS_FLAG(F_ZF))
7748                break;          /* zero flag set means equal */
7749        }
7750        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7751    } else {
7752        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7753        cmp_byte(M.x86.R_AL, val2);
7754        M.x86.R_DI += inc;
7755    }
7756    DECODE_CLEAR_SEGOVR();
7757    END_OF_INSTR();
7758}
7759
7760/****************************************************************************
7761REMARKS:
7762Handles opcode 0xaf
7763****************************************************************************/
7764static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7765{
7766    int inc;
7767    u32 val;
7768
7769    START_OF_INSTR();
7770    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7771        DECODE_PRINTF("SCAS\tDWORD\n");
7772        if (ACCESS_FLAG(F_DF))   /* down */
7773            inc = -4;
7774        else
7775            inc = 4;
7776    } else {
7777        DECODE_PRINTF("SCAS\tWORD\n");
7778        if (ACCESS_FLAG(F_DF))   /* down */
7779            inc = -2;
7780        else
7781            inc = 2;
7782    }
7783    TRACE_AND_STEP();
7784    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7785        /* REPE  */
7786        /* move them until CX is ZERO. */
7787        while (M.x86.R_CX != 0) {
7788            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7789                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7790                cmp_long(M.x86.R_EAX, val);
7791            } else {
7792                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7793                cmp_word(M.x86.R_AX, (u16)val);
7794            }
7795            M.x86.R_CX -= 1;
7796            M.x86.R_DI += inc;
7797            if (ACCESS_FLAG(F_ZF) == 0)
7798                break;
7799        }
7800        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7801    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7802        /* REPNE  */
7803        /* move them until CX is ZERO. */
7804        while (M.x86.R_CX != 0) {
7805            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7806                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7807                cmp_long(M.x86.R_EAX, val);
7808            } else {
7809                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7810                cmp_word(M.x86.R_AX, (u16)val);
7811            }
7812            M.x86.R_CX -= 1;
7813            M.x86.R_DI += inc;
7814            if (ACCESS_FLAG(F_ZF))
7815                break;          /* zero flag set means equal */
7816        }
7817        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7818    } else {
7819        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7820            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7821            cmp_long(M.x86.R_EAX, val);
7822        } else {
7823            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7824            cmp_word(M.x86.R_AX, (u16)val);
7825        }
7826        M.x86.R_DI += inc;
7827    }
7828    DECODE_CLEAR_SEGOVR();
7829    END_OF_INSTR();
7830}
7831
7832/****************************************************************************
7833REMARKS:
7834Handles opcode 0xb0
7835****************************************************************************/
7836static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7837{
7838    u8 imm;
7839
7840    START_OF_INSTR();
7841    DECODE_PRINTF("MOV\tAL,");
7842    imm = fetch_byte_imm();
7843    DECODE_PRINTF2("%x\n", imm);
7844    TRACE_AND_STEP();
7845    M.x86.R_AL = imm;
7846    DECODE_CLEAR_SEGOVR();
7847    END_OF_INSTR();
7848}
7849
7850/****************************************************************************
7851REMARKS:
7852Handles opcode 0xb1
7853****************************************************************************/
7854static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7855{
7856    u8 imm;
7857
7858    START_OF_INSTR();
7859    DECODE_PRINTF("MOV\tCL,");
7860    imm = fetch_byte_imm();
7861    DECODE_PRINTF2("%x\n", imm);
7862    TRACE_AND_STEP();
7863    M.x86.R_CL = imm;
7864    DECODE_CLEAR_SEGOVR();
7865    END_OF_INSTR();
7866}
7867
7868/****************************************************************************
7869REMARKS:
7870Handles opcode 0xb2
7871****************************************************************************/
7872static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7873{
7874    u8 imm;
7875
7876    START_OF_INSTR();
7877    DECODE_PRINTF("MOV\tDL,");
7878    imm = fetch_byte_imm();
7879    DECODE_PRINTF2("%x\n", imm);
7880    TRACE_AND_STEP();
7881    M.x86.R_DL = imm;
7882    DECODE_CLEAR_SEGOVR();
7883    END_OF_INSTR();
7884}
7885
7886/****************************************************************************
7887REMARKS:
7888Handles opcode 0xb3
7889****************************************************************************/
7890static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7891{
7892    u8 imm;
7893
7894    START_OF_INSTR();
7895    DECODE_PRINTF("MOV\tBL,");
7896    imm = fetch_byte_imm();
7897    DECODE_PRINTF2("%x\n", imm);
7898    TRACE_AND_STEP();
7899    M.x86.R_BL = imm;
7900    DECODE_CLEAR_SEGOVR();
7901    END_OF_INSTR();
7902}
7903
7904/****************************************************************************
7905REMARKS:
7906Handles opcode 0xb4
7907****************************************************************************/
7908static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7909{
7910    u8 imm;
7911
7912    START_OF_INSTR();
7913    DECODE_PRINTF("MOV\tAH,");
7914    imm = fetch_byte_imm();
7915    DECODE_PRINTF2("%x\n", imm);
7916    TRACE_AND_STEP();
7917    M.x86.R_AH = imm;
7918    DECODE_CLEAR_SEGOVR();
7919    END_OF_INSTR();
7920}
7921
7922/****************************************************************************
7923REMARKS:
7924Handles opcode 0xb5
7925****************************************************************************/
7926static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7927{
7928    u8 imm;
7929
7930    START_OF_INSTR();
7931    DECODE_PRINTF("MOV\tCH,");
7932    imm = fetch_byte_imm();
7933    DECODE_PRINTF2("%x\n", imm);
7934    TRACE_AND_STEP();
7935    M.x86.R_CH = imm;
7936    DECODE_CLEAR_SEGOVR();
7937    END_OF_INSTR();
7938}
7939
7940/****************************************************************************
7941REMARKS:
7942Handles opcode 0xb6
7943****************************************************************************/
7944static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7945{
7946    u8 imm;
7947
7948    START_OF_INSTR();
7949    DECODE_PRINTF("MOV\tDH,");
7950    imm = fetch_byte_imm();
7951    DECODE_PRINTF2("%x\n", imm);
7952    TRACE_AND_STEP();
7953    M.x86.R_DH = imm;
7954    DECODE_CLEAR_SEGOVR();
7955    END_OF_INSTR();
7956}
7957
7958/****************************************************************************
7959REMARKS:
7960Handles opcode 0xb7
7961****************************************************************************/
7962static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7963{
7964    u8 imm;
7965
7966    START_OF_INSTR();
7967    DECODE_PRINTF("MOV\tBH,");
7968    imm = fetch_byte_imm();
7969    DECODE_PRINTF2("%x\n", imm);
7970    TRACE_AND_STEP();
7971    M.x86.R_BH = imm;
7972    DECODE_CLEAR_SEGOVR();
7973    END_OF_INSTR();
7974}
7975
7976/****************************************************************************
7977REMARKS:
7978Handles opcode 0xb8
7979****************************************************************************/
7980static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7981{
7982    u32 srcval;
7983
7984    START_OF_INSTR();
7985    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7986        DECODE_PRINTF("MOV\tEAX,");
7987        srcval = fetch_long_imm();
7988    } else {
7989        DECODE_PRINTF("MOV\tAX,");
7990        srcval = fetch_word_imm();
7991    }
7992    DECODE_PRINTF2("%x\n", srcval);
7993    TRACE_AND_STEP();
7994    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7995        M.x86.R_EAX = srcval;
7996    } else {
7997        M.x86.R_AX = (u16)srcval;
7998    }
7999    DECODE_CLEAR_SEGOVR();
8000    END_OF_INSTR();
8001}
8002
8003/****************************************************************************
8004REMARKS:
8005Handles opcode 0xb9
8006****************************************************************************/
8007static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8008{
8009    u32 srcval;
8010
8011    START_OF_INSTR();
8012    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8013        DECODE_PRINTF("MOV\tECX,");
8014        srcval = fetch_long_imm();
8015    } else {
8016        DECODE_PRINTF("MOV\tCX,");
8017        srcval = fetch_word_imm();
8018    }
8019    DECODE_PRINTF2("%x\n", srcval);
8020    TRACE_AND_STEP();
8021    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8022        M.x86.R_ECX = srcval;
8023    } else {
8024        M.x86.R_CX = (u16)srcval;
8025    }
8026    DECODE_CLEAR_SEGOVR();
8027    END_OF_INSTR();
8028}
8029
8030/****************************************************************************
8031REMARKS:
8032Handles opcode 0xba
8033****************************************************************************/
8034static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8035{
8036    u32 srcval;
8037
8038    START_OF_INSTR();
8039    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8040        DECODE_PRINTF("MOV\tEDX,");
8041        srcval = fetch_long_imm();
8042    } else {
8043        DECODE_PRINTF("MOV\tDX,");
8044        srcval = fetch_word_imm();
8045    }
8046    DECODE_PRINTF2("%x\n", srcval);
8047    TRACE_AND_STEP();
8048    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8049        M.x86.R_EDX = srcval;
8050    } else {
8051        M.x86.R_DX = (u16)srcval;
8052    }
8053    DECODE_CLEAR_SEGOVR();
8054    END_OF_INSTR();
8055}
8056
8057/****************************************************************************
8058REMARKS:
8059Handles opcode 0xbb
8060****************************************************************************/
8061static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8062{
8063    u32 srcval;
8064
8065    START_OF_INSTR();
8066    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8067        DECODE_PRINTF("MOV\tEBX,");
8068        srcval = fetch_long_imm();
8069    } else {
8070        DECODE_PRINTF("MOV\tBX,");
8071        srcval = fetch_word_imm();
8072    }
8073    DECODE_PRINTF2("%x\n", srcval);
8074    TRACE_AND_STEP();
8075    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8076        M.x86.R_EBX = srcval;
8077    } else {
8078        M.x86.R_BX = (u16)srcval;
8079    }
8080    DECODE_CLEAR_SEGOVR();
8081    END_OF_INSTR();
8082}
8083
8084/****************************************************************************
8085REMARKS:
8086Handles opcode 0xbc
8087****************************************************************************/
8088static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8089{
8090    u32 srcval;
8091
8092    START_OF_INSTR();
8093    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8094        DECODE_PRINTF("MOV\tESP,");
8095        srcval = fetch_long_imm();
8096    } else {
8097        DECODE_PRINTF("MOV\tSP,");
8098        srcval = fetch_word_imm();
8099    }
8100    DECODE_PRINTF2("%x\n", srcval);
8101    TRACE_AND_STEP();
8102    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8103        M.x86.R_ESP = srcval;
8104    } else {
8105        M.x86.R_SP = (u16)srcval;
8106    }
8107    DECODE_CLEAR_SEGOVR();
8108    END_OF_INSTR();
8109}
8110
8111/****************************************************************************
8112REMARKS:
8113Handles opcode 0xbd
8114****************************************************************************/
8115static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8116{
8117    u32 srcval;
8118
8119    START_OF_INSTR();
8120    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8121        DECODE_PRINTF("MOV\tEBP,");
8122        srcval = fetch_long_imm();
8123    } else {
8124        DECODE_PRINTF("MOV\tBP,");
8125        srcval = fetch_word_imm();
8126    }
8127    DECODE_PRINTF2("%x\n", srcval);
8128    TRACE_AND_STEP();
8129    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8130        M.x86.R_EBP = srcval;
8131    } else {
8132        M.x86.R_BP = (u16)srcval;
8133    }
8134    DECODE_CLEAR_SEGOVR();
8135    END_OF_INSTR();
8136}
8137
8138/****************************************************************************
8139REMARKS:
8140Handles opcode 0xbe
8141****************************************************************************/
8142static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8143{
8144    u32 srcval;
8145
8146    START_OF_INSTR();
8147    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8148        DECODE_PRINTF("MOV\tESI,");
8149        srcval = fetch_long_imm();
8150    } else {
8151        DECODE_PRINTF("MOV\tSI,");
8152        srcval = fetch_word_imm();
8153    }
8154    DECODE_PRINTF2("%x\n", srcval);
8155    TRACE_AND_STEP();
8156    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8157        M.x86.R_ESI = srcval;
8158    } else {
8159        M.x86.R_SI = (u16)srcval;
8160    }
8161    DECODE_CLEAR_SEGOVR();
8162    END_OF_INSTR();
8163}
8164
8165/****************************************************************************
8166REMARKS:
8167Handles opcode 0xbf
8168****************************************************************************/
8169static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8170{
8171    u32 srcval;
8172
8173    START_OF_INSTR();
8174    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8175        DECODE_PRINTF("MOV\tEDI,");
8176        srcval = fetch_long_imm();
8177    } else {
8178        DECODE_PRINTF("MOV\tDI,");
8179        srcval = fetch_word_imm();
8180    }
8181    DECODE_PRINTF2("%x\n", srcval);
8182    TRACE_AND_STEP();
8183    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8184        M.x86.R_EDI = srcval;
8185    } else {
8186        M.x86.R_DI = (u16)srcval;
8187    }
8188    DECODE_CLEAR_SEGOVR();
8189    END_OF_INSTR();
8190}
8191
8192/* used by opcodes c0, d0, and d2. */
8193static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8194{
8195    rol_byte,
8196    ror_byte,
8197    rcl_byte,
8198    rcr_byte,
8199    shl_byte,
8200    shr_byte,
8201    shl_byte,           /* sal_byte === shl_byte  by definition */
8202    sar_byte,
8203};
8204
8205/****************************************************************************
8206REMARKS:
8207Handles opcode 0xc0
8208****************************************************************************/
8209static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8210{
8211    int mod, rl, rh;
8212    u8 *destreg;
8213    uint destoffset;
8214    u8 destval;
8215    u8 amt;
8216
8217    /*
8218     * Yet another weirdo special case instruction format.  Part of
8219     * the opcode held below in "RH".  Doubly nested case would
8220     * result, except that the decoded instruction
8221     */
8222    START_OF_INSTR();
8223    FETCH_DECODE_MODRM(mod, rh, rl);
8224#ifdef DEBUG
8225    if (DEBUG_DECODE()) {
8226        /* XXX DECODE_PRINTF may be changed to something more
8227           general, so that it is important to leave the strings
8228           in the same format, even though the result is that the
8229           above test is done twice. */
8230
8231        switch (rh) {
8232        case 0:
8233            DECODE_PRINTF("ROL\t");
8234            break;
8235        case 1:
8236            DECODE_PRINTF("ROR\t");
8237            break;
8238        case 2:
8239            DECODE_PRINTF("RCL\t");
8240            break;
8241        case 3:
8242            DECODE_PRINTF("RCR\t");
8243            break;
8244        case 4:
8245            DECODE_PRINTF("SHL\t");
8246            break;
8247        case 5:
8248            DECODE_PRINTF("SHR\t");
8249            break;
8250        case 6:
8251            DECODE_PRINTF("SAL\t");
8252            break;
8253        case 7:
8254            DECODE_PRINTF("SAR\t");
8255            break;
8256        }
8257    }
8258#endif
8259    /* know operation, decode the mod byte to find the addressing
8260       mode. */
8261    switch (mod) {
8262    case 0:
8263        DECODE_PRINTF("BYTE PTR ");
8264        destoffset = decode_rm00_address(rl);
8265        amt = fetch_byte_imm();
8266        DECODE_PRINTF2(",%x\n", amt);
8267        destval = fetch_data_byte(destoffset);
8268        TRACE_AND_STEP();
8269        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8270        store_data_byte(destoffset, destval);
8271        break;
8272    case 1:
8273        DECODE_PRINTF("BYTE PTR ");
8274        destoffset = decode_rm01_address(rl);
8275        amt = fetch_byte_imm();
8276        DECODE_PRINTF2(",%x\n", amt);
8277        destval = fetch_data_byte(destoffset);
8278        TRACE_AND_STEP();
8279        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8280        store_data_byte(destoffset, destval);
8281        break;
8282    case 2:
8283        DECODE_PRINTF("BYTE PTR ");
8284        destoffset = decode_rm10_address(rl);
8285        amt = fetch_byte_imm();
8286        DECODE_PRINTF2(",%x\n", amt);
8287        destval = fetch_data_byte(destoffset);
8288        TRACE_AND_STEP();
8289        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8290        store_data_byte(destoffset, destval);
8291        break;
8292    case 3:                     /* register to register */
8293        destreg = DECODE_RM_BYTE_REGISTER(rl);
8294        amt = fetch_byte_imm();
8295        DECODE_PRINTF2(",%x\n", amt);
8296        TRACE_AND_STEP();
8297        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8298        *destreg = destval;
8299        break;
8300    }
8301    DECODE_CLEAR_SEGOVR();
8302    END_OF_INSTR();
8303}
8304
8305/* used by opcodes c1, d1, and d3. */
8306static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8307{
8308    rol_word,
8309    ror_word,
8310    rcl_word,
8311    rcr_word,
8312    shl_word,
8313    shr_word,
8314    shl_word,           /* sal_byte === shl_byte  by definition */
8315    sar_word,
8316};
8317
8318/* used by opcodes c1, d1, and d3. */
8319static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8320{
8321    rol_long,
8322    ror_long,
8323    rcl_long,
8324    rcr_long,
8325    shl_long,
8326    shr_long,
8327    shl_long,           /* sal_byte === shl_byte  by definition */
8328    sar_long,
8329};
8330
8331/****************************************************************************
8332REMARKS:
8333Handles opcode 0xc1
8334****************************************************************************/
8335static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8336{
8337    int mod, rl, rh;
8338    uint destoffset;
8339    u8 amt;
8340
8341    /*
8342     * Yet another weirdo special case instruction format.  Part of
8343     * the opcode held below in "RH".  Doubly nested case would
8344     * result, except that the decoded instruction
8345     */
8346    START_OF_INSTR();
8347    FETCH_DECODE_MODRM(mod, rh, rl);
8348#ifdef DEBUG
8349    if (DEBUG_DECODE()) {
8350        /* XXX DECODE_PRINTF may be changed to something more
8351           general, so that it is important to leave the strings
8352           in the same format, even though the result is that the
8353           above test is done twice. */
8354
8355        switch (rh) {
8356        case 0:
8357            DECODE_PRINTF("ROL\t");
8358            break;
8359        case 1:
8360            DECODE_PRINTF("ROR\t");
8361            break;
8362        case 2:
8363            DECODE_PRINTF("RCL\t");
8364            break;
8365        case 3:
8366            DECODE_PRINTF("RCR\t");
8367            break;
8368        case 4:
8369            DECODE_PRINTF("SHL\t");
8370            break;
8371        case 5:
8372            DECODE_PRINTF("SHR\t");
8373            break;
8374        case 6:
8375            DECODE_PRINTF("SAL\t");
8376            break;
8377        case 7:
8378            DECODE_PRINTF("SAR\t");
8379            break;
8380        }
8381    }
8382#endif
8383    /* know operation, decode the mod byte to find the addressing
8384       mode. */
8385    switch (mod) {
8386    case 0:
8387        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8388            u32 destval;
8389
8390            DECODE_PRINTF("DWORD PTR ");
8391            destoffset = decode_rm00_address(rl);
8392            amt = fetch_byte_imm();
8393            DECODE_PRINTF2(",%x\n", amt);
8394            destval = fetch_data_long(destoffset);
8395            TRACE_AND_STEP();
8396            destval = (*opcD1_long_operation[rh]) (destval, amt);
8397            store_data_long(destoffset, destval);
8398        } else {
8399            u16 destval;
8400
8401            DECODE_PRINTF("WORD PTR ");
8402            destoffset = decode_rm00_address(rl);
8403            amt = fetch_byte_imm();
8404            DECODE_PRINTF2(",%x\n", amt);
8405            destval = fetch_data_word(destoffset);
8406            TRACE_AND_STEP();
8407            destval = (*opcD1_word_operation[rh]) (destval, amt);
8408            store_data_word(destoffset, destval);
8409        }
8410        break;
8411    case 1:
8412        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8413            u32 destval;
8414
8415            DECODE_PRINTF("DWORD PTR ");
8416            destoffset = decode_rm01_address(rl);
8417            amt = fetch_byte_imm();
8418            DECODE_PRINTF2(",%x\n", amt);
8419            destval = fetch_data_long(destoffset);
8420            TRACE_AND_STEP();
8421            destval = (*opcD1_long_operation[rh]) (destval, amt);
8422            store_data_long(destoffset, destval);
8423        } else {
8424            u16 destval;
8425
8426            DECODE_PRINTF("WORD PTR ");
8427            destoffset = decode_rm01_address(rl);
8428            amt = fetch_byte_imm();
8429            DECODE_PRINTF2(",%x\n", amt);
8430            destval = fetch_data_word(destoffset);
8431            TRACE_AND_STEP();
8432            destval = (*opcD1_word_operation[rh]) (destval, amt);
8433            store_data_word(destoffset, destval);
8434        }
8435        break;
8436    case 2:
8437        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8438            u32 destval;
8439
8440            DECODE_PRINTF("DWORD PTR ");
8441            destoffset = decode_rm10_address(rl);
8442            amt = fetch_byte_imm();
8443            DECODE_PRINTF2(",%x\n", amt);
8444            destval = fetch_data_long(destoffset);
8445            TRACE_AND_STEP();
8446            destval = (*opcD1_long_operation[rh]) (destval, amt);
8447            store_data_long(destoffset, destval);
8448        } else {
8449            u16 destval;
8450
8451            DECODE_PRINTF("WORD PTR ");
8452            destoffset = decode_rm10_address(rl);
8453            amt = fetch_byte_imm();
8454            DECODE_PRINTF2(",%x\n", amt);
8455            destval = fetch_data_word(destoffset);
8456            TRACE_AND_STEP();
8457            destval = (*opcD1_word_operation[rh]) (destval, amt);
8458            store_data_word(destoffset, destval);
8459        }
8460        break;
8461    case 3:                     /* register to register */
8462        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8463            u32 *destreg;
8464
8465            destreg = DECODE_RM_LONG_REGISTER(rl);
8466            amt = fetch_byte_imm();
8467            DECODE_PRINTF2(",%x\n", amt);
8468            TRACE_AND_STEP();
8469            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8470        } else {
8471            u16 *destreg;
8472
8473            destreg = DECODE_RM_WORD_REGISTER(rl);
8474            amt = fetch_byte_imm();
8475            DECODE_PRINTF2(",%x\n", amt);
8476            TRACE_AND_STEP();
8477            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8478        }
8479        break;
8480    }
8481    DECODE_CLEAR_SEGOVR();
8482    END_OF_INSTR();
8483}
8484
8485/****************************************************************************
8486REMARKS:
8487Handles opcode 0xc2
8488****************************************************************************/
8489static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8490{
8491    u16 imm;
8492
8493    START_OF_INSTR();
8494    DECODE_PRINTF("RET\t");
8495    imm = fetch_word_imm();
8496    DECODE_PRINTF2("%x\n", imm);
8497	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8498	TRACE_AND_STEP();
8499    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8500        M.x86.R_IP = pop_long();
8501    } else {
8502        M.x86.R_IP = pop_word();
8503    }
8504    M.x86.R_SP += imm;
8505    DECODE_CLEAR_SEGOVR();
8506    END_OF_INSTR();
8507}
8508
8509/****************************************************************************
8510REMARKS:
8511Handles opcode 0xc3
8512****************************************************************************/
8513static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8514{
8515    START_OF_INSTR();
8516    DECODE_PRINTF("RET\n");
8517	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8518	TRACE_AND_STEP();
8519    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8520        M.x86.R_IP = pop_long();
8521    } else {
8522        M.x86.R_IP = pop_word();
8523    }
8524    DECODE_CLEAR_SEGOVR();
8525    END_OF_INSTR();
8526}
8527
8528/****************************************************************************
8529REMARKS:
8530Handles opcode 0xc4
8531****************************************************************************/
8532static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8533{
8534    int mod, rh, rl;
8535    u16 *dstreg;
8536    uint srcoffset;
8537
8538    START_OF_INSTR();
8539    DECODE_PRINTF("LES\t");
8540    FETCH_DECODE_MODRM(mod, rh, rl);
8541    switch (mod) {
8542    case 0:
8543        dstreg = DECODE_RM_WORD_REGISTER(rh);
8544        DECODE_PRINTF(",");
8545        srcoffset = decode_rm00_address(rl);
8546        DECODE_PRINTF("\n");
8547        TRACE_AND_STEP();
8548        *dstreg = fetch_data_word(srcoffset);
8549        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8550        break;
8551    case 1:
8552        dstreg = DECODE_RM_WORD_REGISTER(rh);
8553        DECODE_PRINTF(",");
8554        srcoffset = decode_rm01_address(rl);
8555        DECODE_PRINTF("\n");
8556        TRACE_AND_STEP();
8557        *dstreg = fetch_data_word(srcoffset);
8558        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8559        break;
8560    case 2:
8561        dstreg = DECODE_RM_WORD_REGISTER(rh);
8562        DECODE_PRINTF(",");
8563        srcoffset = decode_rm10_address(rl);
8564        DECODE_PRINTF("\n");
8565        TRACE_AND_STEP();
8566        *dstreg = fetch_data_word(srcoffset);
8567        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8568        break;
8569    case 3:                     /* register to register */
8570        /* UNDEFINED! */
8571        TRACE_AND_STEP();
8572    }
8573    DECODE_CLEAR_SEGOVR();
8574    END_OF_INSTR();
8575}
8576
8577/****************************************************************************
8578REMARKS:
8579Handles opcode 0xc5
8580****************************************************************************/
8581static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8582{
8583    int mod, rh, rl;
8584    u16 *dstreg;
8585    uint srcoffset;
8586
8587    START_OF_INSTR();
8588    DECODE_PRINTF("LDS\t");
8589    FETCH_DECODE_MODRM(mod, rh, rl);
8590    switch (mod) {
8591    case 0:
8592        dstreg = DECODE_RM_WORD_REGISTER(rh);
8593        DECODE_PRINTF(",");
8594        srcoffset = decode_rm00_address(rl);
8595        DECODE_PRINTF("\n");
8596        TRACE_AND_STEP();
8597        *dstreg = fetch_data_word(srcoffset);
8598        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8599        break;
8600    case 1:
8601        dstreg = DECODE_RM_WORD_REGISTER(rh);
8602        DECODE_PRINTF(",");
8603        srcoffset = decode_rm01_address(rl);
8604        DECODE_PRINTF("\n");
8605        TRACE_AND_STEP();
8606        *dstreg = fetch_data_word(srcoffset);
8607        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8608        break;
8609    case 2:
8610        dstreg = DECODE_RM_WORD_REGISTER(rh);
8611        DECODE_PRINTF(",");
8612        srcoffset = decode_rm10_address(rl);
8613        DECODE_PRINTF("\n");
8614        TRACE_AND_STEP();
8615        *dstreg = fetch_data_word(srcoffset);
8616        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8617        break;
8618    case 3:                     /* register to register */
8619        /* UNDEFINED! */
8620        TRACE_AND_STEP();
8621    }
8622    DECODE_CLEAR_SEGOVR();
8623    END_OF_INSTR();
8624}
8625
8626/****************************************************************************
8627REMARKS:
8628Handles opcode 0xc6
8629****************************************************************************/
8630static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8631{
8632    int mod, rl, rh;
8633    u8 *destreg;
8634    uint destoffset;
8635    u8 imm;
8636
8637    START_OF_INSTR();
8638    DECODE_PRINTF("MOV\t");
8639    FETCH_DECODE_MODRM(mod, rh, rl);
8640    if (rh != 0) {
8641        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8642        HALT_SYS();
8643    }
8644    switch (mod) {
8645    case 0:
8646        DECODE_PRINTF("BYTE PTR ");
8647        destoffset = decode_rm00_address(rl);
8648        imm = fetch_byte_imm();
8649        DECODE_PRINTF2(",%2x\n", imm);
8650        TRACE_AND_STEP();
8651        store_data_byte(destoffset, imm);
8652        break;
8653    case 1:
8654        DECODE_PRINTF("BYTE PTR ");
8655        destoffset = decode_rm01_address(rl);
8656        imm = fetch_byte_imm();
8657        DECODE_PRINTF2(",%2x\n", imm);
8658        TRACE_AND_STEP();
8659        store_data_byte(destoffset, imm);
8660        break;
8661    case 2:
8662        DECODE_PRINTF("BYTE PTR ");
8663        destoffset = decode_rm10_address(rl);
8664        imm = fetch_byte_imm();
8665        DECODE_PRINTF2(",%2x\n", imm);
8666        TRACE_AND_STEP();
8667        store_data_byte(destoffset, imm);
8668        break;
8669    case 3:                     /* register to register */
8670        destreg = DECODE_RM_BYTE_REGISTER(rl);
8671        imm = fetch_byte_imm();
8672        DECODE_PRINTF2(",%2x\n", imm);
8673        TRACE_AND_STEP();
8674        *destreg = imm;
8675        break;
8676    }
8677    DECODE_CLEAR_SEGOVR();
8678    END_OF_INSTR();
8679}
8680
8681/****************************************************************************
8682REMARKS:
8683Handles opcode 0xc7
8684****************************************************************************/
8685static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8686{
8687    int mod, rl, rh;
8688    uint destoffset;
8689
8690    START_OF_INSTR();
8691    DECODE_PRINTF("MOV\t");
8692    FETCH_DECODE_MODRM(mod, rh, rl);
8693    if (rh != 0) {
8694        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8695        HALT_SYS();
8696    }
8697    switch (mod) {
8698    case 0:
8699        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8700            u32 imm;
8701
8702            DECODE_PRINTF("DWORD PTR ");
8703            destoffset = decode_rm00_address(rl);
8704            imm = fetch_long_imm();
8705            DECODE_PRINTF2(",%x\n", imm);
8706            TRACE_AND_STEP();
8707            store_data_long(destoffset, imm);
8708        } else {
8709            u16 imm;
8710
8711            DECODE_PRINTF("WORD PTR ");
8712            destoffset = decode_rm00_address(rl);
8713            imm = fetch_word_imm();
8714            DECODE_PRINTF2(",%x\n", imm);
8715            TRACE_AND_STEP();
8716            store_data_word(destoffset, imm);
8717        }
8718        break;
8719    case 1:
8720        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8721            u32 imm;
8722
8723            DECODE_PRINTF("DWORD PTR ");
8724            destoffset = decode_rm01_address(rl);
8725            imm = fetch_long_imm();
8726            DECODE_PRINTF2(",%x\n", imm);
8727            TRACE_AND_STEP();
8728            store_data_long(destoffset, imm);
8729        } else {
8730            u16 imm;
8731
8732            DECODE_PRINTF("WORD PTR ");
8733            destoffset = decode_rm01_address(rl);
8734            imm = fetch_word_imm();
8735            DECODE_PRINTF2(",%x\n", imm);
8736            TRACE_AND_STEP();
8737            store_data_word(destoffset, imm);
8738        }
8739        break;
8740    case 2:
8741        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8742            u32 imm;
8743
8744            DECODE_PRINTF("DWORD PTR ");
8745            destoffset = decode_rm10_address(rl);
8746            imm = fetch_long_imm();
8747            DECODE_PRINTF2(",%x\n", imm);
8748            TRACE_AND_STEP();
8749            store_data_long(destoffset, imm);
8750        } else {
8751            u16 imm;
8752
8753            DECODE_PRINTF("WORD PTR ");
8754            destoffset = decode_rm10_address(rl);
8755            imm = fetch_word_imm();
8756            DECODE_PRINTF2(",%x\n", imm);
8757            TRACE_AND_STEP();
8758            store_data_word(destoffset, imm);
8759        }
8760        break;
8761    case 3:                     /* register to register */
8762        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8763			u32 *destreg;
8764			u32 imm;
8765
8766            destreg = DECODE_RM_LONG_REGISTER(rl);
8767            imm = fetch_long_imm();
8768            DECODE_PRINTF2(",%x\n", imm);
8769            TRACE_AND_STEP();
8770            *destreg = imm;
8771        } else {
8772			u16 *destreg;
8773			u16 imm;
8774
8775            destreg = DECODE_RM_WORD_REGISTER(rl);
8776            imm = fetch_word_imm();
8777            DECODE_PRINTF2(",%x\n", imm);
8778            TRACE_AND_STEP();
8779            *destreg = imm;
8780        }
8781        break;
8782    }
8783    DECODE_CLEAR_SEGOVR();
8784    END_OF_INSTR();
8785}
8786
8787/****************************************************************************
8788REMARKS:
8789Handles opcode 0xc8
8790****************************************************************************/
8791static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8792{
8793    u16 local,frame_pointer;
8794    u8  nesting;
8795    int i;
8796
8797    START_OF_INSTR();
8798    local = fetch_word_imm();
8799    nesting = fetch_byte_imm();
8800    DECODE_PRINTF2("ENTER %x\n", local);
8801    DECODE_PRINTF2(",%x\n", nesting);
8802    TRACE_AND_STEP();
8803    push_word(M.x86.R_BP);
8804    frame_pointer = M.x86.R_SP;
8805    if (nesting > 0) {
8806        for (i = 1; i < nesting; i++) {
8807            M.x86.R_BP -= 2;
8808            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8809            }
8810        push_word(frame_pointer);
8811        }
8812    M.x86.R_BP = frame_pointer;
8813    M.x86.R_SP = (u16)(M.x86.R_SP - local);
8814    DECODE_CLEAR_SEGOVR();
8815    END_OF_INSTR();
8816}
8817
8818/****************************************************************************
8819REMARKS:
8820Handles opcode 0xc9
8821****************************************************************************/
8822static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8823{
8824    START_OF_INSTR();
8825    DECODE_PRINTF("LEAVE\n");
8826    TRACE_AND_STEP();
8827    M.x86.R_SP = M.x86.R_BP;
8828    M.x86.R_BP = pop_word();
8829    DECODE_CLEAR_SEGOVR();
8830    END_OF_INSTR();
8831}
8832
8833/****************************************************************************
8834REMARKS:
8835Handles opcode 0xca
8836****************************************************************************/
8837static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8838{
8839    u16 imm;
8840
8841    START_OF_INSTR();
8842    DECODE_PRINTF("RETF\t");
8843    imm = fetch_word_imm();
8844    DECODE_PRINTF2("%x\n", imm);
8845	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8846	TRACE_AND_STEP();
8847    M.x86.R_IP = pop_word();
8848    M.x86.R_CS = pop_word();
8849    M.x86.R_SP += imm;
8850    DECODE_CLEAR_SEGOVR();
8851    END_OF_INSTR();
8852}
8853
8854/****************************************************************************
8855REMARKS:
8856Handles opcode 0xcb
8857****************************************************************************/
8858static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8859{
8860    START_OF_INSTR();
8861    DECODE_PRINTF("RETF\n");
8862	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8863	TRACE_AND_STEP();
8864    M.x86.R_IP = pop_word();
8865    M.x86.R_CS = pop_word();
8866    DECODE_CLEAR_SEGOVR();
8867    END_OF_INSTR();
8868}
8869
8870/****************************************************************************
8871REMARKS:
8872Handles opcode 0xcc
8873****************************************************************************/
8874static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8875{
8876    START_OF_INSTR();
8877    DECODE_PRINTF("INT 3\n");
8878    TRACE_AND_STEP();
8879    if (_X86EMU_intrTab[3]) {
8880	(*_X86EMU_intrTab[3])(3);
8881    } else {
8882        push_word((u16)M.x86.R_FLG);
8883        CLEAR_FLAG(F_IF);
8884        CLEAR_FLAG(F_TF);
8885        push_word(M.x86.R_CS);
8886        M.x86.R_CS = mem_access_word(3 * 4 + 2);
8887        push_word(M.x86.R_IP);
8888        M.x86.R_IP = mem_access_word(3 * 4);
8889    }
8890    DECODE_CLEAR_SEGOVR();
8891    END_OF_INSTR();
8892}
8893
8894/****************************************************************************
8895REMARKS:
8896Handles opcode 0xcd
8897****************************************************************************/
8898static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8899{
8900    u8 intnum;
8901
8902    START_OF_INSTR();
8903    DECODE_PRINTF("INT\t");
8904    intnum = fetch_byte_imm();
8905    DECODE_PRINTF2("%x\n", intnum);
8906    TRACE_AND_STEP();
8907    if (_X86EMU_intrTab[intnum]) {
8908	(*_X86EMU_intrTab[intnum])(intnum);
8909    } else {
8910        push_word((u16)M.x86.R_FLG);
8911        CLEAR_FLAG(F_IF);
8912        CLEAR_FLAG(F_TF);
8913        push_word(M.x86.R_CS);
8914        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8915        push_word(M.x86.R_IP);
8916        M.x86.R_IP = mem_access_word(intnum * 4);
8917    }
8918    DECODE_CLEAR_SEGOVR();
8919    END_OF_INSTR();
8920}
8921
8922/****************************************************************************
8923REMARKS:
8924Handles opcode 0xce
8925****************************************************************************/
8926static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8927{
8928    START_OF_INSTR();
8929    DECODE_PRINTF("INTO\n");
8930    TRACE_AND_STEP();
8931    if (ACCESS_FLAG(F_OF)) {
8932	if (_X86EMU_intrTab[4]) {
8933	    (*_X86EMU_intrTab[4])(4);
8934        } else {
8935            push_word((u16)M.x86.R_FLG);
8936            CLEAR_FLAG(F_IF);
8937            CLEAR_FLAG(F_TF);
8938            push_word(M.x86.R_CS);
8939            M.x86.R_CS = mem_access_word(4 * 4 + 2);
8940            push_word(M.x86.R_IP);
8941            M.x86.R_IP = mem_access_word(4 * 4);
8942        }
8943    }
8944    DECODE_CLEAR_SEGOVR();
8945    END_OF_INSTR();
8946}
8947
8948/****************************************************************************
8949REMARKS:
8950Handles opcode 0xcf
8951****************************************************************************/
8952static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8953{
8954    START_OF_INSTR();
8955    DECODE_PRINTF("IRET\n");
8956
8957    TRACE_AND_STEP();
8958
8959    M.x86.R_IP = pop_word();
8960    M.x86.R_CS = pop_word();
8961    M.x86.R_FLG = pop_word();
8962    DECODE_CLEAR_SEGOVR();
8963    END_OF_INSTR();
8964}
8965
8966/****************************************************************************
8967REMARKS:
8968Handles opcode 0xd0
8969****************************************************************************/
8970static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8971{
8972    int mod, rl, rh;
8973    u8 *destreg;
8974    uint destoffset;
8975    u8 destval;
8976
8977    /*
8978     * Yet another weirdo special case instruction format.  Part of
8979     * the opcode held below in "RH".  Doubly nested case would
8980     * result, except that the decoded instruction
8981     */
8982    START_OF_INSTR();
8983    FETCH_DECODE_MODRM(mod, rh, rl);
8984#ifdef DEBUG
8985    if (DEBUG_DECODE()) {
8986        /* XXX DECODE_PRINTF may be changed to something more
8987           general, so that it is important to leave the strings
8988           in the same format, even though the result is that the
8989           above test is done twice. */
8990        switch (rh) {
8991        case 0:
8992            DECODE_PRINTF("ROL\t");
8993            break;
8994        case 1:
8995            DECODE_PRINTF("ROR\t");
8996            break;
8997        case 2:
8998            DECODE_PRINTF("RCL\t");
8999            break;
9000        case 3:
9001            DECODE_PRINTF("RCR\t");
9002            break;
9003        case 4:
9004            DECODE_PRINTF("SHL\t");
9005            break;
9006        case 5:
9007            DECODE_PRINTF("SHR\t");
9008            break;
9009        case 6:
9010            DECODE_PRINTF("SAL\t");
9011            break;
9012        case 7:
9013            DECODE_PRINTF("SAR\t");
9014            break;
9015        }
9016    }
9017#endif
9018    /* know operation, decode the mod byte to find the addressing
9019       mode. */
9020    switch (mod) {
9021    case 0:
9022        DECODE_PRINTF("BYTE PTR ");
9023        destoffset = decode_rm00_address(rl);
9024        DECODE_PRINTF(",1\n");
9025        destval = fetch_data_byte(destoffset);
9026        TRACE_AND_STEP();
9027        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9028        store_data_byte(destoffset, destval);
9029        break;
9030    case 1:
9031        DECODE_PRINTF("BYTE PTR ");
9032        destoffset = decode_rm01_address(rl);
9033        DECODE_PRINTF(",1\n");
9034        destval = fetch_data_byte(destoffset);
9035        TRACE_AND_STEP();
9036        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9037        store_data_byte(destoffset, destval);
9038        break;
9039    case 2:
9040        DECODE_PRINTF("BYTE PTR ");
9041        destoffset = decode_rm10_address(rl);
9042        DECODE_PRINTF(",1\n");
9043        destval = fetch_data_byte(destoffset);
9044        TRACE_AND_STEP();
9045        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9046        store_data_byte(destoffset, destval);
9047        break;
9048    case 3:                     /* register to register */
9049        destreg = DECODE_RM_BYTE_REGISTER(rl);
9050        DECODE_PRINTF(",1\n");
9051        TRACE_AND_STEP();
9052        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9053        *destreg = destval;
9054        break;
9055    }
9056    DECODE_CLEAR_SEGOVR();
9057    END_OF_INSTR();
9058}
9059
9060/****************************************************************************
9061REMARKS:
9062Handles opcode 0xd1
9063****************************************************************************/
9064static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9065{
9066    int mod, rl, rh;
9067    uint destoffset;
9068
9069    /*
9070     * Yet another weirdo special case instruction format.  Part of
9071     * the opcode held below in "RH".  Doubly nested case would
9072     * result, except that the decoded instruction
9073     */
9074    START_OF_INSTR();
9075    FETCH_DECODE_MODRM(mod, rh, rl);
9076#ifdef DEBUG
9077    if (DEBUG_DECODE()) {
9078        /* XXX DECODE_PRINTF may be changed to something more
9079           general, so that it is important to leave the strings
9080           in the same format, even though the result is that the
9081           above test is done twice. */
9082        switch (rh) {
9083        case 0:
9084            DECODE_PRINTF("ROL\t");
9085            break;
9086        case 1:
9087            DECODE_PRINTF("ROR\t");
9088            break;
9089        case 2:
9090            DECODE_PRINTF("RCL\t");
9091            break;
9092        case 3:
9093            DECODE_PRINTF("RCR\t");
9094            break;
9095        case 4:
9096            DECODE_PRINTF("SHL\t");
9097            break;
9098        case 5:
9099            DECODE_PRINTF("SHR\t");
9100            break;
9101        case 6:
9102            DECODE_PRINTF("SAL\t");
9103            break;
9104        case 7:
9105            DECODE_PRINTF("SAR\t");
9106            break;
9107        }
9108    }
9109#endif
9110    /* know operation, decode the mod byte to find the addressing
9111       mode. */
9112    switch (mod) {
9113    case 0:
9114        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9115            u32 destval;
9116
9117            DECODE_PRINTF("DWORD PTR ");
9118            destoffset = decode_rm00_address(rl);
9119            DECODE_PRINTF(",1\n");
9120            destval = fetch_data_long(destoffset);
9121            TRACE_AND_STEP();
9122            destval = (*opcD1_long_operation[rh]) (destval, 1);
9123            store_data_long(destoffset, destval);
9124        } else {
9125            u16 destval;
9126
9127            DECODE_PRINTF("WORD PTR ");
9128            destoffset = decode_rm00_address(rl);
9129            DECODE_PRINTF(",1\n");
9130            destval = fetch_data_word(destoffset);
9131            TRACE_AND_STEP();
9132            destval = (*opcD1_word_operation[rh]) (destval, 1);
9133            store_data_word(destoffset, destval);
9134        }
9135        break;
9136    case 1:
9137        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9138            u32 destval;
9139
9140            DECODE_PRINTF("DWORD PTR ");
9141            destoffset = decode_rm01_address(rl);
9142            DECODE_PRINTF(",1\n");
9143            destval = fetch_data_long(destoffset);
9144            TRACE_AND_STEP();
9145            destval = (*opcD1_long_operation[rh]) (destval, 1);
9146            store_data_long(destoffset, destval);
9147        } else {
9148            u16 destval;
9149
9150            DECODE_PRINTF("WORD PTR ");
9151            destoffset = decode_rm01_address(rl);
9152            DECODE_PRINTF(",1\n");
9153            destval = fetch_data_word(destoffset);
9154            TRACE_AND_STEP();
9155            destval = (*opcD1_word_operation[rh]) (destval, 1);
9156            store_data_word(destoffset, destval);
9157        }
9158        break;
9159    case 2:
9160        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9161            u32 destval;
9162
9163            DECODE_PRINTF("DWORD PTR ");
9164            destoffset = decode_rm10_address(rl);
9165            DECODE_PRINTF(",1\n");
9166            destval = fetch_data_long(destoffset);
9167            TRACE_AND_STEP();
9168            destval = (*opcD1_long_operation[rh]) (destval, 1);
9169            store_data_long(destoffset, destval);
9170        } else {
9171            u16 destval;
9172
9173            DECODE_PRINTF("BYTE PTR ");
9174            destoffset = decode_rm10_address(rl);
9175            DECODE_PRINTF(",1\n");
9176            destval = fetch_data_word(destoffset);
9177            TRACE_AND_STEP();
9178            destval = (*opcD1_word_operation[rh]) (destval, 1);
9179            store_data_word(destoffset, destval);
9180        }
9181        break;
9182    case 3:                     /* register to register */
9183        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9184			u32 destval;
9185			u32 *destreg;
9186
9187            destreg = DECODE_RM_LONG_REGISTER(rl);
9188            DECODE_PRINTF(",1\n");
9189            TRACE_AND_STEP();
9190            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9191            *destreg = destval;
9192        } else {
9193			u16 destval;
9194			u16 *destreg;
9195
9196            destreg = DECODE_RM_WORD_REGISTER(rl);
9197            DECODE_PRINTF(",1\n");
9198            TRACE_AND_STEP();
9199            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9200            *destreg = destval;
9201        }
9202        break;
9203    }
9204    DECODE_CLEAR_SEGOVR();
9205    END_OF_INSTR();
9206}
9207
9208/****************************************************************************
9209REMARKS:
9210Handles opcode 0xd2
9211****************************************************************************/
9212static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9213{
9214    int mod, rl, rh;
9215    u8 *destreg;
9216    uint destoffset;
9217    u8 destval;
9218    u8 amt;
9219
9220    /*
9221     * Yet another weirdo special case instruction format.  Part of
9222     * the opcode held below in "RH".  Doubly nested case would
9223     * result, except that the decoded instruction
9224     */
9225    START_OF_INSTR();
9226    FETCH_DECODE_MODRM(mod, rh, rl);
9227#ifdef DEBUG
9228    if (DEBUG_DECODE()) {
9229        /* XXX DECODE_PRINTF may be changed to something more
9230           general, so that it is important to leave the strings
9231           in the same format, even though the result is that the
9232           above test is done twice. */
9233        switch (rh) {
9234        case 0:
9235            DECODE_PRINTF("ROL\t");
9236            break;
9237        case 1:
9238            DECODE_PRINTF("ROR\t");
9239            break;
9240        case 2:
9241            DECODE_PRINTF("RCL\t");
9242            break;
9243        case 3:
9244            DECODE_PRINTF("RCR\t");
9245            break;
9246        case 4:
9247            DECODE_PRINTF("SHL\t");
9248            break;
9249        case 5:
9250            DECODE_PRINTF("SHR\t");
9251            break;
9252        case 6:
9253            DECODE_PRINTF("SAL\t");
9254            break;
9255        case 7:
9256            DECODE_PRINTF("SAR\t");
9257            break;
9258        }
9259    }
9260#endif
9261    /* know operation, decode the mod byte to find the addressing
9262       mode. */
9263    amt = M.x86.R_CL;
9264    switch (mod) {
9265    case 0:
9266        DECODE_PRINTF("BYTE PTR ");
9267        destoffset = decode_rm00_address(rl);
9268        DECODE_PRINTF(",CL\n");
9269        destval = fetch_data_byte(destoffset);
9270        TRACE_AND_STEP();
9271        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9272        store_data_byte(destoffset, destval);
9273        break;
9274    case 1:
9275        DECODE_PRINTF("BYTE PTR ");
9276        destoffset = decode_rm01_address(rl);
9277        DECODE_PRINTF(",CL\n");
9278        destval = fetch_data_byte(destoffset);
9279        TRACE_AND_STEP();
9280        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9281        store_data_byte(destoffset, destval);
9282        break;
9283    case 2:
9284        DECODE_PRINTF("BYTE PTR ");
9285        destoffset = decode_rm10_address(rl);
9286        DECODE_PRINTF(",CL\n");
9287        destval = fetch_data_byte(destoffset);
9288        TRACE_AND_STEP();
9289        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9290        store_data_byte(destoffset, destval);
9291        break;
9292    case 3:                     /* register to register */
9293        destreg = DECODE_RM_BYTE_REGISTER(rl);
9294        DECODE_PRINTF(",CL\n");
9295        TRACE_AND_STEP();
9296        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9297        *destreg = destval;
9298        break;
9299    }
9300    DECODE_CLEAR_SEGOVR();
9301    END_OF_INSTR();
9302}
9303
9304/****************************************************************************
9305REMARKS:
9306Handles opcode 0xd3
9307****************************************************************************/
9308static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9309{
9310    int mod, rl, rh;
9311    uint destoffset;
9312    u8 amt;
9313
9314    /*
9315     * Yet another weirdo special case instruction format.  Part of
9316     * the opcode held below in "RH".  Doubly nested case would
9317     * result, except that the decoded instruction
9318     */
9319    START_OF_INSTR();
9320    FETCH_DECODE_MODRM(mod, rh, rl);
9321#ifdef DEBUG
9322    if (DEBUG_DECODE()) {
9323        /* XXX DECODE_PRINTF may be changed to something more
9324           general, so that it is important to leave the strings
9325           in the same format, even though the result is that the
9326           above test is done twice. */
9327        switch (rh) {
9328        case 0:
9329            DECODE_PRINTF("ROL\t");
9330            break;
9331        case 1:
9332            DECODE_PRINTF("ROR\t");
9333            break;
9334        case 2:
9335            DECODE_PRINTF("RCL\t");
9336            break;
9337        case 3:
9338            DECODE_PRINTF("RCR\t");
9339            break;
9340        case 4:
9341            DECODE_PRINTF("SHL\t");
9342            break;
9343        case 5:
9344            DECODE_PRINTF("SHR\t");
9345            break;
9346        case 6:
9347            DECODE_PRINTF("SAL\t");
9348            break;
9349        case 7:
9350            DECODE_PRINTF("SAR\t");
9351            break;
9352        }
9353    }
9354#endif
9355    /* know operation, decode the mod byte to find the addressing
9356       mode. */
9357    amt = M.x86.R_CL;
9358    switch (mod) {
9359    case 0:
9360        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9361            u32 destval;
9362
9363            DECODE_PRINTF("DWORD PTR ");
9364            destoffset = decode_rm00_address(rl);
9365            DECODE_PRINTF(",CL\n");
9366            destval = fetch_data_long(destoffset);
9367            TRACE_AND_STEP();
9368            destval = (*opcD1_long_operation[rh]) (destval, amt);
9369            store_data_long(destoffset, destval);
9370        } else {
9371            u16 destval;
9372
9373            DECODE_PRINTF("WORD PTR ");
9374            destoffset = decode_rm00_address(rl);
9375            DECODE_PRINTF(",CL\n");
9376            destval = fetch_data_word(destoffset);
9377            TRACE_AND_STEP();
9378            destval = (*opcD1_word_operation[rh]) (destval, amt);
9379            store_data_word(destoffset, destval);
9380        }
9381        break;
9382    case 1:
9383        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9384            u32 destval;
9385
9386            DECODE_PRINTF("DWORD PTR ");
9387            destoffset = decode_rm01_address(rl);
9388            DECODE_PRINTF(",CL\n");
9389            destval = fetch_data_long(destoffset);
9390            TRACE_AND_STEP();
9391            destval = (*opcD1_long_operation[rh]) (destval, amt);
9392            store_data_long(destoffset, destval);
9393        } else {
9394            u16 destval;
9395
9396            DECODE_PRINTF("WORD PTR ");
9397            destoffset = decode_rm01_address(rl);
9398            DECODE_PRINTF(",CL\n");
9399            destval = fetch_data_word(destoffset);
9400            TRACE_AND_STEP();
9401            destval = (*opcD1_word_operation[rh]) (destval, amt);
9402            store_data_word(destoffset, destval);
9403        }
9404        break;
9405    case 2:
9406        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9407            u32 destval;
9408
9409            DECODE_PRINTF("DWORD PTR ");
9410            destoffset = decode_rm10_address(rl);
9411            DECODE_PRINTF(",CL\n");
9412            destval = fetch_data_long(destoffset);
9413            TRACE_AND_STEP();
9414            destval = (*opcD1_long_operation[rh]) (destval, amt);
9415            store_data_long(destoffset, destval);
9416        } else {
9417            u16 destval;
9418
9419            DECODE_PRINTF("WORD PTR ");
9420            destoffset = decode_rm10_address(rl);
9421            DECODE_PRINTF(",CL\n");
9422            destval = fetch_data_word(destoffset);
9423            TRACE_AND_STEP();
9424            destval = (*opcD1_word_operation[rh]) (destval, amt);
9425            store_data_word(destoffset, destval);
9426        }
9427        break;
9428    case 3:                     /* register to register */
9429        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9430            u32 *destreg;
9431
9432            destreg = DECODE_RM_LONG_REGISTER(rl);
9433            DECODE_PRINTF(",CL\n");
9434            TRACE_AND_STEP();
9435            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9436        } else {
9437            u16 *destreg;
9438
9439            destreg = DECODE_RM_WORD_REGISTER(rl);
9440            DECODE_PRINTF(",CL\n");
9441            TRACE_AND_STEP();
9442            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9443        }
9444        break;
9445    }
9446    DECODE_CLEAR_SEGOVR();
9447    END_OF_INSTR();
9448}
9449
9450/****************************************************************************
9451REMARKS:
9452Handles opcode 0xd4
9453****************************************************************************/
9454static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9455{
9456    u8 a;
9457
9458    START_OF_INSTR();
9459    DECODE_PRINTF("AAM\n");
9460    a = fetch_byte_imm();      /* this is a stupid encoding. */
9461    if (a != 10) {
9462	/* fix: add base decoding
9463	   aam_word(u8 val, int base a) */
9464        DECODE_PRINTF("ERROR DECODING AAM\n");
9465        TRACE_REGS();
9466        HALT_SYS();
9467    }
9468    TRACE_AND_STEP();
9469    /* note the type change here --- returning AL and AH in AX. */
9470    M.x86.R_AX = aam_word(M.x86.R_AL);
9471    DECODE_CLEAR_SEGOVR();
9472    END_OF_INSTR();
9473}
9474
9475/****************************************************************************
9476REMARKS:
9477Handles opcode 0xd5
9478****************************************************************************/
9479static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9480{
9481    u8 a;
9482
9483    START_OF_INSTR();
9484    DECODE_PRINTF("AAD\n");
9485    a = fetch_byte_imm();
9486    if (a != 10) {
9487	/* fix: add base decoding
9488	   aad_word(u16 val, int base a) */
9489        DECODE_PRINTF("ERROR DECODING AAM\n");
9490        TRACE_REGS();
9491        HALT_SYS();
9492    }
9493    TRACE_AND_STEP();
9494    M.x86.R_AX = aad_word(M.x86.R_AX);
9495    DECODE_CLEAR_SEGOVR();
9496    END_OF_INSTR();
9497}
9498
9499/* opcode 0xd6 ILLEGAL OPCODE */
9500
9501/****************************************************************************
9502REMARKS:
9503Handles opcode 0xd7
9504****************************************************************************/
9505static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9506{
9507    u16 addr;
9508
9509    START_OF_INSTR();
9510    DECODE_PRINTF("XLAT\n");
9511    TRACE_AND_STEP();
9512	addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9513    M.x86.R_AL = fetch_data_byte(addr);
9514    DECODE_CLEAR_SEGOVR();
9515    END_OF_INSTR();
9516}
9517
9518/* instuctions  D8 .. DF are in i87_ops.c */
9519
9520/****************************************************************************
9521REMARKS:
9522Handles opcode 0xe0
9523****************************************************************************/
9524static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9525{
9526    s16 ip;
9527
9528    START_OF_INSTR();
9529    DECODE_PRINTF("LOOPNE\t");
9530    ip = (s8) fetch_byte_imm();
9531    ip += (s16) M.x86.R_IP;
9532    DECODE_PRINTF2("%04x\n", ip);
9533    TRACE_AND_STEP();
9534    M.x86.R_CX -= 1;
9535    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9536        M.x86.R_IP = ip;
9537    DECODE_CLEAR_SEGOVR();
9538    END_OF_INSTR();
9539}
9540
9541/****************************************************************************
9542REMARKS:
9543Handles opcode 0xe1
9544****************************************************************************/
9545static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9546{
9547    s16 ip;
9548
9549    START_OF_INSTR();
9550    DECODE_PRINTF("LOOPE\t");
9551    ip = (s8) fetch_byte_imm();
9552    ip += (s16) M.x86.R_IP;
9553    DECODE_PRINTF2("%04x\n", ip);
9554    TRACE_AND_STEP();
9555    M.x86.R_CX -= 1;
9556    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9557        M.x86.R_IP = ip;
9558    DECODE_CLEAR_SEGOVR();
9559    END_OF_INSTR();
9560}
9561
9562/****************************************************************************
9563REMARKS:
9564Handles opcode 0xe2
9565****************************************************************************/
9566static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9567{
9568    s16 ip;
9569
9570    START_OF_INSTR();
9571    DECODE_PRINTF("LOOP\t");
9572    ip = (s8) fetch_byte_imm();
9573    ip += (s16) M.x86.R_IP;
9574    DECODE_PRINTF2("%04x\n", ip);
9575    TRACE_AND_STEP();
9576    M.x86.R_CX -= 1;
9577    if (M.x86.R_CX != 0)
9578        M.x86.R_IP = ip;
9579    DECODE_CLEAR_SEGOVR();
9580    END_OF_INSTR();
9581}
9582
9583/****************************************************************************
9584REMARKS:
9585Handles opcode 0xe3
9586****************************************************************************/
9587static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9588{
9589    u16 target;
9590    s8  offset;
9591
9592    /* jump to byte offset if overflow flag is set */
9593    START_OF_INSTR();
9594    DECODE_PRINTF("JCXZ\t");
9595    offset = (s8)fetch_byte_imm();
9596    target = (u16)(M.x86.R_IP + offset);
9597    DECODE_PRINTF2("%x\n", target);
9598    TRACE_AND_STEP();
9599    if (M.x86.R_CX == 0)
9600        M.x86.R_IP = target;
9601    DECODE_CLEAR_SEGOVR();
9602    END_OF_INSTR();
9603}
9604
9605/****************************************************************************
9606REMARKS:
9607Handles opcode 0xe4
9608****************************************************************************/
9609static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9610{
9611    u8 port;
9612
9613    START_OF_INSTR();
9614    DECODE_PRINTF("IN\t");
9615	port = (u8) fetch_byte_imm();
9616    DECODE_PRINTF2("%x,AL\n", port);
9617    TRACE_AND_STEP();
9618    M.x86.R_AL = (*sys_inb)(port);
9619    DECODE_CLEAR_SEGOVR();
9620    END_OF_INSTR();
9621}
9622
9623/****************************************************************************
9624REMARKS:
9625Handles opcode 0xe5
9626****************************************************************************/
9627static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9628{
9629    u8 port;
9630
9631    START_OF_INSTR();
9632    DECODE_PRINTF("IN\t");
9633	port = (u8) fetch_byte_imm();
9634    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9635        DECODE_PRINTF2("EAX,%x\n", port);
9636    } else {
9637        DECODE_PRINTF2("AX,%x\n", port);
9638    }
9639    TRACE_AND_STEP();
9640    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9641        M.x86.R_EAX = (*sys_inl)(port);
9642    } else {
9643        M.x86.R_AX = (*sys_inw)(port);
9644    }
9645    DECODE_CLEAR_SEGOVR();
9646    END_OF_INSTR();
9647}
9648
9649/****************************************************************************
9650REMARKS:
9651Handles opcode 0xe6
9652****************************************************************************/
9653static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9654{
9655    u8 port;
9656
9657    START_OF_INSTR();
9658    DECODE_PRINTF("OUT\t");
9659	port = (u8) fetch_byte_imm();
9660    DECODE_PRINTF2("%x,AL\n", port);
9661    TRACE_AND_STEP();
9662    (*sys_outb)(port, M.x86.R_AL);
9663    DECODE_CLEAR_SEGOVR();
9664    END_OF_INSTR();
9665}
9666
9667/****************************************************************************
9668REMARKS:
9669Handles opcode 0xe7
9670****************************************************************************/
9671static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9672{
9673    u8 port;
9674
9675    START_OF_INSTR();
9676    DECODE_PRINTF("OUT\t");
9677	port = (u8) fetch_byte_imm();
9678    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9679        DECODE_PRINTF2("%x,EAX\n", port);
9680    } else {
9681        DECODE_PRINTF2("%x,AX\n", port);
9682    }
9683    TRACE_AND_STEP();
9684    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9685        (*sys_outl)(port, M.x86.R_EAX);
9686    } else {
9687        (*sys_outw)(port, M.x86.R_AX);
9688    }
9689    DECODE_CLEAR_SEGOVR();
9690    END_OF_INSTR();
9691}
9692
9693/****************************************************************************
9694REMARKS:
9695Handles opcode 0xe8
9696****************************************************************************/
9697static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9698{
9699    s32 ip
9700
9701    START_OF_INSTR();
9702    DECODE_PRINTF("CALL\t");
9703    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9704        ip = (s32) fetch_long_imm();
9705        ip += (s32) M.x86.R_IP;    /* CHECK SIGN */
9706    } else {
9707        ip = (s16) fetch_word_imm();
9708        ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
9709    }
9710    DECODE_PRINTF2("%04x\n", (u32)ip);
9711    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9712    TRACE_AND_STEP();
9713    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9714        push_long(M.x86.R_IP);
9715    } else {
9716        push_word(M.x86.R_IP);
9717    }
9718    M.x86.R_IP = ip;
9719    DECODE_CLEAR_SEGOVR();
9720    END_OF_INSTR();
9721}
9722
9723/****************************************************************************
9724REMARKS:
9725Handles opcode 0xe9
9726****************************************************************************/
9727static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9728{
9729    int ip;
9730
9731    START_OF_INSTR();
9732    DECODE_PRINTF("JMP\t");
9733    ip = (s16)fetch_word_imm();
9734    ip += (s16)M.x86.R_IP;
9735    DECODE_PRINTF2("%04x\n", (u16)ip);
9736    TRACE_AND_STEP();
9737    M.x86.R_IP = (u16)ip;
9738    DECODE_CLEAR_SEGOVR();
9739    END_OF_INSTR();
9740}
9741
9742/****************************************************************************
9743REMARKS:
9744Handles opcode 0xea
9745****************************************************************************/
9746static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9747{
9748    u16 cs, ip;
9749
9750    START_OF_INSTR();
9751    DECODE_PRINTF("JMP\tFAR ");
9752    ip = fetch_word_imm();
9753    cs = fetch_word_imm();
9754    DECODE_PRINTF2("%04x:", cs);
9755    DECODE_PRINTF2("%04x\n", ip);
9756    TRACE_AND_STEP();
9757    M.x86.R_IP = ip;
9758    M.x86.R_CS = cs;
9759    DECODE_CLEAR_SEGOVR();
9760    END_OF_INSTR();
9761}
9762
9763/****************************************************************************
9764REMARKS:
9765Handles opcode 0xeb
9766****************************************************************************/
9767static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9768{
9769    u16 target;
9770    s8 offset;
9771
9772    START_OF_INSTR();
9773    DECODE_PRINTF("JMP\t");
9774    offset = (s8)fetch_byte_imm();
9775    target = (u16)(M.x86.R_IP + offset);
9776    DECODE_PRINTF2("%x\n", target);
9777    TRACE_AND_STEP();
9778    M.x86.R_IP = target;
9779    DECODE_CLEAR_SEGOVR();
9780    END_OF_INSTR();
9781}
9782
9783/****************************************************************************
9784REMARKS:
9785Handles opcode 0xec
9786****************************************************************************/
9787static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9788{
9789    START_OF_INSTR();
9790    DECODE_PRINTF("IN\tAL,DX\n");
9791    TRACE_AND_STEP();
9792    M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9793    DECODE_CLEAR_SEGOVR();
9794    END_OF_INSTR();
9795}
9796
9797/****************************************************************************
9798REMARKS:
9799Handles opcode 0xed
9800****************************************************************************/
9801static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9802{
9803    START_OF_INSTR();
9804    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9805        DECODE_PRINTF("IN\tEAX,DX\n");
9806    } else {
9807        DECODE_PRINTF("IN\tAX,DX\n");
9808    }
9809    TRACE_AND_STEP();
9810    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9811        M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9812    } else {
9813        M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9814    }
9815    DECODE_CLEAR_SEGOVR();
9816    END_OF_INSTR();
9817}
9818
9819/****************************************************************************
9820REMARKS:
9821Handles opcode 0xee
9822****************************************************************************/
9823static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9824{
9825    START_OF_INSTR();
9826    DECODE_PRINTF("OUT\tDX,AL\n");
9827    TRACE_AND_STEP();
9828    (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9829    DECODE_CLEAR_SEGOVR();
9830    END_OF_INSTR();
9831}
9832
9833/****************************************************************************
9834REMARKS:
9835Handles opcode 0xef
9836****************************************************************************/
9837static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9838{
9839    START_OF_INSTR();
9840    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9841        DECODE_PRINTF("OUT\tDX,EAX\n");
9842    } else {
9843        DECODE_PRINTF("OUT\tDX,AX\n");
9844    }
9845    TRACE_AND_STEP();
9846    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9847        (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9848    } else {
9849        (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9850    }
9851    DECODE_CLEAR_SEGOVR();
9852    END_OF_INSTR();
9853}
9854
9855/****************************************************************************
9856REMARKS:
9857Handles opcode 0xf0
9858****************************************************************************/
9859static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9860{
9861    START_OF_INSTR();
9862    DECODE_PRINTF("LOCK:\n");
9863    TRACE_AND_STEP();
9864    DECODE_CLEAR_SEGOVR();
9865    END_OF_INSTR();
9866}
9867
9868/*opcode 0xf1 ILLEGAL OPERATION */
9869
9870/****************************************************************************
9871REMARKS:
9872Handles opcode 0xf2
9873****************************************************************************/
9874static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9875{
9876    START_OF_INSTR();
9877    DECODE_PRINTF("REPNE\n");
9878    TRACE_AND_STEP();
9879    M.x86.mode |= SYSMODE_PREFIX_REPNE;
9880    DECODE_CLEAR_SEGOVR();
9881    END_OF_INSTR();
9882}
9883
9884/****************************************************************************
9885REMARKS:
9886Handles opcode 0xf3
9887****************************************************************************/
9888static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9889{
9890    START_OF_INSTR();
9891    DECODE_PRINTF("REPE\n");
9892    TRACE_AND_STEP();
9893    M.x86.mode |= SYSMODE_PREFIX_REPE;
9894    DECODE_CLEAR_SEGOVR();
9895    END_OF_INSTR();
9896}
9897
9898/****************************************************************************
9899REMARKS:
9900Handles opcode 0xf4
9901****************************************************************************/
9902static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9903{
9904    START_OF_INSTR();
9905    DECODE_PRINTF("HALT\n");
9906    TRACE_AND_STEP();
9907    HALT_SYS();
9908    DECODE_CLEAR_SEGOVR();
9909    END_OF_INSTR();
9910}
9911
9912/****************************************************************************
9913REMARKS:
9914Handles opcode 0xf5
9915****************************************************************************/
9916static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9917{
9918    /* complement the carry flag. */
9919    START_OF_INSTR();
9920    DECODE_PRINTF("CMC\n");
9921    TRACE_AND_STEP();
9922    TOGGLE_FLAG(F_CF);
9923    DECODE_CLEAR_SEGOVR();
9924    END_OF_INSTR();
9925}
9926
9927/****************************************************************************
9928REMARKS:
9929Handles opcode 0xf6
9930****************************************************************************/
9931static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9932{
9933    int mod, rl, rh;
9934    u8 *destreg;
9935    uint destoffset;
9936    u8 destval, srcval;
9937
9938    /* long, drawn out code follows.  Double switch for a total
9939       of 32 cases.  */
9940    START_OF_INSTR();
9941    FETCH_DECODE_MODRM(mod, rh, rl);
9942    switch (mod) {
9943    case 0:                     /* mod=00 */
9944        switch (rh) {
9945        case 0:         /* test byte imm */
9946            DECODE_PRINTF("TEST\tBYTE PTR ");
9947            destoffset = decode_rm00_address(rl);
9948            DECODE_PRINTF(",");
9949            srcval = fetch_byte_imm();
9950            DECODE_PRINTF2("%02x\n", srcval);
9951            destval = fetch_data_byte(destoffset);
9952            TRACE_AND_STEP();
9953            test_byte(destval, srcval);
9954            break;
9955        case 1:
9956            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9957            HALT_SYS();
9958            break;
9959        case 2:
9960            DECODE_PRINTF("NOT\tBYTE PTR ");
9961            destoffset = decode_rm00_address(rl);
9962            DECODE_PRINTF("\n");
9963            destval = fetch_data_byte(destoffset);
9964            TRACE_AND_STEP();
9965            destval = not_byte(destval);
9966            store_data_byte(destoffset, destval);
9967            break;
9968        case 3:
9969            DECODE_PRINTF("NEG\tBYTE PTR ");
9970            destoffset = decode_rm00_address(rl);
9971            DECODE_PRINTF("\n");
9972            destval = fetch_data_byte(destoffset);
9973            TRACE_AND_STEP();
9974            destval = neg_byte(destval);
9975            store_data_byte(destoffset, destval);
9976            break;
9977        case 4:
9978            DECODE_PRINTF("MUL\tBYTE PTR ");
9979            destoffset = decode_rm00_address(rl);
9980            DECODE_PRINTF("\n");
9981            destval = fetch_data_byte(destoffset);
9982            TRACE_AND_STEP();
9983            mul_byte(destval);
9984            break;
9985        case 5:
9986            DECODE_PRINTF("IMUL\tBYTE PTR ");
9987            destoffset = decode_rm00_address(rl);
9988            DECODE_PRINTF("\n");
9989            destval = fetch_data_byte(destoffset);
9990            TRACE_AND_STEP();
9991            imul_byte(destval);
9992            break;
9993        case 6:
9994            DECODE_PRINTF("DIV\tBYTE PTR ");
9995            destoffset = decode_rm00_address(rl);
9996            DECODE_PRINTF("\n");
9997            destval = fetch_data_byte(destoffset);
9998            TRACE_AND_STEP();
9999            div_byte(destval);
10000            break;
10001        case 7:
10002            DECODE_PRINTF("IDIV\tBYTE PTR ");
10003            destoffset = decode_rm00_address(rl);
10004            DECODE_PRINTF("\n");
10005            destval = fetch_data_byte(destoffset);
10006            TRACE_AND_STEP();
10007            idiv_byte(destval);
10008            break;
10009        }
10010        break;                  /* end mod==00 */
10011    case 1:                     /* mod=01 */
10012        switch (rh) {
10013        case 0:         /* test byte imm */
10014            DECODE_PRINTF("TEST\tBYTE PTR ");
10015            destoffset = decode_rm01_address(rl);
10016            DECODE_PRINTF(",");
10017            srcval = fetch_byte_imm();
10018            DECODE_PRINTF2("%02x\n", srcval);
10019            destval = fetch_data_byte(destoffset);
10020            TRACE_AND_STEP();
10021            test_byte(destval, srcval);
10022            break;
10023        case 1:
10024            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10025            HALT_SYS();
10026            break;
10027        case 2:
10028            DECODE_PRINTF("NOT\tBYTE PTR ");
10029            destoffset = decode_rm01_address(rl);
10030            DECODE_PRINTF("\n");
10031            destval = fetch_data_byte(destoffset);
10032            TRACE_AND_STEP();
10033            destval = not_byte(destval);
10034            store_data_byte(destoffset, destval);
10035            break;
10036        case 3:
10037            DECODE_PRINTF("NEG\tBYTE PTR ");
10038            destoffset = decode_rm01_address(rl);
10039            DECODE_PRINTF("\n");
10040            destval = fetch_data_byte(destoffset);
10041            TRACE_AND_STEP();
10042            destval = neg_byte(destval);
10043            store_data_byte(destoffset, destval);
10044            break;
10045        case 4:
10046            DECODE_PRINTF("MUL\tBYTE PTR ");
10047            destoffset = decode_rm01_address(rl);
10048            DECODE_PRINTF("\n");
10049            destval = fetch_data_byte(destoffset);
10050            TRACE_AND_STEP();
10051            mul_byte(destval);
10052            break;
10053        case 5:
10054            DECODE_PRINTF("IMUL\tBYTE PTR ");
10055            destoffset = decode_rm01_address(rl);
10056            DECODE_PRINTF("\n");
10057            destval = fetch_data_byte(destoffset);
10058            TRACE_AND_STEP();
10059            imul_byte(destval);
10060            break;
10061        case 6:
10062            DECODE_PRINTF("DIV\tBYTE PTR ");
10063            destoffset = decode_rm01_address(rl);
10064            DECODE_PRINTF("\n");
10065            destval = fetch_data_byte(destoffset);
10066            TRACE_AND_STEP();
10067            div_byte(destval);
10068            break;
10069        case 7:
10070            DECODE_PRINTF("IDIV\tBYTE PTR ");
10071            destoffset = decode_rm01_address(rl);
10072            DECODE_PRINTF("\n");
10073            destval = fetch_data_byte(destoffset);
10074            TRACE_AND_STEP();
10075            idiv_byte(destval);
10076            break;
10077        }
10078        break;                  /* end mod==01 */
10079    case 2:                     /* mod=10 */
10080        switch (rh) {
10081        case 0:         /* test byte imm */
10082            DECODE_PRINTF("TEST\tBYTE PTR ");
10083            destoffset = decode_rm10_address(rl);
10084            DECODE_PRINTF(",");
10085            srcval = fetch_byte_imm();
10086            DECODE_PRINTF2("%02x\n", srcval);
10087            destval = fetch_data_byte(destoffset);
10088            TRACE_AND_STEP();
10089            test_byte(destval, srcval);
10090            break;
10091        case 1:
10092            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10093            HALT_SYS();
10094            break;
10095        case 2:
10096            DECODE_PRINTF("NOT\tBYTE PTR ");
10097            destoffset = decode_rm10_address(rl);
10098            DECODE_PRINTF("\n");
10099            destval = fetch_data_byte(destoffset);
10100            TRACE_AND_STEP();
10101            destval = not_byte(destval);
10102            store_data_byte(destoffset, destval);
10103            break;
10104        case 3:
10105            DECODE_PRINTF("NEG\tBYTE PTR ");
10106            destoffset = decode_rm10_address(rl);
10107            DECODE_PRINTF("\n");
10108            destval = fetch_data_byte(destoffset);
10109            TRACE_AND_STEP();
10110            destval = neg_byte(destval);
10111            store_data_byte(destoffset, destval);
10112            break;
10113        case 4:
10114            DECODE_PRINTF("MUL\tBYTE PTR ");
10115            destoffset = decode_rm10_address(rl);
10116            DECODE_PRINTF("\n");
10117            destval = fetch_data_byte(destoffset);
10118            TRACE_AND_STEP();
10119            mul_byte(destval);
10120            break;
10121        case 5:
10122            DECODE_PRINTF("IMUL\tBYTE PTR ");
10123            destoffset = decode_rm10_address(rl);
10124            DECODE_PRINTF("\n");
10125            destval = fetch_data_byte(destoffset);
10126            TRACE_AND_STEP();
10127            imul_byte(destval);
10128            break;
10129        case 6:
10130            DECODE_PRINTF("DIV\tBYTE PTR ");
10131            destoffset = decode_rm10_address(rl);
10132            DECODE_PRINTF("\n");
10133            destval = fetch_data_byte(destoffset);
10134            TRACE_AND_STEP();
10135            div_byte(destval);
10136            break;
10137        case 7:
10138            DECODE_PRINTF("IDIV\tBYTE PTR ");
10139            destoffset = decode_rm10_address(rl);
10140            DECODE_PRINTF("\n");
10141            destval = fetch_data_byte(destoffset);
10142            TRACE_AND_STEP();
10143            idiv_byte(destval);
10144            break;
10145        }
10146        break;                  /* end mod==10 */
10147    case 3:                     /* mod=11 */
10148        switch (rh) {
10149        case 0:         /* test byte imm */
10150            DECODE_PRINTF("TEST\t");
10151            destreg = DECODE_RM_BYTE_REGISTER(rl);
10152            DECODE_PRINTF(",");
10153            srcval = fetch_byte_imm();
10154            DECODE_PRINTF2("%02x\n", srcval);
10155            TRACE_AND_STEP();
10156            test_byte(*destreg, srcval);
10157            break;
10158        case 1:
10159            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10160            HALT_SYS();
10161            break;
10162        case 2:
10163            DECODE_PRINTF("NOT\t");
10164            destreg = DECODE_RM_BYTE_REGISTER(rl);
10165            DECODE_PRINTF("\n");
10166            TRACE_AND_STEP();
10167            *destreg = not_byte(*destreg);
10168            break;
10169        case 3:
10170            DECODE_PRINTF("NEG\t");
10171            destreg = DECODE_RM_BYTE_REGISTER(rl);
10172            DECODE_PRINTF("\n");
10173            TRACE_AND_STEP();
10174            *destreg = neg_byte(*destreg);
10175            break;
10176        case 4:
10177            DECODE_PRINTF("MUL\t");
10178            destreg = DECODE_RM_BYTE_REGISTER(rl);
10179            DECODE_PRINTF("\n");
10180            TRACE_AND_STEP();
10181            mul_byte(*destreg);      /*!!!  */
10182            break;
10183        case 5:
10184            DECODE_PRINTF("IMUL\t");
10185            destreg = DECODE_RM_BYTE_REGISTER(rl);
10186            DECODE_PRINTF("\n");
10187            TRACE_AND_STEP();
10188            imul_byte(*destreg);
10189            break;
10190        case 6:
10191            DECODE_PRINTF("DIV\t");
10192            destreg = DECODE_RM_BYTE_REGISTER(rl);
10193            DECODE_PRINTF("\n");
10194            TRACE_AND_STEP();
10195            div_byte(*destreg);
10196            break;
10197        case 7:
10198            DECODE_PRINTF("IDIV\t");
10199            destreg = DECODE_RM_BYTE_REGISTER(rl);
10200            DECODE_PRINTF("\n");
10201            TRACE_AND_STEP();
10202            idiv_byte(*destreg);
10203            break;
10204        }
10205        break;                  /* end mod==11 */
10206    }
10207    DECODE_CLEAR_SEGOVR();
10208    END_OF_INSTR();
10209}
10210
10211/****************************************************************************
10212REMARKS:
10213Handles opcode 0xf7
10214****************************************************************************/
10215static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10216{
10217    int mod, rl, rh;
10218    uint destoffset;
10219
10220    /* long, drawn out code follows.  Double switch for a total
10221       of 32 cases.  */
10222    START_OF_INSTR();
10223    FETCH_DECODE_MODRM(mod, rh, rl);
10224    switch (mod) {
10225    case 0:                     /* mod=00 */
10226        switch (rh) {
10227        case 0:         /* test word imm */
10228            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10229                u32 destval,srcval;
10230
10231                DECODE_PRINTF("TEST\tDWORD PTR ");
10232                destoffset = decode_rm00_address(rl);
10233                DECODE_PRINTF(",");
10234                srcval = fetch_long_imm();
10235                DECODE_PRINTF2("%x\n", srcval);
10236                destval = fetch_data_long(destoffset);
10237                TRACE_AND_STEP();
10238                test_long(destval, srcval);
10239            } else {
10240                u16 destval,srcval;
10241
10242                DECODE_PRINTF("TEST\tWORD PTR ");
10243                destoffset = decode_rm00_address(rl);
10244                DECODE_PRINTF(",");
10245                srcval = fetch_word_imm();
10246                DECODE_PRINTF2("%x\n", srcval);
10247                destval = fetch_data_word(destoffset);
10248                TRACE_AND_STEP();
10249                test_word(destval, srcval);
10250            }
10251            break;
10252        case 1:
10253            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10254            HALT_SYS();
10255            break;
10256        case 2:
10257            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10258                u32 destval;
10259
10260                DECODE_PRINTF("NOT\tDWORD PTR ");
10261                destoffset = decode_rm00_address(rl);
10262                DECODE_PRINTF("\n");
10263                destval = fetch_data_long(destoffset);
10264                TRACE_AND_STEP();
10265                destval = not_long(destval);
10266                store_data_long(destoffset, destval);
10267            } else {
10268                u16 destval;
10269
10270                DECODE_PRINTF("NOT\tWORD PTR ");
10271                destoffset = decode_rm00_address(rl);
10272                DECODE_PRINTF("\n");
10273                destval = fetch_data_word(destoffset);
10274                TRACE_AND_STEP();
10275                destval = not_word(destval);
10276                store_data_word(destoffset, destval);
10277            }
10278            break;
10279        case 3:
10280            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10281                u32 destval;
10282
10283                DECODE_PRINTF("NEG\tDWORD PTR ");
10284                destoffset = decode_rm00_address(rl);
10285                DECODE_PRINTF("\n");
10286                destval = fetch_data_long(destoffset);
10287                TRACE_AND_STEP();
10288                destval = neg_long(destval);
10289                store_data_long(destoffset, destval);
10290            } else {
10291                u16 destval;
10292
10293                DECODE_PRINTF("NEG\tWORD PTR ");
10294                destoffset = decode_rm00_address(rl);
10295                DECODE_PRINTF("\n");
10296                destval = fetch_data_word(destoffset);
10297                TRACE_AND_STEP();
10298                destval = neg_word(destval);
10299                store_data_word(destoffset, destval);
10300            }
10301            break;
10302        case 4:
10303            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10304                u32 destval;
10305
10306                DECODE_PRINTF("MUL\tDWORD PTR ");
10307                destoffset = decode_rm00_address(rl);
10308                DECODE_PRINTF("\n");
10309                destval = fetch_data_long(destoffset);
10310                TRACE_AND_STEP();
10311                mul_long(destval);
10312            } else {
10313                u16 destval;
10314
10315                DECODE_PRINTF("MUL\tWORD PTR ");
10316                destoffset = decode_rm00_address(rl);
10317                DECODE_PRINTF("\n");
10318                destval = fetch_data_word(destoffset);
10319                TRACE_AND_STEP();
10320                mul_word(destval);
10321            }
10322            break;
10323        case 5:
10324            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10325                u32 destval;
10326
10327                DECODE_PRINTF("IMUL\tDWORD PTR ");
10328                destoffset = decode_rm00_address(rl);
10329                DECODE_PRINTF("\n");
10330                destval = fetch_data_long(destoffset);
10331                TRACE_AND_STEP();
10332                imul_long(destval);
10333            } else {
10334                u16 destval;
10335
10336                DECODE_PRINTF("IMUL\tWORD PTR ");
10337                destoffset = decode_rm00_address(rl);
10338                DECODE_PRINTF("\n");
10339                destval = fetch_data_word(destoffset);
10340                TRACE_AND_STEP();
10341                imul_word(destval);
10342            }
10343            break;
10344        case 6:
10345            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10346                u32 destval;
10347
10348                DECODE_PRINTF("DIV\tDWORD PTR ");
10349                destoffset = decode_rm00_address(rl);
10350                DECODE_PRINTF("\n");
10351                destval = fetch_data_long(destoffset);
10352                TRACE_AND_STEP();
10353                div_long(destval);
10354            } else {
10355                u16 destval;
10356
10357                DECODE_PRINTF("DIV\tWORD PTR ");
10358                destoffset = decode_rm00_address(rl);
10359                DECODE_PRINTF("\n");
10360                destval = fetch_data_word(destoffset);
10361                TRACE_AND_STEP();
10362                div_word(destval);
10363            }
10364            break;
10365        case 7:
10366            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10367                u32 destval;
10368
10369                DECODE_PRINTF("IDIV\tDWORD PTR ");
10370                destoffset = decode_rm00_address(rl);
10371                DECODE_PRINTF("\n");
10372                destval = fetch_data_long(destoffset);
10373                TRACE_AND_STEP();
10374                idiv_long(destval);
10375            } else {
10376                u16 destval;
10377
10378                DECODE_PRINTF("IDIV\tWORD PTR ");
10379                destoffset = decode_rm00_address(rl);
10380                DECODE_PRINTF("\n");
10381                destval = fetch_data_word(destoffset);
10382                TRACE_AND_STEP();
10383                idiv_word(destval);
10384            }
10385            break;
10386        }
10387        break;                  /* end mod==00 */
10388    case 1:                     /* mod=01 */
10389        switch (rh) {
10390        case 0:         /* test word imm */
10391            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10392                u32 destval,srcval;
10393
10394                DECODE_PRINTF("TEST\tDWORD PTR ");
10395                destoffset = decode_rm01_address(rl);
10396                DECODE_PRINTF(",");
10397                srcval = fetch_long_imm();
10398                DECODE_PRINTF2("%x\n", srcval);
10399                destval = fetch_data_long(destoffset);
10400                TRACE_AND_STEP();
10401                test_long(destval, srcval);
10402            } else {
10403                u16 destval,srcval;
10404
10405                DECODE_PRINTF("TEST\tWORD PTR ");
10406                destoffset = decode_rm01_address(rl);
10407                DECODE_PRINTF(",");
10408                srcval = fetch_word_imm();
10409                DECODE_PRINTF2("%x\n", srcval);
10410                destval = fetch_data_word(destoffset);
10411                TRACE_AND_STEP();
10412                test_word(destval, srcval);
10413            }
10414            break;
10415        case 1:
10416            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10417            HALT_SYS();
10418            break;
10419        case 2:
10420            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10421                u32 destval;
10422
10423                DECODE_PRINTF("NOT\tDWORD PTR ");
10424                destoffset = decode_rm01_address(rl);
10425                DECODE_PRINTF("\n");
10426                destval = fetch_data_long(destoffset);
10427                TRACE_AND_STEP();
10428                destval = not_long(destval);
10429                store_data_long(destoffset, destval);
10430            } else {
10431                u16 destval;
10432
10433                DECODE_PRINTF("NOT\tWORD PTR ");
10434                destoffset = decode_rm01_address(rl);
10435                DECODE_PRINTF("\n");
10436                destval = fetch_data_word(destoffset);
10437                TRACE_AND_STEP();
10438                destval = not_word(destval);
10439                store_data_word(destoffset, destval);
10440            }
10441            break;
10442        case 3:
10443            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10444                u32 destval;
10445
10446                DECODE_PRINTF("NEG\tDWORD PTR ");
10447                destoffset = decode_rm01_address(rl);
10448                DECODE_PRINTF("\n");
10449                destval = fetch_data_long(destoffset);
10450                TRACE_AND_STEP();
10451                destval = neg_long(destval);
10452                store_data_long(destoffset, destval);
10453            } else {
10454                u16 destval;
10455
10456                DECODE_PRINTF("NEG\tWORD PTR ");
10457                destoffset = decode_rm01_address(rl);
10458                DECODE_PRINTF("\n");
10459                destval = fetch_data_word(destoffset);
10460                TRACE_AND_STEP();
10461                destval = neg_word(destval);
10462                store_data_word(destoffset, destval);
10463            }
10464            break;
10465        case 4:
10466            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10467                u32 destval;
10468
10469                DECODE_PRINTF("MUL\tDWORD PTR ");
10470                destoffset = decode_rm01_address(rl);
10471                DECODE_PRINTF("\n");
10472                destval = fetch_data_long(destoffset);
10473                TRACE_AND_STEP();
10474                mul_long(destval);
10475            } else {
10476                u16 destval;
10477
10478                DECODE_PRINTF("MUL\tWORD PTR ");
10479                destoffset = decode_rm01_address(rl);
10480                DECODE_PRINTF("\n");
10481                destval = fetch_data_word(destoffset);
10482                TRACE_AND_STEP();
10483                mul_word(destval);
10484            }
10485            break;
10486        case 5:
10487            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10488                u32 destval;
10489
10490                DECODE_PRINTF("IMUL\tDWORD PTR ");
10491                destoffset = decode_rm01_address(rl);
10492                DECODE_PRINTF("\n");
10493                destval = fetch_data_long(destoffset);
10494                TRACE_AND_STEP();
10495                imul_long(destval);
10496            } else {
10497                u16 destval;
10498
10499                DECODE_PRINTF("IMUL\tWORD PTR ");
10500                destoffset = decode_rm01_address(rl);
10501                DECODE_PRINTF("\n");
10502                destval = fetch_data_word(destoffset);
10503                TRACE_AND_STEP();
10504                imul_word(destval);
10505            }
10506            break;
10507        case 6:
10508            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10509                u32 destval;
10510
10511                DECODE_PRINTF("DIV\tDWORD PTR ");
10512                destoffset = decode_rm01_address(rl);
10513                DECODE_PRINTF("\n");
10514                destval = fetch_data_long(destoffset);
10515                TRACE_AND_STEP();
10516                div_long(destval);
10517            } else {
10518                u16 destval;
10519
10520                DECODE_PRINTF("DIV\tWORD PTR ");
10521                destoffset = decode_rm01_address(rl);
10522                DECODE_PRINTF("\n");
10523                destval = fetch_data_word(destoffset);
10524                TRACE_AND_STEP();
10525                div_word(destval);
10526            }
10527            break;
10528        case 7:
10529            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10530                u32 destval;
10531
10532                DECODE_PRINTF("IDIV\tDWORD PTR ");
10533                destoffset = decode_rm01_address(rl);
10534                DECODE_PRINTF("\n");
10535                destval = fetch_data_long(destoffset);
10536                TRACE_AND_STEP();
10537                idiv_long(destval);
10538            } else {
10539                u16 destval;
10540
10541                DECODE_PRINTF("IDIV\tWORD PTR ");
10542                destoffset = decode_rm01_address(rl);
10543                DECODE_PRINTF("\n");
10544                destval = fetch_data_word(destoffset);
10545                TRACE_AND_STEP();
10546                idiv_word(destval);
10547            }
10548            break;
10549        }
10550        break;                  /* end mod==01 */
10551    case 2:                     /* mod=10 */
10552        switch (rh) {
10553        case 0:         /* test word imm */
10554            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10555                u32 destval,srcval;
10556
10557                DECODE_PRINTF("TEST\tDWORD PTR ");
10558                destoffset = decode_rm10_address(rl);
10559                DECODE_PRINTF(",");
10560                srcval = fetch_long_imm();
10561                DECODE_PRINTF2("%x\n", srcval);
10562                destval = fetch_data_long(destoffset);
10563                TRACE_AND_STEP();
10564                test_long(destval, srcval);
10565            } else {
10566                u16 destval,srcval;
10567
10568                DECODE_PRINTF("TEST\tWORD PTR ");
10569                destoffset = decode_rm10_address(rl);
10570                DECODE_PRINTF(",");
10571                srcval = fetch_word_imm();
10572                DECODE_PRINTF2("%x\n", srcval);
10573                destval = fetch_data_word(destoffset);
10574                TRACE_AND_STEP();
10575                test_word(destval, srcval);
10576            }
10577            break;
10578        case 1:
10579            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10580            HALT_SYS();
10581            break;
10582        case 2:
10583            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10584                u32 destval;
10585
10586                DECODE_PRINTF("NOT\tDWORD PTR ");
10587                destoffset = decode_rm10_address(rl);
10588                DECODE_PRINTF("\n");
10589                destval = fetch_data_long(destoffset);
10590                TRACE_AND_STEP();
10591                destval = not_long(destval);
10592                store_data_long(destoffset, destval);
10593            } else {
10594                u16 destval;
10595
10596                DECODE_PRINTF("NOT\tWORD PTR ");
10597                destoffset = decode_rm10_address(rl);
10598                DECODE_PRINTF("\n");
10599                destval = fetch_data_word(destoffset);
10600                TRACE_AND_STEP();
10601                destval = not_word(destval);
10602                store_data_word(destoffset, destval);
10603            }
10604            break;
10605        case 3:
10606            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10607                u32 destval;
10608
10609                DECODE_PRINTF("NEG\tDWORD PTR ");
10610                destoffset = decode_rm10_address(rl);
10611                DECODE_PRINTF("\n");
10612                destval = fetch_data_long(destoffset);
10613                TRACE_AND_STEP();
10614                destval = neg_long(destval);
10615                store_data_long(destoffset, destval);
10616            } else {
10617                u16 destval;
10618
10619                DECODE_PRINTF("NEG\tWORD PTR ");
10620                destoffset = decode_rm10_address(rl);
10621                DECODE_PRINTF("\n");
10622                destval = fetch_data_word(destoffset);
10623                TRACE_AND_STEP();
10624                destval = neg_word(destval);
10625                store_data_word(destoffset, destval);
10626            }
10627            break;
10628        case 4:
10629            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10630                u32 destval;
10631
10632                DECODE_PRINTF("MUL\tDWORD PTR ");
10633                destoffset = decode_rm10_address(rl);
10634                DECODE_PRINTF("\n");
10635                destval = fetch_data_long(destoffset);
10636                TRACE_AND_STEP();
10637                mul_long(destval);
10638            } else {
10639                u16 destval;
10640
10641                DECODE_PRINTF("MUL\tWORD PTR ");
10642                destoffset = decode_rm10_address(rl);
10643                DECODE_PRINTF("\n");
10644                destval = fetch_data_word(destoffset);
10645                TRACE_AND_STEP();
10646                mul_word(destval);
10647            }
10648            break;
10649        case 5:
10650            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10651                u32 destval;
10652
10653                DECODE_PRINTF("IMUL\tDWORD PTR ");
10654                destoffset = decode_rm10_address(rl);
10655                DECODE_PRINTF("\n");
10656                destval = fetch_data_long(destoffset);
10657                TRACE_AND_STEP();
10658                imul_long(destval);
10659            } else {
10660                u16 destval;
10661
10662                DECODE_PRINTF("IMUL\tWORD PTR ");
10663                destoffset = decode_rm10_address(rl);
10664                DECODE_PRINTF("\n");
10665                destval = fetch_data_word(destoffset);
10666                TRACE_AND_STEP();
10667                imul_word(destval);
10668            }
10669            break;
10670        case 6:
10671            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10672                u32 destval;
10673
10674                DECODE_PRINTF("DIV\tDWORD PTR ");
10675                destoffset = decode_rm10_address(rl);
10676                DECODE_PRINTF("\n");
10677                destval = fetch_data_long(destoffset);
10678                TRACE_AND_STEP();
10679                div_long(destval);
10680            } else {
10681                u16 destval;
10682
10683                DECODE_PRINTF("DIV\tWORD PTR ");
10684                destoffset = decode_rm10_address(rl);
10685                DECODE_PRINTF("\n");
10686                destval = fetch_data_word(destoffset);
10687                TRACE_AND_STEP();
10688                div_word(destval);
10689            }
10690            break;
10691        case 7:
10692            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10693                u32 destval;
10694
10695                DECODE_PRINTF("IDIV\tDWORD PTR ");
10696                destoffset = decode_rm10_address(rl);
10697                DECODE_PRINTF("\n");
10698                destval = fetch_data_long(destoffset);
10699                TRACE_AND_STEP();
10700                idiv_long(destval);
10701            } else {
10702                u16 destval;
10703
10704                DECODE_PRINTF("IDIV\tWORD PTR ");
10705                destoffset = decode_rm10_address(rl);
10706                DECODE_PRINTF("\n");
10707                destval = fetch_data_word(destoffset);
10708                TRACE_AND_STEP();
10709                idiv_word(destval);
10710            }
10711            break;
10712        }
10713        break;                  /* end mod==10 */
10714    case 3:                     /* mod=11 */
10715        switch (rh) {
10716        case 0:         /* test word imm */
10717            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10718                u32 *destreg;
10719                u32 srcval;
10720
10721                DECODE_PRINTF("TEST\t");
10722                destreg = DECODE_RM_LONG_REGISTER(rl);
10723                DECODE_PRINTF(",");
10724                srcval = fetch_long_imm();
10725                DECODE_PRINTF2("%x\n", srcval);
10726                TRACE_AND_STEP();
10727                test_long(*destreg, srcval);
10728            } else {
10729                u16 *destreg;
10730                u16 srcval;
10731
10732                DECODE_PRINTF("TEST\t");
10733                destreg = DECODE_RM_WORD_REGISTER(rl);
10734                DECODE_PRINTF(",");
10735                srcval = fetch_word_imm();
10736                DECODE_PRINTF2("%x\n", srcval);
10737                TRACE_AND_STEP();
10738                test_word(*destreg, srcval);
10739            }
10740            break;
10741        case 1:
10742            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10743            HALT_SYS();
10744            break;
10745        case 2:
10746            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10747                u32 *destreg;
10748
10749                DECODE_PRINTF("NOT\t");
10750                destreg = DECODE_RM_LONG_REGISTER(rl);
10751                DECODE_PRINTF("\n");
10752                TRACE_AND_STEP();
10753                *destreg = not_long(*destreg);
10754            } else {
10755                u16 *destreg;
10756
10757                DECODE_PRINTF("NOT\t");
10758                destreg = DECODE_RM_WORD_REGISTER(rl);
10759                DECODE_PRINTF("\n");
10760                TRACE_AND_STEP();
10761                *destreg = not_word(*destreg);
10762            }
10763            break;
10764        case 3:
10765            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10766                u32 *destreg;
10767
10768                DECODE_PRINTF("NEG\t");
10769                destreg = DECODE_RM_LONG_REGISTER(rl);
10770                DECODE_PRINTF("\n");
10771                TRACE_AND_STEP();
10772                *destreg = neg_long(*destreg);
10773            } else {
10774                u16 *destreg;
10775
10776                DECODE_PRINTF("NEG\t");
10777                destreg = DECODE_RM_WORD_REGISTER(rl);
10778                DECODE_PRINTF("\n");
10779                TRACE_AND_STEP();
10780                *destreg = neg_word(*destreg);
10781            }
10782            break;
10783        case 4:
10784            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10785                u32 *destreg;
10786
10787                DECODE_PRINTF("MUL\t");
10788                destreg = DECODE_RM_LONG_REGISTER(rl);
10789                DECODE_PRINTF("\n");
10790                TRACE_AND_STEP();
10791                mul_long(*destreg);      /*!!!  */
10792            } else {
10793                u16 *destreg;
10794
10795                DECODE_PRINTF("MUL\t");
10796                destreg = DECODE_RM_WORD_REGISTER(rl);
10797                DECODE_PRINTF("\n");
10798                TRACE_AND_STEP();
10799                mul_word(*destreg);      /*!!!  */
10800            }
10801            break;
10802        case 5:
10803            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10804                u32 *destreg;
10805
10806                DECODE_PRINTF("IMUL\t");
10807                destreg = DECODE_RM_LONG_REGISTER(rl);
10808                DECODE_PRINTF("\n");
10809                TRACE_AND_STEP();
10810                imul_long(*destreg);
10811            } else {
10812                u16 *destreg;
10813
10814                DECODE_PRINTF("IMUL\t");
10815                destreg = DECODE_RM_WORD_REGISTER(rl);
10816                DECODE_PRINTF("\n");
10817                TRACE_AND_STEP();
10818                imul_word(*destreg);
10819            }
10820            break;
10821        case 6:
10822            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10823                u32 *destreg;
10824
10825                DECODE_PRINTF("DIV\t");
10826                destreg = DECODE_RM_LONG_REGISTER(rl);
10827                DECODE_PRINTF("\n");
10828                TRACE_AND_STEP();
10829                div_long(*destreg);
10830            } else {
10831                u16 *destreg;
10832
10833                DECODE_PRINTF("DIV\t");
10834                destreg = DECODE_RM_WORD_REGISTER(rl);
10835                DECODE_PRINTF("\n");
10836                TRACE_AND_STEP();
10837                div_word(*destreg);
10838            }
10839            break;
10840        case 7:
10841            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10842                u32 *destreg;
10843
10844                DECODE_PRINTF("IDIV\t");
10845                destreg = DECODE_RM_LONG_REGISTER(rl);
10846                DECODE_PRINTF("\n");
10847                TRACE_AND_STEP();
10848                idiv_long(*destreg);
10849            } else {
10850                u16 *destreg;
10851
10852                DECODE_PRINTF("IDIV\t");
10853                destreg = DECODE_RM_WORD_REGISTER(rl);
10854                DECODE_PRINTF("\n");
10855                TRACE_AND_STEP();
10856                idiv_word(*destreg);
10857            }
10858            break;
10859        }
10860        break;                  /* end mod==11 */
10861    }
10862    DECODE_CLEAR_SEGOVR();
10863    END_OF_INSTR();
10864}
10865
10866/****************************************************************************
10867REMARKS:
10868Handles opcode 0xf8
10869****************************************************************************/
10870static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10871{
10872    /* clear the carry flag. */
10873    START_OF_INSTR();
10874    DECODE_PRINTF("CLC\n");
10875    TRACE_AND_STEP();
10876    CLEAR_FLAG(F_CF);
10877    DECODE_CLEAR_SEGOVR();
10878    END_OF_INSTR();
10879}
10880
10881/****************************************************************************
10882REMARKS:
10883Handles opcode 0xf9
10884****************************************************************************/
10885static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10886{
10887    /* set the carry flag. */
10888    START_OF_INSTR();
10889    DECODE_PRINTF("STC\n");
10890    TRACE_AND_STEP();
10891    SET_FLAG(F_CF);
10892    DECODE_CLEAR_SEGOVR();
10893    END_OF_INSTR();
10894}
10895
10896/****************************************************************************
10897REMARKS:
10898Handles opcode 0xfa
10899****************************************************************************/
10900static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10901{
10902    /* clear interrupts. */
10903    START_OF_INSTR();
10904    DECODE_PRINTF("CLI\n");
10905    TRACE_AND_STEP();
10906    CLEAR_FLAG(F_IF);
10907    DECODE_CLEAR_SEGOVR();
10908    END_OF_INSTR();
10909}
10910
10911/****************************************************************************
10912REMARKS:
10913Handles opcode 0xfb
10914****************************************************************************/
10915static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10916{
10917    /* enable  interrupts. */
10918    START_OF_INSTR();
10919    DECODE_PRINTF("STI\n");
10920    TRACE_AND_STEP();
10921    SET_FLAG(F_IF);
10922    DECODE_CLEAR_SEGOVR();
10923    END_OF_INSTR();
10924}
10925
10926/****************************************************************************
10927REMARKS:
10928Handles opcode 0xfc
10929****************************************************************************/
10930static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10931{
10932    /* clear interrupts. */
10933    START_OF_INSTR();
10934    DECODE_PRINTF("CLD\n");
10935    TRACE_AND_STEP();
10936    CLEAR_FLAG(F_DF);
10937    DECODE_CLEAR_SEGOVR();
10938    END_OF_INSTR();
10939}
10940
10941/****************************************************************************
10942REMARKS:
10943Handles opcode 0xfd
10944****************************************************************************/
10945static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10946{
10947    /* clear interrupts. */
10948    START_OF_INSTR();
10949    DECODE_PRINTF("STD\n");
10950    TRACE_AND_STEP();
10951    SET_FLAG(F_DF);
10952    DECODE_CLEAR_SEGOVR();
10953    END_OF_INSTR();
10954}
10955
10956/****************************************************************************
10957REMARKS:
10958Handles opcode 0xfe
10959****************************************************************************/
10960static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10961{
10962    int mod, rh, rl;
10963    u8 destval;
10964    uint destoffset;
10965    u8 *destreg;
10966
10967    /* Yet another special case instruction. */
10968    START_OF_INSTR();
10969    FETCH_DECODE_MODRM(mod, rh, rl);
10970#ifdef DEBUG
10971    if (DEBUG_DECODE()) {
10972        /* XXX DECODE_PRINTF may be changed to something more
10973           general, so that it is important to leave the strings
10974           in the same format, even though the result is that the
10975           above test is done twice. */
10976
10977        switch (rh) {
10978        case 0:
10979            DECODE_PRINTF("INC\t");
10980            break;
10981        case 1:
10982            DECODE_PRINTF("DEC\t");
10983            break;
10984        case 2:
10985        case 3:
10986        case 4:
10987        case 5:
10988        case 6:
10989        case 7:
10990            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10991            HALT_SYS();
10992            break;
10993        }
10994    }
10995#endif
10996    switch (mod) {
10997    case 0:
10998        DECODE_PRINTF("BYTE PTR ");
10999        destoffset = decode_rm00_address(rl);
11000        DECODE_PRINTF("\n");
11001        switch (rh) {
11002        case 0:         /* inc word ptr ... */
11003            destval = fetch_data_byte(destoffset);
11004            TRACE_AND_STEP();
11005            destval = inc_byte(destval);
11006            store_data_byte(destoffset, destval);
11007            break;
11008        case 1:         /* dec word ptr ... */
11009            destval = fetch_data_byte(destoffset);
11010            TRACE_AND_STEP();
11011            destval = dec_byte(destval);
11012            store_data_byte(destoffset, destval);
11013            break;
11014        }
11015        break;
11016    case 1:
11017        DECODE_PRINTF("BYTE PTR ");
11018        destoffset = decode_rm01_address(rl);
11019        DECODE_PRINTF("\n");
11020        switch (rh) {
11021        case 0:
11022            destval = fetch_data_byte(destoffset);
11023            TRACE_AND_STEP();
11024            destval = inc_byte(destval);
11025            store_data_byte(destoffset, destval);
11026            break;
11027        case 1:
11028            destval = fetch_data_byte(destoffset);
11029            TRACE_AND_STEP();
11030            destval = dec_byte(destval);
11031            store_data_byte(destoffset, destval);
11032            break;
11033        }
11034        break;
11035    case 2:
11036        DECODE_PRINTF("BYTE PTR ");
11037        destoffset = decode_rm10_address(rl);
11038        DECODE_PRINTF("\n");
11039        switch (rh) {
11040        case 0:
11041            destval = fetch_data_byte(destoffset);
11042            TRACE_AND_STEP();
11043            destval = inc_byte(destval);
11044            store_data_byte(destoffset, destval);
11045            break;
11046        case 1:
11047            destval = fetch_data_byte(destoffset);
11048            TRACE_AND_STEP();
11049            destval = dec_byte(destval);
11050            store_data_byte(destoffset, destval);
11051            break;
11052        }
11053        break;
11054    case 3:
11055        destreg = DECODE_RM_BYTE_REGISTER(rl);
11056        DECODE_PRINTF("\n");
11057        switch (rh) {
11058        case 0:
11059            TRACE_AND_STEP();
11060            *destreg = inc_byte(*destreg);
11061            break;
11062        case 1:
11063            TRACE_AND_STEP();
11064            *destreg = dec_byte(*destreg);
11065            break;
11066        }
11067        break;
11068    }
11069    DECODE_CLEAR_SEGOVR();
11070    END_OF_INSTR();
11071}
11072
11073/****************************************************************************
11074REMARKS:
11075Handles opcode 0xff
11076****************************************************************************/
11077static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11078{
11079    int mod, rh, rl;
11080    uint destoffset = 0;
11081	u16 *destreg;
11082	u16 destval,destval2;
11083
11084    /* Yet another special case instruction. */
11085    START_OF_INSTR();
11086    FETCH_DECODE_MODRM(mod, rh, rl);
11087#ifdef DEBUG
11088    if (DEBUG_DECODE()) {
11089        /* XXX DECODE_PRINTF may be changed to something more
11090           general, so that it is important to leave the strings
11091           in the same format, even though the result is that the
11092           above test is done twice. */
11093
11094        switch (rh) {
11095        case 0:
11096            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11097                DECODE_PRINTF("INC\tDWORD PTR ");
11098            } else {
11099                DECODE_PRINTF("INC\tWORD PTR ");
11100            }
11101            break;
11102        case 1:
11103            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11104                DECODE_PRINTF("DEC\tDWORD PTR ");
11105            } else {
11106                DECODE_PRINTF("DEC\tWORD PTR ");
11107            }
11108            break;
11109        case 2:
11110            DECODE_PRINTF("CALL\t");
11111            break;
11112        case 3:
11113            DECODE_PRINTF("CALL\tFAR ");
11114            break;
11115        case 4:
11116            DECODE_PRINTF("JMP\t");
11117            break;
11118        case 5:
11119            DECODE_PRINTF("JMP\tFAR ");
11120            break;
11121        case 6:
11122            DECODE_PRINTF("PUSH\t");
11123            break;
11124        case 7:
11125            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11126            HALT_SYS();
11127            break;
11128        }
11129    }
11130#endif
11131    switch (mod) {
11132    case 0:
11133        destoffset = decode_rm00_address(rl);
11134        DECODE_PRINTF("\n");
11135        switch (rh) {
11136        case 0:         /* inc word ptr ... */
11137            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11138                u32 destval;
11139
11140                destval = fetch_data_long(destoffset);
11141                TRACE_AND_STEP();
11142                destval = inc_long(destval);
11143                store_data_long(destoffset, destval);
11144            } else {
11145                u16 destval;
11146
11147                destval = fetch_data_word(destoffset);
11148                TRACE_AND_STEP();
11149                destval = inc_word(destval);
11150                store_data_word(destoffset, destval);
11151            }
11152            break;
11153        case 1:         /* dec word ptr ... */
11154            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11155                u32 destval;
11156
11157                destval = fetch_data_long(destoffset);
11158                TRACE_AND_STEP();
11159                destval = dec_long(destval);
11160                store_data_long(destoffset, destval);
11161            } else {
11162                u16 destval;
11163
11164                destval = fetch_data_word(destoffset);
11165                TRACE_AND_STEP();
11166                destval = dec_word(destval);
11167                store_data_word(destoffset, destval);
11168            }
11169            break;
11170        case 2:         /* call word ptr ... */
11171            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11172                u32 destval;
11173
11174                destval = fetch_data_long(destoffset);
11175                TRACE_AND_STEP();
11176                push_long(M.x86.R_EIP);
11177                M.x86.R_EIP = destval;
11178            } else {
11179                destval = fetch_data_word(destoffset);
11180                TRACE_AND_STEP();
11181                push_word(M.x86.R_IP);
11182                M.x86.R_IP = destval;
11183            }
11184            break;
11185        case 3:         /* call far ptr ... */
11186            destval = fetch_data_word(destoffset);
11187            destval2 = fetch_data_word(destoffset + 2);
11188            TRACE_AND_STEP();
11189            push_word(M.x86.R_CS);
11190            M.x86.R_CS = destval2;
11191            push_word(M.x86.R_IP);
11192            M.x86.R_IP = destval;
11193            break;
11194        case 4:         /* jmp word ptr ... */
11195            destval = fetch_data_word(destoffset);
11196            TRACE_AND_STEP();
11197            M.x86.R_IP = destval;
11198            break;
11199        case 5:         /* jmp far ptr ... */
11200            destval = fetch_data_word(destoffset);
11201            destval2 = fetch_data_word(destoffset + 2);
11202            TRACE_AND_STEP();
11203            M.x86.R_IP = destval;
11204            M.x86.R_CS = destval2;
11205            break;
11206        case 6:         /*  push word ptr ... */
11207            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11208                u32 destval;
11209
11210                destval = fetch_data_long(destoffset);
11211                TRACE_AND_STEP();
11212                push_long(destval);
11213            } else {
11214                u16 destval;
11215
11216                destval = fetch_data_word(destoffset);
11217                TRACE_AND_STEP();
11218                push_word(destval);
11219            }
11220            break;
11221        }
11222        break;
11223    case 1:
11224        destoffset = decode_rm01_address(rl);
11225        DECODE_PRINTF("\n");
11226        switch (rh) {
11227        case 0:
11228            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11229                u32 destval;
11230
11231                destval = fetch_data_long(destoffset);
11232                TRACE_AND_STEP();
11233                destval = inc_long(destval);
11234                store_data_long(destoffset, destval);
11235            } else {
11236                u16 destval;
11237
11238                destval = fetch_data_word(destoffset);
11239                TRACE_AND_STEP();
11240                destval = inc_word(destval);
11241                store_data_word(destoffset, destval);
11242            }
11243            break;
11244        case 1:
11245            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11246                u32 destval;
11247
11248                destval = fetch_data_long(destoffset);
11249                TRACE_AND_STEP();
11250                destval = dec_long(destval);
11251                store_data_long(destoffset, destval);
11252            } else {
11253                u16 destval;
11254
11255                destval = fetch_data_word(destoffset);
11256                TRACE_AND_STEP();
11257                destval = dec_word(destval);
11258                store_data_word(destoffset, destval);
11259            }
11260            break;
11261        case 2:         /* call word ptr ... */
11262            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11263                u32 destval;
11264
11265                destval = fetch_data_long(destoffset);
11266                TRACE_AND_STEP();
11267                push_long(M.x86.R_EIP);
11268                M.x86.R_EIP = destval;
11269            } else {
11270                destval = fetch_data_word(destoffset);
11271                TRACE_AND_STEP();
11272                push_word(M.x86.R_IP);
11273                M.x86.R_IP = destval;
11274            }
11275            break;
11276        case 3:         /* call far ptr ... */
11277            destval = fetch_data_word(destoffset);
11278            destval2 = fetch_data_word(destoffset + 2);
11279            TRACE_AND_STEP();
11280            push_word(M.x86.R_CS);
11281            M.x86.R_CS = destval2;
11282            push_word(M.x86.R_IP);
11283            M.x86.R_IP = destval;
11284            break;
11285        case 4:         /* jmp word ptr ... */
11286            destval = fetch_data_word(destoffset);
11287            TRACE_AND_STEP();
11288            M.x86.R_IP = destval;
11289            break;
11290        case 5:         /* jmp far ptr ... */
11291            destval = fetch_data_word(destoffset);
11292            destval2 = fetch_data_word(destoffset + 2);
11293            TRACE_AND_STEP();
11294            M.x86.R_IP = destval;
11295            M.x86.R_CS = destval2;
11296            break;
11297        case 6:         /*  push word ptr ... */
11298            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11299                u32 destval;
11300
11301                destval = fetch_data_long(destoffset);
11302                TRACE_AND_STEP();
11303                push_long(destval);
11304            } else {
11305                u16 destval;
11306
11307                destval = fetch_data_word(destoffset);
11308                TRACE_AND_STEP();
11309                push_word(destval);
11310            }
11311            break;
11312        }
11313        break;
11314    case 2:
11315        destoffset = decode_rm10_address(rl);
11316        DECODE_PRINTF("\n");
11317        switch (rh) {
11318        case 0:
11319            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11320                u32 destval;
11321
11322                destval = fetch_data_long(destoffset);
11323                TRACE_AND_STEP();
11324                destval = inc_long(destval);
11325                store_data_long(destoffset, destval);
11326            } else {
11327                u16 destval;
11328
11329                destval = fetch_data_word(destoffset);
11330                TRACE_AND_STEP();
11331                destval = inc_word(destval);
11332                store_data_word(destoffset, destval);
11333            }
11334            break;
11335        case 1:
11336            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11337                u32 destval;
11338
11339                destval = fetch_data_long(destoffset);
11340                TRACE_AND_STEP();
11341                destval = dec_long(destval);
11342                store_data_long(destoffset, destval);
11343            } else {
11344                u16 destval;
11345
11346                destval = fetch_data_word(destoffset);
11347                TRACE_AND_STEP();
11348                destval = dec_word(destval);
11349                store_data_word(destoffset, destval);
11350            }
11351            break;
11352        case 2:         /* call word ptr ... */
11353            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11354                u32 destval;
11355
11356                destval = fetch_data_long(destoffset);
11357                TRACE_AND_STEP();
11358                push_long(M.x86.R_EIP);
11359                M.x86.R_EIP = destval;
11360            } else {
11361                destval = fetch_data_word(destoffset);
11362                TRACE_AND_STEP();
11363                push_word(M.x86.R_IP);
11364                M.x86.R_IP = destval;
11365            }
11366            break;
11367        case 3:         /* call far ptr ... */
11368            destval = fetch_data_word(destoffset);
11369            destval2 = fetch_data_word(destoffset + 2);
11370            TRACE_AND_STEP();
11371            push_word(M.x86.R_CS);
11372            M.x86.R_CS = destval2;
11373            push_word(M.x86.R_IP);
11374            M.x86.R_IP = destval;
11375            break;
11376        case 4:         /* jmp word ptr ... */
11377            destval = fetch_data_word(destoffset);
11378            TRACE_AND_STEP();
11379            M.x86.R_IP = destval;
11380            break;
11381        case 5:         /* jmp far ptr ... */
11382            destval = fetch_data_word(destoffset);
11383            destval2 = fetch_data_word(destoffset + 2);
11384            TRACE_AND_STEP();
11385            M.x86.R_IP = destval;
11386            M.x86.R_CS = destval2;
11387            break;
11388        case 6:         /*  push word ptr ... */
11389            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11390                u32 destval;
11391
11392                destval = fetch_data_long(destoffset);
11393                TRACE_AND_STEP();
11394                push_long(destval);
11395            } else {
11396                u16 destval;
11397
11398                destval = fetch_data_word(destoffset);
11399                TRACE_AND_STEP();
11400                push_word(destval);
11401            }
11402            break;
11403        }
11404        break;
11405    case 3:
11406        switch (rh) {
11407        case 0:
11408            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11409                u32 *destreg;
11410
11411                destreg = DECODE_RM_LONG_REGISTER(rl);
11412                DECODE_PRINTF("\n");
11413                TRACE_AND_STEP();
11414                *destreg = inc_long(*destreg);
11415            } else {
11416                u16 *destreg;
11417
11418                destreg = DECODE_RM_WORD_REGISTER(rl);
11419                DECODE_PRINTF("\n");
11420                TRACE_AND_STEP();
11421                *destreg = inc_word(*destreg);
11422            }
11423            break;
11424        case 1:
11425            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11426                u32 *destreg;
11427
11428                destreg = DECODE_RM_LONG_REGISTER(rl);
11429                DECODE_PRINTF("\n");
11430                TRACE_AND_STEP();
11431                *destreg = dec_long(*destreg);
11432            } else {
11433                u16 *destreg;
11434
11435                destreg = DECODE_RM_WORD_REGISTER(rl);
11436                DECODE_PRINTF("\n");
11437                TRACE_AND_STEP();
11438                *destreg = dec_word(*destreg);
11439            }
11440            break;
11441        case 2:         /* call word ptr ... */
11442            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11443                u32 *destreg;
11444
11445                destreg = DECODE_RM_LONG_REGISTER(rl);
11446                DECODE_PRINTF("\n");
11447                TRACE_AND_STEP();
11448                push_long(M.x86.R_EIP);
11449                M.x86.R_EIP = *destreg;
11450            } else {
11451                destreg = DECODE_RM_WORD_REGISTER(rl);
11452                DECODE_PRINTF("\n");
11453                TRACE_AND_STEP();
11454                push_word(M.x86.R_IP);
11455                M.x86.R_IP = *destreg;
11456            }
11457            break;
11458        case 3:         /* jmp far ptr ... */
11459            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11460            TRACE_AND_STEP();
11461            HALT_SYS();
11462            break;
11463
11464        case 4:         /* jmp  ... */
11465            destreg = DECODE_RM_WORD_REGISTER(rl);
11466            DECODE_PRINTF("\n");
11467            TRACE_AND_STEP();
11468            M.x86.R_IP = (u16) (*destreg);
11469            break;
11470        case 5:         /* jmp far ptr ... */
11471            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11472            TRACE_AND_STEP();
11473            HALT_SYS();
11474            break;
11475        case 6:
11476            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11477                u32 *destreg;
11478
11479                destreg = DECODE_RM_LONG_REGISTER(rl);
11480                DECODE_PRINTF("\n");
11481                TRACE_AND_STEP();
11482                push_long(*destreg);
11483            } else {
11484                u16 *destreg;
11485
11486                destreg = DECODE_RM_WORD_REGISTER(rl);
11487                DECODE_PRINTF("\n");
11488                TRACE_AND_STEP();
11489                push_word(*destreg);
11490            }
11491            break;
11492        }
11493        break;
11494    }
11495    DECODE_CLEAR_SEGOVR();
11496    END_OF_INSTR();
11497}
11498
11499/***************************************************************************
11500 * Single byte operation code table:
11501 **************************************************************************/
11502void (*x86emu_optab[256])(u8) =
11503{
11504/*  0x00 */ x86emuOp_add_byte_RM_R,
11505/*  0x01 */ x86emuOp_add_word_RM_R,
11506/*  0x02 */ x86emuOp_add_byte_R_RM,
11507/*  0x03 */ x86emuOp_add_word_R_RM,
11508/*  0x04 */ x86emuOp_add_byte_AL_IMM,
11509/*  0x05 */ x86emuOp_add_word_AX_IMM,
11510/*  0x06 */ x86emuOp_push_ES,
11511/*  0x07 */ x86emuOp_pop_ES,
11512
11513/*  0x08 */ x86emuOp_or_byte_RM_R,
11514/*  0x09 */ x86emuOp_or_word_RM_R,
11515/*  0x0a */ x86emuOp_or_byte_R_RM,
11516/*  0x0b */ x86emuOp_or_word_R_RM,
11517/*  0x0c */ x86emuOp_or_byte_AL_IMM,
11518/*  0x0d */ x86emuOp_or_word_AX_IMM,
11519/*  0x0e */ x86emuOp_push_CS,
11520/*  0x0f */ x86emuOp_two_byte,
11521
11522/*  0x10 */ x86emuOp_adc_byte_RM_R,
11523/*  0x11 */ x86emuOp_adc_word_RM_R,
11524/*  0x12 */ x86emuOp_adc_byte_R_RM,
11525/*  0x13 */ x86emuOp_adc_word_R_RM,
11526/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11527/*  0x15 */ x86emuOp_adc_word_AX_IMM,
11528/*  0x16 */ x86emuOp_push_SS,
11529/*  0x17 */ x86emuOp_pop_SS,
11530
11531/*  0x18 */ x86emuOp_sbb_byte_RM_R,
11532/*  0x19 */ x86emuOp_sbb_word_RM_R,
11533/*  0x1a */ x86emuOp_sbb_byte_R_RM,
11534/*  0x1b */ x86emuOp_sbb_word_R_RM,
11535/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11536/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11537/*  0x1e */ x86emuOp_push_DS,
11538/*  0x1f */ x86emuOp_pop_DS,
11539
11540/*  0x20 */ x86emuOp_and_byte_RM_R,
11541/*  0x21 */ x86emuOp_and_word_RM_R,
11542/*  0x22 */ x86emuOp_and_byte_R_RM,
11543/*  0x23 */ x86emuOp_and_word_R_RM,
11544/*  0x24 */ x86emuOp_and_byte_AL_IMM,
11545/*  0x25 */ x86emuOp_and_word_AX_IMM,
11546/*  0x26 */ x86emuOp_segovr_ES,
11547/*  0x27 */ x86emuOp_daa,
11548
11549/*  0x28 */ x86emuOp_sub_byte_RM_R,
11550/*  0x29 */ x86emuOp_sub_word_RM_R,
11551/*  0x2a */ x86emuOp_sub_byte_R_RM,
11552/*  0x2b */ x86emuOp_sub_word_R_RM,
11553/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11554/*  0x2d */ x86emuOp_sub_word_AX_IMM,
11555/*  0x2e */ x86emuOp_segovr_CS,
11556/*  0x2f */ x86emuOp_das,
11557
11558/*  0x30 */ x86emuOp_xor_byte_RM_R,
11559/*  0x31 */ x86emuOp_xor_word_RM_R,
11560/*  0x32 */ x86emuOp_xor_byte_R_RM,
11561/*  0x33 */ x86emuOp_xor_word_R_RM,
11562/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11563/*  0x35 */ x86emuOp_xor_word_AX_IMM,
11564/*  0x36 */ x86emuOp_segovr_SS,
11565/*  0x37 */ x86emuOp_aaa,
11566
11567/*  0x38 */ x86emuOp_cmp_byte_RM_R,
11568/*  0x39 */ x86emuOp_cmp_word_RM_R,
11569/*  0x3a */ x86emuOp_cmp_byte_R_RM,
11570/*  0x3b */ x86emuOp_cmp_word_R_RM,
11571/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11572/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11573/*  0x3e */ x86emuOp_segovr_DS,
11574/*  0x3f */ x86emuOp_aas,
11575
11576/*  0x40 */ x86emuOp_inc_AX,
11577/*  0x41 */ x86emuOp_inc_CX,
11578/*  0x42 */ x86emuOp_inc_DX,
11579/*  0x43 */ x86emuOp_inc_BX,
11580/*  0x44 */ x86emuOp_inc_SP,
11581/*  0x45 */ x86emuOp_inc_BP,
11582/*  0x46 */ x86emuOp_inc_SI,
11583/*  0x47 */ x86emuOp_inc_DI,
11584
11585/*  0x48 */ x86emuOp_dec_AX,
11586/*  0x49 */ x86emuOp_dec_CX,
11587/*  0x4a */ x86emuOp_dec_DX,
11588/*  0x4b */ x86emuOp_dec_BX,
11589/*  0x4c */ x86emuOp_dec_SP,
11590/*  0x4d */ x86emuOp_dec_BP,
11591/*  0x4e */ x86emuOp_dec_SI,
11592/*  0x4f */ x86emuOp_dec_DI,
11593
11594/*  0x50 */ x86emuOp_push_AX,
11595/*  0x51 */ x86emuOp_push_CX,
11596/*  0x52 */ x86emuOp_push_DX,
11597/*  0x53 */ x86emuOp_push_BX,
11598/*  0x54 */ x86emuOp_push_SP,
11599/*  0x55 */ x86emuOp_push_BP,
11600/*  0x56 */ x86emuOp_push_SI,
11601/*  0x57 */ x86emuOp_push_DI,
11602
11603/*  0x58 */ x86emuOp_pop_AX,
11604/*  0x59 */ x86emuOp_pop_CX,
11605/*  0x5a */ x86emuOp_pop_DX,
11606/*  0x5b */ x86emuOp_pop_BX,
11607/*  0x5c */ x86emuOp_pop_SP,
11608/*  0x5d */ x86emuOp_pop_BP,
11609/*  0x5e */ x86emuOp_pop_SI,
11610/*  0x5f */ x86emuOp_pop_DI,
11611
11612/*  0x60 */ x86emuOp_push_all,
11613/*  0x61 */ x86emuOp_pop_all,
11614/*  0x62 */ x86emuOp_illegal_op,   /* bound */
11615/*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11616/*  0x64 */ x86emuOp_segovr_FS,
11617/*  0x65 */ x86emuOp_segovr_GS,
11618/*  0x66 */ x86emuOp_prefix_data,
11619/*  0x67 */ x86emuOp_prefix_addr,
11620
11621/*  0x68 */ x86emuOp_push_word_IMM,
11622/*  0x69 */ x86emuOp_imul_word_IMM,
11623/*  0x6a */ x86emuOp_push_byte_IMM,
11624/*  0x6b */ x86emuOp_imul_byte_IMM,
11625/*  0x6c */ x86emuOp_ins_byte,
11626/*  0x6d */ x86emuOp_ins_word,
11627/*  0x6e */ x86emuOp_outs_byte,
11628/*  0x6f */ x86emuOp_outs_word,
11629
11630/*  0x70 */ x86emuOp_jump_near_O,
11631/*  0x71 */ x86emuOp_jump_near_NO,
11632/*  0x72 */ x86emuOp_jump_near_B,
11633/*  0x73 */ x86emuOp_jump_near_NB,
11634/*  0x74 */ x86emuOp_jump_near_Z,
11635/*  0x75 */ x86emuOp_jump_near_NZ,
11636/*  0x76 */ x86emuOp_jump_near_BE,
11637/*  0x77 */ x86emuOp_jump_near_NBE,
11638
11639/*  0x78 */ x86emuOp_jump_near_S,
11640/*  0x79 */ x86emuOp_jump_near_NS,
11641/*  0x7a */ x86emuOp_jump_near_P,
11642/*  0x7b */ x86emuOp_jump_near_NP,
11643/*  0x7c */ x86emuOp_jump_near_L,
11644/*  0x7d */ x86emuOp_jump_near_NL,
11645/*  0x7e */ x86emuOp_jump_near_LE,
11646/*  0x7f */ x86emuOp_jump_near_NLE,
11647
11648/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11649/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11650/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11651/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11652/*  0x84 */ x86emuOp_test_byte_RM_R,
11653/*  0x85 */ x86emuOp_test_word_RM_R,
11654/*  0x86 */ x86emuOp_xchg_byte_RM_R,
11655/*  0x87 */ x86emuOp_xchg_word_RM_R,
11656
11657/*  0x88 */ x86emuOp_mov_byte_RM_R,
11658/*  0x89 */ x86emuOp_mov_word_RM_R,
11659/*  0x8a */ x86emuOp_mov_byte_R_RM,
11660/*  0x8b */ x86emuOp_mov_word_R_RM,
11661/*  0x8c */ x86emuOp_mov_word_RM_SR,
11662/*  0x8d */ x86emuOp_lea_word_R_M,
11663/*  0x8e */ x86emuOp_mov_word_SR_RM,
11664/*  0x8f */ x86emuOp_pop_RM,
11665
11666/*  0x90 */ x86emuOp_nop,
11667/*  0x91 */ x86emuOp_xchg_word_AX_CX,
11668/*  0x92 */ x86emuOp_xchg_word_AX_DX,
11669/*  0x93 */ x86emuOp_xchg_word_AX_BX,
11670/*  0x94 */ x86emuOp_xchg_word_AX_SP,
11671/*  0x95 */ x86emuOp_xchg_word_AX_BP,
11672/*  0x96 */ x86emuOp_xchg_word_AX_SI,
11673/*  0x97 */ x86emuOp_xchg_word_AX_DI,
11674
11675/*  0x98 */ x86emuOp_cbw,
11676/*  0x99 */ x86emuOp_cwd,
11677/*  0x9a */ x86emuOp_call_far_IMM,
11678/*  0x9b */ x86emuOp_wait,
11679/*  0x9c */ x86emuOp_pushf_word,
11680/*  0x9d */ x86emuOp_popf_word,
11681/*  0x9e */ x86emuOp_sahf,
11682/*  0x9f */ x86emuOp_lahf,
11683
11684/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11685/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11686/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11687/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11688/*  0xa4 */ x86emuOp_movs_byte,
11689/*  0xa5 */ x86emuOp_movs_word,
11690/*  0xa6 */ x86emuOp_cmps_byte,
11691/*  0xa7 */ x86emuOp_cmps_word,
11692/*  0xa8 */ x86emuOp_test_AL_IMM,
11693/*  0xa9 */ x86emuOp_test_AX_IMM,
11694/*  0xaa */ x86emuOp_stos_byte,
11695/*  0xab */ x86emuOp_stos_word,
11696/*  0xac */ x86emuOp_lods_byte,
11697/*  0xad */ x86emuOp_lods_word,
11698/*  0xac */ x86emuOp_scas_byte,
11699/*  0xad */ x86emuOp_scas_word,
11700
11701
11702/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11703/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11704/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11705/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11706/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11707/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11708/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11709/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11710
11711/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11712/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11713/*  0xba */ x86emuOp_mov_word_DX_IMM,
11714/*  0xbb */ x86emuOp_mov_word_BX_IMM,
11715/*  0xbc */ x86emuOp_mov_word_SP_IMM,
11716/*  0xbd */ x86emuOp_mov_word_BP_IMM,
11717/*  0xbe */ x86emuOp_mov_word_SI_IMM,
11718/*  0xbf */ x86emuOp_mov_word_DI_IMM,
11719
11720/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11721/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11722/*  0xc2 */ x86emuOp_ret_near_IMM,
11723/*  0xc3 */ x86emuOp_ret_near,
11724/*  0xc4 */ x86emuOp_les_R_IMM,
11725/*  0xc5 */ x86emuOp_lds_R_IMM,
11726/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11727/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11728/*  0xc8 */ x86emuOp_enter,
11729/*  0xc9 */ x86emuOp_leave,
11730/*  0xca */ x86emuOp_ret_far_IMM,
11731/*  0xcb */ x86emuOp_ret_far,
11732/*  0xcc */ x86emuOp_int3,
11733/*  0xcd */ x86emuOp_int_IMM,
11734/*  0xce */ x86emuOp_into,
11735/*  0xcf */ x86emuOp_iret,
11736
11737/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11738/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11739/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11740/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11741/*  0xd4 */ x86emuOp_aam,
11742/*  0xd5 */ x86emuOp_aad,
11743/*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11744/*  0xd7 */ x86emuOp_xlat,
11745/*  0xd8 */ x86emuOp_esc_coprocess_d8,
11746/*  0xd9 */ x86emuOp_esc_coprocess_d9,
11747/*  0xda */ x86emuOp_esc_coprocess_da,
11748/*  0xdb */ x86emuOp_esc_coprocess_db,
11749/*  0xdc */ x86emuOp_esc_coprocess_dc,
11750/*  0xdd */ x86emuOp_esc_coprocess_dd,
11751/*  0xde */ x86emuOp_esc_coprocess_de,
11752/*  0xdf */ x86emuOp_esc_coprocess_df,
11753
11754/*  0xe0 */ x86emuOp_loopne,
11755/*  0xe1 */ x86emuOp_loope,
11756/*  0xe2 */ x86emuOp_loop,
11757/*  0xe3 */ x86emuOp_jcxz,
11758/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11759/*  0xe5 */ x86emuOp_in_word_AX_IMM,
11760/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11761/*  0xe7 */ x86emuOp_out_word_IMM_AX,
11762
11763/*  0xe8 */ x86emuOp_call_near_IMM,
11764/*  0xe9 */ x86emuOp_jump_near_IMM,
11765/*  0xea */ x86emuOp_jump_far_IMM,
11766/*  0xeb */ x86emuOp_jump_byte_IMM,
11767/*  0xec */ x86emuOp_in_byte_AL_DX,
11768/*  0xed */ x86emuOp_in_word_AX_DX,
11769/*  0xee */ x86emuOp_out_byte_DX_AL,
11770/*  0xef */ x86emuOp_out_word_DX_AX,
11771
11772/*  0xf0 */ x86emuOp_lock,
11773/*  0xf1 */ x86emuOp_illegal_op,
11774/*  0xf2 */ x86emuOp_repne,
11775/*  0xf3 */ x86emuOp_repe,
11776/*  0xf4 */ x86emuOp_halt,
11777/*  0xf5 */ x86emuOp_cmc,
11778/*  0xf6 */ x86emuOp_opcF6_byte_RM,
11779/*  0xf7 */ x86emuOp_opcF7_word_RM,
11780
11781/*  0xf8 */ x86emuOp_clc,
11782/*  0xf9 */ x86emuOp_stc,
11783/*  0xfa */ x86emuOp_cli,
11784/*  0xfb */ x86emuOp_sti,
11785/*  0xfc */ x86emuOp_cld,
11786/*  0xfd */ x86emuOp_std,
11787/*  0xfe */ x86emuOp_opcFE_byte_RM,
11788/*  0xff */ x86emuOp_opcFF_word_RM,
11789};
11790