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/* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */
74
75#include "x86emu/x86emui.h"
76#include "x86emu/ops_protos.h"
77#include "lib_printf.h"
78
79/*----------------------------- Implementation ----------------------------*/
80
81/****************************************************************************
82PARAMETERS:
83op1 - Instruction op code
84
85REMARKS:
86Handles illegal opcodes.
87****************************************************************************/
88void x86emuOp_illegal_op(
89    u8 op1)
90{
91    START_OF_INSTR();
92    DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
93    TRACE_REGS();
94    printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
95        M.x86.R_CS, M.x86.R_IP-1,op1);
96    HALT_SYS();
97    END_OF_INSTR();
98}
99
100/****************************************************************************
101REMARKS:
102Handles opcode 0x00
103****************************************************************************/
104void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
105{
106    int mod, rl, rh;
107    uint destoffset;
108    u8 *destreg, *srcreg;
109    u8 destval;
110
111    START_OF_INSTR();
112    DECODE_PRINTF("ADD\t");
113    FETCH_DECODE_MODRM(mod, rh, rl);
114    switch (mod) {
115    case 0:
116        destoffset = decode_rm00_address(rl);
117        DECODE_PRINTF(",");
118        destval = fetch_data_byte(destoffset);
119        srcreg = DECODE_RM_BYTE_REGISTER(rh);
120        DECODE_PRINTF("\n");
121        TRACE_AND_STEP();
122        destval = add_byte(destval, *srcreg);
123        store_data_byte(destoffset, destval);
124        break;
125    case 1:
126        destoffset = decode_rm01_address(rl);
127        DECODE_PRINTF(",");
128        destval = fetch_data_byte(destoffset);
129        srcreg = DECODE_RM_BYTE_REGISTER(rh);
130        DECODE_PRINTF("\n");
131        TRACE_AND_STEP();
132        destval = add_byte(destval, *srcreg);
133        store_data_byte(destoffset, destval);
134        break;
135    case 2:
136        destoffset = decode_rm10_address(rl);
137        DECODE_PRINTF(",");
138        destval = fetch_data_byte(destoffset);
139        srcreg = DECODE_RM_BYTE_REGISTER(rh);
140        DECODE_PRINTF("\n");
141        TRACE_AND_STEP();
142        destval = add_byte(destval, *srcreg);
143        store_data_byte(destoffset, destval);
144        break;
145    case 3:                     /* register to register */
146        destreg = DECODE_RM_BYTE_REGISTER(rl);
147        DECODE_PRINTF(",");
148        srcreg = DECODE_RM_BYTE_REGISTER(rh);
149        DECODE_PRINTF("\n");
150        TRACE_AND_STEP();
151        *destreg = add_byte(*destreg, *srcreg);
152        break;
153    }
154    DECODE_CLEAR_SEGOVR();
155    END_OF_INSTR();
156}
157
158/****************************************************************************
159REMARKS:
160Handles opcode 0x01
161****************************************************************************/
162void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
163{
164    int mod, rl, rh;
165    uint destoffset;
166
167    START_OF_INSTR();
168    DECODE_PRINTF("ADD\t");
169    FETCH_DECODE_MODRM(mod, rh, rl);
170    switch (mod) {
171    case 0:
172        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
173            u32 destval;
174            u32 *srcreg;
175
176            destoffset = decode_rm00_address(rl);
177            DECODE_PRINTF(",");
178            destval = fetch_data_long(destoffset);
179            srcreg = DECODE_RM_LONG_REGISTER(rh);
180            DECODE_PRINTF("\n");
181            TRACE_AND_STEP();
182            destval = add_long(destval, *srcreg);
183            store_data_long(destoffset, destval);
184        } else {
185            u16 destval;
186            u16 *srcreg;
187
188            destoffset = decode_rm00_address(rl);
189            DECODE_PRINTF(",");
190            destval = fetch_data_word(destoffset);
191            srcreg = DECODE_RM_WORD_REGISTER(rh);
192            DECODE_PRINTF("\n");
193            TRACE_AND_STEP();
194            destval = add_word(destval, *srcreg);
195            store_data_word(destoffset, destval);
196        }
197        break;
198    case 1:
199        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
200            u32 destval;
201            u32 *srcreg;
202
203            destoffset = decode_rm01_address(rl);
204            DECODE_PRINTF(",");
205            destval = fetch_data_long(destoffset);
206            srcreg = DECODE_RM_LONG_REGISTER(rh);
207            DECODE_PRINTF("\n");
208            TRACE_AND_STEP();
209            destval = add_long(destval, *srcreg);
210            store_data_long(destoffset, destval);
211        } else {
212            u16 destval;
213            u16 *srcreg;
214
215            destoffset = decode_rm01_address(rl);
216            DECODE_PRINTF(",");
217            destval = fetch_data_word(destoffset);
218            srcreg = DECODE_RM_WORD_REGISTER(rh);
219            DECODE_PRINTF("\n");
220            TRACE_AND_STEP();
221            destval = add_word(destval, *srcreg);
222            store_data_word(destoffset, destval);
223        }
224        break;
225    case 2:
226        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
227            u32 destval;
228            u32 *srcreg;
229
230            destoffset = decode_rm10_address(rl);
231            DECODE_PRINTF(",");
232            destval = fetch_data_long(destoffset);
233            srcreg = DECODE_RM_LONG_REGISTER(rh);
234            DECODE_PRINTF("\n");
235            TRACE_AND_STEP();
236            destval = add_long(destval, *srcreg);
237            store_data_long(destoffset, destval);
238        } else {
239            u16 destval;
240            u16 *srcreg;
241
242            destoffset = decode_rm10_address(rl);
243            DECODE_PRINTF(",");
244            destval = fetch_data_word(destoffset);
245            srcreg = DECODE_RM_WORD_REGISTER(rh);
246            DECODE_PRINTF("\n");
247            TRACE_AND_STEP();
248            destval = add_word(destval, *srcreg);
249            store_data_word(destoffset, destval);
250        }
251        break;
252    case 3:                     /* register to register */
253        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
254            u32 *destreg,*srcreg;
255
256            destreg = DECODE_RM_LONG_REGISTER(rl);
257            DECODE_PRINTF(",");
258            srcreg = DECODE_RM_LONG_REGISTER(rh);
259            DECODE_PRINTF("\n");
260            TRACE_AND_STEP();
261            *destreg = add_long(*destreg, *srcreg);
262        } else {
263            u16 *destreg,*srcreg;
264
265            destreg = DECODE_RM_WORD_REGISTER(rl);
266            DECODE_PRINTF(",");
267            srcreg = DECODE_RM_WORD_REGISTER(rh);
268            DECODE_PRINTF("\n");
269            TRACE_AND_STEP();
270            *destreg = add_word(*destreg, *srcreg);
271        }
272        break;
273    }
274    DECODE_CLEAR_SEGOVR();
275    END_OF_INSTR();
276}
277
278/****************************************************************************
279REMARKS:
280Handles opcode 0x02
281****************************************************************************/
282void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
283{
284    int mod, rl, rh;
285    u8 *destreg, *srcreg;
286    uint srcoffset;
287    u8 srcval;
288
289    START_OF_INSTR();
290    DECODE_PRINTF("ADD\t");
291    FETCH_DECODE_MODRM(mod, rh, rl);
292    switch (mod) {
293    case 0:
294        destreg = DECODE_RM_BYTE_REGISTER(rh);
295        DECODE_PRINTF(",");
296        srcoffset = decode_rm00_address(rl);
297        srcval = fetch_data_byte(srcoffset);
298        DECODE_PRINTF("\n");
299        TRACE_AND_STEP();
300        *destreg = add_byte(*destreg, srcval);
301        break;
302    case 1:
303        destreg = DECODE_RM_BYTE_REGISTER(rh);
304        DECODE_PRINTF(",");
305        srcoffset = decode_rm01_address(rl);
306        srcval = fetch_data_byte(srcoffset);
307        DECODE_PRINTF("\n");
308        TRACE_AND_STEP();
309        *destreg = add_byte(*destreg, srcval);
310        break;
311    case 2:
312        destreg = DECODE_RM_BYTE_REGISTER(rh);
313        DECODE_PRINTF(",");
314        srcoffset = decode_rm10_address(rl);
315        srcval = fetch_data_byte(srcoffset);
316        DECODE_PRINTF("\n");
317        TRACE_AND_STEP();
318        *destreg = add_byte(*destreg, srcval);
319        break;
320    case 3:                     /* register to register */
321        destreg = DECODE_RM_BYTE_REGISTER(rh);
322        DECODE_PRINTF(",");
323        srcreg = DECODE_RM_BYTE_REGISTER(rl);
324        DECODE_PRINTF("\n");
325        TRACE_AND_STEP();
326        *destreg = add_byte(*destreg, *srcreg);
327        break;
328    }
329    DECODE_CLEAR_SEGOVR();
330    END_OF_INSTR();
331}
332
333/****************************************************************************
334REMARKS:
335Handles opcode 0x03
336****************************************************************************/
337void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
338{
339    int mod, rl, rh;
340    uint srcoffset;
341
342    START_OF_INSTR();
343    DECODE_PRINTF("ADD\t");
344    FETCH_DECODE_MODRM(mod, rh, rl);
345    switch (mod) {
346    case 0:
347        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
348            u32 *destreg;
349            u32 srcval;
350
351            destreg = DECODE_RM_LONG_REGISTER(rh);
352            DECODE_PRINTF(",");
353            srcoffset = decode_rm00_address(rl);
354            srcval = fetch_data_long(srcoffset);
355            DECODE_PRINTF("\n");
356            TRACE_AND_STEP();
357            *destreg = add_long(*destreg, srcval);
358        } else {
359            u16 *destreg;
360            u16 srcval;
361
362            destreg = DECODE_RM_WORD_REGISTER(rh);
363            DECODE_PRINTF(",");
364            srcoffset = decode_rm00_address(rl);
365            srcval = fetch_data_word(srcoffset);
366            DECODE_PRINTF("\n");
367            TRACE_AND_STEP();
368            *destreg = add_word(*destreg, srcval);
369        }
370        break;
371    case 1:
372        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
373            u32 *destreg;
374            u32 srcval;
375
376            destreg = DECODE_RM_LONG_REGISTER(rh);
377            DECODE_PRINTF(",");
378            srcoffset = decode_rm01_address(rl);
379            srcval = fetch_data_long(srcoffset);
380            DECODE_PRINTF("\n");
381            TRACE_AND_STEP();
382            *destreg = add_long(*destreg, srcval);
383        } else {
384            u16 *destreg;
385            u16 srcval;
386
387            destreg = DECODE_RM_WORD_REGISTER(rh);
388            DECODE_PRINTF(",");
389            srcoffset = decode_rm01_address(rl);
390            srcval = fetch_data_word(srcoffset);
391            DECODE_PRINTF("\n");
392            TRACE_AND_STEP();
393            *destreg = add_word(*destreg, srcval);
394        }
395        break;
396    case 2:
397        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
398            u32 *destreg;
399            u32 srcval;
400
401            destreg = DECODE_RM_LONG_REGISTER(rh);
402            DECODE_PRINTF(",");
403            srcoffset = decode_rm10_address(rl);
404            srcval = fetch_data_long(srcoffset);
405            DECODE_PRINTF("\n");
406            TRACE_AND_STEP();
407            *destreg = add_long(*destreg, srcval);
408        } else {
409            u16 *destreg;
410            u16 srcval;
411
412            destreg = DECODE_RM_WORD_REGISTER(rh);
413            DECODE_PRINTF(",");
414            srcoffset = decode_rm10_address(rl);
415            srcval = fetch_data_word(srcoffset);
416            DECODE_PRINTF("\n");
417            TRACE_AND_STEP();
418            *destreg = add_word(*destreg, srcval);
419        }
420        break;
421    case 3:                     /* register to register */
422        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
423            u32 *destreg,*srcreg;
424
425            destreg = DECODE_RM_LONG_REGISTER(rh);
426            DECODE_PRINTF(",");
427            srcreg = DECODE_RM_LONG_REGISTER(rl);
428            DECODE_PRINTF("\n");
429            TRACE_AND_STEP();
430            *destreg = add_long(*destreg, *srcreg);
431        } else {
432            u16 *destreg,*srcreg;
433
434            destreg = DECODE_RM_WORD_REGISTER(rh);
435            DECODE_PRINTF(",");
436            srcreg = DECODE_RM_WORD_REGISTER(rl);
437            DECODE_PRINTF("\n");
438            TRACE_AND_STEP();
439            *destreg = add_word(*destreg, *srcreg);
440        }
441        break;
442    }
443    DECODE_CLEAR_SEGOVR();
444    END_OF_INSTR();
445}
446
447/****************************************************************************
448REMARKS:
449Handles opcode 0x04
450****************************************************************************/
451void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
452{
453    u8 srcval;
454
455    START_OF_INSTR();
456    DECODE_PRINTF("ADD\tAL,");
457    srcval = fetch_byte_imm();
458    DECODE_PRINTF2("%x\n", srcval);
459    TRACE_AND_STEP();
460    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
461    DECODE_CLEAR_SEGOVR();
462    END_OF_INSTR();
463}
464
465/****************************************************************************
466REMARKS:
467Handles opcode 0x05
468****************************************************************************/
469void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
470{
471    u32 srcval;
472
473    START_OF_INSTR();
474    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
475        DECODE_PRINTF("ADD\tEAX,");
476        srcval = fetch_long_imm();
477    } else {
478        DECODE_PRINTF("ADD\tAX,");
479        srcval = fetch_word_imm();
480    }
481    DECODE_PRINTF2("%x\n", srcval);
482    TRACE_AND_STEP();
483    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
484        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
485    } else {
486        M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
487    }
488    DECODE_CLEAR_SEGOVR();
489    END_OF_INSTR();
490}
491
492/****************************************************************************
493REMARKS:
494Handles opcode 0x06
495****************************************************************************/
496void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
497{
498    START_OF_INSTR();
499    DECODE_PRINTF("PUSH\tES\n");
500    TRACE_AND_STEP();
501    push_word(M.x86.R_ES);
502    DECODE_CLEAR_SEGOVR();
503    END_OF_INSTR();
504}
505
506/****************************************************************************
507REMARKS:
508Handles opcode 0x07
509****************************************************************************/
510void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
511{
512    START_OF_INSTR();
513    DECODE_PRINTF("POP\tES\n");
514    TRACE_AND_STEP();
515    M.x86.R_ES = pop_word();
516    DECODE_CLEAR_SEGOVR();
517    END_OF_INSTR();
518}
519
520/****************************************************************************
521REMARKS:
522Handles opcode 0x08
523****************************************************************************/
524void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
525{
526    int mod, rl, rh;
527    u8 *destreg, *srcreg;
528    uint destoffset;
529    u8 destval;
530
531    START_OF_INSTR();
532    DECODE_PRINTF("OR\t");
533    FETCH_DECODE_MODRM(mod, rh, rl);
534    switch (mod) {
535    case 0:
536        destoffset = decode_rm00_address(rl);
537        DECODE_PRINTF(",");
538        destval = fetch_data_byte(destoffset);
539        srcreg = DECODE_RM_BYTE_REGISTER(rh);
540        DECODE_PRINTF("\n");
541        TRACE_AND_STEP();
542        destval = or_byte(destval, *srcreg);
543        store_data_byte(destoffset, destval);
544        break;
545    case 1:
546        destoffset = decode_rm01_address(rl);
547        DECODE_PRINTF(",");
548        destval = fetch_data_byte(destoffset);
549        srcreg = DECODE_RM_BYTE_REGISTER(rh);
550        DECODE_PRINTF("\n");
551        TRACE_AND_STEP();
552        destval = or_byte(destval, *srcreg);
553        store_data_byte(destoffset, destval);
554        break;
555    case 2:
556        destoffset = decode_rm10_address(rl);
557        DECODE_PRINTF(",");
558        destval = fetch_data_byte(destoffset);
559        srcreg = DECODE_RM_BYTE_REGISTER(rh);
560        DECODE_PRINTF("\n");
561        TRACE_AND_STEP();
562        destval = or_byte(destval, *srcreg);
563        store_data_byte(destoffset, destval);
564        break;
565    case 3:                     /* register to register */
566        destreg = DECODE_RM_BYTE_REGISTER(rl);
567        DECODE_PRINTF(",");
568        srcreg = DECODE_RM_BYTE_REGISTER(rh);
569        DECODE_PRINTF("\n");
570        TRACE_AND_STEP();
571        *destreg = or_byte(*destreg, *srcreg);
572        break;
573    }
574    DECODE_CLEAR_SEGOVR();
575    END_OF_INSTR();
576}
577
578/****************************************************************************
579REMARKS:
580Handles opcode 0x09
581****************************************************************************/
582void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
583{
584    int mod, rl, rh;
585    uint destoffset;
586
587    START_OF_INSTR();
588    DECODE_PRINTF("OR\t");
589    FETCH_DECODE_MODRM(mod, rh, rl);
590    switch (mod) {
591    case 0:
592        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
593            u32 destval;
594            u32 *srcreg;
595
596            destoffset = decode_rm00_address(rl);
597            DECODE_PRINTF(",");
598            destval = fetch_data_long(destoffset);
599            srcreg = DECODE_RM_LONG_REGISTER(rh);
600            DECODE_PRINTF("\n");
601            TRACE_AND_STEP();
602            destval = or_long(destval, *srcreg);
603            store_data_long(destoffset, destval);
604        } else {
605            u16 destval;
606            u16 *srcreg;
607
608            destoffset = decode_rm00_address(rl);
609            DECODE_PRINTF(",");
610            destval = fetch_data_word(destoffset);
611            srcreg = DECODE_RM_WORD_REGISTER(rh);
612            DECODE_PRINTF("\n");
613            TRACE_AND_STEP();
614            destval = or_word(destval, *srcreg);
615            store_data_word(destoffset, destval);
616        }
617        break;
618    case 1:
619        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620            u32 destval;
621            u32 *srcreg;
622
623            destoffset = decode_rm01_address(rl);
624            DECODE_PRINTF(",");
625            destval = fetch_data_long(destoffset);
626            srcreg = DECODE_RM_LONG_REGISTER(rh);
627            DECODE_PRINTF("\n");
628            TRACE_AND_STEP();
629            destval = or_long(destval, *srcreg);
630            store_data_long(destoffset, destval);
631        } else {
632            u16 destval;
633            u16 *srcreg;
634
635            destoffset = decode_rm01_address(rl);
636            DECODE_PRINTF(",");
637            destval = fetch_data_word(destoffset);
638            srcreg = DECODE_RM_WORD_REGISTER(rh);
639            DECODE_PRINTF("\n");
640            TRACE_AND_STEP();
641            destval = or_word(destval, *srcreg);
642            store_data_word(destoffset, destval);
643        }
644        break;
645    case 2:
646        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
647            u32 destval;
648            u32 *srcreg;
649
650            destoffset = decode_rm10_address(rl);
651            DECODE_PRINTF(",");
652            destval = fetch_data_long(destoffset);
653            srcreg = DECODE_RM_LONG_REGISTER(rh);
654            DECODE_PRINTF("\n");
655            TRACE_AND_STEP();
656            destval = or_long(destval, *srcreg);
657            store_data_long(destoffset, destval);
658        } else {
659            u16 destval;
660            u16 *srcreg;
661
662            destoffset = decode_rm10_address(rl);
663            DECODE_PRINTF(",");
664            destval = fetch_data_word(destoffset);
665            srcreg = DECODE_RM_WORD_REGISTER(rh);
666            DECODE_PRINTF("\n");
667            TRACE_AND_STEP();
668            destval = or_word(destval, *srcreg);
669            store_data_word(destoffset, destval);
670        }
671        break;
672    case 3:                     /* register to register */
673        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
674            u32 *destreg,*srcreg;
675
676            destreg = DECODE_RM_LONG_REGISTER(rl);
677            DECODE_PRINTF(",");
678            srcreg = DECODE_RM_LONG_REGISTER(rh);
679            DECODE_PRINTF("\n");
680            TRACE_AND_STEP();
681            *destreg = or_long(*destreg, *srcreg);
682        } else {
683            u16 *destreg,*srcreg;
684
685            destreg = DECODE_RM_WORD_REGISTER(rl);
686            DECODE_PRINTF(",");
687            srcreg = DECODE_RM_WORD_REGISTER(rh);
688            DECODE_PRINTF("\n");
689            TRACE_AND_STEP();
690            *destreg = or_word(*destreg, *srcreg);
691        }
692        break;
693    }
694    DECODE_CLEAR_SEGOVR();
695    END_OF_INSTR();
696}
697
698/****************************************************************************
699REMARKS:
700Handles opcode 0x0a
701****************************************************************************/
702void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
703{
704    int mod, rl, rh;
705    u8 *destreg, *srcreg;
706    uint srcoffset;
707    u8 srcval;
708
709    START_OF_INSTR();
710    DECODE_PRINTF("OR\t");
711    FETCH_DECODE_MODRM(mod, rh, rl);
712    switch (mod) {
713    case 0:
714        destreg = DECODE_RM_BYTE_REGISTER(rh);
715        DECODE_PRINTF(",");
716        srcoffset = decode_rm00_address(rl);
717        srcval = fetch_data_byte(srcoffset);
718        DECODE_PRINTF("\n");
719        TRACE_AND_STEP();
720        *destreg = or_byte(*destreg, srcval);
721        break;
722    case 1:
723        destreg = DECODE_RM_BYTE_REGISTER(rh);
724        DECODE_PRINTF(",");
725        srcoffset = decode_rm01_address(rl);
726        srcval = fetch_data_byte(srcoffset);
727        DECODE_PRINTF("\n");
728        TRACE_AND_STEP();
729        *destreg = or_byte(*destreg, srcval);
730        break;
731    case 2:
732        destreg = DECODE_RM_BYTE_REGISTER(rh);
733        DECODE_PRINTF(",");
734        srcoffset = decode_rm10_address(rl);
735        srcval = fetch_data_byte(srcoffset);
736        DECODE_PRINTF("\n");
737        TRACE_AND_STEP();
738        *destreg = or_byte(*destreg, srcval);
739        break;
740    case 3:                     /* register to register */
741        destreg = DECODE_RM_BYTE_REGISTER(rh);
742        DECODE_PRINTF(",");
743        srcreg = DECODE_RM_BYTE_REGISTER(rl);
744        DECODE_PRINTF("\n");
745        TRACE_AND_STEP();
746        *destreg = or_byte(*destreg, *srcreg);
747        break;
748    }
749    DECODE_CLEAR_SEGOVR();
750    END_OF_INSTR();
751}
752
753/****************************************************************************
754REMARKS:
755Handles opcode 0x0b
756****************************************************************************/
757void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
758{
759    int mod, rl, rh;
760    uint srcoffset;
761
762    START_OF_INSTR();
763    DECODE_PRINTF("OR\t");
764    FETCH_DECODE_MODRM(mod, rh, rl);
765    switch (mod) {
766    case 0:
767        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
768            u32 *destreg;
769            u32 srcval;
770
771            destreg = DECODE_RM_LONG_REGISTER(rh);
772            DECODE_PRINTF(",");
773            srcoffset = decode_rm00_address(rl);
774            srcval = fetch_data_long(srcoffset);
775            DECODE_PRINTF("\n");
776            TRACE_AND_STEP();
777            *destreg = or_long(*destreg, srcval);
778        } else {
779            u16 *destreg;
780            u16 srcval;
781
782            destreg = DECODE_RM_WORD_REGISTER(rh);
783            DECODE_PRINTF(",");
784            srcoffset = decode_rm00_address(rl);
785            srcval = fetch_data_word(srcoffset);
786            DECODE_PRINTF("\n");
787            TRACE_AND_STEP();
788            *destreg = or_word(*destreg, srcval);
789        }
790        break;
791    case 1:
792        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
793            u32 *destreg;
794            u32 srcval;
795
796            destreg = DECODE_RM_LONG_REGISTER(rh);
797            DECODE_PRINTF(",");
798            srcoffset = decode_rm01_address(rl);
799            srcval = fetch_data_long(srcoffset);
800            DECODE_PRINTF("\n");
801            TRACE_AND_STEP();
802            *destreg = or_long(*destreg, srcval);
803        } else {
804            u16 *destreg;
805            u16 srcval;
806
807            destreg = DECODE_RM_WORD_REGISTER(rh);
808            DECODE_PRINTF(",");
809            srcoffset = decode_rm01_address(rl);
810            srcval = fetch_data_word(srcoffset);
811            DECODE_PRINTF("\n");
812            TRACE_AND_STEP();
813            *destreg = or_word(*destreg, srcval);
814        }
815        break;
816    case 2:
817        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
818            u32 *destreg;
819            u32 srcval;
820
821            destreg = DECODE_RM_LONG_REGISTER(rh);
822            DECODE_PRINTF(",");
823            srcoffset = decode_rm10_address(rl);
824            srcval = fetch_data_long(srcoffset);
825            DECODE_PRINTF("\n");
826            TRACE_AND_STEP();
827            *destreg = or_long(*destreg, srcval);
828        } else {
829            u16 *destreg;
830            u16 srcval;
831
832            destreg = DECODE_RM_WORD_REGISTER(rh);
833            DECODE_PRINTF(",");
834            srcoffset = decode_rm10_address(rl);
835            srcval = fetch_data_word(srcoffset);
836            DECODE_PRINTF("\n");
837            TRACE_AND_STEP();
838            *destreg = or_word(*destreg, srcval);
839        }
840        break;
841    case 3:                     /* register to register */
842        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
843            u32 *destreg,*srcreg;
844
845            destreg = DECODE_RM_LONG_REGISTER(rh);
846            DECODE_PRINTF(",");
847            srcreg = DECODE_RM_LONG_REGISTER(rl);
848            DECODE_PRINTF("\n");
849            TRACE_AND_STEP();
850            *destreg = or_long(*destreg, *srcreg);
851        } else {
852            u16 *destreg,*srcreg;
853
854            destreg = DECODE_RM_WORD_REGISTER(rh);
855            DECODE_PRINTF(",");
856            srcreg = DECODE_RM_WORD_REGISTER(rl);
857            DECODE_PRINTF("\n");
858            TRACE_AND_STEP();
859            *destreg = or_word(*destreg, *srcreg);
860        }
861        break;
862    }
863    DECODE_CLEAR_SEGOVR();
864    END_OF_INSTR();
865}
866
867/****************************************************************************
868REMARKS:
869Handles opcode 0x0c
870****************************************************************************/
871void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
872{
873    u8 srcval;
874
875    START_OF_INSTR();
876    DECODE_PRINTF("OR\tAL,");
877    srcval = fetch_byte_imm();
878    DECODE_PRINTF2("%x\n", srcval);
879    TRACE_AND_STEP();
880    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
881    DECODE_CLEAR_SEGOVR();
882    END_OF_INSTR();
883}
884
885/****************************************************************************
886REMARKS:
887Handles opcode 0x0d
888****************************************************************************/
889void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
890{
891    u32 srcval;
892
893    START_OF_INSTR();
894    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
895        DECODE_PRINTF("OR\tEAX,");
896        srcval = fetch_long_imm();
897    } else {
898        DECODE_PRINTF("OR\tAX,");
899        srcval = fetch_word_imm();
900    }
901    DECODE_PRINTF2("%x\n", srcval);
902    TRACE_AND_STEP();
903    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
904        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
905    } else {
906        M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
907    }
908    DECODE_CLEAR_SEGOVR();
909    END_OF_INSTR();
910}
911
912/****************************************************************************
913REMARKS:
914Handles opcode 0x0e
915****************************************************************************/
916void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
917{
918    START_OF_INSTR();
919    DECODE_PRINTF("PUSH\tCS\n");
920    TRACE_AND_STEP();
921    push_word(M.x86.R_CS);
922    DECODE_CLEAR_SEGOVR();
923    END_OF_INSTR();
924}
925
926/****************************************************************************
927REMARKS:
928Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
929****************************************************************************/
930void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
931{
932    u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
933    INC_DECODED_INST_LEN(1);
934    (*x86emu_optab2[op2])(op2);
935}
936
937/****************************************************************************
938REMARKS:
939Handles opcode 0x10
940****************************************************************************/
941void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
942{
943    int mod, rl, rh;
944    u8 *destreg, *srcreg;
945    uint destoffset;
946    u8 destval;
947
948    START_OF_INSTR();
949    DECODE_PRINTF("ADC\t");
950    FETCH_DECODE_MODRM(mod, rh, rl);
951    switch (mod) {
952    case 0:
953        destoffset = decode_rm00_address(rl);
954        DECODE_PRINTF(",");
955        destval = fetch_data_byte(destoffset);
956        srcreg = DECODE_RM_BYTE_REGISTER(rh);
957        DECODE_PRINTF("\n");
958        TRACE_AND_STEP();
959        destval = adc_byte(destval, *srcreg);
960        store_data_byte(destoffset, destval);
961        break;
962    case 1:
963        destoffset = decode_rm01_address(rl);
964        DECODE_PRINTF(",");
965        destval = fetch_data_byte(destoffset);
966        srcreg = DECODE_RM_BYTE_REGISTER(rh);
967        DECODE_PRINTF("\n");
968        TRACE_AND_STEP();
969        destval = adc_byte(destval, *srcreg);
970        store_data_byte(destoffset, destval);
971        break;
972    case 2:
973        destoffset = decode_rm10_address(rl);
974        DECODE_PRINTF(",");
975        destval = fetch_data_byte(destoffset);
976        srcreg = DECODE_RM_BYTE_REGISTER(rh);
977        DECODE_PRINTF("\n");
978        TRACE_AND_STEP();
979        destval = adc_byte(destval, *srcreg);
980        store_data_byte(destoffset, destval);
981        break;
982    case 3:                     /* register to register */
983        destreg = DECODE_RM_BYTE_REGISTER(rl);
984        DECODE_PRINTF(",");
985        srcreg = DECODE_RM_BYTE_REGISTER(rh);
986        DECODE_PRINTF("\n");
987        TRACE_AND_STEP();
988        *destreg = adc_byte(*destreg, *srcreg);
989        break;
990    }
991    DECODE_CLEAR_SEGOVR();
992    END_OF_INSTR();
993}
994
995/****************************************************************************
996REMARKS:
997Handles opcode 0x11
998****************************************************************************/
999void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1000{
1001    int mod, rl, rh;
1002    uint destoffset;
1003
1004    START_OF_INSTR();
1005    DECODE_PRINTF("ADC\t");
1006    FETCH_DECODE_MODRM(mod, rh, rl);
1007    switch (mod) {
1008    case 0:
1009        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1010            u32 destval;
1011            u32 *srcreg;
1012
1013            destoffset = decode_rm00_address(rl);
1014            DECODE_PRINTF(",");
1015            destval = fetch_data_long(destoffset);
1016            srcreg = DECODE_RM_LONG_REGISTER(rh);
1017            DECODE_PRINTF("\n");
1018            TRACE_AND_STEP();
1019            destval = adc_long(destval, *srcreg);
1020            store_data_long(destoffset, destval);
1021        } else {
1022            u16 destval;
1023            u16 *srcreg;
1024
1025            destoffset = decode_rm00_address(rl);
1026            DECODE_PRINTF(",");
1027            destval = fetch_data_word(destoffset);
1028            srcreg = DECODE_RM_WORD_REGISTER(rh);
1029            DECODE_PRINTF("\n");
1030            TRACE_AND_STEP();
1031            destval = adc_word(destval, *srcreg);
1032            store_data_word(destoffset, destval);
1033        }
1034        break;
1035    case 1:
1036        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1037            u32 destval;
1038            u32 *srcreg;
1039
1040            destoffset = decode_rm01_address(rl);
1041            DECODE_PRINTF(",");
1042            destval = fetch_data_long(destoffset);
1043            srcreg = DECODE_RM_LONG_REGISTER(rh);
1044            DECODE_PRINTF("\n");
1045            TRACE_AND_STEP();
1046            destval = adc_long(destval, *srcreg);
1047            store_data_long(destoffset, destval);
1048        } else {
1049            u16 destval;
1050            u16 *srcreg;
1051
1052            destoffset = decode_rm01_address(rl);
1053            DECODE_PRINTF(",");
1054            destval = fetch_data_word(destoffset);
1055            srcreg = DECODE_RM_WORD_REGISTER(rh);
1056            DECODE_PRINTF("\n");
1057            TRACE_AND_STEP();
1058            destval = adc_word(destval, *srcreg);
1059            store_data_word(destoffset, destval);
1060        }
1061        break;
1062    case 2:
1063        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1064            u32 destval;
1065            u32 *srcreg;
1066
1067            destoffset = decode_rm10_address(rl);
1068            DECODE_PRINTF(",");
1069            destval = fetch_data_long(destoffset);
1070            srcreg = DECODE_RM_LONG_REGISTER(rh);
1071            DECODE_PRINTF("\n");
1072            TRACE_AND_STEP();
1073            destval = adc_long(destval, *srcreg);
1074            store_data_long(destoffset, destval);
1075        } else {
1076            u16 destval;
1077            u16 *srcreg;
1078
1079            destoffset = decode_rm10_address(rl);
1080            DECODE_PRINTF(",");
1081            destval = fetch_data_word(destoffset);
1082            srcreg = DECODE_RM_WORD_REGISTER(rh);
1083            DECODE_PRINTF("\n");
1084            TRACE_AND_STEP();
1085            destval = adc_word(destval, *srcreg);
1086            store_data_word(destoffset, destval);
1087        }
1088        break;
1089    case 3:                     /* register to register */
1090        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1091            u32 *destreg,*srcreg;
1092
1093            destreg = DECODE_RM_LONG_REGISTER(rl);
1094            DECODE_PRINTF(",");
1095            srcreg = DECODE_RM_LONG_REGISTER(rh);
1096            DECODE_PRINTF("\n");
1097            TRACE_AND_STEP();
1098            *destreg = adc_long(*destreg, *srcreg);
1099        } else {
1100            u16 *destreg,*srcreg;
1101
1102            destreg = DECODE_RM_WORD_REGISTER(rl);
1103            DECODE_PRINTF(",");
1104            srcreg = DECODE_RM_WORD_REGISTER(rh);
1105            DECODE_PRINTF("\n");
1106            TRACE_AND_STEP();
1107            *destreg = adc_word(*destreg, *srcreg);
1108        }
1109        break;
1110    }
1111    DECODE_CLEAR_SEGOVR();
1112    END_OF_INSTR();
1113}
1114
1115/****************************************************************************
1116REMARKS:
1117Handles opcode 0x12
1118****************************************************************************/
1119void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1120{
1121    int mod, rl, rh;
1122    u8 *destreg, *srcreg;
1123    uint srcoffset;
1124    u8 srcval;
1125
1126    START_OF_INSTR();
1127    DECODE_PRINTF("ADC\t");
1128    FETCH_DECODE_MODRM(mod, rh, rl);
1129    switch (mod) {
1130    case 0:
1131        destreg = DECODE_RM_BYTE_REGISTER(rh);
1132        DECODE_PRINTF(",");
1133        srcoffset = decode_rm00_address(rl);
1134        srcval = fetch_data_byte(srcoffset);
1135        DECODE_PRINTF("\n");
1136        TRACE_AND_STEP();
1137        *destreg = adc_byte(*destreg, srcval);
1138        break;
1139    case 1:
1140        destreg = DECODE_RM_BYTE_REGISTER(rh);
1141        DECODE_PRINTF(",");
1142        srcoffset = decode_rm01_address(rl);
1143        srcval = fetch_data_byte(srcoffset);
1144        DECODE_PRINTF("\n");
1145        TRACE_AND_STEP();
1146        *destreg = adc_byte(*destreg, srcval);
1147        break;
1148    case 2:
1149        destreg = DECODE_RM_BYTE_REGISTER(rh);
1150        DECODE_PRINTF(",");
1151        srcoffset = decode_rm10_address(rl);
1152        srcval = fetch_data_byte(srcoffset);
1153        DECODE_PRINTF("\n");
1154        TRACE_AND_STEP();
1155        *destreg = adc_byte(*destreg, srcval);
1156        break;
1157    case 3:                     /* register to register */
1158        destreg = DECODE_RM_BYTE_REGISTER(rh);
1159        DECODE_PRINTF(",");
1160        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1161        DECODE_PRINTF("\n");
1162        TRACE_AND_STEP();
1163        *destreg = adc_byte(*destreg, *srcreg);
1164        break;
1165    }
1166    DECODE_CLEAR_SEGOVR();
1167    END_OF_INSTR();
1168}
1169
1170/****************************************************************************
1171REMARKS:
1172Handles opcode 0x13
1173****************************************************************************/
1174void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1175{
1176    int mod, rl, rh;
1177    uint srcoffset;
1178
1179    START_OF_INSTR();
1180    DECODE_PRINTF("ADC\t");
1181    FETCH_DECODE_MODRM(mod, rh, rl);
1182    switch (mod) {
1183    case 0:
1184        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1185            u32 *destreg;
1186            u32 srcval;
1187
1188            destreg = DECODE_RM_LONG_REGISTER(rh);
1189            DECODE_PRINTF(",");
1190            srcoffset = decode_rm00_address(rl);
1191            srcval = fetch_data_long(srcoffset);
1192            DECODE_PRINTF("\n");
1193            TRACE_AND_STEP();
1194            *destreg = adc_long(*destreg, srcval);
1195        } else {
1196            u16 *destreg;
1197            u16 srcval;
1198
1199            destreg = DECODE_RM_WORD_REGISTER(rh);
1200            DECODE_PRINTF(",");
1201            srcoffset = decode_rm00_address(rl);
1202            srcval = fetch_data_word(srcoffset);
1203            DECODE_PRINTF("\n");
1204            TRACE_AND_STEP();
1205            *destreg = adc_word(*destreg, srcval);
1206        }
1207        break;
1208    case 1:
1209        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1210            u32 *destreg;
1211            u32 srcval;
1212
1213            destreg = DECODE_RM_LONG_REGISTER(rh);
1214            DECODE_PRINTF(",");
1215            srcoffset = decode_rm01_address(rl);
1216            srcval = fetch_data_long(srcoffset);
1217            DECODE_PRINTF("\n");
1218            TRACE_AND_STEP();
1219            *destreg = adc_long(*destreg, srcval);
1220        } else {
1221            u16 *destreg;
1222            u16 srcval;
1223
1224            destreg = DECODE_RM_WORD_REGISTER(rh);
1225            DECODE_PRINTF(",");
1226            srcoffset = decode_rm01_address(rl);
1227            srcval = fetch_data_word(srcoffset);
1228            DECODE_PRINTF("\n");
1229            TRACE_AND_STEP();
1230            *destreg = adc_word(*destreg, srcval);
1231        }
1232        break;
1233    case 2:
1234        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1235            u32 *destreg;
1236            u32 srcval;
1237
1238            destreg = DECODE_RM_LONG_REGISTER(rh);
1239            DECODE_PRINTF(",");
1240            srcoffset = decode_rm10_address(rl);
1241            srcval = fetch_data_long(srcoffset);
1242            DECODE_PRINTF("\n");
1243            TRACE_AND_STEP();
1244            *destreg = adc_long(*destreg, srcval);
1245        } else {
1246            u16 *destreg;
1247            u16 srcval;
1248
1249            destreg = DECODE_RM_WORD_REGISTER(rh);
1250            DECODE_PRINTF(",");
1251            srcoffset = decode_rm10_address(rl);
1252            srcval = fetch_data_word(srcoffset);
1253            DECODE_PRINTF("\n");
1254            TRACE_AND_STEP();
1255            *destreg = adc_word(*destreg, srcval);
1256        }
1257        break;
1258    case 3:                     /* register to register */
1259        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1260            u32 *destreg,*srcreg;
1261
1262            destreg = DECODE_RM_LONG_REGISTER(rh);
1263            DECODE_PRINTF(",");
1264            srcreg = DECODE_RM_LONG_REGISTER(rl);
1265            DECODE_PRINTF("\n");
1266            TRACE_AND_STEP();
1267            *destreg = adc_long(*destreg, *srcreg);
1268        } else {
1269            u16 *destreg,*srcreg;
1270
1271            destreg = DECODE_RM_WORD_REGISTER(rh);
1272            DECODE_PRINTF(",");
1273            srcreg = DECODE_RM_WORD_REGISTER(rl);
1274            DECODE_PRINTF("\n");
1275            TRACE_AND_STEP();
1276            *destreg = adc_word(*destreg, *srcreg);
1277        }
1278        break;
1279    }
1280    DECODE_CLEAR_SEGOVR();
1281    END_OF_INSTR();
1282}
1283
1284/****************************************************************************
1285REMARKS:
1286Handles opcode 0x14
1287****************************************************************************/
1288void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1289{
1290    u8 srcval;
1291
1292    START_OF_INSTR();
1293    DECODE_PRINTF("ADC\tAL,");
1294    srcval = fetch_byte_imm();
1295    DECODE_PRINTF2("%x\n", srcval);
1296    TRACE_AND_STEP();
1297    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1298    DECODE_CLEAR_SEGOVR();
1299    END_OF_INSTR();
1300}
1301
1302/****************************************************************************
1303REMARKS:
1304Handles opcode 0x15
1305****************************************************************************/
1306void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1307{
1308    u32 srcval;
1309
1310    START_OF_INSTR();
1311    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1312        DECODE_PRINTF("ADC\tEAX,");
1313        srcval = fetch_long_imm();
1314    } else {
1315        DECODE_PRINTF("ADC\tAX,");
1316        srcval = fetch_word_imm();
1317    }
1318    DECODE_PRINTF2("%x\n", srcval);
1319    TRACE_AND_STEP();
1320    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1321        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1322    } else {
1323        M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1324    }
1325    DECODE_CLEAR_SEGOVR();
1326    END_OF_INSTR();
1327}
1328
1329/****************************************************************************
1330REMARKS:
1331Handles opcode 0x16
1332****************************************************************************/
1333void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1334{
1335    START_OF_INSTR();
1336    DECODE_PRINTF("PUSH\tSS\n");
1337    TRACE_AND_STEP();
1338    push_word(M.x86.R_SS);
1339    DECODE_CLEAR_SEGOVR();
1340    END_OF_INSTR();
1341}
1342
1343/****************************************************************************
1344REMARKS:
1345Handles opcode 0x17
1346****************************************************************************/
1347void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1348{
1349    START_OF_INSTR();
1350    DECODE_PRINTF("POP\tSS\n");
1351    TRACE_AND_STEP();
1352    M.x86.R_SS = pop_word();
1353    DECODE_CLEAR_SEGOVR();
1354    END_OF_INSTR();
1355}
1356
1357/****************************************************************************
1358REMARKS:
1359Handles opcode 0x18
1360****************************************************************************/
1361void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1362{
1363    int mod, rl, rh;
1364    u8 *destreg, *srcreg;
1365    uint destoffset;
1366    u8 destval;
1367
1368    START_OF_INSTR();
1369    DECODE_PRINTF("SBB\t");
1370    FETCH_DECODE_MODRM(mod, rh, rl);
1371    switch (mod) {
1372    case 0:
1373        destoffset = decode_rm00_address(rl);
1374        DECODE_PRINTF(",");
1375        destval = fetch_data_byte(destoffset);
1376        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1377        DECODE_PRINTF("\n");
1378        TRACE_AND_STEP();
1379        destval = sbb_byte(destval, *srcreg);
1380        store_data_byte(destoffset, destval);
1381        break;
1382    case 1:
1383        destoffset = decode_rm01_address(rl);
1384        DECODE_PRINTF(",");
1385        destval = fetch_data_byte(destoffset);
1386        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1387        DECODE_PRINTF("\n");
1388        TRACE_AND_STEP();
1389        destval = sbb_byte(destval, *srcreg);
1390        store_data_byte(destoffset, destval);
1391        break;
1392    case 2:
1393        destoffset = decode_rm10_address(rl);
1394        DECODE_PRINTF(",");
1395        destval = fetch_data_byte(destoffset);
1396        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1397        DECODE_PRINTF("\n");
1398        TRACE_AND_STEP();
1399        destval = sbb_byte(destval, *srcreg);
1400        store_data_byte(destoffset, destval);
1401        break;
1402    case 3:                     /* register to register */
1403        destreg = DECODE_RM_BYTE_REGISTER(rl);
1404        DECODE_PRINTF(",");
1405        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1406        DECODE_PRINTF("\n");
1407        TRACE_AND_STEP();
1408        *destreg = sbb_byte(*destreg, *srcreg);
1409        break;
1410    }
1411    DECODE_CLEAR_SEGOVR();
1412    END_OF_INSTR();
1413}
1414
1415/****************************************************************************
1416REMARKS:
1417Handles opcode 0x19
1418****************************************************************************/
1419void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1420{
1421    int mod, rl, rh;
1422    uint destoffset;
1423
1424    START_OF_INSTR();
1425    DECODE_PRINTF("SBB\t");
1426    FETCH_DECODE_MODRM(mod, rh, rl);
1427    switch (mod) {
1428    case 0:
1429        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1430            u32 destval;
1431            u32 *srcreg;
1432
1433            destoffset = decode_rm00_address(rl);
1434            DECODE_PRINTF(",");
1435            destval = fetch_data_long(destoffset);
1436            srcreg = DECODE_RM_LONG_REGISTER(rh);
1437            DECODE_PRINTF("\n");
1438            TRACE_AND_STEP();
1439            destval = sbb_long(destval, *srcreg);
1440            store_data_long(destoffset, destval);
1441        } else {
1442            u16 destval;
1443            u16 *srcreg;
1444
1445            destoffset = decode_rm00_address(rl);
1446            DECODE_PRINTF(",");
1447            destval = fetch_data_word(destoffset);
1448            srcreg = DECODE_RM_WORD_REGISTER(rh);
1449            DECODE_PRINTF("\n");
1450            TRACE_AND_STEP();
1451            destval = sbb_word(destval, *srcreg);
1452            store_data_word(destoffset, destval);
1453        }
1454        break;
1455    case 1:
1456        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1457            u32 destval;
1458            u32 *srcreg;
1459
1460            destoffset = decode_rm01_address(rl);
1461            DECODE_PRINTF(",");
1462            destval = fetch_data_long(destoffset);
1463            srcreg = DECODE_RM_LONG_REGISTER(rh);
1464            DECODE_PRINTF("\n");
1465            TRACE_AND_STEP();
1466            destval = sbb_long(destval, *srcreg);
1467            store_data_long(destoffset, destval);
1468        } else {
1469            u16 destval;
1470            u16 *srcreg;
1471
1472            destoffset = decode_rm01_address(rl);
1473            DECODE_PRINTF(",");
1474            destval = fetch_data_word(destoffset);
1475            srcreg = DECODE_RM_WORD_REGISTER(rh);
1476            DECODE_PRINTF("\n");
1477            TRACE_AND_STEP();
1478            destval = sbb_word(destval, *srcreg);
1479            store_data_word(destoffset, destval);
1480        }
1481        break;
1482    case 2:
1483        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1484            u32 destval;
1485            u32 *srcreg;
1486
1487            destoffset = decode_rm10_address(rl);
1488            DECODE_PRINTF(",");
1489            destval = fetch_data_long(destoffset);
1490            srcreg = DECODE_RM_LONG_REGISTER(rh);
1491            DECODE_PRINTF("\n");
1492            TRACE_AND_STEP();
1493            destval = sbb_long(destval, *srcreg);
1494            store_data_long(destoffset, destval);
1495        } else {
1496            u16 destval;
1497            u16 *srcreg;
1498
1499            destoffset = decode_rm10_address(rl);
1500            DECODE_PRINTF(",");
1501            destval = fetch_data_word(destoffset);
1502            srcreg = DECODE_RM_WORD_REGISTER(rh);
1503            DECODE_PRINTF("\n");
1504            TRACE_AND_STEP();
1505            destval = sbb_word(destval, *srcreg);
1506            store_data_word(destoffset, destval);
1507        }
1508        break;
1509    case 3:                     /* register to register */
1510        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1511            u32 *destreg,*srcreg;
1512
1513            destreg = DECODE_RM_LONG_REGISTER(rl);
1514            DECODE_PRINTF(",");
1515            srcreg = DECODE_RM_LONG_REGISTER(rh);
1516            DECODE_PRINTF("\n");
1517            TRACE_AND_STEP();
1518            *destreg = sbb_long(*destreg, *srcreg);
1519        } else {
1520            u16 *destreg,*srcreg;
1521
1522            destreg = DECODE_RM_WORD_REGISTER(rl);
1523            DECODE_PRINTF(",");
1524            srcreg = DECODE_RM_WORD_REGISTER(rh);
1525            DECODE_PRINTF("\n");
1526            TRACE_AND_STEP();
1527            *destreg = sbb_word(*destreg, *srcreg);
1528        }
1529        break;
1530    }
1531    DECODE_CLEAR_SEGOVR();
1532    END_OF_INSTR();
1533}
1534
1535/****************************************************************************
1536REMARKS:
1537Handles opcode 0x1a
1538****************************************************************************/
1539void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1540{
1541    int mod, rl, rh;
1542    u8 *destreg, *srcreg;
1543    uint srcoffset;
1544    u8 srcval;
1545
1546    START_OF_INSTR();
1547    DECODE_PRINTF("SBB\t");
1548    FETCH_DECODE_MODRM(mod, rh, rl);
1549    switch (mod) {
1550    case 0:
1551        destreg = DECODE_RM_BYTE_REGISTER(rh);
1552        DECODE_PRINTF(",");
1553        srcoffset = decode_rm00_address(rl);
1554        srcval = fetch_data_byte(srcoffset);
1555        DECODE_PRINTF("\n");
1556        TRACE_AND_STEP();
1557        *destreg = sbb_byte(*destreg, srcval);
1558        break;
1559    case 1:
1560        destreg = DECODE_RM_BYTE_REGISTER(rh);
1561        DECODE_PRINTF(",");
1562        srcoffset = decode_rm01_address(rl);
1563        srcval = fetch_data_byte(srcoffset);
1564        DECODE_PRINTF("\n");
1565        TRACE_AND_STEP();
1566        *destreg = sbb_byte(*destreg, srcval);
1567        break;
1568    case 2:
1569        destreg = DECODE_RM_BYTE_REGISTER(rh);
1570        DECODE_PRINTF(",");
1571        srcoffset = decode_rm10_address(rl);
1572        srcval = fetch_data_byte(srcoffset);
1573        DECODE_PRINTF("\n");
1574        TRACE_AND_STEP();
1575        *destreg = sbb_byte(*destreg, srcval);
1576        break;
1577    case 3:                     /* register to register */
1578        destreg = DECODE_RM_BYTE_REGISTER(rh);
1579        DECODE_PRINTF(",");
1580        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1581        DECODE_PRINTF("\n");
1582        TRACE_AND_STEP();
1583        *destreg = sbb_byte(*destreg, *srcreg);
1584        break;
1585    }
1586    DECODE_CLEAR_SEGOVR();
1587    END_OF_INSTR();
1588}
1589
1590/****************************************************************************
1591REMARKS:
1592Handles opcode 0x1b
1593****************************************************************************/
1594void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1595{
1596    int mod, rl, rh;
1597    uint srcoffset;
1598
1599    START_OF_INSTR();
1600    DECODE_PRINTF("SBB\t");
1601    FETCH_DECODE_MODRM(mod, rh, rl);
1602    switch (mod) {
1603    case 0:
1604        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1605            u32 *destreg;
1606            u32 srcval;
1607
1608            destreg = DECODE_RM_LONG_REGISTER(rh);
1609            DECODE_PRINTF(",");
1610            srcoffset = decode_rm00_address(rl);
1611            srcval = fetch_data_long(srcoffset);
1612            DECODE_PRINTF("\n");
1613            TRACE_AND_STEP();
1614            *destreg = sbb_long(*destreg, srcval);
1615        } else {
1616            u16 *destreg;
1617            u16 srcval;
1618
1619            destreg = DECODE_RM_WORD_REGISTER(rh);
1620            DECODE_PRINTF(",");
1621            srcoffset = decode_rm00_address(rl);
1622            srcval = fetch_data_word(srcoffset);
1623            DECODE_PRINTF("\n");
1624            TRACE_AND_STEP();
1625            *destreg = sbb_word(*destreg, srcval);
1626        }
1627        break;
1628    case 1:
1629        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1630            u32 *destreg;
1631            u32 srcval;
1632
1633            destreg = DECODE_RM_LONG_REGISTER(rh);
1634            DECODE_PRINTF(",");
1635            srcoffset = decode_rm01_address(rl);
1636            srcval = fetch_data_long(srcoffset);
1637            DECODE_PRINTF("\n");
1638            TRACE_AND_STEP();
1639            *destreg = sbb_long(*destreg, srcval);
1640        } else {
1641            u16 *destreg;
1642            u16 srcval;
1643
1644            destreg = DECODE_RM_WORD_REGISTER(rh);
1645            DECODE_PRINTF(",");
1646            srcoffset = decode_rm01_address(rl);
1647            srcval = fetch_data_word(srcoffset);
1648            DECODE_PRINTF("\n");
1649            TRACE_AND_STEP();
1650            *destreg = sbb_word(*destreg, srcval);
1651        }
1652        break;
1653    case 2:
1654        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1655            u32 *destreg;
1656            u32 srcval;
1657
1658            destreg = DECODE_RM_LONG_REGISTER(rh);
1659            DECODE_PRINTF(",");
1660            srcoffset = decode_rm10_address(rl);
1661            srcval = fetch_data_long(srcoffset);
1662            DECODE_PRINTF("\n");
1663            TRACE_AND_STEP();
1664            *destreg = sbb_long(*destreg, srcval);
1665        } else {
1666            u16 *destreg;
1667            u16 srcval;
1668
1669            destreg = DECODE_RM_WORD_REGISTER(rh);
1670            DECODE_PRINTF(",");
1671            srcoffset = decode_rm10_address(rl);
1672            srcval = fetch_data_word(srcoffset);
1673            DECODE_PRINTF("\n");
1674            TRACE_AND_STEP();
1675            *destreg = sbb_word(*destreg, srcval);
1676        }
1677        break;
1678    case 3:                     /* register to register */
1679        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1680            u32 *destreg,*srcreg;
1681
1682            destreg = DECODE_RM_LONG_REGISTER(rh);
1683            DECODE_PRINTF(",");
1684            srcreg = DECODE_RM_LONG_REGISTER(rl);
1685            DECODE_PRINTF("\n");
1686            TRACE_AND_STEP();
1687            *destreg = sbb_long(*destreg, *srcreg);
1688        } else {
1689            u16 *destreg,*srcreg;
1690
1691            destreg = DECODE_RM_WORD_REGISTER(rh);
1692            DECODE_PRINTF(",");
1693            srcreg = DECODE_RM_WORD_REGISTER(rl);
1694            DECODE_PRINTF("\n");
1695            TRACE_AND_STEP();
1696            *destreg = sbb_word(*destreg, *srcreg);
1697        }
1698        break;
1699    }
1700    DECODE_CLEAR_SEGOVR();
1701    END_OF_INSTR();
1702}
1703
1704/****************************************************************************
1705REMARKS:
1706Handles opcode 0x1c
1707****************************************************************************/
1708void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1709{
1710    u8 srcval;
1711
1712    START_OF_INSTR();
1713    DECODE_PRINTF("SBB\tAL,");
1714    srcval = fetch_byte_imm();
1715    DECODE_PRINTF2("%x\n", srcval);
1716    TRACE_AND_STEP();
1717    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1718    DECODE_CLEAR_SEGOVR();
1719    END_OF_INSTR();
1720}
1721
1722/****************************************************************************
1723REMARKS:
1724Handles opcode 0x1d
1725****************************************************************************/
1726void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1727{
1728    u32 srcval;
1729
1730    START_OF_INSTR();
1731    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1732        DECODE_PRINTF("SBB\tEAX,");
1733        srcval = fetch_long_imm();
1734    } else {
1735        DECODE_PRINTF("SBB\tAX,");
1736        srcval = fetch_word_imm();
1737    }
1738    DECODE_PRINTF2("%x\n", srcval);
1739    TRACE_AND_STEP();
1740    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1741        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1742    } else {
1743        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1744    }
1745    DECODE_CLEAR_SEGOVR();
1746    END_OF_INSTR();
1747}
1748
1749/****************************************************************************
1750REMARKS:
1751Handles opcode 0x1e
1752****************************************************************************/
1753void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1754{
1755    START_OF_INSTR();
1756    DECODE_PRINTF("PUSH\tDS\n");
1757    TRACE_AND_STEP();
1758    push_word(M.x86.R_DS);
1759    DECODE_CLEAR_SEGOVR();
1760    END_OF_INSTR();
1761}
1762
1763/****************************************************************************
1764REMARKS:
1765Handles opcode 0x1f
1766****************************************************************************/
1767void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1768{
1769    START_OF_INSTR();
1770    DECODE_PRINTF("POP\tDS\n");
1771    TRACE_AND_STEP();
1772    M.x86.R_DS = pop_word();
1773    DECODE_CLEAR_SEGOVR();
1774    END_OF_INSTR();
1775}
1776
1777/****************************************************************************
1778REMARKS:
1779Handles opcode 0x20
1780****************************************************************************/
1781void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1782{
1783    int mod, rl, rh;
1784    u8 *destreg, *srcreg;
1785    uint destoffset;
1786    u8 destval;
1787
1788    START_OF_INSTR();
1789    DECODE_PRINTF("AND\t");
1790    FETCH_DECODE_MODRM(mod, rh, rl);
1791
1792    switch (mod) {
1793    case 0:
1794        destoffset = decode_rm00_address(rl);
1795        DECODE_PRINTF(",");
1796        destval = fetch_data_byte(destoffset);
1797        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1798        DECODE_PRINTF("\n");
1799        TRACE_AND_STEP();
1800        destval = and_byte(destval, *srcreg);
1801        store_data_byte(destoffset, destval);
1802        break;
1803
1804    case 1:
1805        destoffset = decode_rm01_address(rl);
1806        DECODE_PRINTF(",");
1807        destval = fetch_data_byte(destoffset);
1808        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1809        DECODE_PRINTF("\n");
1810        TRACE_AND_STEP();
1811        destval = and_byte(destval, *srcreg);
1812        store_data_byte(destoffset, destval);
1813        break;
1814
1815    case 2:
1816        destoffset = decode_rm10_address(rl);
1817        DECODE_PRINTF(",");
1818        destval = fetch_data_byte(destoffset);
1819        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1820        DECODE_PRINTF("\n");
1821        TRACE_AND_STEP();
1822        destval = and_byte(destval, *srcreg);
1823        store_data_byte(destoffset, destval);
1824        break;
1825
1826    case 3:                     /* register to register */
1827        destreg = DECODE_RM_BYTE_REGISTER(rl);
1828        DECODE_PRINTF(",");
1829        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1830        DECODE_PRINTF("\n");
1831        TRACE_AND_STEP();
1832        *destreg = and_byte(*destreg, *srcreg);
1833        break;
1834    }
1835    DECODE_CLEAR_SEGOVR();
1836    END_OF_INSTR();
1837}
1838
1839/****************************************************************************
1840REMARKS:
1841Handles opcode 0x21
1842****************************************************************************/
1843void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1844{
1845    int mod, rl, rh;
1846    uint destoffset;
1847
1848    START_OF_INSTR();
1849    DECODE_PRINTF("AND\t");
1850    FETCH_DECODE_MODRM(mod, rh, rl);
1851    switch (mod) {
1852    case 0:
1853        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1854            u32 destval;
1855            u32 *srcreg;
1856
1857            destoffset = decode_rm00_address(rl);
1858            DECODE_PRINTF(",");
1859            destval = fetch_data_long(destoffset);
1860            srcreg = DECODE_RM_LONG_REGISTER(rh);
1861            DECODE_PRINTF("\n");
1862            TRACE_AND_STEP();
1863            destval = and_long(destval, *srcreg);
1864            store_data_long(destoffset, destval);
1865        } else {
1866            u16 destval;
1867            u16 *srcreg;
1868
1869            destoffset = decode_rm00_address(rl);
1870            DECODE_PRINTF(",");
1871            destval = fetch_data_word(destoffset);
1872            srcreg = DECODE_RM_WORD_REGISTER(rh);
1873            DECODE_PRINTF("\n");
1874            TRACE_AND_STEP();
1875            destval = and_word(destval, *srcreg);
1876            store_data_word(destoffset, destval);
1877        }
1878        break;
1879    case 1:
1880        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1881            u32 destval;
1882            u32 *srcreg;
1883
1884            destoffset = decode_rm01_address(rl);
1885            DECODE_PRINTF(",");
1886            destval = fetch_data_long(destoffset);
1887            srcreg = DECODE_RM_LONG_REGISTER(rh);
1888            DECODE_PRINTF("\n");
1889            TRACE_AND_STEP();
1890            destval = and_long(destval, *srcreg);
1891            store_data_long(destoffset, destval);
1892        } else {
1893            u16 destval;
1894            u16 *srcreg;
1895
1896            destoffset = decode_rm01_address(rl);
1897            DECODE_PRINTF(",");
1898            destval = fetch_data_word(destoffset);
1899            srcreg = DECODE_RM_WORD_REGISTER(rh);
1900            DECODE_PRINTF("\n");
1901            TRACE_AND_STEP();
1902            destval = and_word(destval, *srcreg);
1903            store_data_word(destoffset, destval);
1904        }
1905        break;
1906    case 2:
1907        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1908            u32 destval;
1909            u32 *srcreg;
1910
1911            destoffset = decode_rm10_address(rl);
1912            DECODE_PRINTF(",");
1913            destval = fetch_data_long(destoffset);
1914            srcreg = DECODE_RM_LONG_REGISTER(rh);
1915            DECODE_PRINTF("\n");
1916            TRACE_AND_STEP();
1917            destval = and_long(destval, *srcreg);
1918            store_data_long(destoffset, destval);
1919        } else {
1920            u16 destval;
1921            u16 *srcreg;
1922
1923            destoffset = decode_rm10_address(rl);
1924            DECODE_PRINTF(",");
1925            destval = fetch_data_word(destoffset);
1926            srcreg = DECODE_RM_WORD_REGISTER(rh);
1927            DECODE_PRINTF("\n");
1928            TRACE_AND_STEP();
1929            destval = and_word(destval, *srcreg);
1930            store_data_word(destoffset, destval);
1931        }
1932        break;
1933    case 3:                     /* register to register */
1934        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1935            u32 *destreg,*srcreg;
1936
1937            destreg = DECODE_RM_LONG_REGISTER(rl);
1938            DECODE_PRINTF(",");
1939            srcreg = DECODE_RM_LONG_REGISTER(rh);
1940            DECODE_PRINTF("\n");
1941            TRACE_AND_STEP();
1942            *destreg = and_long(*destreg, *srcreg);
1943        } else {
1944            u16 *destreg,*srcreg;
1945
1946            destreg = DECODE_RM_WORD_REGISTER(rl);
1947            DECODE_PRINTF(",");
1948            srcreg = DECODE_RM_WORD_REGISTER(rh);
1949            DECODE_PRINTF("\n");
1950            TRACE_AND_STEP();
1951            *destreg = and_word(*destreg, *srcreg);
1952        }
1953        break;
1954    }
1955    DECODE_CLEAR_SEGOVR();
1956    END_OF_INSTR();
1957}
1958
1959/****************************************************************************
1960REMARKS:
1961Handles opcode 0x22
1962****************************************************************************/
1963void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1964{
1965    int mod, rl, rh;
1966    u8 *destreg, *srcreg;
1967    uint srcoffset;
1968    u8 srcval;
1969
1970    START_OF_INSTR();
1971    DECODE_PRINTF("AND\t");
1972    FETCH_DECODE_MODRM(mod, rh, rl);
1973    switch (mod) {
1974    case 0:
1975        destreg = DECODE_RM_BYTE_REGISTER(rh);
1976        DECODE_PRINTF(",");
1977        srcoffset = decode_rm00_address(rl);
1978        srcval = fetch_data_byte(srcoffset);
1979        DECODE_PRINTF("\n");
1980        TRACE_AND_STEP();
1981        *destreg = and_byte(*destreg, srcval);
1982        break;
1983    case 1:
1984        destreg = DECODE_RM_BYTE_REGISTER(rh);
1985        DECODE_PRINTF(",");
1986        srcoffset = decode_rm01_address(rl);
1987        srcval = fetch_data_byte(srcoffset);
1988        DECODE_PRINTF("\n");
1989        TRACE_AND_STEP();
1990        *destreg = and_byte(*destreg, srcval);
1991        break;
1992    case 2:
1993        destreg = DECODE_RM_BYTE_REGISTER(rh);
1994        DECODE_PRINTF(",");
1995        srcoffset = decode_rm10_address(rl);
1996        srcval = fetch_data_byte(srcoffset);
1997        DECODE_PRINTF("\n");
1998        TRACE_AND_STEP();
1999        *destreg = and_byte(*destreg, srcval);
2000        break;
2001    case 3:                     /* register to register */
2002        destreg = DECODE_RM_BYTE_REGISTER(rh);
2003        DECODE_PRINTF(",");
2004        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2005        DECODE_PRINTF("\n");
2006        TRACE_AND_STEP();
2007        *destreg = and_byte(*destreg, *srcreg);
2008        break;
2009    }
2010    DECODE_CLEAR_SEGOVR();
2011    END_OF_INSTR();
2012}
2013
2014/****************************************************************************
2015REMARKS:
2016Handles opcode 0x23
2017****************************************************************************/
2018void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2019{
2020    int mod, rl, rh;
2021    uint srcoffset;
2022
2023    START_OF_INSTR();
2024    DECODE_PRINTF("AND\t");
2025    FETCH_DECODE_MODRM(mod, rh, rl);
2026    switch (mod) {
2027    case 0:
2028        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2029            u32 *destreg;
2030            u32 srcval;
2031
2032            destreg = DECODE_RM_LONG_REGISTER(rh);
2033            DECODE_PRINTF(",");
2034            srcoffset = decode_rm00_address(rl);
2035            srcval = fetch_data_long(srcoffset);
2036            DECODE_PRINTF("\n");
2037            TRACE_AND_STEP();
2038            *destreg = and_long(*destreg, srcval);
2039        } else {
2040            u16 *destreg;
2041            u16 srcval;
2042
2043            destreg = DECODE_RM_WORD_REGISTER(rh);
2044            DECODE_PRINTF(",");
2045            srcoffset = decode_rm00_address(rl);
2046            srcval = fetch_data_word(srcoffset);
2047            DECODE_PRINTF("\n");
2048            TRACE_AND_STEP();
2049            *destreg = and_word(*destreg, srcval);
2050        }
2051        break;
2052    case 1:
2053        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2054            u32 *destreg;
2055            u32 srcval;
2056
2057            destreg = DECODE_RM_LONG_REGISTER(rh);
2058            DECODE_PRINTF(",");
2059            srcoffset = decode_rm01_address(rl);
2060            srcval = fetch_data_long(srcoffset);
2061            DECODE_PRINTF("\n");
2062            TRACE_AND_STEP();
2063            *destreg = and_long(*destreg, srcval);
2064            break;
2065        } else {
2066            u16 *destreg;
2067            u16 srcval;
2068
2069            destreg = DECODE_RM_WORD_REGISTER(rh);
2070            DECODE_PRINTF(",");
2071            srcoffset = decode_rm01_address(rl);
2072            srcval = fetch_data_word(srcoffset);
2073            DECODE_PRINTF("\n");
2074            TRACE_AND_STEP();
2075            *destreg = and_word(*destreg, srcval);
2076            break;
2077        }
2078    case 2:
2079        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2080            u32 *destreg;
2081            u32 srcval;
2082
2083            destreg = DECODE_RM_LONG_REGISTER(rh);
2084            DECODE_PRINTF(",");
2085            srcoffset = decode_rm10_address(rl);
2086            srcval = fetch_data_long(srcoffset);
2087            DECODE_PRINTF("\n");
2088            TRACE_AND_STEP();
2089            *destreg = and_long(*destreg, srcval);
2090        } else {
2091            u16 *destreg;
2092            u16 srcval;
2093
2094            destreg = DECODE_RM_WORD_REGISTER(rh);
2095            DECODE_PRINTF(",");
2096            srcoffset = decode_rm10_address(rl);
2097            srcval = fetch_data_word(srcoffset);
2098            DECODE_PRINTF("\n");
2099            TRACE_AND_STEP();
2100            *destreg = and_word(*destreg, srcval);
2101        }
2102        break;
2103    case 3:                     /* register to register */
2104        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2105            u32 *destreg,*srcreg;
2106
2107            destreg = DECODE_RM_LONG_REGISTER(rh);
2108            DECODE_PRINTF(",");
2109            srcreg = DECODE_RM_LONG_REGISTER(rl);
2110            DECODE_PRINTF("\n");
2111            TRACE_AND_STEP();
2112            *destreg = and_long(*destreg, *srcreg);
2113        } else {
2114            u16 *destreg,*srcreg;
2115
2116            destreg = DECODE_RM_WORD_REGISTER(rh);
2117            DECODE_PRINTF(",");
2118            srcreg = DECODE_RM_WORD_REGISTER(rl);
2119            DECODE_PRINTF("\n");
2120            TRACE_AND_STEP();
2121            *destreg = and_word(*destreg, *srcreg);
2122        }
2123        break;
2124    }
2125    DECODE_CLEAR_SEGOVR();
2126    END_OF_INSTR();
2127}
2128
2129/****************************************************************************
2130REMARKS:
2131Handles opcode 0x24
2132****************************************************************************/
2133void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2134{
2135    u8 srcval;
2136
2137    START_OF_INSTR();
2138    DECODE_PRINTF("AND\tAL,");
2139    srcval = fetch_byte_imm();
2140    DECODE_PRINTF2("%x\n", srcval);
2141    TRACE_AND_STEP();
2142    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2143    DECODE_CLEAR_SEGOVR();
2144    END_OF_INSTR();
2145}
2146
2147/****************************************************************************
2148REMARKS:
2149Handles opcode 0x25
2150****************************************************************************/
2151void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2152{
2153    u32 srcval;
2154
2155    START_OF_INSTR();
2156    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2157        DECODE_PRINTF("AND\tEAX,");
2158        srcval = fetch_long_imm();
2159    } else {
2160        DECODE_PRINTF("AND\tAX,");
2161        srcval = fetch_word_imm();
2162    }
2163    DECODE_PRINTF2("%x\n", srcval);
2164    TRACE_AND_STEP();
2165    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2166        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2167    } else {
2168        M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2169    }
2170    DECODE_CLEAR_SEGOVR();
2171    END_OF_INSTR();
2172}
2173
2174/****************************************************************************
2175REMARKS:
2176Handles opcode 0x26
2177****************************************************************************/
2178void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2179{
2180    START_OF_INSTR();
2181    DECODE_PRINTF("ES:\n");
2182    TRACE_AND_STEP();
2183    M.x86.mode |= SYSMODE_SEGOVR_ES;
2184    /*
2185     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2186     * opcode subroutines we do not want to do this.
2187     */
2188    END_OF_INSTR();
2189}
2190
2191/****************************************************************************
2192REMARKS:
2193Handles opcode 0x27
2194****************************************************************************/
2195void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2196{
2197    START_OF_INSTR();
2198    DECODE_PRINTF("DAA\n");
2199    TRACE_AND_STEP();
2200    M.x86.R_AL = daa_byte(M.x86.R_AL);
2201    DECODE_CLEAR_SEGOVR();
2202    END_OF_INSTR();
2203}
2204
2205/****************************************************************************
2206REMARKS:
2207Handles opcode 0x28
2208****************************************************************************/
2209void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2210{
2211    int mod, rl, rh;
2212    u8 *destreg, *srcreg;
2213    uint destoffset;
2214    u8 destval;
2215
2216    START_OF_INSTR();
2217    DECODE_PRINTF("SUB\t");
2218    FETCH_DECODE_MODRM(mod, rh, rl);
2219    switch (mod) {
2220    case 0:
2221        destoffset = decode_rm00_address(rl);
2222        DECODE_PRINTF(",");
2223        destval = fetch_data_byte(destoffset);
2224        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2225        DECODE_PRINTF("\n");
2226        TRACE_AND_STEP();
2227        destval = sub_byte(destval, *srcreg);
2228        store_data_byte(destoffset, destval);
2229        break;
2230    case 1:
2231        destoffset = decode_rm01_address(rl);
2232        DECODE_PRINTF(",");
2233        destval = fetch_data_byte(destoffset);
2234        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2235        DECODE_PRINTF("\n");
2236        TRACE_AND_STEP();
2237        destval = sub_byte(destval, *srcreg);
2238        store_data_byte(destoffset, destval);
2239        break;
2240    case 2:
2241        destoffset = decode_rm10_address(rl);
2242        DECODE_PRINTF(",");
2243        destval = fetch_data_byte(destoffset);
2244        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2245        DECODE_PRINTF("\n");
2246        TRACE_AND_STEP();
2247        destval = sub_byte(destval, *srcreg);
2248        store_data_byte(destoffset, destval);
2249        break;
2250    case 3:                     /* register to register */
2251        destreg = DECODE_RM_BYTE_REGISTER(rl);
2252        DECODE_PRINTF(",");
2253        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2254        DECODE_PRINTF("\n");
2255        TRACE_AND_STEP();
2256        *destreg = sub_byte(*destreg, *srcreg);
2257        break;
2258    }
2259    DECODE_CLEAR_SEGOVR();
2260    END_OF_INSTR();
2261}
2262
2263/****************************************************************************
2264REMARKS:
2265Handles opcode 0x29
2266****************************************************************************/
2267void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2268{
2269    int mod, rl, rh;
2270    uint destoffset;
2271
2272    START_OF_INSTR();
2273    DECODE_PRINTF("SUB\t");
2274    FETCH_DECODE_MODRM(mod, rh, rl);
2275    switch (mod) {
2276    case 0:
2277        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2278            u32 destval;
2279            u32 *srcreg;
2280
2281            destoffset = decode_rm00_address(rl);
2282            DECODE_PRINTF(",");
2283            destval = fetch_data_long(destoffset);
2284            srcreg = DECODE_RM_LONG_REGISTER(rh);
2285            DECODE_PRINTF("\n");
2286            TRACE_AND_STEP();
2287            destval = sub_long(destval, *srcreg);
2288            store_data_long(destoffset, destval);
2289        } else {
2290            u16 destval;
2291            u16 *srcreg;
2292
2293            destoffset = decode_rm00_address(rl);
2294            DECODE_PRINTF(",");
2295            destval = fetch_data_word(destoffset);
2296            srcreg = DECODE_RM_WORD_REGISTER(rh);
2297            DECODE_PRINTF("\n");
2298            TRACE_AND_STEP();
2299            destval = sub_word(destval, *srcreg);
2300            store_data_word(destoffset, destval);
2301        }
2302        break;
2303    case 1:
2304        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2305            u32 destval;
2306            u32 *srcreg;
2307
2308            destoffset = decode_rm01_address(rl);
2309            DECODE_PRINTF(",");
2310            destval = fetch_data_long(destoffset);
2311            srcreg = DECODE_RM_LONG_REGISTER(rh);
2312            DECODE_PRINTF("\n");
2313            TRACE_AND_STEP();
2314            destval = sub_long(destval, *srcreg);
2315            store_data_long(destoffset, destval);
2316        } else {
2317            u16 destval;
2318            u16 *srcreg;
2319
2320            destoffset = decode_rm01_address(rl);
2321            DECODE_PRINTF(",");
2322            destval = fetch_data_word(destoffset);
2323            srcreg = DECODE_RM_WORD_REGISTER(rh);
2324            DECODE_PRINTF("\n");
2325            TRACE_AND_STEP();
2326            destval = sub_word(destval, *srcreg);
2327            store_data_word(destoffset, destval);
2328        }
2329        break;
2330    case 2:
2331        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2332            u32 destval;
2333            u32 *srcreg;
2334
2335            destoffset = decode_rm10_address(rl);
2336            DECODE_PRINTF(",");
2337            destval = fetch_data_long(destoffset);
2338            srcreg = DECODE_RM_LONG_REGISTER(rh);
2339            DECODE_PRINTF("\n");
2340            TRACE_AND_STEP();
2341            destval = sub_long(destval, *srcreg);
2342            store_data_long(destoffset, destval);
2343        } else {
2344            u16 destval;
2345            u16 *srcreg;
2346
2347            destoffset = decode_rm10_address(rl);
2348            DECODE_PRINTF(",");
2349            destval = fetch_data_word(destoffset);
2350            srcreg = DECODE_RM_WORD_REGISTER(rh);
2351            DECODE_PRINTF("\n");
2352            TRACE_AND_STEP();
2353            destval = sub_word(destval, *srcreg);
2354            store_data_word(destoffset, destval);
2355        }
2356        break;
2357    case 3:                     /* register to register */
2358        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2359            u32 *destreg,*srcreg;
2360
2361            destreg = DECODE_RM_LONG_REGISTER(rl);
2362            DECODE_PRINTF(",");
2363            srcreg = DECODE_RM_LONG_REGISTER(rh);
2364            DECODE_PRINTF("\n");
2365            TRACE_AND_STEP();
2366            *destreg = sub_long(*destreg, *srcreg);
2367        } else {
2368            u16 *destreg,*srcreg;
2369
2370            destreg = DECODE_RM_WORD_REGISTER(rl);
2371            DECODE_PRINTF(",");
2372            srcreg = DECODE_RM_WORD_REGISTER(rh);
2373            DECODE_PRINTF("\n");
2374            TRACE_AND_STEP();
2375            *destreg = sub_word(*destreg, *srcreg);
2376        }
2377        break;
2378    }
2379    DECODE_CLEAR_SEGOVR();
2380    END_OF_INSTR();
2381}
2382
2383/****************************************************************************
2384REMARKS:
2385Handles opcode 0x2a
2386****************************************************************************/
2387void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2388{
2389    int mod, rl, rh;
2390    u8 *destreg, *srcreg;
2391    uint srcoffset;
2392    u8 srcval;
2393
2394    START_OF_INSTR();
2395    DECODE_PRINTF("SUB\t");
2396    FETCH_DECODE_MODRM(mod, rh, rl);
2397    switch (mod) {
2398    case 0:
2399        destreg = DECODE_RM_BYTE_REGISTER(rh);
2400        DECODE_PRINTF(",");
2401        srcoffset = decode_rm00_address(rl);
2402        srcval = fetch_data_byte(srcoffset);
2403        DECODE_PRINTF("\n");
2404        TRACE_AND_STEP();
2405        *destreg = sub_byte(*destreg, srcval);
2406        break;
2407    case 1:
2408        destreg = DECODE_RM_BYTE_REGISTER(rh);
2409        DECODE_PRINTF(",");
2410        srcoffset = decode_rm01_address(rl);
2411        srcval = fetch_data_byte(srcoffset);
2412        DECODE_PRINTF("\n");
2413        TRACE_AND_STEP();
2414        *destreg = sub_byte(*destreg, srcval);
2415        break;
2416    case 2:
2417        destreg = DECODE_RM_BYTE_REGISTER(rh);
2418        DECODE_PRINTF(",");
2419        srcoffset = decode_rm10_address(rl);
2420        srcval = fetch_data_byte(srcoffset);
2421        DECODE_PRINTF("\n");
2422        TRACE_AND_STEP();
2423        *destreg = sub_byte(*destreg, srcval);
2424        break;
2425    case 3:                     /* register to register */
2426        destreg = DECODE_RM_BYTE_REGISTER(rh);
2427        DECODE_PRINTF(",");
2428        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2429        DECODE_PRINTF("\n");
2430        TRACE_AND_STEP();
2431        *destreg = sub_byte(*destreg, *srcreg);
2432        break;
2433    }
2434    DECODE_CLEAR_SEGOVR();
2435    END_OF_INSTR();
2436}
2437
2438/****************************************************************************
2439REMARKS:
2440Handles opcode 0x2b
2441****************************************************************************/
2442void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2443{
2444    int mod, rl, rh;
2445    uint srcoffset;
2446
2447    START_OF_INSTR();
2448    DECODE_PRINTF("SUB\t");
2449    FETCH_DECODE_MODRM(mod, rh, rl);
2450    switch (mod) {
2451    case 0:
2452        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2453            u32 *destreg;
2454            u32 srcval;
2455
2456            destreg = DECODE_RM_LONG_REGISTER(rh);
2457            DECODE_PRINTF(",");
2458            srcoffset = decode_rm00_address(rl);
2459            srcval = fetch_data_long(srcoffset);
2460            DECODE_PRINTF("\n");
2461            TRACE_AND_STEP();
2462            *destreg = sub_long(*destreg, srcval);
2463        } else {
2464            u16 *destreg;
2465            u16 srcval;
2466
2467            destreg = DECODE_RM_WORD_REGISTER(rh);
2468            DECODE_PRINTF(",");
2469            srcoffset = decode_rm00_address(rl);
2470            srcval = fetch_data_word(srcoffset);
2471            DECODE_PRINTF("\n");
2472            TRACE_AND_STEP();
2473            *destreg = sub_word(*destreg, srcval);
2474        }
2475        break;
2476    case 1:
2477        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2478            u32 *destreg;
2479            u32 srcval;
2480
2481            destreg = DECODE_RM_LONG_REGISTER(rh);
2482            DECODE_PRINTF(",");
2483            srcoffset = decode_rm01_address(rl);
2484            srcval = fetch_data_long(srcoffset);
2485            DECODE_PRINTF("\n");
2486            TRACE_AND_STEP();
2487            *destreg = sub_long(*destreg, srcval);
2488        } else {
2489            u16 *destreg;
2490            u16 srcval;
2491
2492            destreg = DECODE_RM_WORD_REGISTER(rh);
2493            DECODE_PRINTF(",");
2494            srcoffset = decode_rm01_address(rl);
2495            srcval = fetch_data_word(srcoffset);
2496            DECODE_PRINTF("\n");
2497            TRACE_AND_STEP();
2498            *destreg = sub_word(*destreg, srcval);
2499        }
2500        break;
2501    case 2:
2502        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2503            u32 *destreg;
2504            u32 srcval;
2505
2506            destreg = DECODE_RM_LONG_REGISTER(rh);
2507            DECODE_PRINTF(",");
2508            srcoffset = decode_rm10_address(rl);
2509            srcval = fetch_data_long(srcoffset);
2510            DECODE_PRINTF("\n");
2511            TRACE_AND_STEP();
2512            *destreg = sub_long(*destreg, srcval);
2513        } else {
2514            u16 *destreg;
2515            u16 srcval;
2516
2517            destreg = DECODE_RM_WORD_REGISTER(rh);
2518            DECODE_PRINTF(",");
2519            srcoffset = decode_rm10_address(rl);
2520            srcval = fetch_data_word(srcoffset);
2521            DECODE_PRINTF("\n");
2522            TRACE_AND_STEP();
2523            *destreg = sub_word(*destreg, srcval);
2524        }
2525        break;
2526    case 3:                     /* register to register */
2527        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2528            u32 *destreg,*srcreg;
2529
2530            destreg = DECODE_RM_LONG_REGISTER(rh);
2531            DECODE_PRINTF(",");
2532            srcreg = DECODE_RM_LONG_REGISTER(rl);
2533            DECODE_PRINTF("\n");
2534            TRACE_AND_STEP();
2535            *destreg = sub_long(*destreg, *srcreg);
2536        } else {
2537            u16 *destreg,*srcreg;
2538
2539            destreg = DECODE_RM_WORD_REGISTER(rh);
2540            DECODE_PRINTF(",");
2541            srcreg = DECODE_RM_WORD_REGISTER(rl);
2542            DECODE_PRINTF("\n");
2543            TRACE_AND_STEP();
2544            *destreg = sub_word(*destreg, *srcreg);
2545        }
2546        break;
2547    }
2548    DECODE_CLEAR_SEGOVR();
2549    END_OF_INSTR();
2550}
2551
2552/****************************************************************************
2553REMARKS:
2554Handles opcode 0x2c
2555****************************************************************************/
2556void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2557{
2558    u8 srcval;
2559
2560    START_OF_INSTR();
2561    DECODE_PRINTF("SUB\tAL,");
2562    srcval = fetch_byte_imm();
2563    DECODE_PRINTF2("%x\n", srcval);
2564    TRACE_AND_STEP();
2565    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2566    DECODE_CLEAR_SEGOVR();
2567    END_OF_INSTR();
2568}
2569
2570/****************************************************************************
2571REMARKS:
2572Handles opcode 0x2d
2573****************************************************************************/
2574void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2575{
2576    u32 srcval;
2577
2578    START_OF_INSTR();
2579    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2580        DECODE_PRINTF("SUB\tEAX,");
2581        srcval = fetch_long_imm();
2582    } else {
2583        DECODE_PRINTF("SUB\tAX,");
2584        srcval = fetch_word_imm();
2585    }
2586    DECODE_PRINTF2("%x\n", srcval);
2587    TRACE_AND_STEP();
2588    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2589        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2590    } else {
2591        M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2592    }
2593    DECODE_CLEAR_SEGOVR();
2594    END_OF_INSTR();
2595}
2596
2597/****************************************************************************
2598REMARKS:
2599Handles opcode 0x2e
2600****************************************************************************/
2601void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2602{
2603    START_OF_INSTR();
2604    DECODE_PRINTF("CS:\n");
2605    TRACE_AND_STEP();
2606    M.x86.mode |= SYSMODE_SEGOVR_CS;
2607    /* note no DECODE_CLEAR_SEGOVR here. */
2608    END_OF_INSTR();
2609}
2610
2611/****************************************************************************
2612REMARKS:
2613Handles opcode 0x2f
2614****************************************************************************/
2615void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2616{
2617    START_OF_INSTR();
2618    DECODE_PRINTF("DAS\n");
2619    TRACE_AND_STEP();
2620    M.x86.R_AL = das_byte(M.x86.R_AL);
2621    DECODE_CLEAR_SEGOVR();
2622    END_OF_INSTR();
2623}
2624
2625/****************************************************************************
2626REMARKS:
2627Handles opcode 0x30
2628****************************************************************************/
2629void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2630{
2631    int mod, rl, rh;
2632    u8 *destreg, *srcreg;
2633    uint destoffset;
2634    u8 destval;
2635
2636    START_OF_INSTR();
2637    DECODE_PRINTF("XOR\t");
2638    FETCH_DECODE_MODRM(mod, rh, rl);
2639    switch (mod) {
2640    case 0:
2641        destoffset = decode_rm00_address(rl);
2642        DECODE_PRINTF(",");
2643        destval = fetch_data_byte(destoffset);
2644        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2645        DECODE_PRINTF("\n");
2646        TRACE_AND_STEP();
2647        destval = xor_byte(destval, *srcreg);
2648        store_data_byte(destoffset, destval);
2649        break;
2650    case 1:
2651        destoffset = decode_rm01_address(rl);
2652        DECODE_PRINTF(",");
2653        destval = fetch_data_byte(destoffset);
2654        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2655        DECODE_PRINTF("\n");
2656        TRACE_AND_STEP();
2657        destval = xor_byte(destval, *srcreg);
2658        store_data_byte(destoffset, destval);
2659        break;
2660    case 2:
2661        destoffset = decode_rm10_address(rl);
2662        DECODE_PRINTF(",");
2663        destval = fetch_data_byte(destoffset);
2664        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2665        DECODE_PRINTF("\n");
2666        TRACE_AND_STEP();
2667        destval = xor_byte(destval, *srcreg);
2668        store_data_byte(destoffset, destval);
2669        break;
2670    case 3:                     /* register to register */
2671        destreg = DECODE_RM_BYTE_REGISTER(rl);
2672        DECODE_PRINTF(",");
2673        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2674        DECODE_PRINTF("\n");
2675        TRACE_AND_STEP();
2676        *destreg = xor_byte(*destreg, *srcreg);
2677        break;
2678    }
2679    DECODE_CLEAR_SEGOVR();
2680    END_OF_INSTR();
2681}
2682
2683/****************************************************************************
2684REMARKS:
2685Handles opcode 0x31
2686****************************************************************************/
2687void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2688{
2689    int mod, rl, rh;
2690    uint destoffset;
2691
2692    START_OF_INSTR();
2693    DECODE_PRINTF("XOR\t");
2694    FETCH_DECODE_MODRM(mod, rh, rl);
2695    switch (mod) {
2696    case 0:
2697        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2698            u32 destval;
2699            u32 *srcreg;
2700
2701            destoffset = decode_rm00_address(rl);
2702            DECODE_PRINTF(",");
2703            destval = fetch_data_long(destoffset);
2704            srcreg = DECODE_RM_LONG_REGISTER(rh);
2705            DECODE_PRINTF("\n");
2706            TRACE_AND_STEP();
2707            destval = xor_long(destval, *srcreg);
2708            store_data_long(destoffset, destval);
2709        } else {
2710            u16 destval;
2711            u16 *srcreg;
2712
2713            destoffset = decode_rm00_address(rl);
2714            DECODE_PRINTF(",");
2715            destval = fetch_data_word(destoffset);
2716            srcreg = DECODE_RM_WORD_REGISTER(rh);
2717            DECODE_PRINTF("\n");
2718            TRACE_AND_STEP();
2719            destval = xor_word(destval, *srcreg);
2720            store_data_word(destoffset, destval);
2721        }
2722        break;
2723    case 1:
2724        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2725            u32 destval;
2726            u32 *srcreg;
2727
2728            destoffset = decode_rm01_address(rl);
2729            DECODE_PRINTF(",");
2730            destval = fetch_data_long(destoffset);
2731            srcreg = DECODE_RM_LONG_REGISTER(rh);
2732            DECODE_PRINTF("\n");
2733            TRACE_AND_STEP();
2734            destval = xor_long(destval, *srcreg);
2735            store_data_long(destoffset, destval);
2736        } else {
2737            u16 destval;
2738            u16 *srcreg;
2739
2740            destoffset = decode_rm01_address(rl);
2741            DECODE_PRINTF(",");
2742            destval = fetch_data_word(destoffset);
2743            srcreg = DECODE_RM_WORD_REGISTER(rh);
2744            DECODE_PRINTF("\n");
2745            TRACE_AND_STEP();
2746            destval = xor_word(destval, *srcreg);
2747            store_data_word(destoffset, destval);
2748        }
2749        break;
2750    case 2:
2751        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2752            u32 destval;
2753            u32 *srcreg;
2754
2755            destoffset = decode_rm10_address(rl);
2756            DECODE_PRINTF(",");
2757            destval = fetch_data_long(destoffset);
2758            srcreg = DECODE_RM_LONG_REGISTER(rh);
2759            DECODE_PRINTF("\n");
2760            TRACE_AND_STEP();
2761            destval = xor_long(destval, *srcreg);
2762            store_data_long(destoffset, destval);
2763        } else {
2764            u16 destval;
2765            u16 *srcreg;
2766
2767            destoffset = decode_rm10_address(rl);
2768            DECODE_PRINTF(",");
2769            destval = fetch_data_word(destoffset);
2770            srcreg = DECODE_RM_WORD_REGISTER(rh);
2771            DECODE_PRINTF("\n");
2772            TRACE_AND_STEP();
2773            destval = xor_word(destval, *srcreg);
2774            store_data_word(destoffset, destval);
2775        }
2776        break;
2777    case 3:                     /* register to register */
2778        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2779            u32 *destreg,*srcreg;
2780
2781            destreg = DECODE_RM_LONG_REGISTER(rl);
2782            DECODE_PRINTF(",");
2783            srcreg = DECODE_RM_LONG_REGISTER(rh);
2784            DECODE_PRINTF("\n");
2785            TRACE_AND_STEP();
2786            *destreg = xor_long(*destreg, *srcreg);
2787        } else {
2788            u16 *destreg,*srcreg;
2789
2790            destreg = DECODE_RM_WORD_REGISTER(rl);
2791            DECODE_PRINTF(",");
2792            srcreg = DECODE_RM_WORD_REGISTER(rh);
2793            DECODE_PRINTF("\n");
2794            TRACE_AND_STEP();
2795            *destreg = xor_word(*destreg, *srcreg);
2796        }
2797        break;
2798    }
2799    DECODE_CLEAR_SEGOVR();
2800    END_OF_INSTR();
2801}
2802
2803/****************************************************************************
2804REMARKS:
2805Handles opcode 0x32
2806****************************************************************************/
2807void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2808{
2809    int mod, rl, rh;
2810    u8 *destreg, *srcreg;
2811    uint srcoffset;
2812    u8 srcval;
2813
2814    START_OF_INSTR();
2815    DECODE_PRINTF("XOR\t");
2816    FETCH_DECODE_MODRM(mod, rh, rl);
2817    switch (mod) {
2818    case 0:
2819        destreg = DECODE_RM_BYTE_REGISTER(rh);
2820        DECODE_PRINTF(",");
2821        srcoffset = decode_rm00_address(rl);
2822        srcval = fetch_data_byte(srcoffset);
2823        DECODE_PRINTF("\n");
2824        TRACE_AND_STEP();
2825        *destreg = xor_byte(*destreg, srcval);
2826        break;
2827    case 1:
2828        destreg = DECODE_RM_BYTE_REGISTER(rh);
2829        DECODE_PRINTF(",");
2830        srcoffset = decode_rm01_address(rl);
2831        srcval = fetch_data_byte(srcoffset);
2832        DECODE_PRINTF("\n");
2833        TRACE_AND_STEP();
2834        *destreg = xor_byte(*destreg, srcval);
2835        break;
2836    case 2:
2837        destreg = DECODE_RM_BYTE_REGISTER(rh);
2838        DECODE_PRINTF(",");
2839        srcoffset = decode_rm10_address(rl);
2840        srcval = fetch_data_byte(srcoffset);
2841        DECODE_PRINTF("\n");
2842        TRACE_AND_STEP();
2843        *destreg = xor_byte(*destreg, srcval);
2844        break;
2845    case 3:                     /* register to register */
2846        destreg = DECODE_RM_BYTE_REGISTER(rh);
2847        DECODE_PRINTF(",");
2848        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2849        DECODE_PRINTF("\n");
2850        TRACE_AND_STEP();
2851        *destreg = xor_byte(*destreg, *srcreg);
2852        break;
2853    }
2854    DECODE_CLEAR_SEGOVR();
2855    END_OF_INSTR();
2856}
2857
2858/****************************************************************************
2859REMARKS:
2860Handles opcode 0x33
2861****************************************************************************/
2862void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2863{
2864    int mod, rl, rh;
2865    uint srcoffset;
2866
2867    START_OF_INSTR();
2868    DECODE_PRINTF("XOR\t");
2869    FETCH_DECODE_MODRM(mod, rh, rl);
2870    switch (mod) {
2871    case 0:
2872        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2873            u32 *destreg;
2874            u32 srcval;
2875
2876            destreg = DECODE_RM_LONG_REGISTER(rh);
2877            DECODE_PRINTF(",");
2878            srcoffset = decode_rm00_address(rl);
2879            srcval = fetch_data_long(srcoffset);
2880            DECODE_PRINTF("\n");
2881            TRACE_AND_STEP();
2882            *destreg = xor_long(*destreg, srcval);
2883        } else {
2884            u16 *destreg;
2885            u16 srcval;
2886
2887            destreg = DECODE_RM_WORD_REGISTER(rh);
2888            DECODE_PRINTF(",");
2889            srcoffset = decode_rm00_address(rl);
2890            srcval = fetch_data_word(srcoffset);
2891            DECODE_PRINTF("\n");
2892            TRACE_AND_STEP();
2893            *destreg = xor_word(*destreg, srcval);
2894        }
2895        break;
2896    case 1:
2897        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2898            u32 *destreg;
2899            u32 srcval;
2900
2901            destreg = DECODE_RM_LONG_REGISTER(rh);
2902            DECODE_PRINTF(",");
2903            srcoffset = decode_rm01_address(rl);
2904            srcval = fetch_data_long(srcoffset);
2905            DECODE_PRINTF("\n");
2906            TRACE_AND_STEP();
2907            *destreg = xor_long(*destreg, srcval);
2908        } else {
2909            u16 *destreg;
2910            u16 srcval;
2911
2912            destreg = DECODE_RM_WORD_REGISTER(rh);
2913            DECODE_PRINTF(",");
2914            srcoffset = decode_rm01_address(rl);
2915            srcval = fetch_data_word(srcoffset);
2916            DECODE_PRINTF("\n");
2917            TRACE_AND_STEP();
2918            *destreg = xor_word(*destreg, srcval);
2919        }
2920        break;
2921    case 2:
2922        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2923            u32 *destreg;
2924            u32 srcval;
2925
2926            destreg = DECODE_RM_LONG_REGISTER(rh);
2927            DECODE_PRINTF(",");
2928            srcoffset = decode_rm10_address(rl);
2929            srcval = fetch_data_long(srcoffset);
2930            DECODE_PRINTF("\n");
2931            TRACE_AND_STEP();
2932            *destreg = xor_long(*destreg, srcval);
2933        } else {
2934            u16 *destreg;
2935            u16 srcval;
2936
2937            destreg = DECODE_RM_WORD_REGISTER(rh);
2938            DECODE_PRINTF(",");
2939            srcoffset = decode_rm10_address(rl);
2940            srcval = fetch_data_word(srcoffset);
2941            DECODE_PRINTF("\n");
2942            TRACE_AND_STEP();
2943            *destreg = xor_word(*destreg, srcval);
2944        }
2945        break;
2946    case 3:                     /* register to register */
2947        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2948            u32 *destreg,*srcreg;
2949
2950            destreg = DECODE_RM_LONG_REGISTER(rh);
2951            DECODE_PRINTF(",");
2952            srcreg = DECODE_RM_LONG_REGISTER(rl);
2953            DECODE_PRINTF("\n");
2954            TRACE_AND_STEP();
2955            *destreg = xor_long(*destreg, *srcreg);
2956        } else {
2957            u16 *destreg,*srcreg;
2958
2959            destreg = DECODE_RM_WORD_REGISTER(rh);
2960            DECODE_PRINTF(",");
2961            srcreg = DECODE_RM_WORD_REGISTER(rl);
2962            DECODE_PRINTF("\n");
2963            TRACE_AND_STEP();
2964            *destreg = xor_word(*destreg, *srcreg);
2965        }
2966        break;
2967    }
2968    DECODE_CLEAR_SEGOVR();
2969    END_OF_INSTR();
2970}
2971
2972/****************************************************************************
2973REMARKS:
2974Handles opcode 0x34
2975****************************************************************************/
2976void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2977{
2978    u8 srcval;
2979
2980    START_OF_INSTR();
2981    DECODE_PRINTF("XOR\tAL,");
2982    srcval = fetch_byte_imm();
2983    DECODE_PRINTF2("%x\n", srcval);
2984    TRACE_AND_STEP();
2985    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2986    DECODE_CLEAR_SEGOVR();
2987    END_OF_INSTR();
2988}
2989
2990/****************************************************************************
2991REMARKS:
2992Handles opcode 0x35
2993****************************************************************************/
2994void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2995{
2996    u32 srcval;
2997
2998    START_OF_INSTR();
2999    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3000        DECODE_PRINTF("XOR\tEAX,");
3001        srcval = fetch_long_imm();
3002    } else {
3003        DECODE_PRINTF("XOR\tAX,");
3004        srcval = fetch_word_imm();
3005    }
3006    DECODE_PRINTF2("%x\n", srcval);
3007    TRACE_AND_STEP();
3008    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3009        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3010    } else {
3011        M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3012    }
3013    DECODE_CLEAR_SEGOVR();
3014    END_OF_INSTR();
3015}
3016
3017/****************************************************************************
3018REMARKS:
3019Handles opcode 0x36
3020****************************************************************************/
3021void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3022{
3023    START_OF_INSTR();
3024    DECODE_PRINTF("SS:\n");
3025    TRACE_AND_STEP();
3026    M.x86.mode |= SYSMODE_SEGOVR_SS;
3027    /* no DECODE_CLEAR_SEGOVR ! */
3028    END_OF_INSTR();
3029}
3030
3031/****************************************************************************
3032REMARKS:
3033Handles opcode 0x37
3034****************************************************************************/
3035void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3036{
3037    START_OF_INSTR();
3038    DECODE_PRINTF("AAA\n");
3039    TRACE_AND_STEP();
3040    M.x86.R_AX = aaa_word(M.x86.R_AX);
3041    DECODE_CLEAR_SEGOVR();
3042    END_OF_INSTR();
3043}
3044
3045/****************************************************************************
3046REMARKS:
3047Handles opcode 0x38
3048****************************************************************************/
3049void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3050{
3051    int mod, rl, rh;
3052    uint destoffset;
3053    u8 *destreg, *srcreg;
3054    u8 destval;
3055
3056    START_OF_INSTR();
3057    DECODE_PRINTF("CMP\t");
3058    FETCH_DECODE_MODRM(mod, rh, rl);
3059    switch (mod) {
3060    case 0:
3061        destoffset = decode_rm00_address(rl);
3062        DECODE_PRINTF(",");
3063        destval = fetch_data_byte(destoffset);
3064        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3065        DECODE_PRINTF("\n");
3066        TRACE_AND_STEP();
3067        cmp_byte(destval, *srcreg);
3068        break;
3069    case 1:
3070        destoffset = decode_rm01_address(rl);
3071        DECODE_PRINTF(",");
3072        destval = fetch_data_byte(destoffset);
3073        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3074        DECODE_PRINTF("\n");
3075        TRACE_AND_STEP();
3076        cmp_byte(destval, *srcreg);
3077        break;
3078    case 2:
3079        destoffset = decode_rm10_address(rl);
3080        DECODE_PRINTF(",");
3081        destval = fetch_data_byte(destoffset);
3082        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3083        DECODE_PRINTF("\n");
3084        TRACE_AND_STEP();
3085        cmp_byte(destval, *srcreg);
3086        break;
3087    case 3:                     /* register to register */
3088        destreg = DECODE_RM_BYTE_REGISTER(rl);
3089        DECODE_PRINTF(",");
3090        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3091        DECODE_PRINTF("\n");
3092        TRACE_AND_STEP();
3093        cmp_byte(*destreg, *srcreg);
3094        break;
3095    }
3096    DECODE_CLEAR_SEGOVR();
3097    END_OF_INSTR();
3098}
3099
3100/****************************************************************************
3101REMARKS:
3102Handles opcode 0x39
3103****************************************************************************/
3104void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3105{
3106    int mod, rl, rh;
3107    uint destoffset;
3108
3109    START_OF_INSTR();
3110    DECODE_PRINTF("CMP\t");
3111    FETCH_DECODE_MODRM(mod, rh, rl);
3112    switch (mod) {
3113    case 0:
3114        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3115            u32 destval;
3116            u32 *srcreg;
3117
3118            destoffset = decode_rm00_address(rl);
3119            DECODE_PRINTF(",");
3120            destval = fetch_data_long(destoffset);
3121            srcreg = DECODE_RM_LONG_REGISTER(rh);
3122            DECODE_PRINTF("\n");
3123            TRACE_AND_STEP();
3124            cmp_long(destval, *srcreg);
3125        } else {
3126            u16 destval;
3127            u16 *srcreg;
3128
3129            destoffset = decode_rm00_address(rl);
3130            DECODE_PRINTF(",");
3131            destval = fetch_data_word(destoffset);
3132            srcreg = DECODE_RM_WORD_REGISTER(rh);
3133            DECODE_PRINTF("\n");
3134            TRACE_AND_STEP();
3135            cmp_word(destval, *srcreg);
3136        }
3137        break;
3138    case 1:
3139        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140            u32 destval;
3141            u32 *srcreg;
3142
3143            destoffset = decode_rm01_address(rl);
3144            DECODE_PRINTF(",");
3145            destval = fetch_data_long(destoffset);
3146            srcreg = DECODE_RM_LONG_REGISTER(rh);
3147            DECODE_PRINTF("\n");
3148            TRACE_AND_STEP();
3149            cmp_long(destval, *srcreg);
3150        } else {
3151            u16 destval;
3152            u16 *srcreg;
3153
3154            destoffset = decode_rm01_address(rl);
3155            DECODE_PRINTF(",");
3156            destval = fetch_data_word(destoffset);
3157            srcreg = DECODE_RM_WORD_REGISTER(rh);
3158            DECODE_PRINTF("\n");
3159            TRACE_AND_STEP();
3160            cmp_word(destval, *srcreg);
3161        }
3162        break;
3163    case 2:
3164        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3165            u32 destval;
3166            u32 *srcreg;
3167
3168            destoffset = decode_rm10_address(rl);
3169            DECODE_PRINTF(",");
3170            destval = fetch_data_long(destoffset);
3171            srcreg = DECODE_RM_LONG_REGISTER(rh);
3172            DECODE_PRINTF("\n");
3173            TRACE_AND_STEP();
3174            cmp_long(destval, *srcreg);
3175        } else {
3176            u16 destval;
3177            u16 *srcreg;
3178
3179            destoffset = decode_rm10_address(rl);
3180            DECODE_PRINTF(",");
3181            destval = fetch_data_word(destoffset);
3182            srcreg = DECODE_RM_WORD_REGISTER(rh);
3183            DECODE_PRINTF("\n");
3184            TRACE_AND_STEP();
3185            cmp_word(destval, *srcreg);
3186        }
3187        break;
3188    case 3:                     /* register to register */
3189        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3190            u32 *destreg,*srcreg;
3191
3192            destreg = DECODE_RM_LONG_REGISTER(rl);
3193            DECODE_PRINTF(",");
3194            srcreg = DECODE_RM_LONG_REGISTER(rh);
3195            DECODE_PRINTF("\n");
3196            TRACE_AND_STEP();
3197            cmp_long(*destreg, *srcreg);
3198        } else {
3199            u16 *destreg,*srcreg;
3200
3201            destreg = DECODE_RM_WORD_REGISTER(rl);
3202            DECODE_PRINTF(",");
3203            srcreg = DECODE_RM_WORD_REGISTER(rh);
3204            DECODE_PRINTF("\n");
3205            TRACE_AND_STEP();
3206            cmp_word(*destreg, *srcreg);
3207        }
3208        break;
3209    }
3210    DECODE_CLEAR_SEGOVR();
3211    END_OF_INSTR();
3212}
3213
3214/****************************************************************************
3215REMARKS:
3216Handles opcode 0x3a
3217****************************************************************************/
3218void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3219{
3220    int mod, rl, rh;
3221    u8 *destreg, *srcreg;
3222    uint srcoffset;
3223    u8 srcval;
3224
3225    START_OF_INSTR();
3226    DECODE_PRINTF("CMP\t");
3227    FETCH_DECODE_MODRM(mod, rh, rl);
3228    switch (mod) {
3229    case 0:
3230        destreg = DECODE_RM_BYTE_REGISTER(rh);
3231        DECODE_PRINTF(",");
3232        srcoffset = decode_rm00_address(rl);
3233        srcval = fetch_data_byte(srcoffset);
3234        DECODE_PRINTF("\n");
3235        TRACE_AND_STEP();
3236        cmp_byte(*destreg, srcval);
3237        break;
3238    case 1:
3239        destreg = DECODE_RM_BYTE_REGISTER(rh);
3240        DECODE_PRINTF(",");
3241        srcoffset = decode_rm01_address(rl);
3242        srcval = fetch_data_byte(srcoffset);
3243        DECODE_PRINTF("\n");
3244        TRACE_AND_STEP();
3245        cmp_byte(*destreg, srcval);
3246        break;
3247    case 2:
3248        destreg = DECODE_RM_BYTE_REGISTER(rh);
3249        DECODE_PRINTF(",");
3250        srcoffset = decode_rm10_address(rl);
3251        srcval = fetch_data_byte(srcoffset);
3252        DECODE_PRINTF("\n");
3253        TRACE_AND_STEP();
3254        cmp_byte(*destreg, srcval);
3255        break;
3256    case 3:                     /* register to register */
3257        destreg = DECODE_RM_BYTE_REGISTER(rh);
3258        DECODE_PRINTF(",");
3259        srcreg = DECODE_RM_BYTE_REGISTER(rl);
3260        DECODE_PRINTF("\n");
3261        TRACE_AND_STEP();
3262        cmp_byte(*destreg, *srcreg);
3263        break;
3264    }
3265    DECODE_CLEAR_SEGOVR();
3266    END_OF_INSTR();
3267}
3268
3269/****************************************************************************
3270REMARKS:
3271Handles opcode 0x3b
3272****************************************************************************/
3273void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3274{
3275    int mod, rl, rh;
3276    uint srcoffset;
3277
3278    START_OF_INSTR();
3279    DECODE_PRINTF("CMP\t");
3280    FETCH_DECODE_MODRM(mod, rh, rl);
3281    switch (mod) {
3282    case 0:
3283        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3284            u32 *destreg;
3285            u32 srcval;
3286
3287            destreg = DECODE_RM_LONG_REGISTER(rh);
3288            DECODE_PRINTF(",");
3289            srcoffset = decode_rm00_address(rl);
3290            srcval = fetch_data_long(srcoffset);
3291            DECODE_PRINTF("\n");
3292            TRACE_AND_STEP();
3293            cmp_long(*destreg, srcval);
3294        } else {
3295            u16 *destreg;
3296            u16 srcval;
3297
3298            destreg = DECODE_RM_WORD_REGISTER(rh);
3299            DECODE_PRINTF(",");
3300            srcoffset = decode_rm00_address(rl);
3301            srcval = fetch_data_word(srcoffset);
3302            DECODE_PRINTF("\n");
3303            TRACE_AND_STEP();
3304            cmp_word(*destreg, srcval);
3305        }
3306        break;
3307    case 1:
3308        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3309            u32 *destreg;
3310            u32 srcval;
3311
3312            destreg = DECODE_RM_LONG_REGISTER(rh);
3313            DECODE_PRINTF(",");
3314            srcoffset = decode_rm01_address(rl);
3315            srcval = fetch_data_long(srcoffset);
3316            DECODE_PRINTF("\n");
3317            TRACE_AND_STEP();
3318            cmp_long(*destreg, srcval);
3319        } else {
3320            u16 *destreg;
3321            u16 srcval;
3322
3323            destreg = DECODE_RM_WORD_REGISTER(rh);
3324            DECODE_PRINTF(",");
3325            srcoffset = decode_rm01_address(rl);
3326            srcval = fetch_data_word(srcoffset);
3327            DECODE_PRINTF("\n");
3328            TRACE_AND_STEP();
3329            cmp_word(*destreg, srcval);
3330        }
3331        break;
3332    case 2:
3333        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3334            u32 *destreg;
3335            u32 srcval;
3336
3337            destreg = DECODE_RM_LONG_REGISTER(rh);
3338            DECODE_PRINTF(",");
3339            srcoffset = decode_rm10_address(rl);
3340            srcval = fetch_data_long(srcoffset);
3341            DECODE_PRINTF("\n");
3342            TRACE_AND_STEP();
3343            cmp_long(*destreg, srcval);
3344        } else {
3345            u16 *destreg;
3346            u16 srcval;
3347
3348            destreg = DECODE_RM_WORD_REGISTER(rh);
3349            DECODE_PRINTF(",");
3350            srcoffset = decode_rm10_address(rl);
3351            srcval = fetch_data_word(srcoffset);
3352            DECODE_PRINTF("\n");
3353            TRACE_AND_STEP();
3354            cmp_word(*destreg, srcval);
3355        }
3356        break;
3357    case 3:                     /* register to register */
3358        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3359            u32 *destreg,*srcreg;
3360
3361            destreg = DECODE_RM_LONG_REGISTER(rh);
3362            DECODE_PRINTF(",");
3363            srcreg = DECODE_RM_LONG_REGISTER(rl);
3364            DECODE_PRINTF("\n");
3365            TRACE_AND_STEP();
3366            cmp_long(*destreg, *srcreg);
3367        } else {
3368            u16 *destreg,*srcreg;
3369
3370            destreg = DECODE_RM_WORD_REGISTER(rh);
3371            DECODE_PRINTF(",");
3372            srcreg = DECODE_RM_WORD_REGISTER(rl);
3373            DECODE_PRINTF("\n");
3374            TRACE_AND_STEP();
3375            cmp_word(*destreg, *srcreg);
3376        }
3377        break;
3378    }
3379    DECODE_CLEAR_SEGOVR();
3380    END_OF_INSTR();
3381}
3382
3383/****************************************************************************
3384REMARKS:
3385Handles opcode 0x3c
3386****************************************************************************/
3387void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3388{
3389    u8 srcval;
3390
3391    START_OF_INSTR();
3392    DECODE_PRINTF("CMP\tAL,");
3393    srcval = fetch_byte_imm();
3394    DECODE_PRINTF2("%x\n", srcval);
3395    TRACE_AND_STEP();
3396    cmp_byte(M.x86.R_AL, srcval);
3397    DECODE_CLEAR_SEGOVR();
3398    END_OF_INSTR();
3399}
3400
3401/****************************************************************************
3402REMARKS:
3403Handles opcode 0x3d
3404****************************************************************************/
3405void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3406{
3407    u32 srcval;
3408
3409    START_OF_INSTR();
3410    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3411        DECODE_PRINTF("CMP\tEAX,");
3412        srcval = fetch_long_imm();
3413    } else {
3414        DECODE_PRINTF("CMP\tAX,");
3415        srcval = fetch_word_imm();
3416    }
3417    DECODE_PRINTF2("%x\n", srcval);
3418    TRACE_AND_STEP();
3419    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3420        cmp_long(M.x86.R_EAX, srcval);
3421    } else {
3422        cmp_word(M.x86.R_AX, (u16)srcval);
3423    }
3424    DECODE_CLEAR_SEGOVR();
3425    END_OF_INSTR();
3426}
3427
3428/****************************************************************************
3429REMARKS:
3430Handles opcode 0x3e
3431****************************************************************************/
3432void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3433{
3434    START_OF_INSTR();
3435    DECODE_PRINTF("DS:\n");
3436    TRACE_AND_STEP();
3437    M.x86.mode |= SYSMODE_SEGOVR_DS;
3438    /* NO DECODE_CLEAR_SEGOVR! */
3439    END_OF_INSTR();
3440}
3441
3442/****************************************************************************
3443REMARKS:
3444Handles opcode 0x3f
3445****************************************************************************/
3446void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3447{
3448    START_OF_INSTR();
3449    DECODE_PRINTF("AAS\n");
3450    TRACE_AND_STEP();
3451    M.x86.R_AX = aas_word(M.x86.R_AX);
3452    DECODE_CLEAR_SEGOVR();
3453    END_OF_INSTR();
3454}
3455
3456/****************************************************************************
3457REMARKS:
3458Handles opcode 0x40
3459****************************************************************************/
3460void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3461{
3462    START_OF_INSTR();
3463    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3464        DECODE_PRINTF("INC\tEAX\n");
3465    } else {
3466        DECODE_PRINTF("INC\tAX\n");
3467    }
3468    TRACE_AND_STEP();
3469    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3470        M.x86.R_EAX = inc_long(M.x86.R_EAX);
3471    } else {
3472        M.x86.R_AX = inc_word(M.x86.R_AX);
3473    }
3474    DECODE_CLEAR_SEGOVR();
3475    END_OF_INSTR();
3476}
3477
3478/****************************************************************************
3479REMARKS:
3480Handles opcode 0x41
3481****************************************************************************/
3482void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3483{
3484    START_OF_INSTR();
3485    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3486        DECODE_PRINTF("INC\tECX\n");
3487    } else {
3488        DECODE_PRINTF("INC\tCX\n");
3489    }
3490    TRACE_AND_STEP();
3491    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3492        M.x86.R_ECX = inc_long(M.x86.R_ECX);
3493    } else {
3494        M.x86.R_CX = inc_word(M.x86.R_CX);
3495    }
3496    DECODE_CLEAR_SEGOVR();
3497    END_OF_INSTR();
3498}
3499
3500/****************************************************************************
3501REMARKS:
3502Handles opcode 0x42
3503****************************************************************************/
3504void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3505{
3506    START_OF_INSTR();
3507    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3508        DECODE_PRINTF("INC\tEDX\n");
3509    } else {
3510        DECODE_PRINTF("INC\tDX\n");
3511    }
3512    TRACE_AND_STEP();
3513    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3514        M.x86.R_EDX = inc_long(M.x86.R_EDX);
3515    } else {
3516        M.x86.R_DX = inc_word(M.x86.R_DX);
3517    }
3518    DECODE_CLEAR_SEGOVR();
3519    END_OF_INSTR();
3520}
3521
3522/****************************************************************************
3523REMARKS:
3524Handles opcode 0x43
3525****************************************************************************/
3526void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3527{
3528    START_OF_INSTR();
3529    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3530        DECODE_PRINTF("INC\tEBX\n");
3531    } else {
3532        DECODE_PRINTF("INC\tBX\n");
3533    }
3534    TRACE_AND_STEP();
3535    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3536        M.x86.R_EBX = inc_long(M.x86.R_EBX);
3537    } else {
3538        M.x86.R_BX = inc_word(M.x86.R_BX);
3539    }
3540    DECODE_CLEAR_SEGOVR();
3541    END_OF_INSTR();
3542}
3543
3544/****************************************************************************
3545REMARKS:
3546Handles opcode 0x44
3547****************************************************************************/
3548void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3549{
3550    START_OF_INSTR();
3551    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3552        DECODE_PRINTF("INC\tESP\n");
3553    } else {
3554        DECODE_PRINTF("INC\tSP\n");
3555    }
3556    TRACE_AND_STEP();
3557    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3558        M.x86.R_ESP = inc_long(M.x86.R_ESP);
3559    } else {
3560        M.x86.R_SP = inc_word(M.x86.R_SP);
3561    }
3562    DECODE_CLEAR_SEGOVR();
3563    END_OF_INSTR();
3564}
3565
3566/****************************************************************************
3567REMARKS:
3568Handles opcode 0x45
3569****************************************************************************/
3570void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3571{
3572    START_OF_INSTR();
3573    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3574        DECODE_PRINTF("INC\tEBP\n");
3575    } else {
3576        DECODE_PRINTF("INC\tBP\n");
3577    }
3578    TRACE_AND_STEP();
3579    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3580        M.x86.R_EBP = inc_long(M.x86.R_EBP);
3581    } else {
3582        M.x86.R_BP = inc_word(M.x86.R_BP);
3583    }
3584    DECODE_CLEAR_SEGOVR();
3585    END_OF_INSTR();
3586}
3587
3588/****************************************************************************
3589REMARKS:
3590Handles opcode 0x46
3591****************************************************************************/
3592void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3593{
3594    START_OF_INSTR();
3595    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3596        DECODE_PRINTF("INC\tESI\n");
3597    } else {
3598        DECODE_PRINTF("INC\tSI\n");
3599    }
3600    TRACE_AND_STEP();
3601    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3602        M.x86.R_ESI = inc_long(M.x86.R_ESI);
3603    } else {
3604        M.x86.R_SI = inc_word(M.x86.R_SI);
3605    }
3606    DECODE_CLEAR_SEGOVR();
3607    END_OF_INSTR();
3608}
3609
3610/****************************************************************************
3611REMARKS:
3612Handles opcode 0x47
3613****************************************************************************/
3614void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3615{
3616    START_OF_INSTR();
3617    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3618        DECODE_PRINTF("INC\tEDI\n");
3619    } else {
3620        DECODE_PRINTF("INC\tDI\n");
3621    }
3622    TRACE_AND_STEP();
3623    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624        M.x86.R_EDI = inc_long(M.x86.R_EDI);
3625    } else {
3626        M.x86.R_DI = inc_word(M.x86.R_DI);
3627    }
3628    DECODE_CLEAR_SEGOVR();
3629    END_OF_INSTR();
3630}
3631
3632/****************************************************************************
3633REMARKS:
3634Handles opcode 0x48
3635****************************************************************************/
3636void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3637{
3638    START_OF_INSTR();
3639    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3640        DECODE_PRINTF("DEC\tEAX\n");
3641    } else {
3642        DECODE_PRINTF("DEC\tAX\n");
3643    }
3644    TRACE_AND_STEP();
3645    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3646        M.x86.R_EAX = dec_long(M.x86.R_EAX);
3647    } else {
3648        M.x86.R_AX = dec_word(M.x86.R_AX);
3649    }
3650    DECODE_CLEAR_SEGOVR();
3651    END_OF_INSTR();
3652}
3653
3654/****************************************************************************
3655REMARKS:
3656Handles opcode 0x49
3657****************************************************************************/
3658void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3659{
3660    START_OF_INSTR();
3661    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3662        DECODE_PRINTF("DEC\tECX\n");
3663    } else {
3664        DECODE_PRINTF("DEC\tCX\n");
3665    }
3666    TRACE_AND_STEP();
3667    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3668        M.x86.R_ECX = dec_long(M.x86.R_ECX);
3669    } else {
3670        M.x86.R_CX = dec_word(M.x86.R_CX);
3671    }
3672    DECODE_CLEAR_SEGOVR();
3673    END_OF_INSTR();
3674}
3675
3676/****************************************************************************
3677REMARKS:
3678Handles opcode 0x4a
3679****************************************************************************/
3680void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3681{
3682    START_OF_INSTR();
3683    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3684        DECODE_PRINTF("DEC\tEDX\n");
3685    } else {
3686        DECODE_PRINTF("DEC\tDX\n");
3687    }
3688    TRACE_AND_STEP();
3689    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3690        M.x86.R_EDX = dec_long(M.x86.R_EDX);
3691    } else {
3692        M.x86.R_DX = dec_word(M.x86.R_DX);
3693    }
3694    DECODE_CLEAR_SEGOVR();
3695    END_OF_INSTR();
3696}
3697
3698/****************************************************************************
3699REMARKS:
3700Handles opcode 0x4b
3701****************************************************************************/
3702void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3703{
3704    START_OF_INSTR();
3705    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3706        DECODE_PRINTF("DEC\tEBX\n");
3707    } else {
3708        DECODE_PRINTF("DEC\tBX\n");
3709    }
3710    TRACE_AND_STEP();
3711    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3712        M.x86.R_EBX = dec_long(M.x86.R_EBX);
3713    } else {
3714        M.x86.R_BX = dec_word(M.x86.R_BX);
3715    }
3716    DECODE_CLEAR_SEGOVR();
3717    END_OF_INSTR();
3718}
3719
3720/****************************************************************************
3721REMARKS:
3722Handles opcode 0x4c
3723****************************************************************************/
3724void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3725{
3726    START_OF_INSTR();
3727    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3728        DECODE_PRINTF("DEC\tESP\n");
3729    } else {
3730        DECODE_PRINTF("DEC\tSP\n");
3731    }
3732    TRACE_AND_STEP();
3733    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3734        M.x86.R_ESP = dec_long(M.x86.R_ESP);
3735    } else {
3736        M.x86.R_SP = dec_word(M.x86.R_SP);
3737    }
3738    DECODE_CLEAR_SEGOVR();
3739    END_OF_INSTR();
3740}
3741
3742/****************************************************************************
3743REMARKS:
3744Handles opcode 0x4d
3745****************************************************************************/
3746void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3747{
3748    START_OF_INSTR();
3749    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3750        DECODE_PRINTF("DEC\tEBP\n");
3751    } else {
3752        DECODE_PRINTF("DEC\tBP\n");
3753    }
3754    TRACE_AND_STEP();
3755    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3756        M.x86.R_EBP = dec_long(M.x86.R_EBP);
3757    } else {
3758        M.x86.R_BP = dec_word(M.x86.R_BP);
3759    }
3760    DECODE_CLEAR_SEGOVR();
3761    END_OF_INSTR();
3762}
3763
3764/****************************************************************************
3765REMARKS:
3766Handles opcode 0x4e
3767****************************************************************************/
3768void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3769{
3770    START_OF_INSTR();
3771    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3772        DECODE_PRINTF("DEC\tESI\n");
3773    } else {
3774        DECODE_PRINTF("DEC\tSI\n");
3775    }
3776    TRACE_AND_STEP();
3777    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3778        M.x86.R_ESI = dec_long(M.x86.R_ESI);
3779    } else {
3780        M.x86.R_SI = dec_word(M.x86.R_SI);
3781    }
3782    DECODE_CLEAR_SEGOVR();
3783    END_OF_INSTR();
3784}
3785
3786/****************************************************************************
3787REMARKS:
3788Handles opcode 0x4f
3789****************************************************************************/
3790void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3791{
3792    START_OF_INSTR();
3793    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3794        DECODE_PRINTF("DEC\tEDI\n");
3795    } else {
3796        DECODE_PRINTF("DEC\tDI\n");
3797    }
3798    TRACE_AND_STEP();
3799    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3800        M.x86.R_EDI = dec_long(M.x86.R_EDI);
3801    } else {
3802        M.x86.R_DI = dec_word(M.x86.R_DI);
3803    }
3804    DECODE_CLEAR_SEGOVR();
3805    END_OF_INSTR();
3806}
3807
3808/****************************************************************************
3809REMARKS:
3810Handles opcode 0x50
3811****************************************************************************/
3812void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3813{
3814    START_OF_INSTR();
3815    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3816        DECODE_PRINTF("PUSH\tEAX\n");
3817    } else {
3818        DECODE_PRINTF("PUSH\tAX\n");
3819    }
3820    TRACE_AND_STEP();
3821    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3822        push_long(M.x86.R_EAX);
3823    } else {
3824        push_word(M.x86.R_AX);
3825    }
3826    DECODE_CLEAR_SEGOVR();
3827    END_OF_INSTR();
3828}
3829
3830/****************************************************************************
3831REMARKS:
3832Handles opcode 0x51
3833****************************************************************************/
3834void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3835{
3836    START_OF_INSTR();
3837    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3838        DECODE_PRINTF("PUSH\tECX\n");
3839    } else {
3840        DECODE_PRINTF("PUSH\tCX\n");
3841    }
3842    TRACE_AND_STEP();
3843    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3844        push_long(M.x86.R_ECX);
3845    } else {
3846        push_word(M.x86.R_CX);
3847    }
3848    DECODE_CLEAR_SEGOVR();
3849    END_OF_INSTR();
3850}
3851
3852/****************************************************************************
3853REMARKS:
3854Handles opcode 0x52
3855****************************************************************************/
3856void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3857{
3858    START_OF_INSTR();
3859    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3860        DECODE_PRINTF("PUSH\tEDX\n");
3861    } else {
3862        DECODE_PRINTF("PUSH\tDX\n");
3863    }
3864    TRACE_AND_STEP();
3865    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3866        push_long(M.x86.R_EDX);
3867    } else {
3868        push_word(M.x86.R_DX);
3869    }
3870    DECODE_CLEAR_SEGOVR();
3871    END_OF_INSTR();
3872}
3873
3874/****************************************************************************
3875REMARKS:
3876Handles opcode 0x53
3877****************************************************************************/
3878void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3879{
3880    START_OF_INSTR();
3881    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3882        DECODE_PRINTF("PUSH\tEBX\n");
3883    } else {
3884        DECODE_PRINTF("PUSH\tBX\n");
3885    }
3886    TRACE_AND_STEP();
3887    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3888        push_long(M.x86.R_EBX);
3889    } else {
3890        push_word(M.x86.R_BX);
3891    }
3892    DECODE_CLEAR_SEGOVR();
3893    END_OF_INSTR();
3894}
3895
3896/****************************************************************************
3897REMARKS:
3898Handles opcode 0x54
3899****************************************************************************/
3900void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3901{
3902    START_OF_INSTR();
3903    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3904        DECODE_PRINTF("PUSH\tESP\n");
3905    } else {
3906        DECODE_PRINTF("PUSH\tSP\n");
3907    }
3908    TRACE_AND_STEP();
3909	/* Always push (E)SP, since we are emulating an i386 and above
3910	 * processor. This is necessary as some BIOS'es use this to check
3911	 * what type of processor is in the system.
3912	 */
3913	if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3914		push_long(M.x86.R_ESP);
3915	} else {
3916		push_word((u16)(M.x86.R_SP));
3917    }
3918    DECODE_CLEAR_SEGOVR();
3919    END_OF_INSTR();
3920}
3921
3922/****************************************************************************
3923REMARKS:
3924Handles opcode 0x55
3925****************************************************************************/
3926void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3927{
3928    START_OF_INSTR();
3929    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3930        DECODE_PRINTF("PUSH\tEBP\n");
3931    } else {
3932        DECODE_PRINTF("PUSH\tBP\n");
3933    }
3934    TRACE_AND_STEP();
3935    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3936        push_long(M.x86.R_EBP);
3937    } else {
3938        push_word(M.x86.R_BP);
3939    }
3940    DECODE_CLEAR_SEGOVR();
3941    END_OF_INSTR();
3942}
3943
3944/****************************************************************************
3945REMARKS:
3946Handles opcode 0x56
3947****************************************************************************/
3948void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3949{
3950    START_OF_INSTR();
3951    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3952        DECODE_PRINTF("PUSH\tESI\n");
3953    } else {
3954        DECODE_PRINTF("PUSH\tSI\n");
3955    }
3956    TRACE_AND_STEP();
3957    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3958        push_long(M.x86.R_ESI);
3959    } else {
3960        push_word(M.x86.R_SI);
3961    }
3962    DECODE_CLEAR_SEGOVR();
3963    END_OF_INSTR();
3964}
3965
3966/****************************************************************************
3967REMARKS:
3968Handles opcode 0x57
3969****************************************************************************/
3970void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3971{
3972    START_OF_INSTR();
3973    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974        DECODE_PRINTF("PUSH\tEDI\n");
3975    } else {
3976        DECODE_PRINTF("PUSH\tDI\n");
3977    }
3978    TRACE_AND_STEP();
3979    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3980        push_long(M.x86.R_EDI);
3981    } else {
3982        push_word(M.x86.R_DI);
3983    }
3984    DECODE_CLEAR_SEGOVR();
3985    END_OF_INSTR();
3986}
3987
3988/****************************************************************************
3989REMARKS:
3990Handles opcode 0x58
3991****************************************************************************/
3992void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
3993{
3994    START_OF_INSTR();
3995    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3996        DECODE_PRINTF("POP\tEAX\n");
3997    } else {
3998        DECODE_PRINTF("POP\tAX\n");
3999    }
4000    TRACE_AND_STEP();
4001    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4002        M.x86.R_EAX = pop_long();
4003    } else {
4004        M.x86.R_AX = pop_word();
4005    }
4006    DECODE_CLEAR_SEGOVR();
4007    END_OF_INSTR();
4008}
4009
4010/****************************************************************************
4011REMARKS:
4012Handles opcode 0x59
4013****************************************************************************/
4014void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4015{
4016    START_OF_INSTR();
4017    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4018        DECODE_PRINTF("POP\tECX\n");
4019    } else {
4020        DECODE_PRINTF("POP\tCX\n");
4021    }
4022    TRACE_AND_STEP();
4023    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024        M.x86.R_ECX = pop_long();
4025    } else {
4026        M.x86.R_CX = pop_word();
4027    }
4028    DECODE_CLEAR_SEGOVR();
4029    END_OF_INSTR();
4030}
4031
4032/****************************************************************************
4033REMARKS:
4034Handles opcode 0x5a
4035****************************************************************************/
4036void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4037{
4038    START_OF_INSTR();
4039    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4040        DECODE_PRINTF("POP\tEDX\n");
4041    } else {
4042        DECODE_PRINTF("POP\tDX\n");
4043    }
4044    TRACE_AND_STEP();
4045    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4046        M.x86.R_EDX = pop_long();
4047    } else {
4048        M.x86.R_DX = pop_word();
4049    }
4050    DECODE_CLEAR_SEGOVR();
4051    END_OF_INSTR();
4052}
4053
4054/****************************************************************************
4055REMARKS:
4056Handles opcode 0x5b
4057****************************************************************************/
4058void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4059{
4060    START_OF_INSTR();
4061    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4062        DECODE_PRINTF("POP\tEBX\n");
4063    } else {
4064        DECODE_PRINTF("POP\tBX\n");
4065    }
4066    TRACE_AND_STEP();
4067    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4068        M.x86.R_EBX = pop_long();
4069    } else {
4070        M.x86.R_BX = pop_word();
4071    }
4072    DECODE_CLEAR_SEGOVR();
4073    END_OF_INSTR();
4074}
4075
4076/****************************************************************************
4077REMARKS:
4078Handles opcode 0x5c
4079****************************************************************************/
4080void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4081{
4082    START_OF_INSTR();
4083    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4084        DECODE_PRINTF("POP\tESP\n");
4085    } else {
4086        DECODE_PRINTF("POP\tSP\n");
4087    }
4088    TRACE_AND_STEP();
4089    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4090        M.x86.R_ESP = pop_long();
4091    } else {
4092        M.x86.R_SP = pop_word();
4093    }
4094    DECODE_CLEAR_SEGOVR();
4095    END_OF_INSTR();
4096}
4097
4098/****************************************************************************
4099REMARKS:
4100Handles opcode 0x5d
4101****************************************************************************/
4102void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4103{
4104    START_OF_INSTR();
4105    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4106        DECODE_PRINTF("POP\tEBP\n");
4107    } else {
4108        DECODE_PRINTF("POP\tBP\n");
4109    }
4110    TRACE_AND_STEP();
4111    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4112        M.x86.R_EBP = pop_long();
4113    } else {
4114        M.x86.R_BP = pop_word();
4115    }
4116    DECODE_CLEAR_SEGOVR();
4117    END_OF_INSTR();
4118}
4119
4120/****************************************************************************
4121REMARKS:
4122Handles opcode 0x5e
4123****************************************************************************/
4124void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4125{
4126    START_OF_INSTR();
4127    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128        DECODE_PRINTF("POP\tESI\n");
4129    } else {
4130        DECODE_PRINTF("POP\tSI\n");
4131    }
4132    TRACE_AND_STEP();
4133    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4134        M.x86.R_ESI = pop_long();
4135    } else {
4136        M.x86.R_SI = pop_word();
4137    }
4138    DECODE_CLEAR_SEGOVR();
4139    END_OF_INSTR();
4140}
4141
4142/****************************************************************************
4143REMARKS:
4144Handles opcode 0x5f
4145****************************************************************************/
4146void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4147{
4148    START_OF_INSTR();
4149    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4150        DECODE_PRINTF("POP\tEDI\n");
4151    } else {
4152        DECODE_PRINTF("POP\tDI\n");
4153    }
4154    TRACE_AND_STEP();
4155    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4156        M.x86.R_EDI = pop_long();
4157    } else {
4158        M.x86.R_DI = pop_word();
4159    }
4160    DECODE_CLEAR_SEGOVR();
4161    END_OF_INSTR();
4162}
4163
4164/****************************************************************************
4165REMARKS:
4166Handles opcode 0x60
4167****************************************************************************/
4168void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4169{
4170    START_OF_INSTR();
4171    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4172        DECODE_PRINTF("PUSHAD\n");
4173    } else {
4174        DECODE_PRINTF("PUSHA\n");
4175    }
4176    TRACE_AND_STEP();
4177    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178        u32 old_sp = M.x86.R_ESP;
4179
4180        push_long(M.x86.R_EAX);
4181        push_long(M.x86.R_ECX);
4182        push_long(M.x86.R_EDX);
4183        push_long(M.x86.R_EBX);
4184        push_long(old_sp);
4185        push_long(M.x86.R_EBP);
4186        push_long(M.x86.R_ESI);
4187        push_long(M.x86.R_EDI);
4188    } else {
4189        u16 old_sp = M.x86.R_SP;
4190
4191        push_word(M.x86.R_AX);
4192        push_word(M.x86.R_CX);
4193        push_word(M.x86.R_DX);
4194        push_word(M.x86.R_BX);
4195        push_word(old_sp);
4196        push_word(M.x86.R_BP);
4197        push_word(M.x86.R_SI);
4198        push_word(M.x86.R_DI);
4199    }
4200    DECODE_CLEAR_SEGOVR();
4201    END_OF_INSTR();
4202}
4203
4204/****************************************************************************
4205REMARKS:
4206Handles opcode 0x61
4207****************************************************************************/
4208void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4209{
4210    START_OF_INSTR();
4211    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4212        DECODE_PRINTF("POPAD\n");
4213    } else {
4214        DECODE_PRINTF("POPA\n");
4215    }
4216    TRACE_AND_STEP();
4217    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4218        M.x86.R_EDI = pop_long();
4219        M.x86.R_ESI = pop_long();
4220        M.x86.R_EBP = pop_long();
4221        M.x86.R_ESP += 4;              /* skip ESP */
4222        M.x86.R_EBX = pop_long();
4223        M.x86.R_EDX = pop_long();
4224        M.x86.R_ECX = pop_long();
4225        M.x86.R_EAX = pop_long();
4226    } else {
4227        M.x86.R_DI = pop_word();
4228        M.x86.R_SI = pop_word();
4229        M.x86.R_BP = pop_word();
4230        M.x86.R_SP += 2;               /* skip SP */
4231        M.x86.R_BX = pop_word();
4232        M.x86.R_DX = pop_word();
4233        M.x86.R_CX = pop_word();
4234        M.x86.R_AX = pop_word();
4235    }
4236    DECODE_CLEAR_SEGOVR();
4237    END_OF_INSTR();
4238}
4239
4240/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4241/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4242
4243/****************************************************************************
4244REMARKS:
4245Handles opcode 0x64
4246****************************************************************************/
4247void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4248{
4249    START_OF_INSTR();
4250    DECODE_PRINTF("FS:\n");
4251    TRACE_AND_STEP();
4252    M.x86.mode |= SYSMODE_SEGOVR_FS;
4253    /*
4254     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4255     * opcode subroutines we do not want to do this.
4256     */
4257    END_OF_INSTR();
4258}
4259
4260/****************************************************************************
4261REMARKS:
4262Handles opcode 0x65
4263****************************************************************************/
4264void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4265{
4266    START_OF_INSTR();
4267    DECODE_PRINTF("GS:\n");
4268    TRACE_AND_STEP();
4269    M.x86.mode |= SYSMODE_SEGOVR_GS;
4270    /*
4271     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4272     * opcode subroutines we do not want to do this.
4273     */
4274    END_OF_INSTR();
4275}
4276
4277/****************************************************************************
4278REMARKS:
4279Handles opcode 0x66 - prefix for 32-bit register
4280****************************************************************************/
4281void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4282{
4283    START_OF_INSTR();
4284    DECODE_PRINTF("DATA:\n");
4285    TRACE_AND_STEP();
4286    M.x86.mode |= SYSMODE_PREFIX_DATA;
4287    /* note no DECODE_CLEAR_SEGOVR here. */
4288    END_OF_INSTR();
4289}
4290
4291/****************************************************************************
4292REMARKS:
4293Handles opcode 0x67 - prefix for 32-bit address
4294****************************************************************************/
4295void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4296{
4297    START_OF_INSTR();
4298    DECODE_PRINTF("ADDR:\n");
4299    TRACE_AND_STEP();
4300    M.x86.mode |= SYSMODE_PREFIX_ADDR;
4301    /* note no DECODE_CLEAR_SEGOVR here. */
4302    END_OF_INSTR();
4303}
4304
4305/****************************************************************************
4306REMARKS:
4307Handles opcode 0x68
4308****************************************************************************/
4309void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4310{
4311    u32 imm;
4312
4313    START_OF_INSTR();
4314    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4315        imm = fetch_long_imm();
4316    } else {
4317        imm = fetch_word_imm();
4318    }
4319    DECODE_PRINTF2("PUSH\t%x\n", imm);
4320    TRACE_AND_STEP();
4321    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322        push_long(imm);
4323    } else {
4324        push_word((u16)imm);
4325    }
4326    DECODE_CLEAR_SEGOVR();
4327    END_OF_INSTR();
4328}
4329
4330/****************************************************************************
4331REMARKS:
4332Handles opcode 0x69
4333****************************************************************************/
4334void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4335{
4336    int mod, rl, rh;
4337    uint srcoffset;
4338
4339    START_OF_INSTR();
4340    DECODE_PRINTF("IMUL\t");
4341    FETCH_DECODE_MODRM(mod, rh, rl);
4342    switch (mod) {
4343    case 0:
4344        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4345            u32 *destreg;
4346            u32 srcval;
4347            u32 res_lo,res_hi;
4348            s32 imm;
4349
4350            destreg = DECODE_RM_LONG_REGISTER(rh);
4351            DECODE_PRINTF(",");
4352            srcoffset = decode_rm00_address(rl);
4353            srcval = fetch_data_long(srcoffset);
4354            imm = fetch_long_imm();
4355            DECODE_PRINTF2(",%d\n", (s32)imm);
4356            TRACE_AND_STEP();
4357            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4358            if (res_hi != 0) {
4359                SET_FLAG(F_CF);
4360                SET_FLAG(F_OF);
4361            } else {
4362                CLEAR_FLAG(F_CF);
4363                CLEAR_FLAG(F_OF);
4364            }
4365            *destreg = (u32)res_lo;
4366        } else {
4367            u16 *destreg;
4368            u16 srcval;
4369            u32 res;
4370            s16 imm;
4371
4372            destreg = DECODE_RM_WORD_REGISTER(rh);
4373            DECODE_PRINTF(",");
4374            srcoffset = decode_rm00_address(rl);
4375            srcval = fetch_data_word(srcoffset);
4376            imm = fetch_word_imm();
4377            DECODE_PRINTF2(",%d\n", (s32)imm);
4378            TRACE_AND_STEP();
4379            res = (s16)srcval * (s16)imm;
4380            if (res > 0xFFFF) {
4381                SET_FLAG(F_CF);
4382                SET_FLAG(F_OF);
4383            } else {
4384                CLEAR_FLAG(F_CF);
4385                CLEAR_FLAG(F_OF);
4386            }
4387            *destreg = (u16)res;
4388        }
4389        break;
4390    case 1:
4391        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4392            u32 *destreg;
4393            u32 srcval;
4394            u32 res_lo,res_hi;
4395            s32 imm;
4396
4397            destreg = DECODE_RM_LONG_REGISTER(rh);
4398            DECODE_PRINTF(",");
4399            srcoffset = decode_rm01_address(rl);
4400            srcval = fetch_data_long(srcoffset);
4401            imm = fetch_long_imm();
4402            DECODE_PRINTF2(",%d\n", (s32)imm);
4403            TRACE_AND_STEP();
4404            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4405            if (res_hi != 0) {
4406                SET_FLAG(F_CF);
4407                SET_FLAG(F_OF);
4408            } else {
4409                CLEAR_FLAG(F_CF);
4410                CLEAR_FLAG(F_OF);
4411            }
4412            *destreg = (u32)res_lo;
4413        } else {
4414            u16 *destreg;
4415            u16 srcval;
4416            u32 res;
4417            s16 imm;
4418
4419            destreg = DECODE_RM_WORD_REGISTER(rh);
4420            DECODE_PRINTF(",");
4421            srcoffset = decode_rm01_address(rl);
4422            srcval = fetch_data_word(srcoffset);
4423            imm = fetch_word_imm();
4424            DECODE_PRINTF2(",%d\n", (s32)imm);
4425            TRACE_AND_STEP();
4426            res = (s16)srcval * (s16)imm;
4427            if (res > 0xFFFF) {
4428                SET_FLAG(F_CF);
4429                SET_FLAG(F_OF);
4430            } else {
4431                CLEAR_FLAG(F_CF);
4432                CLEAR_FLAG(F_OF);
4433            }
4434            *destreg = (u16)res;
4435        }
4436        break;
4437    case 2:
4438        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4439            u32 *destreg;
4440            u32 srcval;
4441            u32 res_lo,res_hi;
4442            s32 imm;
4443
4444            destreg = DECODE_RM_LONG_REGISTER(rh);
4445            DECODE_PRINTF(",");
4446            srcoffset = decode_rm10_address(rl);
4447            srcval = fetch_data_long(srcoffset);
4448            imm = fetch_long_imm();
4449            DECODE_PRINTF2(",%d\n", (s32)imm);
4450            TRACE_AND_STEP();
4451            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4452            if (res_hi != 0) {
4453                SET_FLAG(F_CF);
4454                SET_FLAG(F_OF);
4455            } else {
4456                CLEAR_FLAG(F_CF);
4457                CLEAR_FLAG(F_OF);
4458            }
4459            *destreg = (u32)res_lo;
4460        } else {
4461            u16 *destreg;
4462            u16 srcval;
4463            u32 res;
4464            s16 imm;
4465
4466            destreg = DECODE_RM_WORD_REGISTER(rh);
4467            DECODE_PRINTF(",");
4468            srcoffset = decode_rm10_address(rl);
4469            srcval = fetch_data_word(srcoffset);
4470            imm = fetch_word_imm();
4471            DECODE_PRINTF2(",%d\n", (s32)imm);
4472            TRACE_AND_STEP();
4473            res = (s16)srcval * (s16)imm;
4474            if (res > 0xFFFF) {
4475                SET_FLAG(F_CF);
4476                SET_FLAG(F_OF);
4477            } else {
4478                CLEAR_FLAG(F_CF);
4479                CLEAR_FLAG(F_OF);
4480            }
4481            *destreg = (u16)res;
4482        }
4483        break;
4484    case 3:                     /* register to register */
4485        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4486            u32 *destreg,*srcreg;
4487            u32 res_lo,res_hi;
4488            s32 imm;
4489
4490            destreg = DECODE_RM_LONG_REGISTER(rh);
4491            DECODE_PRINTF(",");
4492            srcreg = DECODE_RM_LONG_REGISTER(rl);
4493            imm = fetch_long_imm();
4494            DECODE_PRINTF2(",%d\n", (s32)imm);
4495            TRACE_AND_STEP();
4496            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4497            if (res_hi != 0) {
4498                SET_FLAG(F_CF);
4499                SET_FLAG(F_OF);
4500            } else {
4501                CLEAR_FLAG(F_CF);
4502                CLEAR_FLAG(F_OF);
4503            }
4504            *destreg = (u32)res_lo;
4505        } else {
4506            u16 *destreg,*srcreg;
4507            u32 res;
4508            s16 imm;
4509
4510            destreg = DECODE_RM_WORD_REGISTER(rh);
4511            DECODE_PRINTF(",");
4512            srcreg = DECODE_RM_WORD_REGISTER(rl);
4513            imm = fetch_word_imm();
4514            DECODE_PRINTF2(",%d\n", (s32)imm);
4515            res = (s16)*srcreg * (s16)imm;
4516            if (res > 0xFFFF) {
4517                SET_FLAG(F_CF);
4518                SET_FLAG(F_OF);
4519            } else {
4520                CLEAR_FLAG(F_CF);
4521                CLEAR_FLAG(F_OF);
4522            }
4523            *destreg = (u16)res;
4524        }
4525        break;
4526    }
4527    DECODE_CLEAR_SEGOVR();
4528    END_OF_INSTR();
4529}
4530
4531/****************************************************************************
4532REMARKS:
4533Handles opcode 0x6a
4534****************************************************************************/
4535void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4536{
4537    s16 imm;
4538
4539    START_OF_INSTR();
4540    imm = (s8)fetch_byte_imm();
4541    DECODE_PRINTF2("PUSH\t%d\n", imm);
4542    TRACE_AND_STEP();
4543    push_word(imm);
4544    DECODE_CLEAR_SEGOVR();
4545    END_OF_INSTR();
4546}
4547
4548/****************************************************************************
4549REMARKS:
4550Handles opcode 0x6b
4551****************************************************************************/
4552void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4553{
4554    int mod, rl, rh;
4555    uint srcoffset;
4556    s8  imm;
4557
4558    START_OF_INSTR();
4559    DECODE_PRINTF("IMUL\t");
4560    FETCH_DECODE_MODRM(mod, rh, rl);
4561    switch (mod) {
4562    case 0:
4563        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4564            u32 *destreg;
4565            u32 srcval;
4566            u32 res_lo,res_hi;
4567
4568            destreg = DECODE_RM_LONG_REGISTER(rh);
4569            DECODE_PRINTF(",");
4570            srcoffset = decode_rm00_address(rl);
4571            srcval = fetch_data_long(srcoffset);
4572            imm = fetch_byte_imm();
4573            DECODE_PRINTF2(",%d\n", (s32)imm);
4574            TRACE_AND_STEP();
4575            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4576            if (res_hi != 0) {
4577                SET_FLAG(F_CF);
4578                SET_FLAG(F_OF);
4579            } else {
4580                CLEAR_FLAG(F_CF);
4581                CLEAR_FLAG(F_OF);
4582            }
4583            *destreg = (u32)res_lo;
4584        } else {
4585            u16 *destreg;
4586            u16 srcval;
4587            u32 res;
4588
4589            destreg = DECODE_RM_WORD_REGISTER(rh);
4590            DECODE_PRINTF(",");
4591            srcoffset = decode_rm00_address(rl);
4592            srcval = fetch_data_word(srcoffset);
4593            imm = fetch_byte_imm();
4594            DECODE_PRINTF2(",%d\n", (s32)imm);
4595            TRACE_AND_STEP();
4596            res = (s16)srcval * (s16)imm;
4597            if (res > 0xFFFF) {
4598                SET_FLAG(F_CF);
4599                SET_FLAG(F_OF);
4600            } else {
4601                CLEAR_FLAG(F_CF);
4602                CLEAR_FLAG(F_OF);
4603            }
4604            *destreg = (u16)res;
4605        }
4606        break;
4607    case 1:
4608        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4609            u32 *destreg;
4610            u32 srcval;
4611            u32 res_lo,res_hi;
4612
4613            destreg = DECODE_RM_LONG_REGISTER(rh);
4614            DECODE_PRINTF(",");
4615            srcoffset = decode_rm01_address(rl);
4616            srcval = fetch_data_long(srcoffset);
4617            imm = fetch_byte_imm();
4618            DECODE_PRINTF2(",%d\n", (s32)imm);
4619            TRACE_AND_STEP();
4620            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4621            if (res_hi != 0) {
4622                SET_FLAG(F_CF);
4623                SET_FLAG(F_OF);
4624            } else {
4625                CLEAR_FLAG(F_CF);
4626                CLEAR_FLAG(F_OF);
4627            }
4628            *destreg = (u32)res_lo;
4629        } else {
4630            u16 *destreg;
4631            u16 srcval;
4632            u32 res;
4633
4634            destreg = DECODE_RM_WORD_REGISTER(rh);
4635            DECODE_PRINTF(",");
4636            srcoffset = decode_rm01_address(rl);
4637            srcval = fetch_data_word(srcoffset);
4638            imm = fetch_byte_imm();
4639            DECODE_PRINTF2(",%d\n", (s32)imm);
4640            TRACE_AND_STEP();
4641            res = (s16)srcval * (s16)imm;
4642            if (res > 0xFFFF) {
4643                SET_FLAG(F_CF);
4644                SET_FLAG(F_OF);
4645            } else {
4646                CLEAR_FLAG(F_CF);
4647                CLEAR_FLAG(F_OF);
4648            }
4649            *destreg = (u16)res;
4650        }
4651        break;
4652    case 2:
4653        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4654            u32 *destreg;
4655            u32 srcval;
4656            u32 res_lo,res_hi;
4657
4658            destreg = DECODE_RM_LONG_REGISTER(rh);
4659            DECODE_PRINTF(",");
4660            srcoffset = decode_rm10_address(rl);
4661            srcval = fetch_data_long(srcoffset);
4662            imm = fetch_byte_imm();
4663            DECODE_PRINTF2(",%d\n", (s32)imm);
4664            TRACE_AND_STEP();
4665            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4666            if (res_hi != 0) {
4667                SET_FLAG(F_CF);
4668                SET_FLAG(F_OF);
4669            } else {
4670                CLEAR_FLAG(F_CF);
4671                CLEAR_FLAG(F_OF);
4672            }
4673            *destreg = (u32)res_lo;
4674        } else {
4675            u16 *destreg;
4676            u16 srcval;
4677            u32 res;
4678
4679            destreg = DECODE_RM_WORD_REGISTER(rh);
4680            DECODE_PRINTF(",");
4681            srcoffset = decode_rm10_address(rl);
4682            srcval = fetch_data_word(srcoffset);
4683            imm = fetch_byte_imm();
4684            DECODE_PRINTF2(",%d\n", (s32)imm);
4685            TRACE_AND_STEP();
4686            res = (s16)srcval * (s16)imm;
4687            if (res > 0xFFFF) {
4688                SET_FLAG(F_CF);
4689                SET_FLAG(F_OF);
4690            } else {
4691                CLEAR_FLAG(F_CF);
4692                CLEAR_FLAG(F_OF);
4693            }
4694            *destreg = (u16)res;
4695        }
4696        break;
4697    case 3:                     /* register to register */
4698        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4699            u32 *destreg,*srcreg;
4700            u32 res_lo,res_hi;
4701
4702            destreg = DECODE_RM_LONG_REGISTER(rh);
4703            DECODE_PRINTF(",");
4704            srcreg = DECODE_RM_LONG_REGISTER(rl);
4705            imm = fetch_byte_imm();
4706            DECODE_PRINTF2(",%d\n", (s32)imm);
4707            TRACE_AND_STEP();
4708            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4709            if (res_hi != 0) {
4710                SET_FLAG(F_CF);
4711                SET_FLAG(F_OF);
4712            } else {
4713                CLEAR_FLAG(F_CF);
4714                CLEAR_FLAG(F_OF);
4715            }
4716            *destreg = (u32)res_lo;
4717        } else {
4718            u16 *destreg,*srcreg;
4719            u32 res;
4720
4721            destreg = DECODE_RM_WORD_REGISTER(rh);
4722            DECODE_PRINTF(",");
4723            srcreg = DECODE_RM_WORD_REGISTER(rl);
4724            imm = fetch_byte_imm();
4725            DECODE_PRINTF2(",%d\n", (s32)imm);
4726            res = (s16)*srcreg * (s16)imm;
4727            if (res > 0xFFFF) {
4728                SET_FLAG(F_CF);
4729                SET_FLAG(F_OF);
4730            } else {
4731                CLEAR_FLAG(F_CF);
4732                CLEAR_FLAG(F_OF);
4733            }
4734            *destreg = (u16)res;
4735        }
4736        break;
4737    }
4738    DECODE_CLEAR_SEGOVR();
4739    END_OF_INSTR();
4740}
4741
4742/****************************************************************************
4743REMARKS:
4744Handles opcode 0x6c
4745****************************************************************************/
4746void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4747{
4748    START_OF_INSTR();
4749    DECODE_PRINTF("INSB\n");
4750    ins(1);
4751    TRACE_AND_STEP();
4752    DECODE_CLEAR_SEGOVR();
4753    END_OF_INSTR();
4754}
4755
4756/****************************************************************************
4757REMARKS:
4758Handles opcode 0x6d
4759****************************************************************************/
4760void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4761{
4762    START_OF_INSTR();
4763    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4764        DECODE_PRINTF("INSD\n");
4765        ins(4);
4766    } else {
4767        DECODE_PRINTF("INSW\n");
4768        ins(2);
4769    }
4770    TRACE_AND_STEP();
4771    DECODE_CLEAR_SEGOVR();
4772    END_OF_INSTR();
4773}
4774
4775/****************************************************************************
4776REMARKS:
4777Handles opcode 0x6e
4778****************************************************************************/
4779void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4780{
4781    START_OF_INSTR();
4782    DECODE_PRINTF("OUTSB\n");
4783    outs(1);
4784    TRACE_AND_STEP();
4785    DECODE_CLEAR_SEGOVR();
4786    END_OF_INSTR();
4787}
4788
4789/****************************************************************************
4790REMARKS:
4791Handles opcode 0x6f
4792****************************************************************************/
4793void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4794{
4795    START_OF_INSTR();
4796    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4797        DECODE_PRINTF("OUTSD\n");
4798        outs(4);
4799    } else {
4800        DECODE_PRINTF("OUTSW\n");
4801        outs(2);
4802    }
4803    TRACE_AND_STEP();
4804    DECODE_CLEAR_SEGOVR();
4805    END_OF_INSTR();
4806}
4807
4808/****************************************************************************
4809REMARKS:
4810Handles opcode 0x70
4811****************************************************************************/
4812void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4813{
4814    s8 offset;
4815    u16 target;
4816
4817    /* jump to byte offset if overflow flag is set */
4818    START_OF_INSTR();
4819    DECODE_PRINTF("JO\t");
4820    offset = (s8)fetch_byte_imm();
4821    target = (u16)(M.x86.R_IP + (s16)offset);
4822    DECODE_PRINTF2("%x\n", target);
4823    TRACE_AND_STEP();
4824    if (ACCESS_FLAG(F_OF))
4825        M.x86.R_IP = target;
4826    DECODE_CLEAR_SEGOVR();
4827    END_OF_INSTR();
4828}
4829
4830/****************************************************************************
4831REMARKS:
4832Handles opcode 0x71
4833****************************************************************************/
4834void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4835{
4836    s8 offset;
4837    u16 target;
4838
4839    /* jump to byte offset if overflow is not set */
4840    START_OF_INSTR();
4841    DECODE_PRINTF("JNO\t");
4842    offset = (s8)fetch_byte_imm();
4843    target = (u16)(M.x86.R_IP + (s16)offset);
4844    DECODE_PRINTF2("%x\n", target);
4845    TRACE_AND_STEP();
4846    if (!ACCESS_FLAG(F_OF))
4847        M.x86.R_IP = target;
4848    DECODE_CLEAR_SEGOVR();
4849    END_OF_INSTR();
4850}
4851
4852/****************************************************************************
4853REMARKS:
4854Handles opcode 0x72
4855****************************************************************************/
4856void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4857{
4858    s8 offset;
4859    u16 target;
4860
4861    /* jump to byte offset if carry flag is set. */
4862    START_OF_INSTR();
4863    DECODE_PRINTF("JB\t");
4864    offset = (s8)fetch_byte_imm();
4865    target = (u16)(M.x86.R_IP + (s16)offset);
4866    DECODE_PRINTF2("%x\n", target);
4867    TRACE_AND_STEP();
4868    if (ACCESS_FLAG(F_CF))
4869        M.x86.R_IP = target;
4870    DECODE_CLEAR_SEGOVR();
4871    END_OF_INSTR();
4872}
4873
4874/****************************************************************************
4875REMARKS:
4876Handles opcode 0x73
4877****************************************************************************/
4878void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4879{
4880    s8 offset;
4881    u16 target;
4882
4883    /* jump to byte offset if carry flag is clear. */
4884    START_OF_INSTR();
4885    DECODE_PRINTF("JNB\t");
4886    offset = (s8)fetch_byte_imm();
4887    target = (u16)(M.x86.R_IP + (s16)offset);
4888    DECODE_PRINTF2("%x\n", target);
4889    TRACE_AND_STEP();
4890    if (!ACCESS_FLAG(F_CF))
4891        M.x86.R_IP = target;
4892    DECODE_CLEAR_SEGOVR();
4893    END_OF_INSTR();
4894}
4895
4896/****************************************************************************
4897REMARKS:
4898Handles opcode 0x74
4899****************************************************************************/
4900void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4901{
4902    s8 offset;
4903    u16 target;
4904
4905    /* jump to byte offset if zero flag is set. */
4906    START_OF_INSTR();
4907    DECODE_PRINTF("JZ\t");
4908    offset = (s8)fetch_byte_imm();
4909    target = (u16)(M.x86.R_IP + (s16)offset);
4910    DECODE_PRINTF2("%x\n", target);
4911    TRACE_AND_STEP();
4912    if (ACCESS_FLAG(F_ZF))
4913        M.x86.R_IP = target;
4914    DECODE_CLEAR_SEGOVR();
4915    END_OF_INSTR();
4916}
4917
4918/****************************************************************************
4919REMARKS:
4920Handles opcode 0x75
4921****************************************************************************/
4922void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4923{
4924    s8 offset;
4925    u16 target;
4926
4927    /* jump to byte offset if zero flag is clear. */
4928    START_OF_INSTR();
4929    DECODE_PRINTF("JNZ\t");
4930    offset = (s8)fetch_byte_imm();
4931    target = (u16)(M.x86.R_IP + (s16)offset);
4932    DECODE_PRINTF2("%x\n", target);
4933    TRACE_AND_STEP();
4934    if (!ACCESS_FLAG(F_ZF))
4935        M.x86.R_IP = target;
4936    DECODE_CLEAR_SEGOVR();
4937    END_OF_INSTR();
4938}
4939
4940/****************************************************************************
4941REMARKS:
4942Handles opcode 0x76
4943****************************************************************************/
4944void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4945{
4946    s8 offset;
4947    u16 target;
4948
4949    /* jump to byte offset if carry flag is set or if the zero
4950       flag is set. */
4951    START_OF_INSTR();
4952    DECODE_PRINTF("JBE\t");
4953    offset = (s8)fetch_byte_imm();
4954    target = (u16)(M.x86.R_IP + (s16)offset);
4955    DECODE_PRINTF2("%x\n", target);
4956    TRACE_AND_STEP();
4957    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4958        M.x86.R_IP = target;
4959    DECODE_CLEAR_SEGOVR();
4960    END_OF_INSTR();
4961}
4962
4963/****************************************************************************
4964REMARKS:
4965Handles opcode 0x77
4966****************************************************************************/
4967void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4968{
4969    s8 offset;
4970    u16 target;
4971
4972    /* jump to byte offset if carry flag is clear and if the zero
4973       flag is clear */
4974    START_OF_INSTR();
4975    DECODE_PRINTF("JNBE\t");
4976    offset = (s8)fetch_byte_imm();
4977    target = (u16)(M.x86.R_IP + (s16)offset);
4978    DECODE_PRINTF2("%x\n", target);
4979    TRACE_AND_STEP();
4980    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4981        M.x86.R_IP = target;
4982    DECODE_CLEAR_SEGOVR();
4983    END_OF_INSTR();
4984}
4985
4986/****************************************************************************
4987REMARKS:
4988Handles opcode 0x78
4989****************************************************************************/
4990void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
4991{
4992    s8 offset;
4993    u16 target;
4994
4995    /* jump to byte offset if sign flag is set */
4996    START_OF_INSTR();
4997    DECODE_PRINTF("JS\t");
4998    offset = (s8)fetch_byte_imm();
4999    target = (u16)(M.x86.R_IP + (s16)offset);
5000    DECODE_PRINTF2("%x\n", target);
5001    TRACE_AND_STEP();
5002    if (ACCESS_FLAG(F_SF))
5003        M.x86.R_IP = target;
5004    DECODE_CLEAR_SEGOVR();
5005    END_OF_INSTR();
5006}
5007
5008/****************************************************************************
5009REMARKS:
5010Handles opcode 0x79
5011****************************************************************************/
5012void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5013{
5014    s8 offset;
5015    u16 target;
5016
5017    /* jump to byte offset if sign flag is clear */
5018    START_OF_INSTR();
5019    DECODE_PRINTF("JNS\t");
5020    offset = (s8)fetch_byte_imm();
5021    target = (u16)(M.x86.R_IP + (s16)offset);
5022    DECODE_PRINTF2("%x\n", target);
5023    TRACE_AND_STEP();
5024    if (!ACCESS_FLAG(F_SF))
5025        M.x86.R_IP = target;
5026    DECODE_CLEAR_SEGOVR();
5027    END_OF_INSTR();
5028}
5029
5030/****************************************************************************
5031REMARKS:
5032Handles opcode 0x7a
5033****************************************************************************/
5034void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5035{
5036    s8 offset;
5037    u16 target;
5038
5039    /* jump to byte offset if parity flag is set (even parity) */
5040    START_OF_INSTR();
5041    DECODE_PRINTF("JP\t");
5042    offset = (s8)fetch_byte_imm();
5043    target = (u16)(M.x86.R_IP + (s16)offset);
5044    DECODE_PRINTF2("%x\n", target);
5045    TRACE_AND_STEP();
5046    if (ACCESS_FLAG(F_PF))
5047        M.x86.R_IP = target;
5048    DECODE_CLEAR_SEGOVR();
5049    END_OF_INSTR();
5050}
5051
5052/****************************************************************************
5053REMARKS:
5054Handles opcode 0x7b
5055****************************************************************************/
5056void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5057{
5058    s8 offset;
5059    u16 target;
5060
5061    /* jump to byte offset if parity flag is clear (odd parity) */
5062    START_OF_INSTR();
5063    DECODE_PRINTF("JNP\t");
5064    offset = (s8)fetch_byte_imm();
5065    target = (u16)(M.x86.R_IP + (s16)offset);
5066    DECODE_PRINTF2("%x\n", target);
5067    TRACE_AND_STEP();
5068    if (!ACCESS_FLAG(F_PF))
5069        M.x86.R_IP = target;
5070    DECODE_CLEAR_SEGOVR();
5071    END_OF_INSTR();
5072}
5073
5074/****************************************************************************
5075REMARKS:
5076Handles opcode 0x7c
5077****************************************************************************/
5078void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5079{
5080    s8 offset;
5081    u16 target;
5082    int sf, of;
5083
5084    /* jump to byte offset if sign flag not equal to overflow flag. */
5085    START_OF_INSTR();
5086    DECODE_PRINTF("JL\t");
5087    offset = (s8)fetch_byte_imm();
5088    target = (u16)(M.x86.R_IP + (s16)offset);
5089    DECODE_PRINTF2("%x\n", target);
5090    TRACE_AND_STEP();
5091    sf = ACCESS_FLAG(F_SF) != 0;
5092    of = ACCESS_FLAG(F_OF) != 0;
5093    if (sf ^ of)
5094        M.x86.R_IP = target;
5095    DECODE_CLEAR_SEGOVR();
5096    END_OF_INSTR();
5097}
5098
5099/****************************************************************************
5100REMARKS:
5101Handles opcode 0x7d
5102****************************************************************************/
5103void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5104{
5105    s8 offset;
5106    u16 target;
5107    int sf, of;
5108
5109    /* jump to byte offset if sign flag not equal to overflow flag. */
5110    START_OF_INSTR();
5111    DECODE_PRINTF("JNL\t");
5112    offset = (s8)fetch_byte_imm();
5113    target = (u16)(M.x86.R_IP + (s16)offset);
5114    DECODE_PRINTF2("%x\n", target);
5115    TRACE_AND_STEP();
5116    sf = ACCESS_FLAG(F_SF) != 0;
5117    of = ACCESS_FLAG(F_OF) != 0;
5118    /* note: inverse of above, but using == instead of xor. */
5119    if (sf == of)
5120        M.x86.R_IP = target;
5121    DECODE_CLEAR_SEGOVR();
5122    END_OF_INSTR();
5123}
5124
5125/****************************************************************************
5126REMARKS:
5127Handles opcode 0x7e
5128****************************************************************************/
5129void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5130{
5131    s8 offset;
5132    u16 target;
5133    int sf, of;
5134
5135    /* jump to byte offset if sign flag not equal to overflow flag
5136       or the zero flag is set */
5137    START_OF_INSTR();
5138    DECODE_PRINTF("JLE\t");
5139    offset = (s8)fetch_byte_imm();
5140    target = (u16)(M.x86.R_IP + (s16)offset);
5141    DECODE_PRINTF2("%x\n", target);
5142    TRACE_AND_STEP();
5143    sf = ACCESS_FLAG(F_SF) != 0;
5144    of = ACCESS_FLAG(F_OF) != 0;
5145    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5146        M.x86.R_IP = target;
5147    DECODE_CLEAR_SEGOVR();
5148    END_OF_INSTR();
5149}
5150
5151/****************************************************************************
5152REMARKS:
5153Handles opcode 0x7f
5154****************************************************************************/
5155void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5156{
5157    s8 offset;
5158    u16 target;
5159    int sf, of;
5160
5161    /* jump to byte offset if sign flag equal to overflow flag.
5162       and the zero flag is clear */
5163    START_OF_INSTR();
5164    DECODE_PRINTF("JNLE\t");
5165    offset = (s8)fetch_byte_imm();
5166    target = (u16)(M.x86.R_IP + (s16)offset);
5167    DECODE_PRINTF2("%x\n", target);
5168    TRACE_AND_STEP();
5169    sf = ACCESS_FLAG(F_SF) != 0;
5170    of = ACCESS_FLAG(F_OF) != 0;
5171    if ((sf == of) && !ACCESS_FLAG(F_ZF))
5172        M.x86.R_IP = target;
5173    DECODE_CLEAR_SEGOVR();
5174    END_OF_INSTR();
5175}
5176
5177static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5178{
5179    add_byte,           /* 00 */
5180    or_byte,            /* 01 */
5181    adc_byte,           /* 02 */
5182    sbb_byte,           /* 03 */
5183    and_byte,           /* 04 */
5184    sub_byte,           /* 05 */
5185    xor_byte,           /* 06 */
5186    cmp_byte,           /* 07 */
5187};
5188
5189/****************************************************************************
5190REMARKS:
5191Handles opcode 0x80
5192****************************************************************************/
5193void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5194{
5195    int mod, rl, rh;
5196    u8 *destreg;
5197    uint destoffset;
5198    u8 imm;
5199    u8 destval;
5200
5201    /*
5202     * Weirdo special case instruction format.  Part of the opcode
5203     * held below in "RH".  Doubly nested case would result, except
5204     * that the decoded instruction
5205     */
5206    START_OF_INSTR();
5207    FETCH_DECODE_MODRM(mod, rh, rl);
5208#ifdef DEBUG
5209    if (DEBUG_DECODE()) {
5210
5211        switch (rh) {
5212        case 0:
5213            DECODE_PRINTF("ADD\t");
5214            break;
5215        case 1:
5216            DECODE_PRINTF("OR\t");
5217            break;
5218        case 2:
5219            DECODE_PRINTF("ADC\t");
5220            break;
5221        case 3:
5222            DECODE_PRINTF("SBB\t");
5223            break;
5224        case 4:
5225            DECODE_PRINTF("AND\t");
5226            break;
5227        case 5:
5228            DECODE_PRINTF("SUB\t");
5229            break;
5230        case 6:
5231            DECODE_PRINTF("XOR\t");
5232            break;
5233        case 7:
5234            DECODE_PRINTF("CMP\t");
5235            break;
5236        }
5237    }
5238#endif
5239    /* know operation, decode the mod byte to find the addressing
5240       mode. */
5241    switch (mod) {
5242    case 0:
5243        DECODE_PRINTF("BYTE PTR ");
5244        destoffset = decode_rm00_address(rl);
5245        DECODE_PRINTF(",");
5246        destval = fetch_data_byte(destoffset);
5247        imm = fetch_byte_imm();
5248        DECODE_PRINTF2("%x\n", imm);
5249        TRACE_AND_STEP();
5250        destval = (*opc80_byte_operation[rh]) (destval, imm);
5251        if (rh != 7)
5252            store_data_byte(destoffset, destval);
5253        break;
5254    case 1:
5255        DECODE_PRINTF("BYTE PTR ");
5256        destoffset = decode_rm01_address(rl);
5257        DECODE_PRINTF(",");
5258        destval = fetch_data_byte(destoffset);
5259        imm = fetch_byte_imm();
5260        DECODE_PRINTF2("%x\n", imm);
5261        TRACE_AND_STEP();
5262        destval = (*opc80_byte_operation[rh]) (destval, imm);
5263        if (rh != 7)
5264            store_data_byte(destoffset, destval);
5265        break;
5266    case 2:
5267        DECODE_PRINTF("BYTE PTR ");
5268        destoffset = decode_rm10_address(rl);
5269        DECODE_PRINTF(",");
5270        destval = fetch_data_byte(destoffset);
5271        imm = fetch_byte_imm();
5272        DECODE_PRINTF2("%x\n", imm);
5273        TRACE_AND_STEP();
5274        destval = (*opc80_byte_operation[rh]) (destval, imm);
5275        if (rh != 7)
5276            store_data_byte(destoffset, destval);
5277        break;
5278    case 3:                     /* register to register */
5279        destreg = DECODE_RM_BYTE_REGISTER(rl);
5280        DECODE_PRINTF(",");
5281        imm = fetch_byte_imm();
5282        DECODE_PRINTF2("%x\n", imm);
5283        TRACE_AND_STEP();
5284        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5285        if (rh != 7)
5286            *destreg = destval;
5287        break;
5288    }
5289    DECODE_CLEAR_SEGOVR();
5290    END_OF_INSTR();
5291}
5292
5293static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5294{
5295    add_word,           /*00 */
5296    or_word,            /*01 */
5297    adc_word,           /*02 */
5298    sbb_word,           /*03 */
5299    and_word,           /*04 */
5300    sub_word,           /*05 */
5301    xor_word,           /*06 */
5302    cmp_word,           /*07 */
5303};
5304
5305static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5306{
5307    add_long,           /*00 */
5308    or_long,            /*01 */
5309    adc_long,           /*02 */
5310    sbb_long,           /*03 */
5311    and_long,           /*04 */
5312    sub_long,           /*05 */
5313    xor_long,           /*06 */
5314    cmp_long,           /*07 */
5315};
5316
5317/****************************************************************************
5318REMARKS:
5319Handles opcode 0x81
5320****************************************************************************/
5321void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5322{
5323    int mod, rl, rh;
5324    uint destoffset;
5325
5326    /*
5327     * Weirdo special case instruction format.  Part of the opcode
5328     * held below in "RH".  Doubly nested case would result, except
5329     * that the decoded instruction
5330     */
5331    START_OF_INSTR();
5332    FETCH_DECODE_MODRM(mod, rh, rl);
5333#ifdef DEBUG
5334    if (DEBUG_DECODE()) {
5335
5336        switch (rh) {
5337        case 0:
5338            DECODE_PRINTF("ADD\t");
5339            break;
5340        case 1:
5341            DECODE_PRINTF("OR\t");
5342            break;
5343        case 2:
5344            DECODE_PRINTF("ADC\t");
5345            break;
5346        case 3:
5347            DECODE_PRINTF("SBB\t");
5348            break;
5349        case 4:
5350            DECODE_PRINTF("AND\t");
5351            break;
5352        case 5:
5353            DECODE_PRINTF("SUB\t");
5354            break;
5355        case 6:
5356            DECODE_PRINTF("XOR\t");
5357            break;
5358        case 7:
5359            DECODE_PRINTF("CMP\t");
5360            break;
5361        }
5362    }
5363#endif
5364    /*
5365     * Know operation, decode the mod byte to find the addressing
5366     * mode.
5367     */
5368    switch (mod) {
5369    case 0:
5370        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5371            u32 destval,imm;
5372
5373            DECODE_PRINTF("DWORD PTR ");
5374            destoffset = decode_rm00_address(rl);
5375            DECODE_PRINTF(",");
5376            destval = fetch_data_long(destoffset);
5377            imm = fetch_long_imm();
5378            DECODE_PRINTF2("%x\n", imm);
5379            TRACE_AND_STEP();
5380            destval = (*opc81_long_operation[rh]) (destval, imm);
5381            if (rh != 7)
5382                store_data_long(destoffset, destval);
5383        } else {
5384            u16 destval,imm;
5385
5386            DECODE_PRINTF("WORD PTR ");
5387            destoffset = decode_rm00_address(rl);
5388            DECODE_PRINTF(",");
5389            destval = fetch_data_word(destoffset);
5390            imm = fetch_word_imm();
5391            DECODE_PRINTF2("%x\n", imm);
5392            TRACE_AND_STEP();
5393            destval = (*opc81_word_operation[rh]) (destval, imm);
5394            if (rh != 7)
5395                store_data_word(destoffset, destval);
5396        }
5397        break;
5398    case 1:
5399        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5400            u32 destval,imm;
5401
5402            DECODE_PRINTF("DWORD PTR ");
5403            destoffset = decode_rm01_address(rl);
5404            DECODE_PRINTF(",");
5405            destval = fetch_data_long(destoffset);
5406            imm = fetch_long_imm();
5407            DECODE_PRINTF2("%x\n", imm);
5408            TRACE_AND_STEP();
5409            destval = (*opc81_long_operation[rh]) (destval, imm);
5410            if (rh != 7)
5411                store_data_long(destoffset, destval);
5412        } else {
5413            u16 destval,imm;
5414
5415            DECODE_PRINTF("WORD PTR ");
5416            destoffset = decode_rm01_address(rl);
5417            DECODE_PRINTF(",");
5418            destval = fetch_data_word(destoffset);
5419            imm = fetch_word_imm();
5420            DECODE_PRINTF2("%x\n", imm);
5421            TRACE_AND_STEP();
5422            destval = (*opc81_word_operation[rh]) (destval, imm);
5423            if (rh != 7)
5424                store_data_word(destoffset, destval);
5425        }
5426        break;
5427    case 2:
5428        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5429            u32 destval,imm;
5430
5431            DECODE_PRINTF("DWORD PTR ");
5432            destoffset = decode_rm10_address(rl);
5433            DECODE_PRINTF(",");
5434            destval = fetch_data_long(destoffset);
5435            imm = fetch_long_imm();
5436            DECODE_PRINTF2("%x\n", imm);
5437            TRACE_AND_STEP();
5438            destval = (*opc81_long_operation[rh]) (destval, imm);
5439            if (rh != 7)
5440                store_data_long(destoffset, destval);
5441        } else {
5442            u16 destval,imm;
5443
5444            DECODE_PRINTF("WORD PTR ");
5445            destoffset = decode_rm10_address(rl);
5446            DECODE_PRINTF(",");
5447            destval = fetch_data_word(destoffset);
5448            imm = fetch_word_imm();
5449            DECODE_PRINTF2("%x\n", imm);
5450            TRACE_AND_STEP();
5451            destval = (*opc81_word_operation[rh]) (destval, imm);
5452            if (rh != 7)
5453                store_data_word(destoffset, destval);
5454        }
5455        break;
5456    case 3:                     /* register to register */
5457        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5458            u32 *destreg;
5459            u32 destval,imm;
5460
5461            destreg = DECODE_RM_LONG_REGISTER(rl);
5462            DECODE_PRINTF(",");
5463            imm = fetch_long_imm();
5464            DECODE_PRINTF2("%x\n", imm);
5465            TRACE_AND_STEP();
5466            destval = (*opc81_long_operation[rh]) (*destreg, imm);
5467            if (rh != 7)
5468                *destreg = destval;
5469        } else {
5470            u16 *destreg;
5471            u16 destval,imm;
5472
5473            destreg = DECODE_RM_WORD_REGISTER(rl);
5474            DECODE_PRINTF(",");
5475            imm = fetch_word_imm();
5476            DECODE_PRINTF2("%x\n", imm);
5477            TRACE_AND_STEP();
5478            destval = (*opc81_word_operation[rh]) (*destreg, imm);
5479            if (rh != 7)
5480                *destreg = destval;
5481        }
5482        break;
5483    }
5484    DECODE_CLEAR_SEGOVR();
5485    END_OF_INSTR();
5486}
5487
5488static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5489{
5490    add_byte,           /*00 */
5491    or_byte,            /*01 *//*YYY UNUSED ???? */
5492    adc_byte,           /*02 */
5493    sbb_byte,           /*03 */
5494    and_byte,           /*04 *//*YYY UNUSED ???? */
5495    sub_byte,           /*05 */
5496    xor_byte,           /*06 *//*YYY UNUSED ???? */
5497    cmp_byte,           /*07 */
5498};
5499
5500/****************************************************************************
5501REMARKS:
5502Handles opcode 0x82
5503****************************************************************************/
5504void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5505{
5506    int mod, rl, rh;
5507    u8 *destreg;
5508    uint destoffset;
5509    u8 imm;
5510    u8 destval;
5511
5512    /*
5513     * Weirdo special case instruction format.  Part of the opcode
5514     * held below in "RH".  Doubly nested case would result, except
5515     * that the decoded instruction Similar to opcode 81, except that
5516     * the immediate byte is sign extended to a word length.
5517     */
5518    START_OF_INSTR();
5519    FETCH_DECODE_MODRM(mod, rh, rl);
5520#ifdef DEBUG
5521    if (DEBUG_DECODE()) {
5522        switch (rh) {
5523        case 0:
5524            DECODE_PRINTF("ADD\t");
5525            break;
5526        case 1:
5527            DECODE_PRINTF("OR\t");
5528            break;
5529        case 2:
5530            DECODE_PRINTF("ADC\t");
5531            break;
5532        case 3:
5533            DECODE_PRINTF("SBB\t");
5534            break;
5535        case 4:
5536            DECODE_PRINTF("AND\t");
5537            break;
5538        case 5:
5539            DECODE_PRINTF("SUB\t");
5540            break;
5541        case 6:
5542            DECODE_PRINTF("XOR\t");
5543            break;
5544        case 7:
5545            DECODE_PRINTF("CMP\t");
5546            break;
5547        }
5548    }
5549#endif
5550    /* know operation, decode the mod byte to find the addressing
5551       mode. */
5552    switch (mod) {
5553    case 0:
5554        DECODE_PRINTF("BYTE PTR ");
5555        destoffset = decode_rm00_address(rl);
5556        destval = fetch_data_byte(destoffset);
5557        imm = fetch_byte_imm();
5558        DECODE_PRINTF2(",%x\n", imm);
5559        TRACE_AND_STEP();
5560        destval = (*opc82_byte_operation[rh]) (destval, imm);
5561        if (rh != 7)
5562            store_data_byte(destoffset, destval);
5563        break;
5564    case 1:
5565        DECODE_PRINTF("BYTE PTR ");
5566        destoffset = decode_rm01_address(rl);
5567        destval = fetch_data_byte(destoffset);
5568        imm = fetch_byte_imm();
5569        DECODE_PRINTF2(",%x\n", imm);
5570        TRACE_AND_STEP();
5571        destval = (*opc82_byte_operation[rh]) (destval, imm);
5572        if (rh != 7)
5573            store_data_byte(destoffset, destval);
5574        break;
5575    case 2:
5576        DECODE_PRINTF("BYTE PTR ");
5577        destoffset = decode_rm10_address(rl);
5578        destval = fetch_data_byte(destoffset);
5579        imm = fetch_byte_imm();
5580        DECODE_PRINTF2(",%x\n", imm);
5581        TRACE_AND_STEP();
5582        destval = (*opc82_byte_operation[rh]) (destval, imm);
5583        if (rh != 7)
5584            store_data_byte(destoffset, destval);
5585        break;
5586    case 3:                     /* register to register */
5587        destreg = DECODE_RM_BYTE_REGISTER(rl);
5588        imm = fetch_byte_imm();
5589        DECODE_PRINTF2(",%x\n", imm);
5590        TRACE_AND_STEP();
5591        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5592        if (rh != 7)
5593            *destreg = destval;
5594        break;
5595    }
5596    DECODE_CLEAR_SEGOVR();
5597    END_OF_INSTR();
5598}
5599
5600static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5601{
5602    add_word,           /*00 */
5603    or_word,            /*01 *//*YYY UNUSED ???? */
5604    adc_word,           /*02 */
5605    sbb_word,           /*03 */
5606    and_word,           /*04 *//*YYY UNUSED ???? */
5607    sub_word,           /*05 */
5608    xor_word,           /*06 *//*YYY UNUSED ???? */
5609    cmp_word,           /*07 */
5610};
5611
5612static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5613{
5614    add_long,           /*00 */
5615    or_long,            /*01 *//*YYY UNUSED ???? */
5616    adc_long,           /*02 */
5617    sbb_long,           /*03 */
5618    and_long,           /*04 *//*YYY UNUSED ???? */
5619    sub_long,           /*05 */
5620    xor_long,           /*06 *//*YYY UNUSED ???? */
5621    cmp_long,           /*07 */
5622};
5623
5624/****************************************************************************
5625REMARKS:
5626Handles opcode 0x83
5627****************************************************************************/
5628void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5629{
5630    int mod, rl, rh;
5631    uint destoffset;
5632
5633    /*
5634     * Weirdo special case instruction format.  Part of the opcode
5635     * held below in "RH".  Doubly nested case would result, except
5636     * that the decoded instruction Similar to opcode 81, except that
5637     * the immediate byte is sign extended to a word length.
5638     */
5639    START_OF_INSTR();
5640    FETCH_DECODE_MODRM(mod, rh, rl);
5641#ifdef DEBUG
5642    if (DEBUG_DECODE()) {
5643       switch (rh) {
5644        case 0:
5645            DECODE_PRINTF("ADD\t");
5646            break;
5647        case 1:
5648            DECODE_PRINTF("OR\t");
5649            break;
5650        case 2:
5651            DECODE_PRINTF("ADC\t");
5652            break;
5653        case 3:
5654            DECODE_PRINTF("SBB\t");
5655            break;
5656        case 4:
5657            DECODE_PRINTF("AND\t");
5658            break;
5659        case 5:
5660            DECODE_PRINTF("SUB\t");
5661            break;
5662        case 6:
5663            DECODE_PRINTF("XOR\t");
5664            break;
5665        case 7:
5666            DECODE_PRINTF("CMP\t");
5667            break;
5668        }
5669    }
5670#endif
5671    /* know operation, decode the mod byte to find the addressing
5672       mode. */
5673    switch (mod) {
5674    case 0:
5675        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5676            u32 destval,imm;
5677
5678            DECODE_PRINTF("DWORD PTR ");
5679            destoffset = decode_rm00_address(rl);
5680            destval = fetch_data_long(destoffset);
5681            imm = (s8) fetch_byte_imm();
5682            DECODE_PRINTF2(",%x\n", imm);
5683            TRACE_AND_STEP();
5684            destval = (*opc83_long_operation[rh]) (destval, imm);
5685            if (rh != 7)
5686                store_data_long(destoffset, destval);
5687        } else {
5688            u16 destval,imm;
5689
5690            DECODE_PRINTF("WORD PTR ");
5691            destoffset = decode_rm00_address(rl);
5692            destval = fetch_data_word(destoffset);
5693            imm = (s8) fetch_byte_imm();
5694            DECODE_PRINTF2(",%x\n", imm);
5695            TRACE_AND_STEP();
5696            destval = (*opc83_word_operation[rh]) (destval, imm);
5697            if (rh != 7)
5698                store_data_word(destoffset, destval);
5699        }
5700        break;
5701    case 1:
5702        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5703            u32 destval,imm;
5704
5705            DECODE_PRINTF("DWORD PTR ");
5706            destoffset = decode_rm01_address(rl);
5707            destval = fetch_data_long(destoffset);
5708            imm = (s8) fetch_byte_imm();
5709            DECODE_PRINTF2(",%x\n", imm);
5710            TRACE_AND_STEP();
5711            destval = (*opc83_long_operation[rh]) (destval, imm);
5712            if (rh != 7)
5713                store_data_long(destoffset, destval);
5714        } else {
5715            u16 destval,imm;
5716
5717            DECODE_PRINTF("WORD PTR ");
5718            destoffset = decode_rm01_address(rl);
5719            destval = fetch_data_word(destoffset);
5720            imm = (s8) fetch_byte_imm();
5721            DECODE_PRINTF2(",%x\n", imm);
5722            TRACE_AND_STEP();
5723            destval = (*opc83_word_operation[rh]) (destval, imm);
5724            if (rh != 7)
5725                store_data_word(destoffset, destval);
5726        }
5727        break;
5728    case 2:
5729        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5730            u32 destval,imm;
5731
5732            DECODE_PRINTF("DWORD PTR ");
5733            destoffset = decode_rm10_address(rl);
5734            destval = fetch_data_long(destoffset);
5735            imm = (s8) fetch_byte_imm();
5736            DECODE_PRINTF2(",%x\n", imm);
5737            TRACE_AND_STEP();
5738            destval = (*opc83_long_operation[rh]) (destval, imm);
5739            if (rh != 7)
5740                store_data_long(destoffset, destval);
5741        } else {
5742            u16 destval,imm;
5743
5744            DECODE_PRINTF("WORD PTR ");
5745            destoffset = decode_rm10_address(rl);
5746            destval = fetch_data_word(destoffset);
5747            imm = (s8) fetch_byte_imm();
5748            DECODE_PRINTF2(",%x\n", imm);
5749            TRACE_AND_STEP();
5750            destval = (*opc83_word_operation[rh]) (destval, imm);
5751            if (rh != 7)
5752                store_data_word(destoffset, destval);
5753        }
5754        break;
5755    case 3:                     /* register to register */
5756        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5757            u32 *destreg;
5758            u32 destval,imm;
5759
5760            destreg = DECODE_RM_LONG_REGISTER(rl);
5761            imm = (s8) fetch_byte_imm();
5762            DECODE_PRINTF2(",%x\n", imm);
5763            TRACE_AND_STEP();
5764            destval = (*opc83_long_operation[rh]) (*destreg, imm);
5765            if (rh != 7)
5766                *destreg = destval;
5767        } else {
5768            u16 *destreg;
5769            u16 destval,imm;
5770
5771            destreg = DECODE_RM_WORD_REGISTER(rl);
5772            imm = (s8) fetch_byte_imm();
5773            DECODE_PRINTF2(",%x\n", imm);
5774            TRACE_AND_STEP();
5775            destval = (*opc83_word_operation[rh]) (*destreg, imm);
5776            if (rh != 7)
5777                *destreg = destval;
5778        }
5779        break;
5780    }
5781    DECODE_CLEAR_SEGOVR();
5782    END_OF_INSTR();
5783}
5784
5785/****************************************************************************
5786REMARKS:
5787Handles opcode 0x84
5788****************************************************************************/
5789void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5790{
5791    int mod, rl, rh;
5792    u8 *destreg, *srcreg;
5793    uint destoffset;
5794    u8 destval;
5795
5796    START_OF_INSTR();
5797    DECODE_PRINTF("TEST\t");
5798    FETCH_DECODE_MODRM(mod, rh, rl);
5799    switch (mod) {
5800    case 0:
5801        destoffset = decode_rm00_address(rl);
5802        DECODE_PRINTF(",");
5803        destval = fetch_data_byte(destoffset);
5804        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5805        DECODE_PRINTF("\n");
5806        TRACE_AND_STEP();
5807        test_byte(destval, *srcreg);
5808        break;
5809    case 1:
5810        destoffset = decode_rm01_address(rl);
5811        DECODE_PRINTF(",");
5812        destval = fetch_data_byte(destoffset);
5813        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5814        DECODE_PRINTF("\n");
5815        TRACE_AND_STEP();
5816        test_byte(destval, *srcreg);
5817        break;
5818    case 2:
5819        destoffset = decode_rm10_address(rl);
5820        DECODE_PRINTF(",");
5821        destval = fetch_data_byte(destoffset);
5822        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5823        DECODE_PRINTF("\n");
5824        TRACE_AND_STEP();
5825        test_byte(destval, *srcreg);
5826        break;
5827    case 3:                     /* register to register */
5828        destreg = DECODE_RM_BYTE_REGISTER(rl);
5829        DECODE_PRINTF(",");
5830        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5831        DECODE_PRINTF("\n");
5832        TRACE_AND_STEP();
5833        test_byte(*destreg, *srcreg);
5834        break;
5835    }
5836    DECODE_CLEAR_SEGOVR();
5837    END_OF_INSTR();
5838}
5839
5840/****************************************************************************
5841REMARKS:
5842Handles opcode 0x85
5843****************************************************************************/
5844void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5845{
5846    int mod, rl, rh;
5847    uint destoffset;
5848
5849    START_OF_INSTR();
5850    DECODE_PRINTF("TEST\t");
5851    FETCH_DECODE_MODRM(mod, rh, rl);
5852    switch (mod) {
5853    case 0:
5854        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5855            u32 destval;
5856            u32 *srcreg;
5857
5858            destoffset = decode_rm00_address(rl);
5859            DECODE_PRINTF(",");
5860            destval = fetch_data_long(destoffset);
5861            srcreg = DECODE_RM_LONG_REGISTER(rh);
5862            DECODE_PRINTF("\n");
5863            TRACE_AND_STEP();
5864            test_long(destval, *srcreg);
5865        } else {
5866            u16 destval;
5867            u16 *srcreg;
5868
5869            destoffset = decode_rm00_address(rl);
5870            DECODE_PRINTF(",");
5871            destval = fetch_data_word(destoffset);
5872            srcreg = DECODE_RM_WORD_REGISTER(rh);
5873            DECODE_PRINTF("\n");
5874            TRACE_AND_STEP();
5875            test_word(destval, *srcreg);
5876        }
5877        break;
5878    case 1:
5879        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5880            u32 destval;
5881            u32 *srcreg;
5882
5883            destoffset = decode_rm01_address(rl);
5884            DECODE_PRINTF(",");
5885            destval = fetch_data_long(destoffset);
5886            srcreg = DECODE_RM_LONG_REGISTER(rh);
5887            DECODE_PRINTF("\n");
5888            TRACE_AND_STEP();
5889            test_long(destval, *srcreg);
5890        } else {
5891            u16 destval;
5892            u16 *srcreg;
5893
5894            destoffset = decode_rm01_address(rl);
5895            DECODE_PRINTF(",");
5896            destval = fetch_data_word(destoffset);
5897            srcreg = DECODE_RM_WORD_REGISTER(rh);
5898            DECODE_PRINTF("\n");
5899            TRACE_AND_STEP();
5900            test_word(destval, *srcreg);
5901        }
5902        break;
5903    case 2:
5904        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5905            u32 destval;
5906            u32 *srcreg;
5907
5908            destoffset = decode_rm10_address(rl);
5909            DECODE_PRINTF(",");
5910            destval = fetch_data_long(destoffset);
5911            srcreg = DECODE_RM_LONG_REGISTER(rh);
5912            DECODE_PRINTF("\n");
5913            TRACE_AND_STEP();
5914            test_long(destval, *srcreg);
5915        } else {
5916            u16 destval;
5917            u16 *srcreg;
5918
5919            destoffset = decode_rm10_address(rl);
5920            DECODE_PRINTF(",");
5921            destval = fetch_data_word(destoffset);
5922            srcreg = DECODE_RM_WORD_REGISTER(rh);
5923            DECODE_PRINTF("\n");
5924            TRACE_AND_STEP();
5925            test_word(destval, *srcreg);
5926        }
5927        break;
5928    case 3:                     /* register to register */
5929        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5930            u32 *destreg,*srcreg;
5931
5932            destreg = DECODE_RM_LONG_REGISTER(rl);
5933            DECODE_PRINTF(",");
5934            srcreg = DECODE_RM_LONG_REGISTER(rh);
5935            DECODE_PRINTF("\n");
5936            TRACE_AND_STEP();
5937            test_long(*destreg, *srcreg);
5938        } else {
5939            u16 *destreg,*srcreg;
5940
5941            destreg = DECODE_RM_WORD_REGISTER(rl);
5942            DECODE_PRINTF(",");
5943            srcreg = DECODE_RM_WORD_REGISTER(rh);
5944            DECODE_PRINTF("\n");
5945            TRACE_AND_STEP();
5946            test_word(*destreg, *srcreg);
5947        }
5948        break;
5949    }
5950    DECODE_CLEAR_SEGOVR();
5951    END_OF_INSTR();
5952}
5953
5954/****************************************************************************
5955REMARKS:
5956Handles opcode 0x86
5957****************************************************************************/
5958void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5959{
5960    int mod, rl, rh;
5961    u8 *destreg, *srcreg;
5962    uint destoffset;
5963    u8 destval;
5964    u8 tmp;
5965
5966    START_OF_INSTR();
5967    DECODE_PRINTF("XCHG\t");
5968    FETCH_DECODE_MODRM(mod, rh, rl);
5969    switch (mod) {
5970    case 0:
5971        destoffset = decode_rm00_address(rl);
5972        DECODE_PRINTF(",");
5973        destval = fetch_data_byte(destoffset);
5974        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5975        DECODE_PRINTF("\n");
5976        TRACE_AND_STEP();
5977        tmp = *srcreg;
5978        *srcreg = destval;
5979        destval = tmp;
5980        store_data_byte(destoffset, destval);
5981        break;
5982    case 1:
5983        destoffset = decode_rm01_address(rl);
5984        DECODE_PRINTF(",");
5985        destval = fetch_data_byte(destoffset);
5986        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5987        DECODE_PRINTF("\n");
5988        TRACE_AND_STEP();
5989        tmp = *srcreg;
5990        *srcreg = destval;
5991        destval = tmp;
5992        store_data_byte(destoffset, destval);
5993        break;
5994    case 2:
5995        destoffset = decode_rm10_address(rl);
5996        DECODE_PRINTF(",");
5997        destval = fetch_data_byte(destoffset);
5998        srcreg = DECODE_RM_BYTE_REGISTER(rh);
5999        DECODE_PRINTF("\n");
6000        TRACE_AND_STEP();
6001        tmp = *srcreg;
6002        *srcreg = destval;
6003        destval = tmp;
6004        store_data_byte(destoffset, destval);
6005        break;
6006    case 3:                     /* register to register */
6007        destreg = DECODE_RM_BYTE_REGISTER(rl);
6008        DECODE_PRINTF(",");
6009        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6010        DECODE_PRINTF("\n");
6011        TRACE_AND_STEP();
6012        tmp = *srcreg;
6013        *srcreg = *destreg;
6014        *destreg = tmp;
6015        break;
6016    }
6017    DECODE_CLEAR_SEGOVR();
6018    END_OF_INSTR();
6019}
6020
6021/****************************************************************************
6022REMARKS:
6023Handles opcode 0x87
6024****************************************************************************/
6025void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6026{
6027    int mod, rl, rh;
6028    uint destoffset;
6029
6030    START_OF_INSTR();
6031    DECODE_PRINTF("XCHG\t");
6032    FETCH_DECODE_MODRM(mod, rh, rl);
6033    switch (mod) {
6034    case 0:
6035        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6036            u32 *srcreg;
6037            u32 destval,tmp;
6038
6039            destoffset = decode_rm00_address(rl);
6040            DECODE_PRINTF(",");
6041            destval = fetch_data_long(destoffset);
6042            srcreg = DECODE_RM_LONG_REGISTER(rh);
6043            DECODE_PRINTF("\n");
6044            TRACE_AND_STEP();
6045            tmp = *srcreg;
6046            *srcreg = destval;
6047            destval = tmp;
6048            store_data_long(destoffset, destval);
6049        } else {
6050            u16 *srcreg;
6051            u16 destval,tmp;
6052
6053            destoffset = decode_rm00_address(rl);
6054            DECODE_PRINTF(",");
6055            destval = fetch_data_word(destoffset);
6056            srcreg = DECODE_RM_WORD_REGISTER(rh);
6057            DECODE_PRINTF("\n");
6058            TRACE_AND_STEP();
6059            tmp = *srcreg;
6060            *srcreg = destval;
6061            destval = tmp;
6062            store_data_word(destoffset, destval);
6063        }
6064        break;
6065    case 1:
6066        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6067            u32 *srcreg;
6068            u32 destval,tmp;
6069
6070            destoffset = decode_rm01_address(rl);
6071            DECODE_PRINTF(",");
6072            destval = fetch_data_long(destoffset);
6073            srcreg = DECODE_RM_LONG_REGISTER(rh);
6074            DECODE_PRINTF("\n");
6075            TRACE_AND_STEP();
6076            tmp = *srcreg;
6077            *srcreg = destval;
6078            destval = tmp;
6079            store_data_long(destoffset, destval);
6080        } else {
6081            u16 *srcreg;
6082            u16 destval,tmp;
6083
6084            destoffset = decode_rm01_address(rl);
6085            DECODE_PRINTF(",");
6086            destval = fetch_data_word(destoffset);
6087            srcreg = DECODE_RM_WORD_REGISTER(rh);
6088            DECODE_PRINTF("\n");
6089            TRACE_AND_STEP();
6090            tmp = *srcreg;
6091            *srcreg = destval;
6092            destval = tmp;
6093            store_data_word(destoffset, destval);
6094        }
6095        break;
6096    case 2:
6097        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6098            u32 *srcreg;
6099            u32 destval,tmp;
6100
6101            destoffset = decode_rm10_address(rl);
6102            DECODE_PRINTF(",");
6103            destval = fetch_data_long(destoffset);
6104            srcreg = DECODE_RM_LONG_REGISTER(rh);
6105            DECODE_PRINTF("\n");
6106            TRACE_AND_STEP();
6107            tmp = *srcreg;
6108            *srcreg = destval;
6109            destval = tmp;
6110            store_data_long(destoffset, destval);
6111        } else {
6112            u16 *srcreg;
6113            u16 destval,tmp;
6114
6115            destoffset = decode_rm10_address(rl);
6116            DECODE_PRINTF(",");
6117            destval = fetch_data_word(destoffset);
6118            srcreg = DECODE_RM_WORD_REGISTER(rh);
6119            DECODE_PRINTF("\n");
6120            TRACE_AND_STEP();
6121            tmp = *srcreg;
6122            *srcreg = destval;
6123            destval = tmp;
6124            store_data_word(destoffset, destval);
6125        }
6126        break;
6127    case 3:                     /* register to register */
6128        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6129            u32 *destreg,*srcreg;
6130            u32 tmp;
6131
6132            destreg = DECODE_RM_LONG_REGISTER(rl);
6133            DECODE_PRINTF(",");
6134            srcreg = DECODE_RM_LONG_REGISTER(rh);
6135            DECODE_PRINTF("\n");
6136            TRACE_AND_STEP();
6137            tmp = *srcreg;
6138            *srcreg = *destreg;
6139            *destreg = tmp;
6140        } else {
6141            u16 *destreg,*srcreg;
6142            u16 tmp;
6143
6144            destreg = DECODE_RM_WORD_REGISTER(rl);
6145            DECODE_PRINTF(",");
6146            srcreg = DECODE_RM_WORD_REGISTER(rh);
6147            DECODE_PRINTF("\n");
6148            TRACE_AND_STEP();
6149            tmp = *srcreg;
6150            *srcreg = *destreg;
6151            *destreg = tmp;
6152        }
6153        break;
6154    }
6155    DECODE_CLEAR_SEGOVR();
6156    END_OF_INSTR();
6157}
6158
6159/****************************************************************************
6160REMARKS:
6161Handles opcode 0x88
6162****************************************************************************/
6163void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6164{
6165    int mod, rl, rh;
6166    u8 *destreg, *srcreg;
6167    uint destoffset;
6168
6169    START_OF_INSTR();
6170    DECODE_PRINTF("MOV\t");
6171    FETCH_DECODE_MODRM(mod, rh, rl);
6172    switch (mod) {
6173    case 0:
6174        destoffset = decode_rm00_address(rl);
6175        DECODE_PRINTF(",");
6176        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6177        DECODE_PRINTF("\n");
6178        TRACE_AND_STEP();
6179        store_data_byte(destoffset, *srcreg);
6180        break;
6181    case 1:
6182        destoffset = decode_rm01_address(rl);
6183        DECODE_PRINTF(",");
6184        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6185        DECODE_PRINTF("\n");
6186        TRACE_AND_STEP();
6187        store_data_byte(destoffset, *srcreg);
6188        break;
6189    case 2:
6190        destoffset = decode_rm10_address(rl);
6191        DECODE_PRINTF(",");
6192        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6193        DECODE_PRINTF("\n");
6194        TRACE_AND_STEP();
6195        store_data_byte(destoffset, *srcreg);
6196        break;
6197    case 3:                     /* register to register */
6198        destreg = DECODE_RM_BYTE_REGISTER(rl);
6199        DECODE_PRINTF(",");
6200        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6201        DECODE_PRINTF("\n");
6202        TRACE_AND_STEP();
6203        *destreg = *srcreg;
6204        break;
6205    }
6206    DECODE_CLEAR_SEGOVR();
6207    END_OF_INSTR();
6208}
6209
6210/****************************************************************************
6211REMARKS:
6212Handles opcode 0x89
6213****************************************************************************/
6214void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6215{
6216    int mod, rl, rh;
6217    uint destoffset;
6218
6219    START_OF_INSTR();
6220    DECODE_PRINTF("MOV\t");
6221    FETCH_DECODE_MODRM(mod, rh, rl);
6222    switch (mod) {
6223    case 0:
6224        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6225            u32 *srcreg;
6226
6227            destoffset = decode_rm00_address(rl);
6228            DECODE_PRINTF(",");
6229            srcreg = DECODE_RM_LONG_REGISTER(rh);
6230            DECODE_PRINTF("\n");
6231            TRACE_AND_STEP();
6232            store_data_long(destoffset, *srcreg);
6233        } else {
6234            u16 *srcreg;
6235
6236            destoffset = decode_rm00_address(rl);
6237            DECODE_PRINTF(",");
6238            srcreg = DECODE_RM_WORD_REGISTER(rh);
6239            DECODE_PRINTF("\n");
6240            TRACE_AND_STEP();
6241            store_data_word(destoffset, *srcreg);
6242        }
6243        break;
6244    case 1:
6245        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6246            u32 *srcreg;
6247
6248            destoffset = decode_rm01_address(rl);
6249            DECODE_PRINTF(",");
6250            srcreg = DECODE_RM_LONG_REGISTER(rh);
6251            DECODE_PRINTF("\n");
6252            TRACE_AND_STEP();
6253            store_data_long(destoffset, *srcreg);
6254        } else {
6255            u16 *srcreg;
6256
6257            destoffset = decode_rm01_address(rl);
6258            DECODE_PRINTF(",");
6259            srcreg = DECODE_RM_WORD_REGISTER(rh);
6260            DECODE_PRINTF("\n");
6261            TRACE_AND_STEP();
6262            store_data_word(destoffset, *srcreg);
6263        }
6264        break;
6265    case 2:
6266        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6267            u32 *srcreg;
6268
6269            destoffset = decode_rm10_address(rl);
6270            DECODE_PRINTF(",");
6271            srcreg = DECODE_RM_LONG_REGISTER(rh);
6272            DECODE_PRINTF("\n");
6273            TRACE_AND_STEP();
6274            store_data_long(destoffset, *srcreg);
6275        } else {
6276            u16 *srcreg;
6277
6278            destoffset = decode_rm10_address(rl);
6279            DECODE_PRINTF(",");
6280            srcreg = DECODE_RM_WORD_REGISTER(rh);
6281            DECODE_PRINTF("\n");
6282            TRACE_AND_STEP();
6283            store_data_word(destoffset, *srcreg);
6284        }
6285        break;
6286    case 3:                     /* register to register */
6287        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6288            u32 *destreg,*srcreg;
6289
6290            destreg = DECODE_RM_LONG_REGISTER(rl);
6291            DECODE_PRINTF(",");
6292            srcreg = DECODE_RM_LONG_REGISTER(rh);
6293            DECODE_PRINTF("\n");
6294            TRACE_AND_STEP();
6295            *destreg = *srcreg;
6296        } else {
6297            u16 *destreg,*srcreg;
6298
6299            destreg = DECODE_RM_WORD_REGISTER(rl);
6300            DECODE_PRINTF(",");
6301            srcreg = DECODE_RM_WORD_REGISTER(rh);
6302            DECODE_PRINTF("\n");
6303            TRACE_AND_STEP();
6304            *destreg = *srcreg;
6305        }
6306        break;
6307    }
6308    DECODE_CLEAR_SEGOVR();
6309    END_OF_INSTR();
6310}
6311
6312/****************************************************************************
6313REMARKS:
6314Handles opcode 0x8a
6315****************************************************************************/
6316void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6317{
6318    int mod, rl, rh;
6319    u8 *destreg, *srcreg;
6320    uint srcoffset;
6321    u8 srcval;
6322
6323    START_OF_INSTR();
6324    DECODE_PRINTF("MOV\t");
6325    FETCH_DECODE_MODRM(mod, rh, rl);
6326    switch (mod) {
6327    case 0:
6328        destreg = DECODE_RM_BYTE_REGISTER(rh);
6329        DECODE_PRINTF(",");
6330        srcoffset = decode_rm00_address(rl);
6331        srcval = fetch_data_byte(srcoffset);
6332        DECODE_PRINTF("\n");
6333        TRACE_AND_STEP();
6334        *destreg = srcval;
6335        break;
6336    case 1:
6337        destreg = DECODE_RM_BYTE_REGISTER(rh);
6338        DECODE_PRINTF(",");
6339        srcoffset = decode_rm01_address(rl);
6340        srcval = fetch_data_byte(srcoffset);
6341        DECODE_PRINTF("\n");
6342        TRACE_AND_STEP();
6343        *destreg = srcval;
6344        break;
6345    case 2:
6346        destreg = DECODE_RM_BYTE_REGISTER(rh);
6347        DECODE_PRINTF(",");
6348        srcoffset = decode_rm10_address(rl);
6349        srcval = fetch_data_byte(srcoffset);
6350        DECODE_PRINTF("\n");
6351        TRACE_AND_STEP();
6352        *destreg = srcval;
6353        break;
6354    case 3:                     /* register to register */
6355        destreg = DECODE_RM_BYTE_REGISTER(rh);
6356        DECODE_PRINTF(",");
6357        srcreg = DECODE_RM_BYTE_REGISTER(rl);
6358        DECODE_PRINTF("\n");
6359        TRACE_AND_STEP();
6360        *destreg = *srcreg;
6361        break;
6362    }
6363    DECODE_CLEAR_SEGOVR();
6364    END_OF_INSTR();
6365}
6366
6367/****************************************************************************
6368REMARKS:
6369Handles opcode 0x8b
6370****************************************************************************/
6371void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6372{
6373    int mod, rl, rh;
6374    uint srcoffset;
6375
6376    START_OF_INSTR();
6377    DECODE_PRINTF("MOV\t");
6378    FETCH_DECODE_MODRM(mod, rh, rl);
6379    switch (mod) {
6380    case 0:
6381        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6382            u32 *destreg;
6383            u32 srcval;
6384
6385            destreg = DECODE_RM_LONG_REGISTER(rh);
6386            DECODE_PRINTF(",");
6387            srcoffset = decode_rm00_address(rl);
6388            srcval = fetch_data_long(srcoffset);
6389            DECODE_PRINTF("\n");
6390            TRACE_AND_STEP();
6391            *destreg = srcval;
6392        } else {
6393            u16 *destreg;
6394            u16 srcval;
6395
6396            destreg = DECODE_RM_WORD_REGISTER(rh);
6397            DECODE_PRINTF(",");
6398            srcoffset = decode_rm00_address(rl);
6399            srcval = fetch_data_word(srcoffset);
6400            DECODE_PRINTF("\n");
6401            TRACE_AND_STEP();
6402            *destreg = srcval;
6403        }
6404        break;
6405    case 1:
6406        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6407            u32 *destreg;
6408            u32 srcval;
6409
6410            destreg = DECODE_RM_LONG_REGISTER(rh);
6411            DECODE_PRINTF(",");
6412            srcoffset = decode_rm01_address(rl);
6413            srcval = fetch_data_long(srcoffset);
6414            DECODE_PRINTF("\n");
6415            TRACE_AND_STEP();
6416            *destreg = srcval;
6417        } else {
6418            u16 *destreg;
6419            u16 srcval;
6420
6421            destreg = DECODE_RM_WORD_REGISTER(rh);
6422            DECODE_PRINTF(",");
6423            srcoffset = decode_rm01_address(rl);
6424            srcval = fetch_data_word(srcoffset);
6425            DECODE_PRINTF("\n");
6426            TRACE_AND_STEP();
6427            *destreg = srcval;
6428        }
6429        break;
6430    case 2:
6431        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6432            u32 *destreg;
6433            u32 srcval;
6434
6435            destreg = DECODE_RM_LONG_REGISTER(rh);
6436            DECODE_PRINTF(",");
6437            srcoffset = decode_rm10_address(rl);
6438            srcval = fetch_data_long(srcoffset);
6439            DECODE_PRINTF("\n");
6440            TRACE_AND_STEP();
6441            *destreg = srcval;
6442        } else {
6443            u16 *destreg;
6444            u16 srcval;
6445
6446            destreg = DECODE_RM_WORD_REGISTER(rh);
6447            DECODE_PRINTF(",");
6448            srcoffset = decode_rm10_address(rl);
6449            srcval = fetch_data_word(srcoffset);
6450            DECODE_PRINTF("\n");
6451            TRACE_AND_STEP();
6452            *destreg = srcval;
6453        }
6454        break;
6455    case 3:                     /* register to register */
6456        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6457            u32 *destreg, *srcreg;
6458
6459            destreg = DECODE_RM_LONG_REGISTER(rh);
6460            DECODE_PRINTF(",");
6461            srcreg = DECODE_RM_LONG_REGISTER(rl);
6462            DECODE_PRINTF("\n");
6463            TRACE_AND_STEP();
6464            *destreg = *srcreg;
6465        } else {
6466            u16 *destreg, *srcreg;
6467
6468            destreg = DECODE_RM_WORD_REGISTER(rh);
6469            DECODE_PRINTF(",");
6470            srcreg = DECODE_RM_WORD_REGISTER(rl);
6471            DECODE_PRINTF("\n");
6472            TRACE_AND_STEP();
6473            *destreg = *srcreg;
6474        }
6475        break;
6476    }
6477    DECODE_CLEAR_SEGOVR();
6478    END_OF_INSTR();
6479}
6480
6481/****************************************************************************
6482REMARKS:
6483Handles opcode 0x8c
6484****************************************************************************/
6485void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6486{
6487    int mod, rl, rh;
6488    u16 *destreg, *srcreg;
6489    uint destoffset;
6490    u16 destval;
6491
6492    START_OF_INSTR();
6493    DECODE_PRINTF("MOV\t");
6494    FETCH_DECODE_MODRM(mod, rh, rl);
6495    switch (mod) {
6496    case 0:
6497        destoffset = decode_rm00_address(rl);
6498        DECODE_PRINTF(",");
6499        srcreg = decode_rm_seg_register(rh);
6500        DECODE_PRINTF("\n");
6501        TRACE_AND_STEP();
6502        destval = *srcreg;
6503        store_data_word(destoffset, destval);
6504        break;
6505    case 1:
6506        destoffset = decode_rm01_address(rl);
6507        DECODE_PRINTF(",");
6508        srcreg = decode_rm_seg_register(rh);
6509        DECODE_PRINTF("\n");
6510        TRACE_AND_STEP();
6511        destval = *srcreg;
6512        store_data_word(destoffset, destval);
6513        break;
6514    case 2:
6515        destoffset = decode_rm10_address(rl);
6516        DECODE_PRINTF(",");
6517        srcreg = decode_rm_seg_register(rh);
6518        DECODE_PRINTF("\n");
6519        TRACE_AND_STEP();
6520        destval = *srcreg;
6521        store_data_word(destoffset, destval);
6522        break;
6523    case 3:                     /* register to register */
6524        destreg = DECODE_RM_WORD_REGISTER(rl);
6525        DECODE_PRINTF(",");
6526        srcreg = decode_rm_seg_register(rh);
6527        DECODE_PRINTF("\n");
6528        TRACE_AND_STEP();
6529        *destreg = *srcreg;
6530        break;
6531    }
6532    DECODE_CLEAR_SEGOVR();
6533    END_OF_INSTR();
6534}
6535
6536/****************************************************************************
6537REMARKS:
6538Handles opcode 0x8d
6539****************************************************************************/
6540void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6541{
6542    int mod, rl, rh;
6543    u16 *srcreg;
6544    uint destoffset;
6545
6546/*
6547 * TODO: Need to handle address size prefix!
6548 *
6549 * lea  eax,[eax+ebx*2] ??
6550 */
6551
6552    START_OF_INSTR();
6553    DECODE_PRINTF("LEA\t");
6554    FETCH_DECODE_MODRM(mod, rh, rl);
6555    switch (mod) {
6556    case 0:
6557        srcreg = DECODE_RM_WORD_REGISTER(rh);
6558        DECODE_PRINTF(",");
6559        destoffset = decode_rm00_address(rl);
6560        DECODE_PRINTF("\n");
6561        TRACE_AND_STEP();
6562        *srcreg = (u16)destoffset;
6563        break;
6564    case 1:
6565        srcreg = DECODE_RM_WORD_REGISTER(rh);
6566        DECODE_PRINTF(",");
6567        destoffset = decode_rm01_address(rl);
6568        DECODE_PRINTF("\n");
6569        TRACE_AND_STEP();
6570        *srcreg = (u16)destoffset;
6571        break;
6572    case 2:
6573        srcreg = DECODE_RM_WORD_REGISTER(rh);
6574        DECODE_PRINTF(",");
6575        destoffset = decode_rm10_address(rl);
6576        DECODE_PRINTF("\n");
6577        TRACE_AND_STEP();
6578        *srcreg = (u16)destoffset;
6579        break;
6580    case 3:                     /* register to register */
6581        /* undefined.  Do nothing. */
6582        break;
6583    }
6584    DECODE_CLEAR_SEGOVR();
6585    END_OF_INSTR();
6586}
6587
6588/****************************************************************************
6589REMARKS:
6590Handles opcode 0x8e
6591****************************************************************************/
6592void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6593{
6594    int mod, rl, rh;
6595    u16 *destreg, *srcreg;
6596    uint srcoffset;
6597    u16 srcval;
6598
6599    START_OF_INSTR();
6600    DECODE_PRINTF("MOV\t");
6601    FETCH_DECODE_MODRM(mod, rh, rl);
6602    switch (mod) {
6603    case 0:
6604        destreg = decode_rm_seg_register(rh);
6605        DECODE_PRINTF(",");
6606        srcoffset = decode_rm00_address(rl);
6607        srcval = fetch_data_word(srcoffset);
6608        DECODE_PRINTF("\n");
6609        TRACE_AND_STEP();
6610        *destreg = srcval;
6611        break;
6612    case 1:
6613        destreg = decode_rm_seg_register(rh);
6614        DECODE_PRINTF(",");
6615        srcoffset = decode_rm01_address(rl);
6616        srcval = fetch_data_word(srcoffset);
6617        DECODE_PRINTF("\n");
6618        TRACE_AND_STEP();
6619        *destreg = srcval;
6620        break;
6621    case 2:
6622        destreg = decode_rm_seg_register(rh);
6623        DECODE_PRINTF(",");
6624        srcoffset = decode_rm10_address(rl);
6625        srcval = fetch_data_word(srcoffset);
6626        DECODE_PRINTF("\n");
6627        TRACE_AND_STEP();
6628        *destreg = srcval;
6629        break;
6630    case 3:                     /* register to register */
6631        destreg = decode_rm_seg_register(rh);
6632        DECODE_PRINTF(",");
6633        srcreg = DECODE_RM_WORD_REGISTER(rl);
6634        DECODE_PRINTF("\n");
6635        TRACE_AND_STEP();
6636        *destreg = *srcreg;
6637        break;
6638    }
6639    /*
6640     * Clean up, and reset all the R_xSP pointers to the correct
6641     * locations.  This is about 3x too much overhead (doing all the
6642     * segreg ptrs when only one is needed, but this instruction
6643     * *cannot* be that common, and this isn't too much work anyway.
6644     */
6645    DECODE_CLEAR_SEGOVR();
6646    END_OF_INSTR();
6647}
6648
6649/****************************************************************************
6650REMARKS:
6651Handles opcode 0x8f
6652****************************************************************************/
6653void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6654{
6655    int mod, rl, rh;
6656    uint destoffset;
6657
6658    START_OF_INSTR();
6659    DECODE_PRINTF("POP\t");
6660    FETCH_DECODE_MODRM(mod, rh, rl);
6661    if (rh != 0) {
6662        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6663        HALT_SYS();
6664    }
6665    switch (mod) {
6666    case 0:
6667        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6668            u32 destval;
6669
6670            destoffset = decode_rm00_address(rl);
6671            DECODE_PRINTF("\n");
6672            TRACE_AND_STEP();
6673            destval = pop_long();
6674            store_data_long(destoffset, destval);
6675        } else {
6676            u16 destval;
6677
6678            destoffset = decode_rm00_address(rl);
6679            DECODE_PRINTF("\n");
6680            TRACE_AND_STEP();
6681            destval = pop_word();
6682            store_data_word(destoffset, destval);
6683        }
6684        break;
6685    case 1:
6686        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6687            u32 destval;
6688
6689            destoffset = decode_rm01_address(rl);
6690            DECODE_PRINTF("\n");
6691            TRACE_AND_STEP();
6692            destval = pop_long();
6693            store_data_long(destoffset, destval);
6694        } else {
6695            u16 destval;
6696
6697            destoffset = decode_rm01_address(rl);
6698            DECODE_PRINTF("\n");
6699            TRACE_AND_STEP();
6700            destval = pop_word();
6701            store_data_word(destoffset, destval);
6702        }
6703        break;
6704    case 2:
6705        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6706            u32 destval;
6707
6708            destoffset = decode_rm10_address(rl);
6709            DECODE_PRINTF("\n");
6710            TRACE_AND_STEP();
6711            destval = pop_long();
6712            store_data_long(destoffset, destval);
6713        } else {
6714            u16 destval;
6715
6716            destoffset = decode_rm10_address(rl);
6717            DECODE_PRINTF("\n");
6718            TRACE_AND_STEP();
6719            destval = pop_word();
6720            store_data_word(destoffset, destval);
6721        }
6722        break;
6723    case 3:                     /* register to register */
6724        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6725            u32 *destreg;
6726
6727            destreg = DECODE_RM_LONG_REGISTER(rl);
6728            DECODE_PRINTF("\n");
6729            TRACE_AND_STEP();
6730            *destreg = pop_long();
6731        } else {
6732            u16 *destreg;
6733
6734            destreg = DECODE_RM_WORD_REGISTER(rl);
6735            DECODE_PRINTF("\n");
6736            TRACE_AND_STEP();
6737            *destreg = pop_word();
6738        }
6739        break;
6740    }
6741    DECODE_CLEAR_SEGOVR();
6742    END_OF_INSTR();
6743}
6744
6745/****************************************************************************
6746REMARKS:
6747Handles opcode 0x90
6748****************************************************************************/
6749void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6750{
6751    START_OF_INSTR();
6752    DECODE_PRINTF("NOP\n");
6753    TRACE_AND_STEP();
6754    DECODE_CLEAR_SEGOVR();
6755    END_OF_INSTR();
6756}
6757
6758/****************************************************************************
6759REMARKS:
6760Handles opcode 0x91
6761****************************************************************************/
6762void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6763{
6764    u32 tmp;
6765
6766    START_OF_INSTR();
6767    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6768        DECODE_PRINTF("XCHG\tEAX,ECX\n");
6769    } else {
6770        DECODE_PRINTF("XCHG\tAX,CX\n");
6771    }
6772    TRACE_AND_STEP();
6773    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6774        tmp = M.x86.R_EAX;
6775        M.x86.R_EAX = M.x86.R_ECX;
6776        M.x86.R_ECX = tmp;
6777    } else {
6778        tmp = M.x86.R_AX;
6779        M.x86.R_AX = M.x86.R_CX;
6780        M.x86.R_CX = (u16)tmp;
6781    }
6782    DECODE_CLEAR_SEGOVR();
6783    END_OF_INSTR();
6784}
6785
6786/****************************************************************************
6787REMARKS:
6788Handles opcode 0x92
6789****************************************************************************/
6790void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6791{
6792    u32 tmp;
6793
6794    START_OF_INSTR();
6795    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6796        DECODE_PRINTF("XCHG\tEAX,EDX\n");
6797    } else {
6798        DECODE_PRINTF("XCHG\tAX,DX\n");
6799    }
6800    TRACE_AND_STEP();
6801    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6802        tmp = M.x86.R_EAX;
6803        M.x86.R_EAX = M.x86.R_EDX;
6804        M.x86.R_EDX = tmp;
6805    } else {
6806        tmp = M.x86.R_AX;
6807        M.x86.R_AX = M.x86.R_DX;
6808        M.x86.R_DX = (u16)tmp;
6809    }
6810    DECODE_CLEAR_SEGOVR();
6811    END_OF_INSTR();
6812}
6813
6814/****************************************************************************
6815REMARKS:
6816Handles opcode 0x93
6817****************************************************************************/
6818void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6819{
6820    u32 tmp;
6821
6822    START_OF_INSTR();
6823    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6824        DECODE_PRINTF("XCHG\tEAX,EBX\n");
6825    } else {
6826        DECODE_PRINTF("XCHG\tAX,BX\n");
6827    }
6828    TRACE_AND_STEP();
6829    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6830        tmp = M.x86.R_EAX;
6831        M.x86.R_EAX = M.x86.R_EBX;
6832        M.x86.R_EBX = tmp;
6833    } else {
6834        tmp = M.x86.R_AX;
6835        M.x86.R_AX = M.x86.R_BX;
6836        M.x86.R_BX = (u16)tmp;
6837    }
6838    DECODE_CLEAR_SEGOVR();
6839    END_OF_INSTR();
6840}
6841
6842/****************************************************************************
6843REMARKS:
6844Handles opcode 0x94
6845****************************************************************************/
6846void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6847{
6848    u32 tmp;
6849
6850    START_OF_INSTR();
6851    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6852        DECODE_PRINTF("XCHG\tEAX,ESP\n");
6853    } else {
6854        DECODE_PRINTF("XCHG\tAX,SP\n");
6855    }
6856    TRACE_AND_STEP();
6857    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6858        tmp = M.x86.R_EAX;
6859        M.x86.R_EAX = M.x86.R_ESP;
6860        M.x86.R_ESP = tmp;
6861    } else {
6862        tmp = M.x86.R_AX;
6863        M.x86.R_AX = M.x86.R_SP;
6864        M.x86.R_SP = (u16)tmp;
6865    }
6866    DECODE_CLEAR_SEGOVR();
6867    END_OF_INSTR();
6868}
6869
6870/****************************************************************************
6871REMARKS:
6872Handles opcode 0x95
6873****************************************************************************/
6874void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6875{
6876    u32 tmp;
6877
6878    START_OF_INSTR();
6879    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6880        DECODE_PRINTF("XCHG\tEAX,EBP\n");
6881    } else {
6882        DECODE_PRINTF("XCHG\tAX,BP\n");
6883    }
6884    TRACE_AND_STEP();
6885    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6886        tmp = M.x86.R_EAX;
6887        M.x86.R_EAX = M.x86.R_EBP;
6888        M.x86.R_EBP = tmp;
6889    } else {
6890        tmp = M.x86.R_AX;
6891        M.x86.R_AX = M.x86.R_BP;
6892        M.x86.R_BP = (u16)tmp;
6893    }
6894    DECODE_CLEAR_SEGOVR();
6895    END_OF_INSTR();
6896}
6897
6898/****************************************************************************
6899REMARKS:
6900Handles opcode 0x96
6901****************************************************************************/
6902void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6903{
6904    u32 tmp;
6905
6906    START_OF_INSTR();
6907    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6908        DECODE_PRINTF("XCHG\tEAX,ESI\n");
6909    } else {
6910        DECODE_PRINTF("XCHG\tAX,SI\n");
6911    }
6912    TRACE_AND_STEP();
6913    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6914        tmp = M.x86.R_EAX;
6915        M.x86.R_EAX = M.x86.R_ESI;
6916        M.x86.R_ESI = tmp;
6917    } else {
6918        tmp = M.x86.R_AX;
6919        M.x86.R_AX = M.x86.R_SI;
6920        M.x86.R_SI = (u16)tmp;
6921    }
6922    DECODE_CLEAR_SEGOVR();
6923    END_OF_INSTR();
6924}
6925
6926/****************************************************************************
6927REMARKS:
6928Handles opcode 0x97
6929****************************************************************************/
6930void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6931{
6932    u32 tmp;
6933
6934    START_OF_INSTR();
6935    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6936        DECODE_PRINTF("XCHG\tEAX,EDI\n");
6937    } else {
6938        DECODE_PRINTF("XCHG\tAX,DI\n");
6939    }
6940    TRACE_AND_STEP();
6941    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6942        tmp = M.x86.R_EAX;
6943        M.x86.R_EAX = M.x86.R_EDI;
6944        M.x86.R_EDI = tmp;
6945    } else {
6946        tmp = M.x86.R_AX;
6947        M.x86.R_AX = M.x86.R_DI;
6948        M.x86.R_DI = (u16)tmp;
6949    }
6950    DECODE_CLEAR_SEGOVR();
6951    END_OF_INSTR();
6952}
6953
6954/****************************************************************************
6955REMARKS:
6956Handles opcode 0x98
6957****************************************************************************/
6958void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
6959{
6960    START_OF_INSTR();
6961    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6962        DECODE_PRINTF("CWDE\n");
6963    } else {
6964        DECODE_PRINTF("CBW\n");
6965    }
6966    TRACE_AND_STEP();
6967    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6968        if (M.x86.R_AX & 0x8000) {
6969            M.x86.R_EAX |= 0xffff0000;
6970        } else {
6971            M.x86.R_EAX &= 0x0000ffff;
6972        }
6973    } else {
6974        if (M.x86.R_AL & 0x80) {
6975            M.x86.R_AH = 0xff;
6976        } else {
6977            M.x86.R_AH = 0x0;
6978        }
6979    }
6980    DECODE_CLEAR_SEGOVR();
6981    END_OF_INSTR();
6982}
6983
6984/****************************************************************************
6985REMARKS:
6986Handles opcode 0x99
6987****************************************************************************/
6988void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
6989{
6990    START_OF_INSTR();
6991    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6992        DECODE_PRINTF("CDQ\n");
6993    } else {
6994        DECODE_PRINTF("CWD\n");
6995    }
6996    DECODE_PRINTF("CWD\n");
6997    TRACE_AND_STEP();
6998    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6999        if (M.x86.R_EAX & 0x80000000) {
7000            M.x86.R_EDX = 0xffffffff;
7001        } else {
7002            M.x86.R_EDX = 0x0;
7003        }
7004    } else {
7005        if (M.x86.R_AX & 0x8000) {
7006            M.x86.R_DX = 0xffff;
7007        } else {
7008            M.x86.R_DX = 0x0;
7009        }
7010    }
7011    DECODE_CLEAR_SEGOVR();
7012    END_OF_INSTR();
7013}
7014
7015/****************************************************************************
7016REMARKS:
7017Handles opcode 0x9a
7018****************************************************************************/
7019void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7020{
7021    u16 farseg, faroff;
7022
7023    START_OF_INSTR();
7024	DECODE_PRINTF("CALL\t");
7025	faroff = fetch_word_imm();
7026	farseg = fetch_word_imm();
7027	DECODE_PRINTF2("%04x:", farseg);
7028	DECODE_PRINTF2("%04x\n", faroff);
7029	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7030
7031    TRACE_AND_STEP();
7032    push_word(M.x86.R_CS);
7033    M.x86.R_CS = farseg;
7034    push_word(M.x86.R_IP);
7035    M.x86.R_IP = faroff;
7036    DECODE_CLEAR_SEGOVR();
7037    END_OF_INSTR();
7038}
7039
7040/****************************************************************************
7041REMARKS:
7042Handles opcode 0x9b
7043****************************************************************************/
7044void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7045{
7046    START_OF_INSTR();
7047    DECODE_PRINTF("WAIT");
7048    TRACE_AND_STEP();
7049    /* NADA.  */
7050    DECODE_CLEAR_SEGOVR();
7051    END_OF_INSTR();
7052}
7053
7054/****************************************************************************
7055REMARKS:
7056Handles opcode 0x9c
7057****************************************************************************/
7058void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7059{
7060    u32 flags;
7061
7062    START_OF_INSTR();
7063    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7064        DECODE_PRINTF("PUSHFD\n");
7065    } else {
7066        DECODE_PRINTF("PUSHF\n");
7067    }
7068    TRACE_AND_STEP();
7069
7070    /* clear out *all* bits not representing flags, and turn on real bits */
7071    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7072    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7073        push_long(flags);
7074    } else {
7075        push_word((u16)flags);
7076    }
7077    DECODE_CLEAR_SEGOVR();
7078    END_OF_INSTR();
7079}
7080
7081/****************************************************************************
7082REMARKS:
7083Handles opcode 0x9d
7084****************************************************************************/
7085void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7086{
7087    START_OF_INSTR();
7088    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7089        DECODE_PRINTF("POPFD\n");
7090    } else {
7091        DECODE_PRINTF("POPF\n");
7092    }
7093    TRACE_AND_STEP();
7094    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7095        M.x86.R_EFLG = pop_long();
7096    } else {
7097        M.x86.R_FLG = pop_word();
7098    }
7099    DECODE_CLEAR_SEGOVR();
7100    END_OF_INSTR();
7101}
7102
7103/****************************************************************************
7104REMARKS:
7105Handles opcode 0x9e
7106****************************************************************************/
7107void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7108{
7109    START_OF_INSTR();
7110    DECODE_PRINTF("SAHF\n");
7111    TRACE_AND_STEP();
7112    /* clear the lower bits of the flag register */
7113    M.x86.R_FLG &= 0xffffff00;
7114    /* or in the AH register into the flags register */
7115    M.x86.R_FLG |= M.x86.R_AH;
7116    DECODE_CLEAR_SEGOVR();
7117    END_OF_INSTR();
7118}
7119
7120/****************************************************************************
7121REMARKS:
7122Handles opcode 0x9f
7123****************************************************************************/
7124void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7125{
7126    START_OF_INSTR();
7127    DECODE_PRINTF("LAHF\n");
7128    TRACE_AND_STEP();
7129	M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7130    /*undocumented TC++ behavior??? Nope.  It's documented, but
7131       you have too look real hard to notice it. */
7132    M.x86.R_AH |= 0x2;
7133    DECODE_CLEAR_SEGOVR();
7134    END_OF_INSTR();
7135}
7136
7137/****************************************************************************
7138REMARKS:
7139Handles opcode 0xa0
7140****************************************************************************/
7141void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7142{
7143    u16 offset;
7144
7145    START_OF_INSTR();
7146    DECODE_PRINTF("MOV\tAL,");
7147    offset = fetch_word_imm();
7148    DECODE_PRINTF2("[%04x]\n", offset);
7149    TRACE_AND_STEP();
7150    M.x86.R_AL = fetch_data_byte(offset);
7151    DECODE_CLEAR_SEGOVR();
7152    END_OF_INSTR();
7153}
7154
7155/****************************************************************************
7156REMARKS:
7157Handles opcode 0xa1
7158****************************************************************************/
7159void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7160{
7161    u16 offset;
7162
7163    START_OF_INSTR();
7164    offset = fetch_word_imm();
7165    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7166        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7167    } else {
7168        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7169    }
7170    TRACE_AND_STEP();
7171    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7172        M.x86.R_EAX = fetch_data_long(offset);
7173    } else {
7174        M.x86.R_AX = fetch_data_word(offset);
7175    }
7176    DECODE_CLEAR_SEGOVR();
7177    END_OF_INSTR();
7178}
7179
7180/****************************************************************************
7181REMARKS:
7182Handles opcode 0xa2
7183****************************************************************************/
7184void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7185{
7186    u16 offset;
7187
7188    START_OF_INSTR();
7189    DECODE_PRINTF("MOV\t");
7190    offset = fetch_word_imm();
7191    DECODE_PRINTF2("[%04x],AL\n", offset);
7192    TRACE_AND_STEP();
7193    store_data_byte(offset, M.x86.R_AL);
7194    DECODE_CLEAR_SEGOVR();
7195    END_OF_INSTR();
7196}
7197
7198/****************************************************************************
7199REMARKS:
7200Handles opcode 0xa3
7201****************************************************************************/
7202void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7203{
7204    u16 offset;
7205
7206    START_OF_INSTR();
7207    offset = fetch_word_imm();
7208    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7209        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7210    } else {
7211        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7212    }
7213    TRACE_AND_STEP();
7214    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7215        store_data_long(offset, M.x86.R_EAX);
7216    } else {
7217        store_data_word(offset, M.x86.R_AX);
7218    }
7219    DECODE_CLEAR_SEGOVR();
7220    END_OF_INSTR();
7221}
7222
7223/****************************************************************************
7224REMARKS:
7225Handles opcode 0xa4
7226****************************************************************************/
7227void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7228{
7229    u8  val;
7230    u32 count;
7231    int inc;
7232
7233    START_OF_INSTR();
7234    DECODE_PRINTF("MOVS\tBYTE\n");
7235    if (ACCESS_FLAG(F_DF))   /* down */
7236        inc = -1;
7237    else
7238        inc = 1;
7239    TRACE_AND_STEP();
7240    count = 1;
7241    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7242        /* dont care whether REPE or REPNE */
7243        /* move them until CX is ZERO. */
7244        count = M.x86.R_CX;
7245        M.x86.R_CX = 0;
7246        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7247    }
7248    while (count--) {
7249        val = fetch_data_byte(M.x86.R_SI);
7250        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7251        M.x86.R_SI += inc;
7252        M.x86.R_DI += inc;
7253    }
7254    DECODE_CLEAR_SEGOVR();
7255    END_OF_INSTR();
7256}
7257
7258/****************************************************************************
7259REMARKS:
7260Handles opcode 0xa5
7261****************************************************************************/
7262void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7263{
7264    u32 val;
7265    int inc;
7266    u32 count;
7267
7268    START_OF_INSTR();
7269    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7270        DECODE_PRINTF("MOVS\tDWORD\n");
7271        if (ACCESS_FLAG(F_DF))      /* down */
7272            inc = -4;
7273        else
7274            inc = 4;
7275    } else {
7276        DECODE_PRINTF("MOVS\tWORD\n");
7277        if (ACCESS_FLAG(F_DF))      /* down */
7278            inc = -2;
7279        else
7280            inc = 2;
7281    }
7282    TRACE_AND_STEP();
7283    count = 1;
7284    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7285        /* dont care whether REPE or REPNE */
7286        /* move them until CX is ZERO. */
7287        count = M.x86.R_CX;
7288        M.x86.R_CX = 0;
7289        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7290    }
7291    while (count--) {
7292        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7293            val = fetch_data_long(M.x86.R_SI);
7294            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7295        } else {
7296            val = fetch_data_word(M.x86.R_SI);
7297            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7298        }
7299        M.x86.R_SI += inc;
7300        M.x86.R_DI += inc;
7301    }
7302    DECODE_CLEAR_SEGOVR();
7303    END_OF_INSTR();
7304}
7305
7306/****************************************************************************
7307REMARKS:
7308Handles opcode 0xa6
7309****************************************************************************/
7310void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7311{
7312    s8 val1, val2;
7313    int inc;
7314
7315    START_OF_INSTR();
7316    DECODE_PRINTF("CMPS\tBYTE\n");
7317    TRACE_AND_STEP();
7318    if (ACCESS_FLAG(F_DF))   /* down */
7319        inc = -1;
7320    else
7321        inc = 1;
7322
7323    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7324        /* REPE  */
7325        /* move them until CX is ZERO. */
7326        while (M.x86.R_CX != 0) {
7327            val1 = fetch_data_byte(M.x86.R_SI);
7328            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7329                     cmp_byte(val1, val2);
7330            M.x86.R_CX -= 1;
7331            M.x86.R_SI += inc;
7332            M.x86.R_DI += inc;
7333            if (ACCESS_FLAG(F_ZF) == 0)
7334                break;
7335        }
7336        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7337    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7338        /* REPNE  */
7339        /* move them until CX is ZERO. */
7340        while (M.x86.R_CX != 0) {
7341            val1 = fetch_data_byte(M.x86.R_SI);
7342            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7343            cmp_byte(val1, val2);
7344            M.x86.R_CX -= 1;
7345            M.x86.R_SI += inc;
7346            M.x86.R_DI += inc;
7347            if (ACCESS_FLAG(F_ZF))
7348                break;          /* zero flag set means equal */
7349        }
7350        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7351    } else {
7352        val1 = fetch_data_byte(M.x86.R_SI);
7353        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7354        cmp_byte(val1, val2);
7355        M.x86.R_SI += inc;
7356        M.x86.R_DI += inc;
7357    }
7358    DECODE_CLEAR_SEGOVR();
7359    END_OF_INSTR();
7360}
7361
7362/****************************************************************************
7363REMARKS:
7364Handles opcode 0xa7
7365****************************************************************************/
7366void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7367{
7368    u32 val1,val2;
7369    int inc;
7370
7371    START_OF_INSTR();
7372    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7373        DECODE_PRINTF("CMPS\tDWORD\n");
7374        if (ACCESS_FLAG(F_DF))   /* down */
7375            inc = -4;
7376        else
7377            inc = 4;
7378    } else {
7379        DECODE_PRINTF("CMPS\tWORD\n");
7380        if (ACCESS_FLAG(F_DF))   /* down */
7381            inc = -2;
7382        else
7383            inc = 2;
7384    }
7385    TRACE_AND_STEP();
7386    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7387        /* REPE  */
7388        /* move them until CX is ZERO. */
7389        while (M.x86.R_CX != 0) {
7390            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7391                val1 = fetch_data_long(M.x86.R_SI);
7392                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7393                cmp_long(val1, val2);
7394            } else {
7395                val1 = fetch_data_word(M.x86.R_SI);
7396                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7397                cmp_word((u16)val1, (u16)val2);
7398            }
7399            M.x86.R_CX -= 1;
7400            M.x86.R_SI += inc;
7401            M.x86.R_DI += inc;
7402            if (ACCESS_FLAG(F_ZF) == 0)
7403                break;
7404        }
7405        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7406    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7407        /* REPNE  */
7408        /* move them until CX is ZERO. */
7409        while (M.x86.R_CX != 0) {
7410            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7411                val1 = fetch_data_long(M.x86.R_SI);
7412                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7413                cmp_long(val1, val2);
7414            } else {
7415                val1 = fetch_data_word(M.x86.R_SI);
7416                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7417                cmp_word((u16)val1, (u16)val2);
7418            }
7419            M.x86.R_CX -= 1;
7420            M.x86.R_SI += inc;
7421            M.x86.R_DI += inc;
7422            if (ACCESS_FLAG(F_ZF))
7423                break;          /* zero flag set means equal */
7424        }
7425        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7426    } else {
7427        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7428            val1 = fetch_data_long(M.x86.R_SI);
7429            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7430            cmp_long(val1, val2);
7431        } else {
7432            val1 = fetch_data_word(M.x86.R_SI);
7433            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7434            cmp_word((u16)val1, (u16)val2);
7435        }
7436        M.x86.R_SI += inc;
7437        M.x86.R_DI += inc;
7438    }
7439    DECODE_CLEAR_SEGOVR();
7440    END_OF_INSTR();
7441}
7442
7443/****************************************************************************
7444REMARKS:
7445Handles opcode 0xa8
7446****************************************************************************/
7447void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7448{
7449    int imm;
7450
7451    START_OF_INSTR();
7452    DECODE_PRINTF("TEST\tAL,");
7453    imm = fetch_byte_imm();
7454    DECODE_PRINTF2("%04x\n", imm);
7455    TRACE_AND_STEP();
7456	test_byte(M.x86.R_AL, (u8)imm);
7457    DECODE_CLEAR_SEGOVR();
7458    END_OF_INSTR();
7459}
7460
7461/****************************************************************************
7462REMARKS:
7463Handles opcode 0xa9
7464****************************************************************************/
7465void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7466{
7467    u32 srcval;
7468
7469    START_OF_INSTR();
7470    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7471        DECODE_PRINTF("TEST\tEAX,");
7472        srcval = fetch_long_imm();
7473    } else {
7474        DECODE_PRINTF("TEST\tAX,");
7475        srcval = fetch_word_imm();
7476    }
7477    DECODE_PRINTF2("%x\n", srcval);
7478    TRACE_AND_STEP();
7479    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7480        test_long(M.x86.R_EAX, srcval);
7481    } else {
7482        test_word(M.x86.R_AX, (u16)srcval);
7483    }
7484    DECODE_CLEAR_SEGOVR();
7485    END_OF_INSTR();
7486}
7487
7488/****************************************************************************
7489REMARKS:
7490Handles opcode 0xaa
7491****************************************************************************/
7492void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7493{
7494    int inc;
7495
7496    START_OF_INSTR();
7497    DECODE_PRINTF("STOS\tBYTE\n");
7498    if (ACCESS_FLAG(F_DF))   /* down */
7499        inc = -1;
7500    else
7501        inc = 1;
7502    TRACE_AND_STEP();
7503    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7504        /* dont care whether REPE or REPNE */
7505        /* move them until CX is ZERO. */
7506        while (M.x86.R_CX != 0) {
7507            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7508            M.x86.R_CX -= 1;
7509            M.x86.R_DI += inc;
7510        }
7511        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7512    } else {
7513        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7514        M.x86.R_DI += inc;
7515    }
7516    DECODE_CLEAR_SEGOVR();
7517    END_OF_INSTR();
7518}
7519
7520/****************************************************************************
7521REMARKS:
7522Handles opcode 0xab
7523****************************************************************************/
7524void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7525{
7526    int inc;
7527    u32 count;
7528
7529    START_OF_INSTR();
7530    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7531        DECODE_PRINTF("STOS\tDWORD\n");
7532        if (ACCESS_FLAG(F_DF))   /* down */
7533            inc = -4;
7534        else
7535            inc = 4;
7536    } else {
7537        DECODE_PRINTF("STOS\tWORD\n");
7538        if (ACCESS_FLAG(F_DF))   /* down */
7539            inc = -2;
7540        else
7541            inc = 2;
7542    }
7543    TRACE_AND_STEP();
7544    count = 1;
7545    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7546        /* dont care whether REPE or REPNE */
7547        /* move them until CX is ZERO. */
7548        count = M.x86.R_CX;
7549        M.x86.R_CX = 0;
7550        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7551    }
7552    while (count--) {
7553        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7554            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7555        } else {
7556            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7557        }
7558        M.x86.R_DI += inc;
7559    }
7560    DECODE_CLEAR_SEGOVR();
7561    END_OF_INSTR();
7562}
7563
7564/****************************************************************************
7565REMARKS:
7566Handles opcode 0xac
7567****************************************************************************/
7568void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7569{
7570    int inc;
7571
7572    START_OF_INSTR();
7573    DECODE_PRINTF("LODS\tBYTE\n");
7574    TRACE_AND_STEP();
7575    if (ACCESS_FLAG(F_DF))   /* down */
7576        inc = -1;
7577    else
7578        inc = 1;
7579    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7580        /* dont care whether REPE or REPNE */
7581        /* move them until CX is ZERO. */
7582        while (M.x86.R_CX != 0) {
7583            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7584            M.x86.R_CX -= 1;
7585            M.x86.R_SI += inc;
7586        }
7587        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7588    } else {
7589        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7590        M.x86.R_SI += inc;
7591    }
7592    DECODE_CLEAR_SEGOVR();
7593    END_OF_INSTR();
7594}
7595
7596/****************************************************************************
7597REMARKS:
7598Handles opcode 0xad
7599****************************************************************************/
7600void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7601{
7602    int inc;
7603    u32 count;
7604
7605    START_OF_INSTR();
7606    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7607        DECODE_PRINTF("LODS\tDWORD\n");
7608        if (ACCESS_FLAG(F_DF))   /* down */
7609            inc = -4;
7610        else
7611            inc = 4;
7612    } else {
7613        DECODE_PRINTF("LODS\tWORD\n");
7614        if (ACCESS_FLAG(F_DF))   /* down */
7615            inc = -2;
7616        else
7617            inc = 2;
7618    }
7619    TRACE_AND_STEP();
7620    count = 1;
7621    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7622        /* dont care whether REPE or REPNE */
7623        /* move them until CX is ZERO. */
7624        count = M.x86.R_CX;
7625        M.x86.R_CX = 0;
7626        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7627    }
7628    while (count--) {
7629        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7630            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7631        } else {
7632            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7633        }
7634        M.x86.R_SI += inc;
7635    }
7636    DECODE_CLEAR_SEGOVR();
7637    END_OF_INSTR();
7638}
7639
7640/****************************************************************************
7641REMARKS:
7642Handles opcode 0xae
7643****************************************************************************/
7644void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7645{
7646    s8 val2;
7647    int inc;
7648
7649    START_OF_INSTR();
7650    DECODE_PRINTF("SCAS\tBYTE\n");
7651    TRACE_AND_STEP();
7652    if (ACCESS_FLAG(F_DF))   /* down */
7653        inc = -1;
7654    else
7655        inc = 1;
7656    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7657        /* REPE  */
7658        /* move them until CX is ZERO. */
7659        while (M.x86.R_CX != 0) {
7660            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7661            cmp_byte(M.x86.R_AL, val2);
7662            M.x86.R_CX -= 1;
7663            M.x86.R_DI += inc;
7664            if (ACCESS_FLAG(F_ZF) == 0)
7665                break;
7666        }
7667        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7668    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7669        /* REPNE  */
7670        /* move them until CX is ZERO. */
7671        while (M.x86.R_CX != 0) {
7672            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7673            cmp_byte(M.x86.R_AL, val2);
7674            M.x86.R_CX -= 1;
7675            M.x86.R_DI += inc;
7676            if (ACCESS_FLAG(F_ZF))
7677                break;          /* zero flag set means equal */
7678        }
7679        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7680    } else {
7681        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7682        cmp_byte(M.x86.R_AL, val2);
7683        M.x86.R_DI += inc;
7684    }
7685    DECODE_CLEAR_SEGOVR();
7686    END_OF_INSTR();
7687}
7688
7689/****************************************************************************
7690REMARKS:
7691Handles opcode 0xaf
7692****************************************************************************/
7693void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7694{
7695    int inc;
7696    u32 val;
7697
7698    START_OF_INSTR();
7699    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7700        DECODE_PRINTF("SCAS\tDWORD\n");
7701        if (ACCESS_FLAG(F_DF))   /* down */
7702            inc = -4;
7703        else
7704            inc = 4;
7705    } else {
7706        DECODE_PRINTF("SCAS\tWORD\n");
7707        if (ACCESS_FLAG(F_DF))   /* down */
7708            inc = -2;
7709        else
7710            inc = 2;
7711    }
7712    TRACE_AND_STEP();
7713    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7714        /* REPE  */
7715        /* move them until CX is ZERO. */
7716        while (M.x86.R_CX != 0) {
7717            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7718                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7719                cmp_long(M.x86.R_EAX, val);
7720            } else {
7721                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7722                cmp_word(M.x86.R_AX, (u16)val);
7723            }
7724            M.x86.R_CX -= 1;
7725            M.x86.R_DI += inc;
7726            if (ACCESS_FLAG(F_ZF) == 0)
7727                break;
7728        }
7729        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7730    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7731        /* REPNE  */
7732        /* move them until CX is ZERO. */
7733        while (M.x86.R_CX != 0) {
7734            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7735                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7736                cmp_long(M.x86.R_EAX, val);
7737            } else {
7738                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7739                cmp_word(M.x86.R_AX, (u16)val);
7740            }
7741            M.x86.R_CX -= 1;
7742            M.x86.R_DI += inc;
7743            if (ACCESS_FLAG(F_ZF))
7744                break;          /* zero flag set means equal */
7745        }
7746        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7747    } else {
7748        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7749            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7750            cmp_long(M.x86.R_EAX, val);
7751        } else {
7752            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7753            cmp_word(M.x86.R_AX, (u16)val);
7754        }
7755        M.x86.R_DI += inc;
7756    }
7757    DECODE_CLEAR_SEGOVR();
7758    END_OF_INSTR();
7759}
7760
7761/****************************************************************************
7762REMARKS:
7763Handles opcode 0xb0
7764****************************************************************************/
7765void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7766{
7767    u8 imm;
7768
7769    START_OF_INSTR();
7770    DECODE_PRINTF("MOV\tAL,");
7771    imm = fetch_byte_imm();
7772    DECODE_PRINTF2("%x\n", imm);
7773    TRACE_AND_STEP();
7774    M.x86.R_AL = imm;
7775    DECODE_CLEAR_SEGOVR();
7776    END_OF_INSTR();
7777}
7778
7779/****************************************************************************
7780REMARKS:
7781Handles opcode 0xb1
7782****************************************************************************/
7783void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7784{
7785    u8 imm;
7786
7787    START_OF_INSTR();
7788    DECODE_PRINTF("MOV\tCL,");
7789    imm = fetch_byte_imm();
7790    DECODE_PRINTF2("%x\n", imm);
7791    TRACE_AND_STEP();
7792    M.x86.R_CL = imm;
7793    DECODE_CLEAR_SEGOVR();
7794    END_OF_INSTR();
7795}
7796
7797/****************************************************************************
7798REMARKS:
7799Handles opcode 0xb2
7800****************************************************************************/
7801void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7802{
7803    u8 imm;
7804
7805    START_OF_INSTR();
7806    DECODE_PRINTF("MOV\tDL,");
7807    imm = fetch_byte_imm();
7808    DECODE_PRINTF2("%x\n", imm);
7809    TRACE_AND_STEP();
7810    M.x86.R_DL = imm;
7811    DECODE_CLEAR_SEGOVR();
7812    END_OF_INSTR();
7813}
7814
7815/****************************************************************************
7816REMARKS:
7817Handles opcode 0xb3
7818****************************************************************************/
7819void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7820{
7821    u8 imm;
7822
7823    START_OF_INSTR();
7824    DECODE_PRINTF("MOV\tBL,");
7825    imm = fetch_byte_imm();
7826    DECODE_PRINTF2("%x\n", imm);
7827    TRACE_AND_STEP();
7828    M.x86.R_BL = imm;
7829    DECODE_CLEAR_SEGOVR();
7830    END_OF_INSTR();
7831}
7832
7833/****************************************************************************
7834REMARKS:
7835Handles opcode 0xb4
7836****************************************************************************/
7837void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7838{
7839    u8 imm;
7840
7841    START_OF_INSTR();
7842    DECODE_PRINTF("MOV\tAH,");
7843    imm = fetch_byte_imm();
7844    DECODE_PRINTF2("%x\n", imm);
7845    TRACE_AND_STEP();
7846    M.x86.R_AH = imm;
7847    DECODE_CLEAR_SEGOVR();
7848    END_OF_INSTR();
7849}
7850
7851/****************************************************************************
7852REMARKS:
7853Handles opcode 0xb5
7854****************************************************************************/
7855void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7856{
7857    u8 imm;
7858
7859    START_OF_INSTR();
7860    DECODE_PRINTF("MOV\tCH,");
7861    imm = fetch_byte_imm();
7862    DECODE_PRINTF2("%x\n", imm);
7863    TRACE_AND_STEP();
7864    M.x86.R_CH = imm;
7865    DECODE_CLEAR_SEGOVR();
7866    END_OF_INSTR();
7867}
7868
7869/****************************************************************************
7870REMARKS:
7871Handles opcode 0xb6
7872****************************************************************************/
7873void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7874{
7875    u8 imm;
7876
7877    START_OF_INSTR();
7878    DECODE_PRINTF("MOV\tDH,");
7879    imm = fetch_byte_imm();
7880    DECODE_PRINTF2("%x\n", imm);
7881    TRACE_AND_STEP();
7882    M.x86.R_DH = imm;
7883    DECODE_CLEAR_SEGOVR();
7884    END_OF_INSTR();
7885}
7886
7887/****************************************************************************
7888REMARKS:
7889Handles opcode 0xb7
7890****************************************************************************/
7891void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7892{
7893    u8 imm;
7894
7895    START_OF_INSTR();
7896    DECODE_PRINTF("MOV\tBH,");
7897    imm = fetch_byte_imm();
7898    DECODE_PRINTF2("%x\n", imm);
7899    TRACE_AND_STEP();
7900    M.x86.R_BH = imm;
7901    DECODE_CLEAR_SEGOVR();
7902    END_OF_INSTR();
7903}
7904
7905/****************************************************************************
7906REMARKS:
7907Handles opcode 0xb8
7908****************************************************************************/
7909void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7910{
7911    u32 srcval;
7912
7913    START_OF_INSTR();
7914    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7915        DECODE_PRINTF("MOV\tEAX,");
7916        srcval = fetch_long_imm();
7917    } else {
7918        DECODE_PRINTF("MOV\tAX,");
7919        srcval = fetch_word_imm();
7920    }
7921    DECODE_PRINTF2("%x\n", srcval);
7922    TRACE_AND_STEP();
7923    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7924        M.x86.R_EAX = srcval;
7925    } else {
7926        M.x86.R_AX = (u16)srcval;
7927    }
7928    DECODE_CLEAR_SEGOVR();
7929    END_OF_INSTR();
7930}
7931
7932/****************************************************************************
7933REMARKS:
7934Handles opcode 0xb9
7935****************************************************************************/
7936void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7937{
7938    u32 srcval;
7939
7940    START_OF_INSTR();
7941    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7942        DECODE_PRINTF("MOV\tECX,");
7943        srcval = fetch_long_imm();
7944    } else {
7945        DECODE_PRINTF("MOV\tCX,");
7946        srcval = fetch_word_imm();
7947    }
7948    DECODE_PRINTF2("%x\n", srcval);
7949    TRACE_AND_STEP();
7950    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7951        M.x86.R_ECX = srcval;
7952    } else {
7953        M.x86.R_CX = (u16)srcval;
7954    }
7955    DECODE_CLEAR_SEGOVR();
7956    END_OF_INSTR();
7957}
7958
7959/****************************************************************************
7960REMARKS:
7961Handles opcode 0xba
7962****************************************************************************/
7963void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
7964{
7965    u32 srcval;
7966
7967    START_OF_INSTR();
7968    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7969        DECODE_PRINTF("MOV\tEDX,");
7970        srcval = fetch_long_imm();
7971    } else {
7972        DECODE_PRINTF("MOV\tDX,");
7973        srcval = fetch_word_imm();
7974    }
7975    DECODE_PRINTF2("%x\n", srcval);
7976    TRACE_AND_STEP();
7977    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7978        M.x86.R_EDX = srcval;
7979    } else {
7980        M.x86.R_DX = (u16)srcval;
7981    }
7982    DECODE_CLEAR_SEGOVR();
7983    END_OF_INSTR();
7984}
7985
7986/****************************************************************************
7987REMARKS:
7988Handles opcode 0xbb
7989****************************************************************************/
7990void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
7991{
7992    u32 srcval;
7993
7994    START_OF_INSTR();
7995    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7996        DECODE_PRINTF("MOV\tEBX,");
7997        srcval = fetch_long_imm();
7998    } else {
7999        DECODE_PRINTF("MOV\tBX,");
8000        srcval = fetch_word_imm();
8001    }
8002    DECODE_PRINTF2("%x\n", srcval);
8003    TRACE_AND_STEP();
8004    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8005        M.x86.R_EBX = srcval;
8006    } else {
8007        M.x86.R_BX = (u16)srcval;
8008    }
8009    DECODE_CLEAR_SEGOVR();
8010    END_OF_INSTR();
8011}
8012
8013/****************************************************************************
8014REMARKS:
8015Handles opcode 0xbc
8016****************************************************************************/
8017void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8018{
8019    u32 srcval;
8020
8021    START_OF_INSTR();
8022    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023        DECODE_PRINTF("MOV\tESP,");
8024        srcval = fetch_long_imm();
8025    } else {
8026        DECODE_PRINTF("MOV\tSP,");
8027        srcval = fetch_word_imm();
8028    }
8029    DECODE_PRINTF2("%x\n", srcval);
8030    TRACE_AND_STEP();
8031    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8032        M.x86.R_ESP = srcval;
8033    } else {
8034        M.x86.R_SP = (u16)srcval;
8035    }
8036    DECODE_CLEAR_SEGOVR();
8037    END_OF_INSTR();
8038}
8039
8040/****************************************************************************
8041REMARKS:
8042Handles opcode 0xbd
8043****************************************************************************/
8044void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8045{
8046    u32 srcval;
8047
8048    START_OF_INSTR();
8049    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8050        DECODE_PRINTF("MOV\tEBP,");
8051        srcval = fetch_long_imm();
8052    } else {
8053        DECODE_PRINTF("MOV\tBP,");
8054        srcval = fetch_word_imm();
8055    }
8056    DECODE_PRINTF2("%x\n", srcval);
8057    TRACE_AND_STEP();
8058    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8059        M.x86.R_EBP = srcval;
8060    } else {
8061        M.x86.R_BP = (u16)srcval;
8062    }
8063    DECODE_CLEAR_SEGOVR();
8064    END_OF_INSTR();
8065}
8066
8067/****************************************************************************
8068REMARKS:
8069Handles opcode 0xbe
8070****************************************************************************/
8071void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8072{
8073    u32 srcval;
8074
8075    START_OF_INSTR();
8076    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8077        DECODE_PRINTF("MOV\tESI,");
8078        srcval = fetch_long_imm();
8079    } else {
8080        DECODE_PRINTF("MOV\tSI,");
8081        srcval = fetch_word_imm();
8082    }
8083    DECODE_PRINTF2("%x\n", srcval);
8084    TRACE_AND_STEP();
8085    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8086        M.x86.R_ESI = srcval;
8087    } else {
8088        M.x86.R_SI = (u16)srcval;
8089    }
8090    DECODE_CLEAR_SEGOVR();
8091    END_OF_INSTR();
8092}
8093
8094/****************************************************************************
8095REMARKS:
8096Handles opcode 0xbf
8097****************************************************************************/
8098void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8099{
8100    u32 srcval;
8101
8102    START_OF_INSTR();
8103    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104        DECODE_PRINTF("MOV\tEDI,");
8105        srcval = fetch_long_imm();
8106    } else {
8107        DECODE_PRINTF("MOV\tDI,");
8108        srcval = fetch_word_imm();
8109    }
8110    DECODE_PRINTF2("%x\n", srcval);
8111    TRACE_AND_STEP();
8112    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8113        M.x86.R_EDI = srcval;
8114    } else {
8115        M.x86.R_DI = (u16)srcval;
8116    }
8117    DECODE_CLEAR_SEGOVR();
8118    END_OF_INSTR();
8119}
8120
8121/* used by opcodes c0, d0, and d2. */
8122static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8123{
8124    rol_byte,
8125    ror_byte,
8126    rcl_byte,
8127    rcr_byte,
8128    shl_byte,
8129    shr_byte,
8130    shl_byte,           /* sal_byte === shl_byte  by definition */
8131    sar_byte,
8132};
8133
8134/****************************************************************************
8135REMARKS:
8136Handles opcode 0xc0
8137****************************************************************************/
8138void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8139{
8140    int mod, rl, rh;
8141    u8 *destreg;
8142    uint destoffset;
8143    u8 destval;
8144    u8 amt;
8145
8146    /*
8147     * Yet another weirdo special case instruction format.  Part of
8148     * the opcode held below in "RH".  Doubly nested case would
8149     * result, except that the decoded instruction
8150     */
8151    START_OF_INSTR();
8152    FETCH_DECODE_MODRM(mod, rh, rl);
8153#ifdef DEBUG
8154    if (DEBUG_DECODE()) {
8155
8156        switch (rh) {
8157        case 0:
8158            DECODE_PRINTF("ROL\t");
8159            break;
8160        case 1:
8161            DECODE_PRINTF("ROR\t");
8162            break;
8163        case 2:
8164            DECODE_PRINTF("RCL\t");
8165            break;
8166        case 3:
8167            DECODE_PRINTF("RCR\t");
8168            break;
8169        case 4:
8170            DECODE_PRINTF("SHL\t");
8171            break;
8172        case 5:
8173            DECODE_PRINTF("SHR\t");
8174            break;
8175        case 6:
8176            DECODE_PRINTF("SAL\t");
8177            break;
8178        case 7:
8179            DECODE_PRINTF("SAR\t");
8180            break;
8181        }
8182    }
8183#endif
8184    /* know operation, decode the mod byte to find the addressing
8185       mode. */
8186    switch (mod) {
8187    case 0:
8188        DECODE_PRINTF("BYTE PTR ");
8189        destoffset = decode_rm00_address(rl);
8190        amt = fetch_byte_imm();
8191        DECODE_PRINTF2(",%x\n", amt);
8192        destval = fetch_data_byte(destoffset);
8193        TRACE_AND_STEP();
8194        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8195        store_data_byte(destoffset, destval);
8196        break;
8197    case 1:
8198        DECODE_PRINTF("BYTE PTR ");
8199        destoffset = decode_rm01_address(rl);
8200        amt = fetch_byte_imm();
8201        DECODE_PRINTF2(",%x\n", amt);
8202        destval = fetch_data_byte(destoffset);
8203        TRACE_AND_STEP();
8204        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8205        store_data_byte(destoffset, destval);
8206        break;
8207    case 2:
8208        DECODE_PRINTF("BYTE PTR ");
8209        destoffset = decode_rm10_address(rl);
8210        amt = fetch_byte_imm();
8211        DECODE_PRINTF2(",%x\n", amt);
8212        destval = fetch_data_byte(destoffset);
8213        TRACE_AND_STEP();
8214        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8215        store_data_byte(destoffset, destval);
8216        break;
8217    case 3:                     /* register to register */
8218        destreg = DECODE_RM_BYTE_REGISTER(rl);
8219        amt = fetch_byte_imm();
8220        DECODE_PRINTF2(",%x\n", amt);
8221        TRACE_AND_STEP();
8222        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8223        *destreg = destval;
8224        break;
8225    }
8226    DECODE_CLEAR_SEGOVR();
8227    END_OF_INSTR();
8228}
8229
8230/* used by opcodes c1, d1, and d3. */
8231static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8232{
8233    rol_word,
8234    ror_word,
8235    rcl_word,
8236    rcr_word,
8237    shl_word,
8238    shr_word,
8239    shl_word,           /* sal_byte === shl_byte  by definition */
8240    sar_word,
8241};
8242
8243/* used by opcodes c1, d1, and d3. */
8244static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8245{
8246    rol_long,
8247    ror_long,
8248    rcl_long,
8249    rcr_long,
8250    shl_long,
8251    shr_long,
8252    shl_long,           /* sal_byte === shl_byte  by definition */
8253    sar_long,
8254};
8255
8256/****************************************************************************
8257REMARKS:
8258Handles opcode 0xc1
8259****************************************************************************/
8260void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8261{
8262    int mod, rl, rh;
8263    uint destoffset;
8264    u8 amt;
8265
8266    /*
8267     * Yet another weirdo special case instruction format.  Part of
8268     * the opcode held below in "RH".  Doubly nested case would
8269     * result, except that the decoded instruction
8270     */
8271    START_OF_INSTR();
8272    FETCH_DECODE_MODRM(mod, rh, rl);
8273#ifdef DEBUG
8274    if (DEBUG_DECODE()) {
8275
8276        switch (rh) {
8277        case 0:
8278            DECODE_PRINTF("ROL\t");
8279            break;
8280        case 1:
8281            DECODE_PRINTF("ROR\t");
8282            break;
8283        case 2:
8284            DECODE_PRINTF("RCL\t");
8285            break;
8286        case 3:
8287            DECODE_PRINTF("RCR\t");
8288            break;
8289        case 4:
8290            DECODE_PRINTF("SHL\t");
8291            break;
8292        case 5:
8293            DECODE_PRINTF("SHR\t");
8294            break;
8295        case 6:
8296            DECODE_PRINTF("SAL\t");
8297            break;
8298        case 7:
8299            DECODE_PRINTF("SAR\t");
8300            break;
8301        }
8302    }
8303#endif
8304    /* know operation, decode the mod byte to find the addressing
8305       mode. */
8306    switch (mod) {
8307    case 0:
8308        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8309            u32 destval;
8310
8311            DECODE_PRINTF("DWORD PTR ");
8312            destoffset = decode_rm00_address(rl);
8313            amt = fetch_byte_imm();
8314            DECODE_PRINTF2(",%x\n", amt);
8315            destval = fetch_data_long(destoffset);
8316            TRACE_AND_STEP();
8317            destval = (*opcD1_long_operation[rh]) (destval, amt);
8318            store_data_long(destoffset, destval);
8319        } else {
8320            u16 destval;
8321
8322            DECODE_PRINTF("WORD PTR ");
8323            destoffset = decode_rm00_address(rl);
8324            amt = fetch_byte_imm();
8325            DECODE_PRINTF2(",%x\n", amt);
8326            destval = fetch_data_word(destoffset);
8327            TRACE_AND_STEP();
8328            destval = (*opcD1_word_operation[rh]) (destval, amt);
8329            store_data_word(destoffset, destval);
8330        }
8331        break;
8332    case 1:
8333        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8334            u32 destval;
8335
8336            DECODE_PRINTF("DWORD PTR ");
8337            destoffset = decode_rm01_address(rl);
8338            amt = fetch_byte_imm();
8339            DECODE_PRINTF2(",%x\n", amt);
8340            destval = fetch_data_long(destoffset);
8341            TRACE_AND_STEP();
8342            destval = (*opcD1_long_operation[rh]) (destval, amt);
8343            store_data_long(destoffset, destval);
8344        } else {
8345            u16 destval;
8346
8347            DECODE_PRINTF("WORD PTR ");
8348            destoffset = decode_rm01_address(rl);
8349            amt = fetch_byte_imm();
8350            DECODE_PRINTF2(",%x\n", amt);
8351            destval = fetch_data_word(destoffset);
8352            TRACE_AND_STEP();
8353            destval = (*opcD1_word_operation[rh]) (destval, amt);
8354            store_data_word(destoffset, destval);
8355        }
8356        break;
8357    case 2:
8358        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8359            u32 destval;
8360
8361            DECODE_PRINTF("DWORD PTR ");
8362            destoffset = decode_rm10_address(rl);
8363            amt = fetch_byte_imm();
8364            DECODE_PRINTF2(",%x\n", amt);
8365            destval = fetch_data_long(destoffset);
8366            TRACE_AND_STEP();
8367            destval = (*opcD1_long_operation[rh]) (destval, amt);
8368            store_data_long(destoffset, destval);
8369        } else {
8370            u16 destval;
8371
8372            DECODE_PRINTF("WORD PTR ");
8373            destoffset = decode_rm10_address(rl);
8374            amt = fetch_byte_imm();
8375            DECODE_PRINTF2(",%x\n", amt);
8376            destval = fetch_data_word(destoffset);
8377            TRACE_AND_STEP();
8378            destval = (*opcD1_word_operation[rh]) (destval, amt);
8379            store_data_word(destoffset, destval);
8380        }
8381        break;
8382    case 3:                     /* register to register */
8383        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8384            u32 *destreg;
8385
8386            destreg = DECODE_RM_LONG_REGISTER(rl);
8387            amt = fetch_byte_imm();
8388            DECODE_PRINTF2(",%x\n", amt);
8389            TRACE_AND_STEP();
8390            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8391        } else {
8392            u16 *destreg;
8393
8394            destreg = DECODE_RM_WORD_REGISTER(rl);
8395            amt = fetch_byte_imm();
8396            DECODE_PRINTF2(",%x\n", amt);
8397            TRACE_AND_STEP();
8398            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8399        }
8400        break;
8401    }
8402    DECODE_CLEAR_SEGOVR();
8403    END_OF_INSTR();
8404}
8405
8406/****************************************************************************
8407REMARKS:
8408Handles opcode 0xc2
8409****************************************************************************/
8410void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8411{
8412    u16 imm;
8413
8414    START_OF_INSTR();
8415    DECODE_PRINTF("RET\t");
8416    imm = fetch_word_imm();
8417    DECODE_PRINTF2("%x\n", imm);
8418	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8419	TRACE_AND_STEP();
8420    M.x86.R_IP = pop_word();
8421    M.x86.R_SP += imm;
8422    DECODE_CLEAR_SEGOVR();
8423    END_OF_INSTR();
8424}
8425
8426/****************************************************************************
8427REMARKS:
8428Handles opcode 0xc3
8429****************************************************************************/
8430void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8431{
8432    START_OF_INSTR();
8433    DECODE_PRINTF("RET\n");
8434	RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8435	TRACE_AND_STEP();
8436    M.x86.R_IP = pop_word();
8437    DECODE_CLEAR_SEGOVR();
8438    END_OF_INSTR();
8439}
8440
8441/****************************************************************************
8442REMARKS:
8443Handles opcode 0xc4
8444****************************************************************************/
8445void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8446{
8447    int mod, rh, rl;
8448    u16 *dstreg;
8449    uint srcoffset;
8450
8451    START_OF_INSTR();
8452    DECODE_PRINTF("LES\t");
8453    FETCH_DECODE_MODRM(mod, rh, rl);
8454    switch (mod) {
8455    case 0:
8456        dstreg = DECODE_RM_WORD_REGISTER(rh);
8457        DECODE_PRINTF(",");
8458        srcoffset = decode_rm00_address(rl);
8459        DECODE_PRINTF("\n");
8460        TRACE_AND_STEP();
8461        *dstreg = fetch_data_word(srcoffset);
8462        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8463        break;
8464    case 1:
8465        dstreg = DECODE_RM_WORD_REGISTER(rh);
8466        DECODE_PRINTF(",");
8467        srcoffset = decode_rm01_address(rl);
8468        DECODE_PRINTF("\n");
8469        TRACE_AND_STEP();
8470        *dstreg = fetch_data_word(srcoffset);
8471        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8472        break;
8473    case 2:
8474        dstreg = DECODE_RM_WORD_REGISTER(rh);
8475        DECODE_PRINTF(",");
8476        srcoffset = decode_rm10_address(rl);
8477        DECODE_PRINTF("\n");
8478        TRACE_AND_STEP();
8479        *dstreg = fetch_data_word(srcoffset);
8480        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8481        break;
8482    case 3:                     /* register to register */
8483        /* UNDEFINED! */
8484        TRACE_AND_STEP();
8485    }
8486    DECODE_CLEAR_SEGOVR();
8487    END_OF_INSTR();
8488}
8489
8490/****************************************************************************
8491REMARKS:
8492Handles opcode 0xc5
8493****************************************************************************/
8494void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8495{
8496    int mod, rh, rl;
8497    u16 *dstreg;
8498    uint srcoffset;
8499
8500    START_OF_INSTR();
8501    DECODE_PRINTF("LDS\t");
8502    FETCH_DECODE_MODRM(mod, rh, rl);
8503    switch (mod) {
8504    case 0:
8505        dstreg = DECODE_RM_WORD_REGISTER(rh);
8506        DECODE_PRINTF(",");
8507        srcoffset = decode_rm00_address(rl);
8508        DECODE_PRINTF("\n");
8509        TRACE_AND_STEP();
8510        *dstreg = fetch_data_word(srcoffset);
8511        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8512        break;
8513    case 1:
8514        dstreg = DECODE_RM_WORD_REGISTER(rh);
8515        DECODE_PRINTF(",");
8516        srcoffset = decode_rm01_address(rl);
8517        DECODE_PRINTF("\n");
8518        TRACE_AND_STEP();
8519        *dstreg = fetch_data_word(srcoffset);
8520        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8521        break;
8522    case 2:
8523        dstreg = DECODE_RM_WORD_REGISTER(rh);
8524        DECODE_PRINTF(",");
8525        srcoffset = decode_rm10_address(rl);
8526        DECODE_PRINTF("\n");
8527        TRACE_AND_STEP();
8528        *dstreg = fetch_data_word(srcoffset);
8529        M.x86.R_DS = fetch_data_word(srcoffset + 2);
8530        break;
8531    case 3:                     /* register to register */
8532        /* UNDEFINED! */
8533        TRACE_AND_STEP();
8534    }
8535    DECODE_CLEAR_SEGOVR();
8536    END_OF_INSTR();
8537}
8538
8539/****************************************************************************
8540REMARKS:
8541Handles opcode 0xc6
8542****************************************************************************/
8543void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8544{
8545    int mod, rl, rh;
8546    u8 *destreg;
8547    uint destoffset;
8548    u8 imm;
8549
8550    START_OF_INSTR();
8551    DECODE_PRINTF("MOV\t");
8552    FETCH_DECODE_MODRM(mod, rh, rl);
8553    if (rh != 0) {
8554        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8555        HALT_SYS();
8556    }
8557    switch (mod) {
8558    case 0:
8559        DECODE_PRINTF("BYTE PTR ");
8560        destoffset = decode_rm00_address(rl);
8561        imm = fetch_byte_imm();
8562        DECODE_PRINTF2(",%2x\n", imm);
8563        TRACE_AND_STEP();
8564        store_data_byte(destoffset, imm);
8565        break;
8566    case 1:
8567        DECODE_PRINTF("BYTE PTR ");
8568        destoffset = decode_rm01_address(rl);
8569        imm = fetch_byte_imm();
8570        DECODE_PRINTF2(",%2x\n", imm);
8571        TRACE_AND_STEP();
8572        store_data_byte(destoffset, imm);
8573        break;
8574    case 2:
8575        DECODE_PRINTF("BYTE PTR ");
8576        destoffset = decode_rm10_address(rl);
8577        imm = fetch_byte_imm();
8578        DECODE_PRINTF2(",%2x\n", imm);
8579        TRACE_AND_STEP();
8580        store_data_byte(destoffset, imm);
8581        break;
8582    case 3:                     /* register to register */
8583        destreg = DECODE_RM_BYTE_REGISTER(rl);
8584        imm = fetch_byte_imm();
8585        DECODE_PRINTF2(",%2x\n", imm);
8586        TRACE_AND_STEP();
8587        *destreg = imm;
8588        break;
8589    }
8590    DECODE_CLEAR_SEGOVR();
8591    END_OF_INSTR();
8592}
8593
8594/****************************************************************************
8595REMARKS:
8596Handles opcode 0xc7
8597****************************************************************************/
8598void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8599{
8600    int mod, rl, rh;
8601    uint destoffset;
8602
8603    START_OF_INSTR();
8604    DECODE_PRINTF("MOV\t");
8605    FETCH_DECODE_MODRM(mod, rh, rl);
8606    if (rh != 0) {
8607        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8608        HALT_SYS();
8609    }
8610    switch (mod) {
8611    case 0:
8612        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613            u32 imm;
8614
8615            DECODE_PRINTF("DWORD PTR ");
8616            destoffset = decode_rm00_address(rl);
8617            imm = fetch_long_imm();
8618            DECODE_PRINTF2(",%x\n", imm);
8619            TRACE_AND_STEP();
8620            store_data_long(destoffset, imm);
8621        } else {
8622            u16 imm;
8623
8624            DECODE_PRINTF("WORD PTR ");
8625            destoffset = decode_rm00_address(rl);
8626            imm = fetch_word_imm();
8627            DECODE_PRINTF2(",%x\n", imm);
8628            TRACE_AND_STEP();
8629            store_data_word(destoffset, imm);
8630        }
8631        break;
8632    case 1:
8633        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8634            u32 imm;
8635
8636            DECODE_PRINTF("DWORD PTR ");
8637            destoffset = decode_rm01_address(rl);
8638            imm = fetch_long_imm();
8639            DECODE_PRINTF2(",%x\n", imm);
8640            TRACE_AND_STEP();
8641            store_data_long(destoffset, imm);
8642        } else {
8643            u16 imm;
8644
8645            DECODE_PRINTF("WORD PTR ");
8646            destoffset = decode_rm01_address(rl);
8647            imm = fetch_word_imm();
8648            DECODE_PRINTF2(",%x\n", imm);
8649            TRACE_AND_STEP();
8650            store_data_word(destoffset, imm);
8651        }
8652        break;
8653    case 2:
8654        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8655            u32 imm;
8656
8657            DECODE_PRINTF("DWORD PTR ");
8658            destoffset = decode_rm10_address(rl);
8659            imm = fetch_long_imm();
8660            DECODE_PRINTF2(",%x\n", imm);
8661            TRACE_AND_STEP();
8662            store_data_long(destoffset, imm);
8663        } else {
8664            u16 imm;
8665
8666            DECODE_PRINTF("WORD PTR ");
8667            destoffset = decode_rm10_address(rl);
8668            imm = fetch_word_imm();
8669            DECODE_PRINTF2(",%x\n", imm);
8670            TRACE_AND_STEP();
8671            store_data_word(destoffset, imm);
8672        }
8673        break;
8674    case 3:                     /* register to register */
8675        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8676			u32 *destreg;
8677			u32 imm;
8678
8679            destreg = DECODE_RM_LONG_REGISTER(rl);
8680            imm = fetch_long_imm();
8681            DECODE_PRINTF2(",%x\n", imm);
8682            TRACE_AND_STEP();
8683            *destreg = imm;
8684        } else {
8685			u16 *destreg;
8686			u16 imm;
8687
8688            destreg = DECODE_RM_WORD_REGISTER(rl);
8689            imm = fetch_word_imm();
8690            DECODE_PRINTF2(",%x\n", imm);
8691            TRACE_AND_STEP();
8692            *destreg = imm;
8693        }
8694        break;
8695    }
8696    DECODE_CLEAR_SEGOVR();
8697    END_OF_INSTR();
8698}
8699
8700/****************************************************************************
8701REMARKS:
8702Handles opcode 0xc8
8703****************************************************************************/
8704void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8705{
8706    u16 local,frame_pointer;
8707    u8  nesting;
8708    int i;
8709
8710    START_OF_INSTR();
8711    local = fetch_word_imm();
8712    nesting = fetch_byte_imm();
8713    DECODE_PRINTF2("ENTER %x\n", local);
8714    DECODE_PRINTF2(",%x\n", nesting);
8715    TRACE_AND_STEP();
8716    push_word(M.x86.R_BP);
8717    frame_pointer = M.x86.R_SP;
8718    if (nesting > 0) {
8719        for (i = 1; i < nesting; i++) {
8720            M.x86.R_BP -= 2;
8721            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8722            }
8723        push_word(frame_pointer);
8724        }
8725    M.x86.R_BP = frame_pointer;
8726    M.x86.R_SP = (u16)(M.x86.R_SP - local);
8727    DECODE_CLEAR_SEGOVR();
8728    END_OF_INSTR();
8729}
8730
8731/****************************************************************************
8732REMARKS:
8733Handles opcode 0xc9
8734****************************************************************************/
8735void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8736{
8737    START_OF_INSTR();
8738    DECODE_PRINTF("LEAVE\n");
8739    TRACE_AND_STEP();
8740    M.x86.R_SP = M.x86.R_BP;
8741    M.x86.R_BP = pop_word();
8742    DECODE_CLEAR_SEGOVR();
8743    END_OF_INSTR();
8744}
8745
8746/****************************************************************************
8747REMARKS:
8748Handles opcode 0xca
8749****************************************************************************/
8750void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8751{
8752    u16 imm;
8753
8754    START_OF_INSTR();
8755    DECODE_PRINTF("RETF\t");
8756    imm = fetch_word_imm();
8757    DECODE_PRINTF2("%x\n", imm);
8758	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8759	TRACE_AND_STEP();
8760    M.x86.R_IP = pop_word();
8761    M.x86.R_CS = pop_word();
8762    M.x86.R_SP += imm;
8763    DECODE_CLEAR_SEGOVR();
8764    END_OF_INSTR();
8765}
8766
8767/****************************************************************************
8768REMARKS:
8769Handles opcode 0xcb
8770****************************************************************************/
8771void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8772{
8773    START_OF_INSTR();
8774    DECODE_PRINTF("RETF\n");
8775	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8776	TRACE_AND_STEP();
8777    M.x86.R_IP = pop_word();
8778    M.x86.R_CS = pop_word();
8779    DECODE_CLEAR_SEGOVR();
8780    END_OF_INSTR();
8781}
8782
8783/****************************************************************************
8784REMARKS:
8785Handles opcode 0xcc
8786****************************************************************************/
8787void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8788{
8789    u16 tmp;
8790
8791    START_OF_INSTR();
8792    DECODE_PRINTF("INT 3\n");
8793    tmp = (u16) mem_access_word(3 * 4 + 2);
8794    /* access the segment register */
8795    TRACE_AND_STEP();
8796	if (_X86EMU_intrTab[3]) {
8797		(*_X86EMU_intrTab[3])(3);
8798    } else {
8799        push_word((u16)M.x86.R_FLG);
8800        CLEAR_FLAG(F_IF);
8801        CLEAR_FLAG(F_TF);
8802        push_word(M.x86.R_CS);
8803        M.x86.R_CS = mem_access_word(3 * 4 + 2);
8804        push_word(M.x86.R_IP);
8805        M.x86.R_IP = mem_access_word(3 * 4);
8806    }
8807    DECODE_CLEAR_SEGOVR();
8808    END_OF_INSTR();
8809}
8810
8811/****************************************************************************
8812REMARKS:
8813Handles opcode 0xcd
8814****************************************************************************/
8815void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8816{
8817    u16 tmp;
8818    u8 intnum;
8819
8820    START_OF_INSTR();
8821    DECODE_PRINTF("INT\t");
8822    intnum = fetch_byte_imm();
8823    DECODE_PRINTF2("%x\n", intnum);
8824    tmp = mem_access_word(intnum * 4 + 2);
8825    TRACE_AND_STEP();
8826	if (_X86EMU_intrTab[intnum]) {
8827		(*_X86EMU_intrTab[intnum])(intnum);
8828    } else {
8829        push_word((u16)M.x86.R_FLG);
8830        CLEAR_FLAG(F_IF);
8831        CLEAR_FLAG(F_TF);
8832        push_word(M.x86.R_CS);
8833        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8834        push_word(M.x86.R_IP);
8835        M.x86.R_IP = mem_access_word(intnum * 4);
8836    }
8837    DECODE_CLEAR_SEGOVR();
8838    END_OF_INSTR();
8839}
8840
8841/****************************************************************************
8842REMARKS:
8843Handles opcode 0xce
8844****************************************************************************/
8845void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8846{
8847    u16 tmp;
8848
8849    START_OF_INSTR();
8850    DECODE_PRINTF("INTO\n");
8851    TRACE_AND_STEP();
8852    if (ACCESS_FLAG(F_OF)) {
8853        tmp = mem_access_word(4 * 4 + 2);
8854		if (_X86EMU_intrTab[4]) {
8855			(*_X86EMU_intrTab[4])(4);
8856        } else {
8857            push_word((u16)M.x86.R_FLG);
8858            CLEAR_FLAG(F_IF);
8859            CLEAR_FLAG(F_TF);
8860            push_word(M.x86.R_CS);
8861            M.x86.R_CS = mem_access_word(4 * 4 + 2);
8862            push_word(M.x86.R_IP);
8863            M.x86.R_IP = mem_access_word(4 * 4);
8864        }
8865    }
8866    DECODE_CLEAR_SEGOVR();
8867    END_OF_INSTR();
8868}
8869
8870/****************************************************************************
8871REMARKS:
8872Handles opcode 0xcf
8873****************************************************************************/
8874void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8875{
8876    START_OF_INSTR();
8877    DECODE_PRINTF("IRET\n");
8878
8879    TRACE_AND_STEP();
8880
8881    M.x86.R_IP = pop_word();
8882    M.x86.R_CS = pop_word();
8883    M.x86.R_FLG = pop_word();
8884    DECODE_CLEAR_SEGOVR();
8885    END_OF_INSTR();
8886}
8887
8888/****************************************************************************
8889REMARKS:
8890Handles opcode 0xd0
8891****************************************************************************/
8892void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8893{
8894    int mod, rl, rh;
8895    u8 *destreg;
8896    uint destoffset;
8897    u8 destval;
8898
8899    /*
8900     * Yet another weirdo special case instruction format.  Part of
8901     * the opcode held below in "RH".  Doubly nested case would
8902     * result, except that the decoded instruction
8903     */
8904    START_OF_INSTR();
8905    FETCH_DECODE_MODRM(mod, rh, rl);
8906#ifdef DEBUG
8907    if (DEBUG_DECODE()) {
8908        switch (rh) {
8909        case 0:
8910            DECODE_PRINTF("ROL\t");
8911            break;
8912        case 1:
8913            DECODE_PRINTF("ROR\t");
8914            break;
8915        case 2:
8916            DECODE_PRINTF("RCL\t");
8917            break;
8918        case 3:
8919            DECODE_PRINTF("RCR\t");
8920            break;
8921        case 4:
8922            DECODE_PRINTF("SHL\t");
8923            break;
8924        case 5:
8925            DECODE_PRINTF("SHR\t");
8926            break;
8927        case 6:
8928            DECODE_PRINTF("SAL\t");
8929            break;
8930        case 7:
8931            DECODE_PRINTF("SAR\t");
8932            break;
8933        }
8934    }
8935#endif
8936    /* know operation, decode the mod byte to find the addressing
8937       mode. */
8938    switch (mod) {
8939    case 0:
8940        DECODE_PRINTF("BYTE PTR ");
8941        destoffset = decode_rm00_address(rl);
8942        DECODE_PRINTF(",1\n");
8943        destval = fetch_data_byte(destoffset);
8944        TRACE_AND_STEP();
8945        destval = (*opcD0_byte_operation[rh]) (destval, 1);
8946        store_data_byte(destoffset, destval);
8947        break;
8948    case 1:
8949        DECODE_PRINTF("BYTE PTR ");
8950        destoffset = decode_rm01_address(rl);
8951        DECODE_PRINTF(",1\n");
8952        destval = fetch_data_byte(destoffset);
8953        TRACE_AND_STEP();
8954        destval = (*opcD0_byte_operation[rh]) (destval, 1);
8955        store_data_byte(destoffset, destval);
8956        break;
8957    case 2:
8958        DECODE_PRINTF("BYTE PTR ");
8959        destoffset = decode_rm10_address(rl);
8960        DECODE_PRINTF(",1\n");
8961        destval = fetch_data_byte(destoffset);
8962        TRACE_AND_STEP();
8963        destval = (*opcD0_byte_operation[rh]) (destval, 1);
8964        store_data_byte(destoffset, destval);
8965        break;
8966    case 3:                     /* register to register */
8967        destreg = DECODE_RM_BYTE_REGISTER(rl);
8968        DECODE_PRINTF(",1\n");
8969        TRACE_AND_STEP();
8970        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
8971        *destreg = destval;
8972        break;
8973    }
8974    DECODE_CLEAR_SEGOVR();
8975    END_OF_INSTR();
8976}
8977
8978/****************************************************************************
8979REMARKS:
8980Handles opcode 0xd1
8981****************************************************************************/
8982void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
8983{
8984    int mod, rl, rh;
8985    uint destoffset;
8986
8987    /*
8988     * Yet another weirdo special case instruction format.  Part of
8989     * the opcode held below in "RH".  Doubly nested case would
8990     * result, except that the decoded instruction
8991     */
8992    START_OF_INSTR();
8993    FETCH_DECODE_MODRM(mod, rh, rl);
8994#ifdef DEBUG
8995    if (DEBUG_DECODE()) {
8996        switch (rh) {
8997        case 0:
8998            DECODE_PRINTF("ROL\t");
8999            break;
9000        case 1:
9001            DECODE_PRINTF("ROR\t");
9002            break;
9003        case 2:
9004            DECODE_PRINTF("RCL\t");
9005            break;
9006        case 3:
9007            DECODE_PRINTF("RCR\t");
9008            break;
9009        case 4:
9010            DECODE_PRINTF("SHL\t");
9011            break;
9012        case 5:
9013            DECODE_PRINTF("SHR\t");
9014            break;
9015        case 6:
9016            DECODE_PRINTF("SAL\t");
9017            break;
9018        case 7:
9019            DECODE_PRINTF("SAR\t");
9020            break;
9021        }
9022    }
9023#endif
9024    /* know operation, decode the mod byte to find the addressing
9025       mode. */
9026    switch (mod) {
9027    case 0:
9028        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9029            u32 destval;
9030
9031            DECODE_PRINTF("DWORD PTR ");
9032            destoffset = decode_rm00_address(rl);
9033            DECODE_PRINTF(",1\n");
9034            destval = fetch_data_long(destoffset);
9035            TRACE_AND_STEP();
9036            destval = (*opcD1_long_operation[rh]) (destval, 1);
9037            store_data_long(destoffset, destval);
9038        } else {
9039            u16 destval;
9040
9041            DECODE_PRINTF("WORD PTR ");
9042            destoffset = decode_rm00_address(rl);
9043            DECODE_PRINTF(",1\n");
9044            destval = fetch_data_word(destoffset);
9045            TRACE_AND_STEP();
9046            destval = (*opcD1_word_operation[rh]) (destval, 1);
9047            store_data_word(destoffset, destval);
9048        }
9049        break;
9050    case 1:
9051        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9052            u32 destval;
9053
9054            DECODE_PRINTF("DWORD PTR ");
9055            destoffset = decode_rm01_address(rl);
9056            DECODE_PRINTF(",1\n");
9057            destval = fetch_data_long(destoffset);
9058            TRACE_AND_STEP();
9059            destval = (*opcD1_long_operation[rh]) (destval, 1);
9060            store_data_long(destoffset, destval);
9061        } else {
9062            u16 destval;
9063
9064            DECODE_PRINTF("WORD PTR ");
9065            destoffset = decode_rm01_address(rl);
9066            DECODE_PRINTF(",1\n");
9067            destval = fetch_data_word(destoffset);
9068            TRACE_AND_STEP();
9069            destval = (*opcD1_word_operation[rh]) (destval, 1);
9070            store_data_word(destoffset, destval);
9071        }
9072        break;
9073    case 2:
9074        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9075            u32 destval;
9076
9077            DECODE_PRINTF("DWORD PTR ");
9078            destoffset = decode_rm10_address(rl);
9079            DECODE_PRINTF(",1\n");
9080            destval = fetch_data_long(destoffset);
9081            TRACE_AND_STEP();
9082            destval = (*opcD1_long_operation[rh]) (destval, 1);
9083            store_data_long(destoffset, destval);
9084        } else {
9085            u16 destval;
9086
9087            DECODE_PRINTF("BYTE PTR ");
9088            destoffset = decode_rm10_address(rl);
9089            DECODE_PRINTF(",1\n");
9090            destval = fetch_data_word(destoffset);
9091            TRACE_AND_STEP();
9092            destval = (*opcD1_word_operation[rh]) (destval, 1);
9093            store_data_word(destoffset, destval);
9094        }
9095        break;
9096    case 3:                     /* register to register */
9097        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9098			u32 destval;
9099			u32 *destreg;
9100
9101            destreg = DECODE_RM_LONG_REGISTER(rl);
9102            DECODE_PRINTF(",1\n");
9103            TRACE_AND_STEP();
9104            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9105            *destreg = destval;
9106        } else {
9107			u16 destval;
9108			u16 *destreg;
9109
9110            destreg = DECODE_RM_WORD_REGISTER(rl);
9111            DECODE_PRINTF(",1\n");
9112            TRACE_AND_STEP();
9113            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9114            *destreg = destval;
9115        }
9116        break;
9117    }
9118    DECODE_CLEAR_SEGOVR();
9119    END_OF_INSTR();
9120}
9121
9122/****************************************************************************
9123REMARKS:
9124Handles opcode 0xd2
9125****************************************************************************/
9126void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9127{
9128    int mod, rl, rh;
9129    u8 *destreg;
9130    uint destoffset;
9131    u8 destval;
9132    u8 amt;
9133
9134    /*
9135     * Yet another weirdo special case instruction format.  Part of
9136     * the opcode held below in "RH".  Doubly nested case would
9137     * result, except that the decoded instruction
9138     */
9139    START_OF_INSTR();
9140    FETCH_DECODE_MODRM(mod, rh, rl);
9141#ifdef DEBUG
9142    if (DEBUG_DECODE()) {
9143        switch (rh) {
9144        case 0:
9145            DECODE_PRINTF("ROL\t");
9146            break;
9147        case 1:
9148            DECODE_PRINTF("ROR\t");
9149            break;
9150        case 2:
9151            DECODE_PRINTF("RCL\t");
9152            break;
9153        case 3:
9154            DECODE_PRINTF("RCR\t");
9155            break;
9156        case 4:
9157            DECODE_PRINTF("SHL\t");
9158            break;
9159        case 5:
9160            DECODE_PRINTF("SHR\t");
9161            break;
9162        case 6:
9163            DECODE_PRINTF("SAL\t");
9164            break;
9165        case 7:
9166            DECODE_PRINTF("SAR\t");
9167            break;
9168        }
9169    }
9170#endif
9171    /* know operation, decode the mod byte to find the addressing
9172       mode. */
9173    amt = M.x86.R_CL;
9174    switch (mod) {
9175    case 0:
9176        DECODE_PRINTF("BYTE PTR ");
9177        destoffset = decode_rm00_address(rl);
9178        DECODE_PRINTF(",CL\n");
9179        destval = fetch_data_byte(destoffset);
9180        TRACE_AND_STEP();
9181        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9182        store_data_byte(destoffset, destval);
9183        break;
9184    case 1:
9185        DECODE_PRINTF("BYTE PTR ");
9186        destoffset = decode_rm01_address(rl);
9187        DECODE_PRINTF(",CL\n");
9188        destval = fetch_data_byte(destoffset);
9189        TRACE_AND_STEP();
9190        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9191        store_data_byte(destoffset, destval);
9192        break;
9193    case 2:
9194        DECODE_PRINTF("BYTE PTR ");
9195        destoffset = decode_rm10_address(rl);
9196        DECODE_PRINTF(",CL\n");
9197        destval = fetch_data_byte(destoffset);
9198        TRACE_AND_STEP();
9199        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9200        store_data_byte(destoffset, destval);
9201        break;
9202    case 3:                     /* register to register */
9203        destreg = DECODE_RM_BYTE_REGISTER(rl);
9204        DECODE_PRINTF(",CL\n");
9205        TRACE_AND_STEP();
9206        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9207        *destreg = destval;
9208        break;
9209    }
9210    DECODE_CLEAR_SEGOVR();
9211    END_OF_INSTR();
9212}
9213
9214/****************************************************************************
9215REMARKS:
9216Handles opcode 0xd3
9217****************************************************************************/
9218void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9219{
9220    int mod, rl, rh;
9221    uint destoffset;
9222    u8 amt;
9223
9224    /*
9225     * Yet another weirdo special case instruction format.  Part of
9226     * the opcode held below in "RH".  Doubly nested case would
9227     * result, except that the decoded instruction
9228     */
9229    START_OF_INSTR();
9230    FETCH_DECODE_MODRM(mod, rh, rl);
9231#ifdef DEBUG
9232    if (DEBUG_DECODE()) {
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        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9267            u32 destval;
9268
9269            DECODE_PRINTF("DWORD PTR ");
9270            destoffset = decode_rm00_address(rl);
9271            DECODE_PRINTF(",CL\n");
9272            destval = fetch_data_long(destoffset);
9273            TRACE_AND_STEP();
9274            destval = (*opcD1_long_operation[rh]) (destval, amt);
9275            store_data_long(destoffset, destval);
9276        } else {
9277            u16 destval;
9278
9279            DECODE_PRINTF("WORD PTR ");
9280            destoffset = decode_rm00_address(rl);
9281            DECODE_PRINTF(",CL\n");
9282            destval = fetch_data_word(destoffset);
9283            TRACE_AND_STEP();
9284            destval = (*opcD1_word_operation[rh]) (destval, amt);
9285            store_data_word(destoffset, destval);
9286        }
9287        break;
9288    case 1:
9289        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9290            u32 destval;
9291
9292            DECODE_PRINTF("DWORD PTR ");
9293            destoffset = decode_rm01_address(rl);
9294            DECODE_PRINTF(",CL\n");
9295            destval = fetch_data_long(destoffset);
9296            TRACE_AND_STEP();
9297            destval = (*opcD1_long_operation[rh]) (destval, amt);
9298            store_data_long(destoffset, destval);
9299        } else {
9300            u16 destval;
9301
9302            DECODE_PRINTF("WORD PTR ");
9303            destoffset = decode_rm01_address(rl);
9304            DECODE_PRINTF(",CL\n");
9305            destval = fetch_data_word(destoffset);
9306            TRACE_AND_STEP();
9307            destval = (*opcD1_word_operation[rh]) (destval, amt);
9308            store_data_word(destoffset, destval);
9309        }
9310        break;
9311    case 2:
9312        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9313            u32 destval;
9314
9315            DECODE_PRINTF("DWORD PTR ");
9316            destoffset = decode_rm10_address(rl);
9317            DECODE_PRINTF(",CL\n");
9318            destval = fetch_data_long(destoffset);
9319            TRACE_AND_STEP();
9320            destval = (*opcD1_long_operation[rh]) (destval, amt);
9321            store_data_long(destoffset, destval);
9322        } else {
9323            u16 destval;
9324
9325            DECODE_PRINTF("WORD PTR ");
9326            destoffset = decode_rm10_address(rl);
9327            DECODE_PRINTF(",CL\n");
9328            destval = fetch_data_word(destoffset);
9329            TRACE_AND_STEP();
9330            destval = (*opcD1_word_operation[rh]) (destval, amt);
9331            store_data_word(destoffset, destval);
9332        }
9333        break;
9334    case 3:                     /* register to register */
9335        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9336            u32 *destreg;
9337
9338            destreg = DECODE_RM_LONG_REGISTER(rl);
9339            DECODE_PRINTF(",CL\n");
9340            TRACE_AND_STEP();
9341            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9342        } else {
9343            u16 *destreg;
9344
9345            destreg = DECODE_RM_WORD_REGISTER(rl);
9346            DECODE_PRINTF(",CL\n");
9347            TRACE_AND_STEP();
9348            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9349        }
9350        break;
9351    }
9352    DECODE_CLEAR_SEGOVR();
9353    END_OF_INSTR();
9354}
9355
9356/****************************************************************************
9357REMARKS:
9358Handles opcode 0xd4
9359****************************************************************************/
9360void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9361{
9362    u8 a;
9363
9364    START_OF_INSTR();
9365    DECODE_PRINTF("AAM\n");
9366    a = fetch_byte_imm();      /* this is a stupid encoding. */
9367    if (a != 10) {
9368        DECODE_PRINTF("ERROR DECODING AAM\n");
9369        TRACE_REGS();
9370        HALT_SYS();
9371    }
9372    TRACE_AND_STEP();
9373    /* note the type change here --- returning AL and AH in AX. */
9374    M.x86.R_AX = aam_word(M.x86.R_AL);
9375    DECODE_CLEAR_SEGOVR();
9376    END_OF_INSTR();
9377}
9378
9379/****************************************************************************
9380REMARKS:
9381Handles opcode 0xd5
9382****************************************************************************/
9383void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9384{
9385    u8 a;
9386
9387    START_OF_INSTR();
9388    DECODE_PRINTF("AAD\n");
9389    a = fetch_byte_imm();
9390    TRACE_AND_STEP();
9391    M.x86.R_AX = aad_word(M.x86.R_AX);
9392    DECODE_CLEAR_SEGOVR();
9393    END_OF_INSTR();
9394}
9395
9396/* opcode 0xd6 ILLEGAL OPCODE */
9397
9398/****************************************************************************
9399REMARKS:
9400Handles opcode 0xd7
9401****************************************************************************/
9402void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9403{
9404    u16 addr;
9405
9406    START_OF_INSTR();
9407    DECODE_PRINTF("XLAT\n");
9408    TRACE_AND_STEP();
9409	addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9410    M.x86.R_AL = fetch_data_byte(addr);
9411    DECODE_CLEAR_SEGOVR();
9412    END_OF_INSTR();
9413}
9414
9415/* instuctions  D8 .. DF are in i87_ops.c */
9416
9417/****************************************************************************
9418REMARKS:
9419Handles opcode 0xe0
9420****************************************************************************/
9421void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9422{
9423    s16 ip;
9424
9425    START_OF_INSTR();
9426    DECODE_PRINTF("LOOPNE\t");
9427    ip = (s8) fetch_byte_imm();
9428    ip += (s16) M.x86.R_IP;
9429    DECODE_PRINTF2("%04x\n", ip);
9430    TRACE_AND_STEP();
9431    M.x86.R_CX -= 1;
9432    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9433        M.x86.R_IP = ip;
9434    DECODE_CLEAR_SEGOVR();
9435    END_OF_INSTR();
9436}
9437
9438/****************************************************************************
9439REMARKS:
9440Handles opcode 0xe1
9441****************************************************************************/
9442void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9443{
9444    s16 ip;
9445
9446    START_OF_INSTR();
9447    DECODE_PRINTF("LOOPE\t");
9448    ip = (s8) fetch_byte_imm();
9449    ip += (s16) M.x86.R_IP;
9450    DECODE_PRINTF2("%04x\n", ip);
9451    TRACE_AND_STEP();
9452    M.x86.R_CX -= 1;
9453    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9454        M.x86.R_IP = ip;
9455    DECODE_CLEAR_SEGOVR();
9456    END_OF_INSTR();
9457}
9458
9459/****************************************************************************
9460REMARKS:
9461Handles opcode 0xe2
9462****************************************************************************/
9463void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9464{
9465    s16 ip;
9466
9467    START_OF_INSTR();
9468    DECODE_PRINTF("LOOP\t");
9469    ip = (s8) fetch_byte_imm();
9470    ip += (s16) M.x86.R_IP;
9471    DECODE_PRINTF2("%04x\n", ip);
9472    TRACE_AND_STEP();
9473    M.x86.R_CX -= 1;
9474    if (M.x86.R_CX != 0)
9475        M.x86.R_IP = ip;
9476    DECODE_CLEAR_SEGOVR();
9477    END_OF_INSTR();
9478}
9479
9480/****************************************************************************
9481REMARKS:
9482Handles opcode 0xe3
9483****************************************************************************/
9484void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9485{
9486    u16 target;
9487    s8  offset;
9488
9489    /* jump to byte offset if overflow flag is set */
9490    START_OF_INSTR();
9491    DECODE_PRINTF("JCXZ\t");
9492    offset = (s8)fetch_byte_imm();
9493    target = (u16)(M.x86.R_IP + offset);
9494    DECODE_PRINTF2("%x\n", target);
9495    TRACE_AND_STEP();
9496    if (M.x86.R_CX == 0)
9497        M.x86.R_IP = target;
9498    DECODE_CLEAR_SEGOVR();
9499    END_OF_INSTR();
9500}
9501
9502/****************************************************************************
9503REMARKS:
9504Handles opcode 0xe4
9505****************************************************************************/
9506void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9507{
9508    u8 port;
9509
9510    START_OF_INSTR();
9511    DECODE_PRINTF("IN\t");
9512	port = (u8) fetch_byte_imm();
9513    DECODE_PRINTF2("%x,AL\n", port);
9514    TRACE_AND_STEP();
9515    M.x86.R_AL = (*sys_inb)(port);
9516    DECODE_CLEAR_SEGOVR();
9517    END_OF_INSTR();
9518}
9519
9520/****************************************************************************
9521REMARKS:
9522Handles opcode 0xe5
9523****************************************************************************/
9524void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9525{
9526    u8 port;
9527
9528    START_OF_INSTR();
9529    DECODE_PRINTF("IN\t");
9530	port = (u8) fetch_byte_imm();
9531    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9532        DECODE_PRINTF2("EAX,%x\n", port);
9533    } else {
9534        DECODE_PRINTF2("AX,%x\n", port);
9535    }
9536    TRACE_AND_STEP();
9537    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9538        M.x86.R_EAX = (*sys_inl)(port);
9539    } else {
9540        M.x86.R_AX = (*sys_inw)(port);
9541    }
9542    DECODE_CLEAR_SEGOVR();
9543    END_OF_INSTR();
9544}
9545
9546/****************************************************************************
9547REMARKS:
9548Handles opcode 0xe6
9549****************************************************************************/
9550void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9551{
9552    u8 port;
9553
9554    START_OF_INSTR();
9555    DECODE_PRINTF("OUT\t");
9556	port = (u8) fetch_byte_imm();
9557    DECODE_PRINTF2("%x,AL\n", port);
9558    TRACE_AND_STEP();
9559    (*sys_outb)(port, M.x86.R_AL);
9560    DECODE_CLEAR_SEGOVR();
9561    END_OF_INSTR();
9562}
9563
9564/****************************************************************************
9565REMARKS:
9566Handles opcode 0xe7
9567****************************************************************************/
9568void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9569{
9570    u8 port;
9571
9572    START_OF_INSTR();
9573    DECODE_PRINTF("OUT\t");
9574	port = (u8) fetch_byte_imm();
9575    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9576        DECODE_PRINTF2("%x,EAX\n", port);
9577    } else {
9578        DECODE_PRINTF2("%x,AX\n", port);
9579    }
9580    TRACE_AND_STEP();
9581    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9582        (*sys_outl)(port, M.x86.R_EAX);
9583    } else {
9584        (*sys_outw)(port, M.x86.R_AX);
9585    }
9586    DECODE_CLEAR_SEGOVR();
9587    END_OF_INSTR();
9588}
9589
9590/****************************************************************************
9591REMARKS:
9592Handles opcode 0xe8
9593****************************************************************************/
9594void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9595{
9596    s16 ip;
9597
9598    START_OF_INSTR();
9599	DECODE_PRINTF("CALL\t");
9600	ip = (s16) fetch_word_imm();
9601	ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
9602	DECODE_PRINTF2("%04x\n", ip);
9603	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9604    TRACE_AND_STEP();
9605    push_word(M.x86.R_IP);
9606    M.x86.R_IP = ip;
9607    DECODE_CLEAR_SEGOVR();
9608    END_OF_INSTR();
9609}
9610
9611/****************************************************************************
9612REMARKS:
9613Handles opcode 0xe9
9614****************************************************************************/
9615void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9616{
9617    int ip;
9618
9619    START_OF_INSTR();
9620    DECODE_PRINTF("JMP\t");
9621    ip = (s16)fetch_word_imm();
9622    ip += (s16)M.x86.R_IP;
9623    DECODE_PRINTF2("%04x\n", ip);
9624    TRACE_AND_STEP();
9625    M.x86.R_IP = (u16)ip;
9626    DECODE_CLEAR_SEGOVR();
9627    END_OF_INSTR();
9628}
9629
9630/****************************************************************************
9631REMARKS:
9632Handles opcode 0xea
9633****************************************************************************/
9634void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9635{
9636    u16 cs, ip;
9637
9638    START_OF_INSTR();
9639    DECODE_PRINTF("JMP\tFAR ");
9640    ip = fetch_word_imm();
9641    cs = fetch_word_imm();
9642    DECODE_PRINTF2("%04x:", cs);
9643    DECODE_PRINTF2("%04x\n", ip);
9644    TRACE_AND_STEP();
9645    M.x86.R_IP = ip;
9646    M.x86.R_CS = cs;
9647    DECODE_CLEAR_SEGOVR();
9648    END_OF_INSTR();
9649}
9650
9651/****************************************************************************
9652REMARKS:
9653Handles opcode 0xeb
9654****************************************************************************/
9655void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9656{
9657    u16 target;
9658    s8 offset;
9659
9660    START_OF_INSTR();
9661    DECODE_PRINTF("JMP\t");
9662    offset = (s8)fetch_byte_imm();
9663    target = (u16)(M.x86.R_IP + offset);
9664    DECODE_PRINTF2("%x\n", target);
9665    TRACE_AND_STEP();
9666    M.x86.R_IP = target;
9667    DECODE_CLEAR_SEGOVR();
9668    END_OF_INSTR();
9669}
9670
9671/****************************************************************************
9672REMARKS:
9673Handles opcode 0xec
9674****************************************************************************/
9675void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9676{
9677    START_OF_INSTR();
9678    DECODE_PRINTF("IN\tAL,DX\n");
9679    TRACE_AND_STEP();
9680    M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9681    DECODE_CLEAR_SEGOVR();
9682    END_OF_INSTR();
9683}
9684
9685/****************************************************************************
9686REMARKS:
9687Handles opcode 0xed
9688****************************************************************************/
9689void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9690{
9691    START_OF_INSTR();
9692    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9693        DECODE_PRINTF("IN\tEAX,DX\n");
9694    } else {
9695        DECODE_PRINTF("IN\tAX,DX\n");
9696    }
9697    TRACE_AND_STEP();
9698    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9699        M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9700    } else {
9701        M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9702    }
9703    DECODE_CLEAR_SEGOVR();
9704    END_OF_INSTR();
9705}
9706
9707/****************************************************************************
9708REMARKS:
9709Handles opcode 0xee
9710****************************************************************************/
9711void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9712{
9713    START_OF_INSTR();
9714    DECODE_PRINTF("OUT\tDX,AL\n");
9715    TRACE_AND_STEP();
9716    (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9717    DECODE_CLEAR_SEGOVR();
9718    END_OF_INSTR();
9719}
9720
9721/****************************************************************************
9722REMARKS:
9723Handles opcode 0xef
9724****************************************************************************/
9725void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9726{
9727    START_OF_INSTR();
9728    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9729        DECODE_PRINTF("OUT\tDX,EAX\n");
9730    } else {
9731        DECODE_PRINTF("OUT\tDX,AX\n");
9732    }
9733    TRACE_AND_STEP();
9734    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9735        (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9736    } else {
9737        (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9738    }
9739    DECODE_CLEAR_SEGOVR();
9740    END_OF_INSTR();
9741}
9742
9743/****************************************************************************
9744REMARKS:
9745Handles opcode 0xf0
9746****************************************************************************/
9747void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9748{
9749    START_OF_INSTR();
9750    DECODE_PRINTF("LOCK:\n");
9751    TRACE_AND_STEP();
9752    DECODE_CLEAR_SEGOVR();
9753    END_OF_INSTR();
9754}
9755
9756/*opcode 0xf1 ILLEGAL OPERATION */
9757
9758/****************************************************************************
9759REMARKS:
9760Handles opcode 0xf2
9761****************************************************************************/
9762void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9763{
9764    START_OF_INSTR();
9765    DECODE_PRINTF("REPNE\n");
9766    TRACE_AND_STEP();
9767    M.x86.mode |= SYSMODE_PREFIX_REPNE;
9768    DECODE_CLEAR_SEGOVR();
9769    END_OF_INSTR();
9770}
9771
9772/****************************************************************************
9773REMARKS:
9774Handles opcode 0xf3
9775****************************************************************************/
9776void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9777{
9778    START_OF_INSTR();
9779    DECODE_PRINTF("REPE\n");
9780    TRACE_AND_STEP();
9781    M.x86.mode |= SYSMODE_PREFIX_REPE;
9782    DECODE_CLEAR_SEGOVR();
9783    END_OF_INSTR();
9784}
9785
9786/****************************************************************************
9787REMARKS:
9788Handles opcode 0xf4
9789****************************************************************************/
9790void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9791{
9792    START_OF_INSTR();
9793    DECODE_PRINTF("HALT\n");
9794    TRACE_AND_STEP();
9795    HALT_SYS();
9796    DECODE_CLEAR_SEGOVR();
9797    END_OF_INSTR();
9798}
9799
9800/****************************************************************************
9801REMARKS:
9802Handles opcode 0xf5
9803****************************************************************************/
9804void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9805{
9806    /* complement the carry flag. */
9807    START_OF_INSTR();
9808    DECODE_PRINTF("CMC\n");
9809    TRACE_AND_STEP();
9810    TOGGLE_FLAG(F_CF);
9811    DECODE_CLEAR_SEGOVR();
9812    END_OF_INSTR();
9813}
9814
9815/****************************************************************************
9816REMARKS:
9817Handles opcode 0xf6
9818****************************************************************************/
9819void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9820{
9821    int mod, rl, rh;
9822    u8 *destreg;
9823    uint destoffset;
9824    u8 destval, srcval;
9825
9826    /* long, drawn out code follows.  Double switch for a total
9827       of 32 cases.  */
9828    START_OF_INSTR();
9829    FETCH_DECODE_MODRM(mod, rh, rl);
9830    switch (mod) {
9831    case 0:                     /* mod=00 */
9832        switch (rh) {
9833        case 0:         /* test byte imm */
9834            DECODE_PRINTF("TEST\tBYTE PTR ");
9835            destoffset = decode_rm00_address(rl);
9836            DECODE_PRINTF(",");
9837            srcval = fetch_byte_imm();
9838            DECODE_PRINTF2("%02x\n", srcval);
9839            destval = fetch_data_byte(destoffset);
9840            TRACE_AND_STEP();
9841            test_byte(destval, srcval);
9842            break;
9843        case 1:
9844            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9845            HALT_SYS();
9846            break;
9847        case 2:
9848            DECODE_PRINTF("NOT\tBYTE PTR ");
9849            destoffset = decode_rm00_address(rl);
9850            DECODE_PRINTF("\n");
9851            destval = fetch_data_byte(destoffset);
9852            TRACE_AND_STEP();
9853            destval = not_byte(destval);
9854            store_data_byte(destoffset, destval);
9855            break;
9856        case 3:
9857            DECODE_PRINTF("NEG\tBYTE PTR ");
9858            destoffset = decode_rm00_address(rl);
9859            DECODE_PRINTF("\n");
9860            destval = fetch_data_byte(destoffset);
9861            TRACE_AND_STEP();
9862            destval = neg_byte(destval);
9863            store_data_byte(destoffset, destval);
9864            break;
9865        case 4:
9866            DECODE_PRINTF("MUL\tBYTE PTR ");
9867            destoffset = decode_rm00_address(rl);
9868            DECODE_PRINTF("\n");
9869            destval = fetch_data_byte(destoffset);
9870            TRACE_AND_STEP();
9871            mul_byte(destval);
9872            break;
9873        case 5:
9874            DECODE_PRINTF("IMUL\tBYTE PTR ");
9875            destoffset = decode_rm00_address(rl);
9876            DECODE_PRINTF("\n");
9877            destval = fetch_data_byte(destoffset);
9878            TRACE_AND_STEP();
9879            imul_byte(destval);
9880            break;
9881        case 6:
9882            DECODE_PRINTF("DIV\tBYTE PTR ");
9883            destoffset = decode_rm00_address(rl);
9884            DECODE_PRINTF("\n");
9885            destval = fetch_data_byte(destoffset);
9886            TRACE_AND_STEP();
9887            div_byte(destval);
9888            break;
9889        case 7:
9890            DECODE_PRINTF("IDIV\tBYTE PTR ");
9891            destoffset = decode_rm00_address(rl);
9892            DECODE_PRINTF("\n");
9893            destval = fetch_data_byte(destoffset);
9894            TRACE_AND_STEP();
9895            idiv_byte(destval);
9896            break;
9897        }
9898        break;                  /* end mod==00 */
9899    case 1:                     /* mod=01 */
9900        switch (rh) {
9901        case 0:         /* test byte imm */
9902            DECODE_PRINTF("TEST\tBYTE PTR ");
9903            destoffset = decode_rm01_address(rl);
9904            DECODE_PRINTF(",");
9905            srcval = fetch_byte_imm();
9906            DECODE_PRINTF2("%02x\n", srcval);
9907            destval = fetch_data_byte(destoffset);
9908            TRACE_AND_STEP();
9909            test_byte(destval, srcval);
9910            break;
9911        case 1:
9912            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9913            HALT_SYS();
9914            break;
9915        case 2:
9916            DECODE_PRINTF("NOT\tBYTE PTR ");
9917            destoffset = decode_rm01_address(rl);
9918            DECODE_PRINTF("\n");
9919            destval = fetch_data_byte(destoffset);
9920            TRACE_AND_STEP();
9921            destval = not_byte(destval);
9922            store_data_byte(destoffset, destval);
9923            break;
9924        case 3:
9925            DECODE_PRINTF("NEG\tBYTE PTR ");
9926            destoffset = decode_rm01_address(rl);
9927            DECODE_PRINTF("\n");
9928            destval = fetch_data_byte(destoffset);
9929            TRACE_AND_STEP();
9930            destval = neg_byte(destval);
9931            store_data_byte(destoffset, destval);
9932            break;
9933        case 4:
9934            DECODE_PRINTF("MUL\tBYTE PTR ");
9935            destoffset = decode_rm01_address(rl);
9936            DECODE_PRINTF("\n");
9937            destval = fetch_data_byte(destoffset);
9938            TRACE_AND_STEP();
9939            mul_byte(destval);
9940            break;
9941        case 5:
9942            DECODE_PRINTF("IMUL\tBYTE PTR ");
9943            destoffset = decode_rm01_address(rl);
9944            DECODE_PRINTF("\n");
9945            destval = fetch_data_byte(destoffset);
9946            TRACE_AND_STEP();
9947            imul_byte(destval);
9948            break;
9949        case 6:
9950            DECODE_PRINTF("DIV\tBYTE PTR ");
9951            destoffset = decode_rm01_address(rl);
9952            DECODE_PRINTF("\n");
9953            destval = fetch_data_byte(destoffset);
9954            TRACE_AND_STEP();
9955            div_byte(destval);
9956            break;
9957        case 7:
9958            DECODE_PRINTF("IDIV\tBYTE PTR ");
9959            destoffset = decode_rm01_address(rl);
9960            DECODE_PRINTF("\n");
9961            destval = fetch_data_byte(destoffset);
9962            TRACE_AND_STEP();
9963            idiv_byte(destval);
9964            break;
9965        }
9966        break;                  /* end mod==01 */
9967    case 2:                     /* mod=10 */
9968        switch (rh) {
9969        case 0:         /* test byte imm */
9970            DECODE_PRINTF("TEST\tBYTE PTR ");
9971            destoffset = decode_rm10_address(rl);
9972            DECODE_PRINTF(",");
9973            srcval = fetch_byte_imm();
9974            DECODE_PRINTF2("%02x\n", srcval);
9975            destval = fetch_data_byte(destoffset);
9976            TRACE_AND_STEP();
9977            test_byte(destval, srcval);
9978            break;
9979        case 1:
9980            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
9981            HALT_SYS();
9982            break;
9983        case 2:
9984            DECODE_PRINTF("NOT\tBYTE PTR ");
9985            destoffset = decode_rm10_address(rl);
9986            DECODE_PRINTF("\n");
9987            destval = fetch_data_byte(destoffset);
9988            TRACE_AND_STEP();
9989            destval = not_byte(destval);
9990            store_data_byte(destoffset, destval);
9991            break;
9992        case 3:
9993            DECODE_PRINTF("NEG\tBYTE PTR ");
9994            destoffset = decode_rm10_address(rl);
9995            DECODE_PRINTF("\n");
9996            destval = fetch_data_byte(destoffset);
9997            TRACE_AND_STEP();
9998            destval = neg_byte(destval);
9999            store_data_byte(destoffset, destval);
10000            break;
10001        case 4:
10002            DECODE_PRINTF("MUL\tBYTE PTR ");
10003            destoffset = decode_rm10_address(rl);
10004            DECODE_PRINTF("\n");
10005            destval = fetch_data_byte(destoffset);
10006            TRACE_AND_STEP();
10007            mul_byte(destval);
10008            break;
10009        case 5:
10010            DECODE_PRINTF("IMUL\tBYTE PTR ");
10011            destoffset = decode_rm10_address(rl);
10012            DECODE_PRINTF("\n");
10013            destval = fetch_data_byte(destoffset);
10014            TRACE_AND_STEP();
10015            imul_byte(destval);
10016            break;
10017        case 6:
10018            DECODE_PRINTF("DIV\tBYTE PTR ");
10019            destoffset = decode_rm10_address(rl);
10020            DECODE_PRINTF("\n");
10021            destval = fetch_data_byte(destoffset);
10022            TRACE_AND_STEP();
10023            div_byte(destval);
10024            break;
10025        case 7:
10026            DECODE_PRINTF("IDIV\tBYTE PTR ");
10027            destoffset = decode_rm10_address(rl);
10028            DECODE_PRINTF("\n");
10029            destval = fetch_data_byte(destoffset);
10030            TRACE_AND_STEP();
10031            idiv_byte(destval);
10032            break;
10033        }
10034        break;                  /* end mod==10 */
10035    case 3:                     /* mod=11 */
10036        switch (rh) {
10037        case 0:         /* test byte imm */
10038            DECODE_PRINTF("TEST\t");
10039            destreg = DECODE_RM_BYTE_REGISTER(rl);
10040            DECODE_PRINTF(",");
10041            srcval = fetch_byte_imm();
10042            DECODE_PRINTF2("%02x\n", srcval);
10043            TRACE_AND_STEP();
10044            test_byte(*destreg, srcval);
10045            break;
10046        case 1:
10047            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10048            HALT_SYS();
10049            break;
10050        case 2:
10051            DECODE_PRINTF("NOT\t");
10052            destreg = DECODE_RM_BYTE_REGISTER(rl);
10053            DECODE_PRINTF("\n");
10054            TRACE_AND_STEP();
10055            *destreg = not_byte(*destreg);
10056            break;
10057        case 3:
10058            DECODE_PRINTF("NEG\t");
10059            destreg = DECODE_RM_BYTE_REGISTER(rl);
10060            DECODE_PRINTF("\n");
10061            TRACE_AND_STEP();
10062            *destreg = neg_byte(*destreg);
10063            break;
10064        case 4:
10065            DECODE_PRINTF("MUL\t");
10066            destreg = DECODE_RM_BYTE_REGISTER(rl);
10067            DECODE_PRINTF("\n");
10068            TRACE_AND_STEP();
10069            mul_byte(*destreg);      /*!!!  */
10070            break;
10071        case 5:
10072            DECODE_PRINTF("IMUL\t");
10073            destreg = DECODE_RM_BYTE_REGISTER(rl);
10074            DECODE_PRINTF("\n");
10075            TRACE_AND_STEP();
10076            imul_byte(*destreg);
10077            break;
10078        case 6:
10079            DECODE_PRINTF("DIV\t");
10080            destreg = DECODE_RM_BYTE_REGISTER(rl);
10081            DECODE_PRINTF("\n");
10082            TRACE_AND_STEP();
10083            div_byte(*destreg);
10084            break;
10085        case 7:
10086            DECODE_PRINTF("IDIV\t");
10087            destreg = DECODE_RM_BYTE_REGISTER(rl);
10088            DECODE_PRINTF("\n");
10089            TRACE_AND_STEP();
10090            idiv_byte(*destreg);
10091            break;
10092        }
10093        break;                  /* end mod==11 */
10094    }
10095    DECODE_CLEAR_SEGOVR();
10096    END_OF_INSTR();
10097}
10098
10099/****************************************************************************
10100REMARKS:
10101Handles opcode 0xf7
10102****************************************************************************/
10103void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10104{
10105    int mod, rl, rh;
10106    uint destoffset;
10107
10108    /* long, drawn out code follows.  Double switch for a total
10109       of 32 cases.  */
10110    START_OF_INSTR();
10111    FETCH_DECODE_MODRM(mod, rh, rl);
10112    switch (mod) {
10113    case 0:                     /* mod=00 */
10114        switch (rh) {
10115        case 0:         /* test word imm */
10116            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10117                u32 destval,srcval;
10118
10119                DECODE_PRINTF("TEST\tDWORD PTR ");
10120                destoffset = decode_rm00_address(rl);
10121                DECODE_PRINTF(",");
10122                srcval = fetch_long_imm();
10123                DECODE_PRINTF2("%x\n", srcval);
10124                destval = fetch_data_long(destoffset);
10125                TRACE_AND_STEP();
10126                test_long(destval, srcval);
10127            } else {
10128                u16 destval,srcval;
10129
10130                DECODE_PRINTF("TEST\tWORD PTR ");
10131                destoffset = decode_rm00_address(rl);
10132                DECODE_PRINTF(",");
10133                srcval = fetch_word_imm();
10134                DECODE_PRINTF2("%x\n", srcval);
10135                destval = fetch_data_word(destoffset);
10136                TRACE_AND_STEP();
10137                test_word(destval, srcval);
10138            }
10139            break;
10140        case 1:
10141            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10142            HALT_SYS();
10143            break;
10144        case 2:
10145            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10146                u32 destval;
10147
10148                DECODE_PRINTF("NOT\tDWORD PTR ");
10149                destoffset = decode_rm00_address(rl);
10150                DECODE_PRINTF("\n");
10151                destval = fetch_data_long(destoffset);
10152                TRACE_AND_STEP();
10153                destval = not_long(destval);
10154                store_data_long(destoffset, destval);
10155            } else {
10156                u16 destval;
10157
10158                DECODE_PRINTF("NOT\tWORD PTR ");
10159                destoffset = decode_rm00_address(rl);
10160                DECODE_PRINTF("\n");
10161                destval = fetch_data_word(destoffset);
10162                TRACE_AND_STEP();
10163                destval = not_word(destval);
10164                store_data_word(destoffset, destval);
10165            }
10166            break;
10167        case 3:
10168            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10169                u32 destval;
10170
10171                DECODE_PRINTF("NEG\tDWORD PTR ");
10172                destoffset = decode_rm00_address(rl);
10173                DECODE_PRINTF("\n");
10174                destval = fetch_data_long(destoffset);
10175                TRACE_AND_STEP();
10176                destval = neg_long(destval);
10177                store_data_long(destoffset, destval);
10178            } else {
10179                u16 destval;
10180
10181                DECODE_PRINTF("NEG\tWORD PTR ");
10182                destoffset = decode_rm00_address(rl);
10183                DECODE_PRINTF("\n");
10184                destval = fetch_data_word(destoffset);
10185                TRACE_AND_STEP();
10186                destval = neg_word(destval);
10187                store_data_word(destoffset, destval);
10188            }
10189            break;
10190        case 4:
10191            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10192                u32 destval;
10193
10194                DECODE_PRINTF("MUL\tDWORD PTR ");
10195                destoffset = decode_rm00_address(rl);
10196                DECODE_PRINTF("\n");
10197                destval = fetch_data_long(destoffset);
10198                TRACE_AND_STEP();
10199                mul_long(destval);
10200            } else {
10201                u16 destval;
10202
10203                DECODE_PRINTF("MUL\tWORD PTR ");
10204                destoffset = decode_rm00_address(rl);
10205                DECODE_PRINTF("\n");
10206                destval = fetch_data_word(destoffset);
10207                TRACE_AND_STEP();
10208                mul_word(destval);
10209            }
10210            break;
10211        case 5:
10212            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10213                u32 destval;
10214
10215                DECODE_PRINTF("IMUL\tDWORD PTR ");
10216                destoffset = decode_rm00_address(rl);
10217                DECODE_PRINTF("\n");
10218                destval = fetch_data_long(destoffset);
10219                TRACE_AND_STEP();
10220                imul_long(destval);
10221            } else {
10222                u16 destval;
10223
10224                DECODE_PRINTF("IMUL\tWORD PTR ");
10225                destoffset = decode_rm00_address(rl);
10226                DECODE_PRINTF("\n");
10227                destval = fetch_data_word(destoffset);
10228                TRACE_AND_STEP();
10229                imul_word(destval);
10230            }
10231            break;
10232        case 6:
10233            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234                u32 destval;
10235
10236                DECODE_PRINTF("DIV\tDWORD PTR ");
10237                destoffset = decode_rm00_address(rl);
10238                DECODE_PRINTF("\n");
10239                destval = fetch_data_long(destoffset);
10240                TRACE_AND_STEP();
10241                div_long(destval);
10242            } else {
10243                u16 destval;
10244
10245                DECODE_PRINTF("DIV\tWORD PTR ");
10246                destoffset = decode_rm00_address(rl);
10247                DECODE_PRINTF("\n");
10248                destval = fetch_data_word(destoffset);
10249                TRACE_AND_STEP();
10250                div_word(destval);
10251            }
10252            break;
10253        case 7:
10254            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10255                u32 destval;
10256
10257                DECODE_PRINTF("IDIV\tDWORD PTR ");
10258                destoffset = decode_rm00_address(rl);
10259                DECODE_PRINTF("\n");
10260                destval = fetch_data_long(destoffset);
10261                TRACE_AND_STEP();
10262                idiv_long(destval);
10263            } else {
10264                u16 destval;
10265
10266                DECODE_PRINTF("IDIV\tWORD PTR ");
10267                destoffset = decode_rm00_address(rl);
10268                DECODE_PRINTF("\n");
10269                destval = fetch_data_word(destoffset);
10270                TRACE_AND_STEP();
10271                idiv_word(destval);
10272            }
10273            break;
10274        }
10275        break;                  /* end mod==00 */
10276    case 1:                     /* mod=01 */
10277        switch (rh) {
10278        case 0:         /* test word imm */
10279            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10280                u32 destval,srcval;
10281
10282                DECODE_PRINTF("TEST\tDWORD PTR ");
10283                destoffset = decode_rm01_address(rl);
10284                DECODE_PRINTF(",");
10285                srcval = fetch_long_imm();
10286                DECODE_PRINTF2("%x\n", srcval);
10287                destval = fetch_data_long(destoffset);
10288                TRACE_AND_STEP();
10289                test_long(destval, srcval);
10290            } else {
10291                u16 destval,srcval;
10292
10293                DECODE_PRINTF("TEST\tWORD PTR ");
10294                destoffset = decode_rm01_address(rl);
10295                DECODE_PRINTF(",");
10296                srcval = fetch_word_imm();
10297                DECODE_PRINTF2("%x\n", srcval);
10298                destval = fetch_data_word(destoffset);
10299                TRACE_AND_STEP();
10300                test_word(destval, srcval);
10301            }
10302            break;
10303        case 1:
10304            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10305            HALT_SYS();
10306            break;
10307        case 2:
10308            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10309                u32 destval;
10310
10311                DECODE_PRINTF("NOT\tDWORD PTR ");
10312                destoffset = decode_rm01_address(rl);
10313                DECODE_PRINTF("\n");
10314                destval = fetch_data_long(destoffset);
10315                TRACE_AND_STEP();
10316                destval = not_long(destval);
10317                store_data_long(destoffset, destval);
10318            } else {
10319                u16 destval;
10320
10321                DECODE_PRINTF("NOT\tWORD PTR ");
10322                destoffset = decode_rm01_address(rl);
10323                DECODE_PRINTF("\n");
10324                destval = fetch_data_word(destoffset);
10325                TRACE_AND_STEP();
10326                destval = not_word(destval);
10327                store_data_word(destoffset, destval);
10328            }
10329            break;
10330        case 3:
10331            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10332                u32 destval;
10333
10334                DECODE_PRINTF("NEG\tDWORD PTR ");
10335                destoffset = decode_rm01_address(rl);
10336                DECODE_PRINTF("\n");
10337                destval = fetch_data_long(destoffset);
10338                TRACE_AND_STEP();
10339                destval = neg_long(destval);
10340                store_data_long(destoffset, destval);
10341            } else {
10342                u16 destval;
10343
10344                DECODE_PRINTF("NEG\tWORD PTR ");
10345                destoffset = decode_rm01_address(rl);
10346                DECODE_PRINTF("\n");
10347                destval = fetch_data_word(destoffset);
10348                TRACE_AND_STEP();
10349                destval = neg_word(destval);
10350                store_data_word(destoffset, destval);
10351            }
10352            break;
10353        case 4:
10354            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10355                u32 destval;
10356
10357                DECODE_PRINTF("MUL\tDWORD PTR ");
10358                destoffset = decode_rm01_address(rl);
10359                DECODE_PRINTF("\n");
10360                destval = fetch_data_long(destoffset);
10361                TRACE_AND_STEP();
10362                mul_long(destval);
10363            } else {
10364                u16 destval;
10365
10366                DECODE_PRINTF("MUL\tWORD PTR ");
10367                destoffset = decode_rm01_address(rl);
10368                DECODE_PRINTF("\n");
10369                destval = fetch_data_word(destoffset);
10370                TRACE_AND_STEP();
10371                mul_word(destval);
10372            }
10373            break;
10374        case 5:
10375            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10376                u32 destval;
10377
10378                DECODE_PRINTF("IMUL\tDWORD PTR ");
10379                destoffset = decode_rm01_address(rl);
10380                DECODE_PRINTF("\n");
10381                destval = fetch_data_long(destoffset);
10382                TRACE_AND_STEP();
10383                imul_long(destval);
10384            } else {
10385                u16 destval;
10386
10387                DECODE_PRINTF("IMUL\tWORD PTR ");
10388                destoffset = decode_rm01_address(rl);
10389                DECODE_PRINTF("\n");
10390                destval = fetch_data_word(destoffset);
10391                TRACE_AND_STEP();
10392                imul_word(destval);
10393            }
10394            break;
10395        case 6:
10396            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397                u32 destval;
10398
10399                DECODE_PRINTF("DIV\tDWORD PTR ");
10400                destoffset = decode_rm01_address(rl);
10401                DECODE_PRINTF("\n");
10402                destval = fetch_data_long(destoffset);
10403                TRACE_AND_STEP();
10404                div_long(destval);
10405            } else {
10406                u16 destval;
10407
10408                DECODE_PRINTF("DIV\tWORD PTR ");
10409                destoffset = decode_rm01_address(rl);
10410                DECODE_PRINTF("\n");
10411                destval = fetch_data_word(destoffset);
10412                TRACE_AND_STEP();
10413                div_word(destval);
10414            }
10415            break;
10416        case 7:
10417            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10418                u32 destval;
10419
10420                DECODE_PRINTF("IDIV\tDWORD PTR ");
10421                destoffset = decode_rm01_address(rl);
10422                DECODE_PRINTF("\n");
10423                destval = fetch_data_long(destoffset);
10424                TRACE_AND_STEP();
10425                idiv_long(destval);
10426            } else {
10427                u16 destval;
10428
10429                DECODE_PRINTF("IDIV\tWORD PTR ");
10430                destoffset = decode_rm01_address(rl);
10431                DECODE_PRINTF("\n");
10432                destval = fetch_data_word(destoffset);
10433                TRACE_AND_STEP();
10434                idiv_word(destval);
10435            }
10436            break;
10437        }
10438        break;                  /* end mod==01 */
10439    case 2:                     /* mod=10 */
10440        switch (rh) {
10441        case 0:         /* test word imm */
10442            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10443                u32 destval,srcval;
10444
10445                DECODE_PRINTF("TEST\tDWORD PTR ");
10446                destoffset = decode_rm10_address(rl);
10447                DECODE_PRINTF(",");
10448                srcval = fetch_long_imm();
10449                DECODE_PRINTF2("%x\n", srcval);
10450                destval = fetch_data_long(destoffset);
10451                TRACE_AND_STEP();
10452                test_long(destval, srcval);
10453            } else {
10454                u16 destval,srcval;
10455
10456                DECODE_PRINTF("TEST\tWORD PTR ");
10457                destoffset = decode_rm10_address(rl);
10458                DECODE_PRINTF(",");
10459                srcval = fetch_word_imm();
10460                DECODE_PRINTF2("%x\n", srcval);
10461                destval = fetch_data_word(destoffset);
10462                TRACE_AND_STEP();
10463                test_word(destval, srcval);
10464            }
10465            break;
10466        case 1:
10467            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10468            HALT_SYS();
10469            break;
10470        case 2:
10471            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10472                u32 destval;
10473
10474                DECODE_PRINTF("NOT\tDWORD PTR ");
10475                destoffset = decode_rm10_address(rl);
10476                DECODE_PRINTF("\n");
10477                destval = fetch_data_long(destoffset);
10478                TRACE_AND_STEP();
10479                destval = not_long(destval);
10480                store_data_long(destoffset, destval);
10481            } else {
10482                u16 destval;
10483
10484                DECODE_PRINTF("NOT\tWORD PTR ");
10485                destoffset = decode_rm10_address(rl);
10486                DECODE_PRINTF("\n");
10487                destval = fetch_data_word(destoffset);
10488                TRACE_AND_STEP();
10489                destval = not_word(destval);
10490                store_data_word(destoffset, destval);
10491            }
10492            break;
10493        case 3:
10494            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10495                u32 destval;
10496
10497                DECODE_PRINTF("NEG\tDWORD PTR ");
10498                destoffset = decode_rm10_address(rl);
10499                DECODE_PRINTF("\n");
10500                destval = fetch_data_long(destoffset);
10501                TRACE_AND_STEP();
10502                destval = neg_long(destval);
10503                store_data_long(destoffset, destval);
10504            } else {
10505                u16 destval;
10506
10507                DECODE_PRINTF("NEG\tWORD PTR ");
10508                destoffset = decode_rm10_address(rl);
10509                DECODE_PRINTF("\n");
10510                destval = fetch_data_word(destoffset);
10511                TRACE_AND_STEP();
10512                destval = neg_word(destval);
10513                store_data_word(destoffset, destval);
10514            }
10515            break;
10516        case 4:
10517            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10518                u32 destval;
10519
10520                DECODE_PRINTF("MUL\tDWORD PTR ");
10521                destoffset = decode_rm10_address(rl);
10522                DECODE_PRINTF("\n");
10523                destval = fetch_data_long(destoffset);
10524                TRACE_AND_STEP();
10525                mul_long(destval);
10526            } else {
10527                u16 destval;
10528
10529                DECODE_PRINTF("MUL\tWORD PTR ");
10530                destoffset = decode_rm10_address(rl);
10531                DECODE_PRINTF("\n");
10532                destval = fetch_data_word(destoffset);
10533                TRACE_AND_STEP();
10534                mul_word(destval);
10535            }
10536            break;
10537        case 5:
10538            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10539                u32 destval;
10540
10541                DECODE_PRINTF("IMUL\tDWORD PTR ");
10542                destoffset = decode_rm10_address(rl);
10543                DECODE_PRINTF("\n");
10544                destval = fetch_data_long(destoffset);
10545                TRACE_AND_STEP();
10546                imul_long(destval);
10547            } else {
10548                u16 destval;
10549
10550                DECODE_PRINTF("IMUL\tWORD PTR ");
10551                destoffset = decode_rm10_address(rl);
10552                DECODE_PRINTF("\n");
10553                destval = fetch_data_word(destoffset);
10554                TRACE_AND_STEP();
10555                imul_word(destval);
10556            }
10557            break;
10558        case 6:
10559            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10560                u32 destval;
10561
10562                DECODE_PRINTF("DIV\tDWORD PTR ");
10563                destoffset = decode_rm10_address(rl);
10564                DECODE_PRINTF("\n");
10565                destval = fetch_data_long(destoffset);
10566                TRACE_AND_STEP();
10567                div_long(destval);
10568            } else {
10569                u16 destval;
10570
10571                DECODE_PRINTF("DIV\tWORD PTR ");
10572                destoffset = decode_rm10_address(rl);
10573                DECODE_PRINTF("\n");
10574                destval = fetch_data_word(destoffset);
10575                TRACE_AND_STEP();
10576                div_word(destval);
10577            }
10578            break;
10579        case 7:
10580            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10581                u32 destval;
10582
10583                DECODE_PRINTF("IDIV\tDWORD PTR ");
10584                destoffset = decode_rm10_address(rl);
10585                DECODE_PRINTF("\n");
10586                destval = fetch_data_long(destoffset);
10587                TRACE_AND_STEP();
10588                idiv_long(destval);
10589            } else {
10590                u16 destval;
10591
10592                DECODE_PRINTF("IDIV\tWORD PTR ");
10593                destoffset = decode_rm10_address(rl);
10594                DECODE_PRINTF("\n");
10595                destval = fetch_data_word(destoffset);
10596                TRACE_AND_STEP();
10597                idiv_word(destval);
10598            }
10599            break;
10600        }
10601        break;                  /* end mod==10 */
10602    case 3:                     /* mod=11 */
10603        switch (rh) {
10604        case 0:         /* test word imm */
10605            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10606                u32 *destreg;
10607                u32 srcval;
10608
10609                DECODE_PRINTF("TEST\t");
10610                destreg = DECODE_RM_LONG_REGISTER(rl);
10611                DECODE_PRINTF(",");
10612                srcval = fetch_long_imm();
10613                DECODE_PRINTF2("%x\n", srcval);
10614                TRACE_AND_STEP();
10615                test_long(*destreg, srcval);
10616            } else {
10617                u16 *destreg;
10618                u16 srcval;
10619
10620                DECODE_PRINTF("TEST\t");
10621                destreg = DECODE_RM_WORD_REGISTER(rl);
10622                DECODE_PRINTF(",");
10623                srcval = fetch_word_imm();
10624                DECODE_PRINTF2("%x\n", srcval);
10625                TRACE_AND_STEP();
10626                test_word(*destreg, srcval);
10627            }
10628            break;
10629        case 1:
10630            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10631            HALT_SYS();
10632            break;
10633        case 2:
10634            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10635                u32 *destreg;
10636
10637                DECODE_PRINTF("NOT\t");
10638                destreg = DECODE_RM_LONG_REGISTER(rl);
10639                DECODE_PRINTF("\n");
10640                TRACE_AND_STEP();
10641                *destreg = not_long(*destreg);
10642            } else {
10643                u16 *destreg;
10644
10645                DECODE_PRINTF("NOT\t");
10646                destreg = DECODE_RM_WORD_REGISTER(rl);
10647                DECODE_PRINTF("\n");
10648                TRACE_AND_STEP();
10649                *destreg = not_word(*destreg);
10650            }
10651            break;
10652        case 3:
10653            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10654                u32 *destreg;
10655
10656                DECODE_PRINTF("NEG\t");
10657                destreg = DECODE_RM_LONG_REGISTER(rl);
10658                DECODE_PRINTF("\n");
10659                TRACE_AND_STEP();
10660                *destreg = neg_long(*destreg);
10661            } else {
10662                u16 *destreg;
10663
10664                DECODE_PRINTF("NEG\t");
10665                destreg = DECODE_RM_WORD_REGISTER(rl);
10666                DECODE_PRINTF("\n");
10667                TRACE_AND_STEP();
10668                *destreg = neg_word(*destreg);
10669            }
10670            break;
10671        case 4:
10672            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10673                u32 *destreg;
10674
10675                DECODE_PRINTF("MUL\t");
10676                destreg = DECODE_RM_LONG_REGISTER(rl);
10677                DECODE_PRINTF("\n");
10678                TRACE_AND_STEP();
10679                mul_long(*destreg);      /*!!!  */
10680            } else {
10681                u16 *destreg;
10682
10683                DECODE_PRINTF("MUL\t");
10684                destreg = DECODE_RM_WORD_REGISTER(rl);
10685                DECODE_PRINTF("\n");
10686                TRACE_AND_STEP();
10687                mul_word(*destreg);      /*!!!  */
10688            }
10689            break;
10690        case 5:
10691            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10692                u32 *destreg;
10693
10694                DECODE_PRINTF("IMUL\t");
10695                destreg = DECODE_RM_LONG_REGISTER(rl);
10696                DECODE_PRINTF("\n");
10697                TRACE_AND_STEP();
10698                imul_long(*destreg);
10699            } else {
10700                u16 *destreg;
10701
10702                DECODE_PRINTF("IMUL\t");
10703                destreg = DECODE_RM_WORD_REGISTER(rl);
10704                DECODE_PRINTF("\n");
10705                TRACE_AND_STEP();
10706                imul_word(*destreg);
10707            }
10708            break;
10709        case 6:
10710            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10711                u32 *destreg;
10712
10713                DECODE_PRINTF("DIV\t");
10714                destreg = DECODE_RM_LONG_REGISTER(rl);
10715                DECODE_PRINTF("\n");
10716                TRACE_AND_STEP();
10717                div_long(*destreg);
10718            } else {
10719                u16 *destreg;
10720
10721                DECODE_PRINTF("DIV\t");
10722                destreg = DECODE_RM_WORD_REGISTER(rl);
10723                DECODE_PRINTF("\n");
10724                TRACE_AND_STEP();
10725                div_word(*destreg);
10726            }
10727            break;
10728        case 7:
10729            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10730                u32 *destreg;
10731
10732                DECODE_PRINTF("IDIV\t");
10733                destreg = DECODE_RM_LONG_REGISTER(rl);
10734                DECODE_PRINTF("\n");
10735                TRACE_AND_STEP();
10736                idiv_long(*destreg);
10737            } else {
10738                u16 *destreg;
10739
10740                DECODE_PRINTF("IDIV\t");
10741                destreg = DECODE_RM_WORD_REGISTER(rl);
10742                DECODE_PRINTF("\n");
10743                TRACE_AND_STEP();
10744                idiv_word(*destreg);
10745            }
10746            break;
10747        }
10748        break;                  /* end mod==11 */
10749    }
10750    DECODE_CLEAR_SEGOVR();
10751    END_OF_INSTR();
10752}
10753
10754/****************************************************************************
10755REMARKS:
10756Handles opcode 0xf8
10757****************************************************************************/
10758void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10759{
10760    /* clear the carry flag. */
10761    START_OF_INSTR();
10762    DECODE_PRINTF("CLC\n");
10763    TRACE_AND_STEP();
10764    CLEAR_FLAG(F_CF);
10765    DECODE_CLEAR_SEGOVR();
10766    END_OF_INSTR();
10767}
10768
10769/****************************************************************************
10770REMARKS:
10771Handles opcode 0xf9
10772****************************************************************************/
10773void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10774{
10775    /* set the carry flag. */
10776    START_OF_INSTR();
10777    DECODE_PRINTF("STC\n");
10778    TRACE_AND_STEP();
10779    SET_FLAG(F_CF);
10780    DECODE_CLEAR_SEGOVR();
10781    END_OF_INSTR();
10782}
10783
10784/****************************************************************************
10785REMARKS:
10786Handles opcode 0xfa
10787****************************************************************************/
10788void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10789{
10790    /* clear interrupts. */
10791    START_OF_INSTR();
10792    DECODE_PRINTF("CLI\n");
10793    TRACE_AND_STEP();
10794    CLEAR_FLAG(F_IF);
10795    DECODE_CLEAR_SEGOVR();
10796    END_OF_INSTR();
10797}
10798
10799/****************************************************************************
10800REMARKS:
10801Handles opcode 0xfb
10802****************************************************************************/
10803void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10804{
10805    /* enable  interrupts. */
10806    START_OF_INSTR();
10807    DECODE_PRINTF("STI\n");
10808    TRACE_AND_STEP();
10809    SET_FLAG(F_IF);
10810    DECODE_CLEAR_SEGOVR();
10811    END_OF_INSTR();
10812}
10813
10814/****************************************************************************
10815REMARKS:
10816Handles opcode 0xfc
10817****************************************************************************/
10818void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10819{
10820    /* clear interrupts. */
10821    START_OF_INSTR();
10822    DECODE_PRINTF("CLD\n");
10823    TRACE_AND_STEP();
10824    CLEAR_FLAG(F_DF);
10825    DECODE_CLEAR_SEGOVR();
10826    END_OF_INSTR();
10827}
10828
10829/****************************************************************************
10830REMARKS:
10831Handles opcode 0xfd
10832****************************************************************************/
10833void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10834{
10835    /* clear interrupts. */
10836    START_OF_INSTR();
10837    DECODE_PRINTF("STD\n");
10838    TRACE_AND_STEP();
10839    SET_FLAG(F_DF);
10840    DECODE_CLEAR_SEGOVR();
10841    END_OF_INSTR();
10842}
10843
10844/****************************************************************************
10845REMARKS:
10846Handles opcode 0xfe
10847****************************************************************************/
10848void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10849{
10850    int mod, rh, rl;
10851    u8 destval;
10852    uint destoffset;
10853    u8 *destreg;
10854
10855    /* Yet another special case instruction. */
10856    START_OF_INSTR();
10857    FETCH_DECODE_MODRM(mod, rh, rl);
10858#ifdef DEBUG
10859    if (DEBUG_DECODE()) {
10860
10861        switch (rh) {
10862        case 0:
10863            DECODE_PRINTF("INC\t");
10864            break;
10865        case 1:
10866            DECODE_PRINTF("DEC\t");
10867            break;
10868        case 2:
10869        case 3:
10870        case 4:
10871        case 5:
10872        case 6:
10873        case 7:
10874            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10875            HALT_SYS();
10876            break;
10877        }
10878    }
10879#endif
10880    switch (mod) {
10881    case 0:
10882        DECODE_PRINTF("BYTE PTR ");
10883        destoffset = decode_rm00_address(rl);
10884        DECODE_PRINTF("\n");
10885        switch (rh) {
10886        case 0:         /* inc word ptr ... */
10887            destval = fetch_data_byte(destoffset);
10888            TRACE_AND_STEP();
10889            destval = inc_byte(destval);
10890            store_data_byte(destoffset, destval);
10891            break;
10892        case 1:         /* dec word ptr ... */
10893            destval = fetch_data_byte(destoffset);
10894            TRACE_AND_STEP();
10895            destval = dec_byte(destval);
10896            store_data_byte(destoffset, destval);
10897            break;
10898        }
10899        break;
10900    case 1:
10901        DECODE_PRINTF("BYTE PTR ");
10902        destoffset = decode_rm01_address(rl);
10903        DECODE_PRINTF("\n");
10904        switch (rh) {
10905        case 0:
10906            destval = fetch_data_byte(destoffset);
10907            TRACE_AND_STEP();
10908            destval = inc_byte(destval);
10909            store_data_byte(destoffset, destval);
10910            break;
10911        case 1:
10912            destval = fetch_data_byte(destoffset);
10913            TRACE_AND_STEP();
10914            destval = dec_byte(destval);
10915            store_data_byte(destoffset, destval);
10916            break;
10917        }
10918        break;
10919    case 2:
10920        DECODE_PRINTF("BYTE PTR ");
10921        destoffset = decode_rm10_address(rl);
10922        DECODE_PRINTF("\n");
10923        switch (rh) {
10924        case 0:
10925            destval = fetch_data_byte(destoffset);
10926            TRACE_AND_STEP();
10927            destval = inc_byte(destval);
10928            store_data_byte(destoffset, destval);
10929            break;
10930        case 1:
10931            destval = fetch_data_byte(destoffset);
10932            TRACE_AND_STEP();
10933            destval = dec_byte(destval);
10934            store_data_byte(destoffset, destval);
10935            break;
10936        }
10937        break;
10938    case 3:
10939        destreg = DECODE_RM_BYTE_REGISTER(rl);
10940        DECODE_PRINTF("\n");
10941        switch (rh) {
10942        case 0:
10943            TRACE_AND_STEP();
10944            *destreg = inc_byte(*destreg);
10945            break;
10946        case 1:
10947            TRACE_AND_STEP();
10948            *destreg = dec_byte(*destreg);
10949            break;
10950        }
10951        break;
10952    }
10953    DECODE_CLEAR_SEGOVR();
10954    END_OF_INSTR();
10955}
10956
10957/****************************************************************************
10958REMARKS:
10959Handles opcode 0xff
10960****************************************************************************/
10961void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
10962{
10963    int mod, rh, rl;
10964    uint destoffset = 0;
10965	u16 *destreg;
10966	u16 destval,destval2;
10967
10968    /* Yet another special case instruction. */
10969    START_OF_INSTR();
10970    FETCH_DECODE_MODRM(mod, rh, rl);
10971#ifdef DEBUG
10972    if (DEBUG_DECODE()) {
10973
10974        switch (rh) {
10975        case 0:
10976            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10977                DECODE_PRINTF("INC\tDWORD PTR ");
10978            } else {
10979                DECODE_PRINTF("INC\tWORD PTR ");
10980            }
10981            break;
10982        case 1:
10983            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10984                DECODE_PRINTF("DEC\tDWORD PTR ");
10985            } else {
10986                DECODE_PRINTF("DEC\tWORD PTR ");
10987            }
10988            break;
10989        case 2:
10990            DECODE_PRINTF("CALL\t ");
10991            break;
10992        case 3:
10993            DECODE_PRINTF("CALL\tFAR ");
10994            break;
10995        case 4:
10996            DECODE_PRINTF("JMP\t");
10997            break;
10998        case 5:
10999            DECODE_PRINTF("JMP\tFAR ");
11000            break;
11001        case 6:
11002            DECODE_PRINTF("PUSH\t");
11003            break;
11004        case 7:
11005            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11006            HALT_SYS();
11007            break;
11008        }
11009    }
11010#endif
11011    switch (mod) {
11012    case 0:
11013        destoffset = decode_rm00_address(rl);
11014        DECODE_PRINTF("\n");
11015        switch (rh) {
11016        case 0:         /* inc word ptr ... */
11017            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018                u32 destval;
11019
11020                destval = fetch_data_long(destoffset);
11021                TRACE_AND_STEP();
11022                destval = inc_long(destval);
11023                store_data_long(destoffset, destval);
11024            } else {
11025                u16 destval;
11026
11027                destval = fetch_data_word(destoffset);
11028                TRACE_AND_STEP();
11029                destval = inc_word(destval);
11030                store_data_word(destoffset, destval);
11031            }
11032            break;
11033        case 1:         /* dec word ptr ... */
11034            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11035                u32 destval;
11036
11037                destval = fetch_data_long(destoffset);
11038                TRACE_AND_STEP();
11039                destval = dec_long(destval);
11040                store_data_long(destoffset, destval);
11041            } else {
11042                u16 destval;
11043
11044                destval = fetch_data_word(destoffset);
11045                TRACE_AND_STEP();
11046                destval = dec_word(destval);
11047                store_data_word(destoffset, destval);
11048            }
11049            break;
11050        case 2:         /* call word ptr ... */
11051            destval = fetch_data_word(destoffset);
11052            TRACE_AND_STEP();
11053            push_word(M.x86.R_IP);
11054            M.x86.R_IP = destval;
11055            break;
11056        case 3:         /* call far ptr ... */
11057            destval = fetch_data_word(destoffset);
11058            destval2 = fetch_data_word(destoffset + 2);
11059            TRACE_AND_STEP();
11060            push_word(M.x86.R_CS);
11061            M.x86.R_CS = destval2;
11062            push_word(M.x86.R_IP);
11063            M.x86.R_IP = destval;
11064            break;
11065        case 4:         /* jmp word ptr ... */
11066            destval = fetch_data_word(destoffset);
11067            TRACE_AND_STEP();
11068            M.x86.R_IP = destval;
11069            break;
11070        case 5:         /* jmp far ptr ... */
11071            destval = fetch_data_word(destoffset);
11072            destval2 = fetch_data_word(destoffset + 2);
11073            TRACE_AND_STEP();
11074            M.x86.R_IP = destval;
11075            M.x86.R_CS = destval2;
11076            break;
11077        case 6:         /*  push word ptr ... */
11078            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11079                u32 destval;
11080
11081                destval = fetch_data_long(destoffset);
11082                TRACE_AND_STEP();
11083                push_long(destval);
11084            } else {
11085                u16 destval;
11086
11087                destval = fetch_data_word(destoffset);
11088                TRACE_AND_STEP();
11089                push_word(destval);
11090            }
11091            break;
11092        }
11093        break;
11094    case 1:
11095        destoffset = decode_rm01_address(rl);
11096        DECODE_PRINTF("\n");
11097        switch (rh) {
11098        case 0:
11099            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11100                u32 destval;
11101
11102                destval = fetch_data_long(destoffset);
11103                TRACE_AND_STEP();
11104                destval = inc_long(destval);
11105                store_data_long(destoffset, destval);
11106            } else {
11107                u16 destval;
11108
11109                destval = fetch_data_word(destoffset);
11110                TRACE_AND_STEP();
11111                destval = inc_word(destval);
11112                store_data_word(destoffset, destval);
11113            }
11114            break;
11115        case 1:
11116            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11117                u32 destval;
11118
11119                destval = fetch_data_long(destoffset);
11120                TRACE_AND_STEP();
11121                destval = dec_long(destval);
11122                store_data_long(destoffset, destval);
11123            } else {
11124                u16 destval;
11125
11126                destval = fetch_data_word(destoffset);
11127                TRACE_AND_STEP();
11128                destval = dec_word(destval);
11129                store_data_word(destoffset, destval);
11130            }
11131            break;
11132        case 2:         /* call word ptr ... */
11133            destval = fetch_data_word(destoffset);
11134            TRACE_AND_STEP();
11135            push_word(M.x86.R_IP);
11136            M.x86.R_IP = destval;
11137            break;
11138        case 3:         /* call far ptr ... */
11139            destval = fetch_data_word(destoffset);
11140            destval2 = fetch_data_word(destoffset + 2);
11141            TRACE_AND_STEP();
11142            push_word(M.x86.R_CS);
11143            M.x86.R_CS = destval2;
11144            push_word(M.x86.R_IP);
11145            M.x86.R_IP = destval;
11146            break;
11147        case 4:         /* jmp word ptr ... */
11148            destval = fetch_data_word(destoffset);
11149            TRACE_AND_STEP();
11150            M.x86.R_IP = destval;
11151            break;
11152        case 5:         /* jmp far ptr ... */
11153            destval = fetch_data_word(destoffset);
11154            destval2 = fetch_data_word(destoffset + 2);
11155            TRACE_AND_STEP();
11156            M.x86.R_IP = destval;
11157            M.x86.R_CS = destval2;
11158            break;
11159        case 6:         /*  push word ptr ... */
11160            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11161                u32 destval;
11162
11163                destval = fetch_data_long(destoffset);
11164                TRACE_AND_STEP();
11165                push_long(destval);
11166            } else {
11167                u16 destval;
11168
11169                destval = fetch_data_word(destoffset);
11170                TRACE_AND_STEP();
11171                push_word(destval);
11172            }
11173            break;
11174        }
11175        break;
11176    case 2:
11177        destoffset = decode_rm10_address(rl);
11178        DECODE_PRINTF("\n");
11179        switch (rh) {
11180        case 0:
11181            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11182                u32 destval;
11183
11184                destval = fetch_data_long(destoffset);
11185                TRACE_AND_STEP();
11186                destval = inc_long(destval);
11187                store_data_long(destoffset, destval);
11188            } else {
11189                u16 destval;
11190
11191                destval = fetch_data_word(destoffset);
11192                TRACE_AND_STEP();
11193                destval = inc_word(destval);
11194                store_data_word(destoffset, destval);
11195            }
11196            break;
11197        case 1:
11198            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11199                u32 destval;
11200
11201                destval = fetch_data_long(destoffset);
11202                TRACE_AND_STEP();
11203                destval = dec_long(destval);
11204                store_data_long(destoffset, destval);
11205            } else {
11206                u16 destval;
11207
11208                destval = fetch_data_word(destoffset);
11209                TRACE_AND_STEP();
11210                destval = dec_word(destval);
11211                store_data_word(destoffset, destval);
11212            }
11213            break;
11214        case 2:         /* call word ptr ... */
11215            destval = fetch_data_word(destoffset);
11216            TRACE_AND_STEP();
11217            push_word(M.x86.R_IP);
11218            M.x86.R_IP = destval;
11219            break;
11220        case 3:         /* call far ptr ... */
11221            destval = fetch_data_word(destoffset);
11222            destval2 = fetch_data_word(destoffset + 2);
11223            TRACE_AND_STEP();
11224            push_word(M.x86.R_CS);
11225            M.x86.R_CS = destval2;
11226            push_word(M.x86.R_IP);
11227            M.x86.R_IP = destval;
11228            break;
11229        case 4:         /* jmp word ptr ... */
11230            destval = fetch_data_word(destoffset);
11231            TRACE_AND_STEP();
11232            M.x86.R_IP = destval;
11233            break;
11234        case 5:         /* jmp far ptr ... */
11235            destval = fetch_data_word(destoffset);
11236            destval2 = fetch_data_word(destoffset + 2);
11237            TRACE_AND_STEP();
11238            M.x86.R_IP = destval;
11239            M.x86.R_CS = destval2;
11240            break;
11241        case 6:         /*  push word ptr ... */
11242            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11243                u32 destval;
11244
11245                destval = fetch_data_long(destoffset);
11246                TRACE_AND_STEP();
11247                push_long(destval);
11248            } else {
11249                u16 destval;
11250
11251                destval = fetch_data_word(destoffset);
11252                TRACE_AND_STEP();
11253                push_word(destval);
11254            }
11255            break;
11256        }
11257        break;
11258    case 3:
11259        switch (rh) {
11260        case 0:
11261            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11262                u32 *destreg;
11263
11264                destreg = DECODE_RM_LONG_REGISTER(rl);
11265                DECODE_PRINTF("\n");
11266                TRACE_AND_STEP();
11267                *destreg = inc_long(*destreg);
11268            } else {
11269                u16 *destreg;
11270
11271                destreg = DECODE_RM_WORD_REGISTER(rl);
11272                DECODE_PRINTF("\n");
11273                TRACE_AND_STEP();
11274                *destreg = inc_word(*destreg);
11275            }
11276            break;
11277        case 1:
11278            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11279                u32 *destreg;
11280
11281                destreg = DECODE_RM_LONG_REGISTER(rl);
11282                DECODE_PRINTF("\n");
11283                TRACE_AND_STEP();
11284                *destreg = dec_long(*destreg);
11285            } else {
11286                u16 *destreg;
11287
11288                destreg = DECODE_RM_WORD_REGISTER(rl);
11289                DECODE_PRINTF("\n");
11290                TRACE_AND_STEP();
11291                *destreg = dec_word(*destreg);
11292            }
11293            break;
11294        case 2:         /* call word ptr ... */
11295            destreg = DECODE_RM_WORD_REGISTER(rl);
11296            DECODE_PRINTF("\n");
11297            TRACE_AND_STEP();
11298            push_word(M.x86.R_IP);
11299            M.x86.R_IP = *destreg;
11300            break;
11301        case 3:         /* jmp far ptr ... */
11302            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11303            TRACE_AND_STEP();
11304            HALT_SYS();
11305            break;
11306
11307        case 4:         /* jmp  ... */
11308            destreg = DECODE_RM_WORD_REGISTER(rl);
11309            DECODE_PRINTF("\n");
11310            TRACE_AND_STEP();
11311            M.x86.R_IP = (u16) (*destreg);
11312            break;
11313        case 5:         /* jmp far ptr ... */
11314            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11315            TRACE_AND_STEP();
11316            HALT_SYS();
11317            break;
11318        case 6:
11319            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11320                u32 *destreg;
11321
11322                destreg = DECODE_RM_LONG_REGISTER(rl);
11323                DECODE_PRINTF("\n");
11324                TRACE_AND_STEP();
11325                push_long(*destreg);
11326            } else {
11327                u16 *destreg;
11328
11329                destreg = DECODE_RM_WORD_REGISTER(rl);
11330                DECODE_PRINTF("\n");
11331                TRACE_AND_STEP();
11332                push_word(*destreg);
11333            }
11334            break;
11335        }
11336        break;
11337    }
11338    DECODE_CLEAR_SEGOVR();
11339    END_OF_INSTR();
11340}
11341
11342/***************************************************************************
11343 * Single byte operation code table:
11344 **************************************************************************/
11345void (*x86emu_optab[256])(u8) =
11346{
11347/*  0x00 */ x86emuOp_add_byte_RM_R,
11348/*  0x01 */ x86emuOp_add_word_RM_R,
11349/*  0x02 */ x86emuOp_add_byte_R_RM,
11350/*  0x03 */ x86emuOp_add_word_R_RM,
11351/*  0x04 */ x86emuOp_add_byte_AL_IMM,
11352/*  0x05 */ x86emuOp_add_word_AX_IMM,
11353/*  0x06 */ x86emuOp_push_ES,
11354/*  0x07 */ x86emuOp_pop_ES,
11355
11356/*  0x08 */ x86emuOp_or_byte_RM_R,
11357/*  0x09 */ x86emuOp_or_word_RM_R,
11358/*  0x0a */ x86emuOp_or_byte_R_RM,
11359/*  0x0b */ x86emuOp_or_word_R_RM,
11360/*  0x0c */ x86emuOp_or_byte_AL_IMM,
11361/*  0x0d */ x86emuOp_or_word_AX_IMM,
11362/*  0x0e */ x86emuOp_push_CS,
11363/*  0x0f */ x86emuOp_two_byte,
11364
11365/*  0x10 */ x86emuOp_adc_byte_RM_R,
11366/*  0x11 */ x86emuOp_adc_word_RM_R,
11367/*  0x12 */ x86emuOp_adc_byte_R_RM,
11368/*  0x13 */ x86emuOp_adc_word_R_RM,
11369/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11370/*  0x15 */ x86emuOp_adc_word_AX_IMM,
11371/*  0x16 */ x86emuOp_push_SS,
11372/*  0x17 */ x86emuOp_pop_SS,
11373
11374/*  0x18 */ x86emuOp_sbb_byte_RM_R,
11375/*  0x19 */ x86emuOp_sbb_word_RM_R,
11376/*  0x1a */ x86emuOp_sbb_byte_R_RM,
11377/*  0x1b */ x86emuOp_sbb_word_R_RM,
11378/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11379/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11380/*  0x1e */ x86emuOp_push_DS,
11381/*  0x1f */ x86emuOp_pop_DS,
11382
11383/*  0x20 */ x86emuOp_and_byte_RM_R,
11384/*  0x21 */ x86emuOp_and_word_RM_R,
11385/*  0x22 */ x86emuOp_and_byte_R_RM,
11386/*  0x23 */ x86emuOp_and_word_R_RM,
11387/*  0x24 */ x86emuOp_and_byte_AL_IMM,
11388/*  0x25 */ x86emuOp_and_word_AX_IMM,
11389/*  0x26 */ x86emuOp_segovr_ES,
11390/*  0x27 */ x86emuOp_daa,
11391
11392/*  0x28 */ x86emuOp_sub_byte_RM_R,
11393/*  0x29 */ x86emuOp_sub_word_RM_R,
11394/*  0x2a */ x86emuOp_sub_byte_R_RM,
11395/*  0x2b */ x86emuOp_sub_word_R_RM,
11396/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11397/*  0x2d */ x86emuOp_sub_word_AX_IMM,
11398/*  0x2e */ x86emuOp_segovr_CS,
11399/*  0x2f */ x86emuOp_das,
11400
11401/*  0x30 */ x86emuOp_xor_byte_RM_R,
11402/*  0x31 */ x86emuOp_xor_word_RM_R,
11403/*  0x32 */ x86emuOp_xor_byte_R_RM,
11404/*  0x33 */ x86emuOp_xor_word_R_RM,
11405/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11406/*  0x35 */ x86emuOp_xor_word_AX_IMM,
11407/*  0x36 */ x86emuOp_segovr_SS,
11408/*  0x37 */ x86emuOp_aaa,
11409
11410/*  0x38 */ x86emuOp_cmp_byte_RM_R,
11411/*  0x39 */ x86emuOp_cmp_word_RM_R,
11412/*  0x3a */ x86emuOp_cmp_byte_R_RM,
11413/*  0x3b */ x86emuOp_cmp_word_R_RM,
11414/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11415/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11416/*  0x3e */ x86emuOp_segovr_DS,
11417/*  0x3f */ x86emuOp_aas,
11418
11419/*  0x40 */ x86emuOp_inc_AX,
11420/*  0x41 */ x86emuOp_inc_CX,
11421/*  0x42 */ x86emuOp_inc_DX,
11422/*  0x43 */ x86emuOp_inc_BX,
11423/*  0x44 */ x86emuOp_inc_SP,
11424/*  0x45 */ x86emuOp_inc_BP,
11425/*  0x46 */ x86emuOp_inc_SI,
11426/*  0x47 */ x86emuOp_inc_DI,
11427
11428/*  0x48 */ x86emuOp_dec_AX,
11429/*  0x49 */ x86emuOp_dec_CX,
11430/*  0x4a */ x86emuOp_dec_DX,
11431/*  0x4b */ x86emuOp_dec_BX,
11432/*  0x4c */ x86emuOp_dec_SP,
11433/*  0x4d */ x86emuOp_dec_BP,
11434/*  0x4e */ x86emuOp_dec_SI,
11435/*  0x4f */ x86emuOp_dec_DI,
11436
11437/*  0x50 */ x86emuOp_push_AX,
11438/*  0x51 */ x86emuOp_push_CX,
11439/*  0x52 */ x86emuOp_push_DX,
11440/*  0x53 */ x86emuOp_push_BX,
11441/*  0x54 */ x86emuOp_push_SP,
11442/*  0x55 */ x86emuOp_push_BP,
11443/*  0x56 */ x86emuOp_push_SI,
11444/*  0x57 */ x86emuOp_push_DI,
11445
11446/*  0x58 */ x86emuOp_pop_AX,
11447/*  0x59 */ x86emuOp_pop_CX,
11448/*  0x5a */ x86emuOp_pop_DX,
11449/*  0x5b */ x86emuOp_pop_BX,
11450/*  0x5c */ x86emuOp_pop_SP,
11451/*  0x5d */ x86emuOp_pop_BP,
11452/*  0x5e */ x86emuOp_pop_SI,
11453/*  0x5f */ x86emuOp_pop_DI,
11454
11455/*  0x60 */ x86emuOp_push_all,
11456/*  0x61 */ x86emuOp_pop_all,
11457/*  0x62 */ x86emuOp_illegal_op,   /* bound */
11458/*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11459/*  0x64 */ x86emuOp_segovr_FS,
11460/*  0x65 */ x86emuOp_segovr_GS,
11461/*  0x66 */ x86emuOp_prefix_data,
11462/*  0x67 */ x86emuOp_prefix_addr,
11463
11464/*  0x68 */ x86emuOp_push_word_IMM,
11465/*  0x69 */ x86emuOp_imul_word_IMM,
11466/*  0x6a */ x86emuOp_push_byte_IMM,
11467/*  0x6b */ x86emuOp_imul_byte_IMM,
11468/*  0x6c */ x86emuOp_ins_byte,
11469/*  0x6d */ x86emuOp_ins_word,
11470/*  0x6e */ x86emuOp_outs_byte,
11471/*  0x6f */ x86emuOp_outs_word,
11472
11473/*  0x70 */ x86emuOp_jump_near_O,
11474/*  0x71 */ x86emuOp_jump_near_NO,
11475/*  0x72 */ x86emuOp_jump_near_B,
11476/*  0x73 */ x86emuOp_jump_near_NB,
11477/*  0x74 */ x86emuOp_jump_near_Z,
11478/*  0x75 */ x86emuOp_jump_near_NZ,
11479/*  0x76 */ x86emuOp_jump_near_BE,
11480/*  0x77 */ x86emuOp_jump_near_NBE,
11481
11482/*  0x78 */ x86emuOp_jump_near_S,
11483/*  0x79 */ x86emuOp_jump_near_NS,
11484/*  0x7a */ x86emuOp_jump_near_P,
11485/*  0x7b */ x86emuOp_jump_near_NP,
11486/*  0x7c */ x86emuOp_jump_near_L,
11487/*  0x7d */ x86emuOp_jump_near_NL,
11488/*  0x7e */ x86emuOp_jump_near_LE,
11489/*  0x7f */ x86emuOp_jump_near_NLE,
11490
11491/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11492/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11493/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11494/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11495/*  0x84 */ x86emuOp_test_byte_RM_R,
11496/*  0x85 */ x86emuOp_test_word_RM_R,
11497/*  0x86 */ x86emuOp_xchg_byte_RM_R,
11498/*  0x87 */ x86emuOp_xchg_word_RM_R,
11499
11500/*  0x88 */ x86emuOp_mov_byte_RM_R,
11501/*  0x89 */ x86emuOp_mov_word_RM_R,
11502/*  0x8a */ x86emuOp_mov_byte_R_RM,
11503/*  0x8b */ x86emuOp_mov_word_R_RM,
11504/*  0x8c */ x86emuOp_mov_word_RM_SR,
11505/*  0x8d */ x86emuOp_lea_word_R_M,
11506/*  0x8e */ x86emuOp_mov_word_SR_RM,
11507/*  0x8f */ x86emuOp_pop_RM,
11508
11509/*  0x90 */ x86emuOp_nop,
11510/*  0x91 */ x86emuOp_xchg_word_AX_CX,
11511/*  0x92 */ x86emuOp_xchg_word_AX_DX,
11512/*  0x93 */ x86emuOp_xchg_word_AX_BX,
11513/*  0x94 */ x86emuOp_xchg_word_AX_SP,
11514/*  0x95 */ x86emuOp_xchg_word_AX_BP,
11515/*  0x96 */ x86emuOp_xchg_word_AX_SI,
11516/*  0x97 */ x86emuOp_xchg_word_AX_DI,
11517
11518/*  0x98 */ x86emuOp_cbw,
11519/*  0x99 */ x86emuOp_cwd,
11520/*  0x9a */ x86emuOp_call_far_IMM,
11521/*  0x9b */ x86emuOp_wait,
11522/*  0x9c */ x86emuOp_pushf_word,
11523/*  0x9d */ x86emuOp_popf_word,
11524/*  0x9e */ x86emuOp_sahf,
11525/*  0x9f */ x86emuOp_lahf,
11526
11527/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11528/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11529/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11530/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11531/*  0xa4 */ x86emuOp_movs_byte,
11532/*  0xa5 */ x86emuOp_movs_word,
11533/*  0xa6 */ x86emuOp_cmps_byte,
11534/*  0xa7 */ x86emuOp_cmps_word,
11535/*  0xa8 */ x86emuOp_test_AL_IMM,
11536/*  0xa9 */ x86emuOp_test_AX_IMM,
11537/*  0xaa */ x86emuOp_stos_byte,
11538/*  0xab */ x86emuOp_stos_word,
11539/*  0xac */ x86emuOp_lods_byte,
11540/*  0xad */ x86emuOp_lods_word,
11541/*  0xac */ x86emuOp_scas_byte,
11542/*  0xad */ x86emuOp_scas_word,
11543
11544
11545/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11546/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11547/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11548/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11549/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11550/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11551/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11552/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11553
11554/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11555/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11556/*  0xba */ x86emuOp_mov_word_DX_IMM,
11557/*  0xbb */ x86emuOp_mov_word_BX_IMM,
11558/*  0xbc */ x86emuOp_mov_word_SP_IMM,
11559/*  0xbd */ x86emuOp_mov_word_BP_IMM,
11560/*  0xbe */ x86emuOp_mov_word_SI_IMM,
11561/*  0xbf */ x86emuOp_mov_word_DI_IMM,
11562
11563/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11564/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11565/*  0xc2 */ x86emuOp_ret_near_IMM,
11566/*  0xc3 */ x86emuOp_ret_near,
11567/*  0xc4 */ x86emuOp_les_R_IMM,
11568/*  0xc5 */ x86emuOp_lds_R_IMM,
11569/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11570/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11571/*  0xc8 */ x86emuOp_enter,
11572/*  0xc9 */ x86emuOp_leave,
11573/*  0xca */ x86emuOp_ret_far_IMM,
11574/*  0xcb */ x86emuOp_ret_far,
11575/*  0xcc */ x86emuOp_int3,
11576/*  0xcd */ x86emuOp_int_IMM,
11577/*  0xce */ x86emuOp_into,
11578/*  0xcf */ x86emuOp_iret,
11579
11580/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11581/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11582/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11583/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11584/*  0xd4 */ x86emuOp_aam,
11585/*  0xd5 */ x86emuOp_aad,
11586/*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11587/*  0xd7 */ x86emuOp_xlat,
11588/*  0xd8 */ x86emuOp_esc_coprocess_d8,
11589/*  0xd9 */ x86emuOp_esc_coprocess_d9,
11590/*  0xda */ x86emuOp_esc_coprocess_da,
11591/*  0xdb */ x86emuOp_esc_coprocess_db,
11592/*  0xdc */ x86emuOp_esc_coprocess_dc,
11593/*  0xdd */ x86emuOp_esc_coprocess_dd,
11594/*  0xde */ x86emuOp_esc_coprocess_de,
11595/*  0xdf */ x86emuOp_esc_coprocess_df,
11596
11597/*  0xe0 */ x86emuOp_loopne,
11598/*  0xe1 */ x86emuOp_loope,
11599/*  0xe2 */ x86emuOp_loop,
11600/*  0xe3 */ x86emuOp_jcxz,
11601/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11602/*  0xe5 */ x86emuOp_in_word_AX_IMM,
11603/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11604/*  0xe7 */ x86emuOp_out_word_IMM_AX,
11605
11606/*  0xe8 */ x86emuOp_call_near_IMM,
11607/*  0xe9 */ x86emuOp_jump_near_IMM,
11608/*  0xea */ x86emuOp_jump_far_IMM,
11609/*  0xeb */ x86emuOp_jump_byte_IMM,
11610/*  0xec */ x86emuOp_in_byte_AL_DX,
11611/*  0xed */ x86emuOp_in_word_AX_DX,
11612/*  0xee */ x86emuOp_out_byte_DX_AL,
11613/*  0xef */ x86emuOp_out_word_DX_AX,
11614
11615/*  0xf0 */ x86emuOp_lock,
11616/*  0xf1 */ x86emuOp_illegal_op,
11617/*  0xf2 */ x86emuOp_repne,
11618/*  0xf3 */ x86emuOp_repe,
11619/*  0xf4 */ x86emuOp_halt,
11620/*  0xf5 */ x86emuOp_cmc,
11621/*  0xf6 */ x86emuOp_opcF6_byte_RM,
11622/*  0xf7 */ x86emuOp_opcF7_word_RM,
11623
11624/*  0xf8 */ x86emuOp_clc,
11625/*  0xf9 */ x86emuOp_stc,
11626/*  0xfa */ x86emuOp_cli,
11627/*  0xfb */ x86emuOp_sti,
11628/*  0xfc */ x86emuOp_cld,
11629/*  0xfd */ x86emuOp_std,
11630/*  0xfe */ x86emuOp_opcFE_byte_RM,
11631/*  0xff */ x86emuOp_opcFF_word_RM,
11632};
11633