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 preceding it which gives its table
43* address.  Several opcodes are missing (undefined) in the table.
44*
45* Each proc includes information for decoding (DECODE_PRINTF and
46* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47* functions (START_OF_INSTR, END_OF_INSTR).
48*
49* Many of the procedures are *VERY* similar in coding.  This has
50* allowed for a very large amount of code to be generated in a fairly
51* short amount of time (i.e. cut, paste, and modify).  The result is
52* that much of the code below could have been folded into subroutines
53* for a large reduction in size of this file.  The downside would be
54* that there would be a penalty in execution speed.  The file could
55* also have been *MUCH* larger by inlining certain functions which
56* were called.  This could have resulted even faster execution.  The
57* prime directive I used to decide whether to inline the code or to
58* modularize it, was basically: 1) no unnecessary subroutine calls,
59* 2) no routines more than about 200 lines in size, and 3) modularize
60* any code that I might not get right the first time.  The fetch_*
61* subroutines fall into the latter category.  The The decode_* fall
62* into the second category.  The coding of the "switch(mod){ .... }"
63* in many of the subroutines below falls into the first category.
64* Especially, the coding of {add,and,or,sub,...}_{byte,word}
65* subroutines are an especially glaring case of the third guideline.
66* Since so much of the code is cloned from other modules (compare
67* opcode #00 to opcode #01), making the basic operations subroutine
68* calls is especially important; otherwise mistakes in coding an
69* "add" would represent a nightmare in maintenance.
70*
71****************************************************************************/
72
73#include "x86emu/x86emui.h"
74
75/*----------------------------- Implementation ----------------------------*/
76
77/****************************************************************************
78PARAMETERS:
79op1 - Instruction op code
80
81REMARKS:
82Handles illegal opcodes.
83****************************************************************************/
84static void
85x86emuOp_illegal_op(u8 op1)
86{
87    START_OF_INSTR();
88    if (M.x86.R_SP != 0) {
89        DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90        TRACE_REGS();
91        DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92                  M.x86.R_CS, M.x86.R_IP - 1, op1));
93        HALT_SYS();
94    }
95    else {
96        /* If we get here, it means the stack pointer is back to zero
97         * so we are just returning from an emulator service call
98         * so therte is no need to display an error message. We trap
99         * the emulator with an 0xF1 opcode to finish the service
100         * call.
101         */
102        X86EMU_halt_sys();
103    }
104    END_OF_INSTR();
105}
106
107/****************************************************************************
108REMARKS:
109Handles opcode 0x00
110****************************************************************************/
111static void
112x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113{
114    int mod, rl, rh;
115    uint destoffset;
116    u8 *destreg, *srcreg;
117    u8 destval;
118
119    START_OF_INSTR();
120    DECODE_PRINTF("ADD\t");
121    FETCH_DECODE_MODRM(mod, rh, rl);
122    switch (mod) {
123    case 0:
124        destoffset = decode_rm00_address(rl);
125        DECODE_PRINTF(",");
126        destval = fetch_data_byte(destoffset);
127        srcreg = DECODE_RM_BYTE_REGISTER(rh);
128        DECODE_PRINTF("\n");
129        TRACE_AND_STEP();
130        destval = add_byte(destval, *srcreg);
131        store_data_byte(destoffset, destval);
132        break;
133    case 1:
134        destoffset = decode_rm01_address(rl);
135        DECODE_PRINTF(",");
136        destval = fetch_data_byte(destoffset);
137        srcreg = DECODE_RM_BYTE_REGISTER(rh);
138        DECODE_PRINTF("\n");
139        TRACE_AND_STEP();
140        destval = add_byte(destval, *srcreg);
141        store_data_byte(destoffset, destval);
142        break;
143    case 2:
144        destoffset = decode_rm10_address(rl);
145        DECODE_PRINTF(",");
146        destval = fetch_data_byte(destoffset);
147        srcreg = DECODE_RM_BYTE_REGISTER(rh);
148        DECODE_PRINTF("\n");
149        TRACE_AND_STEP();
150        destval = add_byte(destval, *srcreg);
151        store_data_byte(destoffset, destval);
152        break;
153    case 3:                    /* register to register */
154        destreg = DECODE_RM_BYTE_REGISTER(rl);
155        DECODE_PRINTF(",");
156        srcreg = DECODE_RM_BYTE_REGISTER(rh);
157        DECODE_PRINTF("\n");
158        TRACE_AND_STEP();
159        *destreg = add_byte(*destreg, *srcreg);
160        break;
161    }
162    DECODE_CLEAR_SEGOVR();
163    END_OF_INSTR();
164}
165
166/****************************************************************************
167REMARKS:
168Handles opcode 0x01
169****************************************************************************/
170static void
171x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172{
173    int mod, rl, rh;
174    uint destoffset;
175
176    START_OF_INSTR();
177    DECODE_PRINTF("ADD\t");
178    FETCH_DECODE_MODRM(mod, rh, rl);
179    switch (mod) {
180    case 0:
181        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182            u32 destval;
183            u32 *srcreg;
184
185            destoffset = decode_rm00_address(rl);
186            DECODE_PRINTF(",");
187            destval = fetch_data_long(destoffset);
188            srcreg = DECODE_RM_LONG_REGISTER(rh);
189            DECODE_PRINTF("\n");
190            TRACE_AND_STEP();
191            destval = add_long(destval, *srcreg);
192            store_data_long(destoffset, destval);
193        }
194        else {
195            u16 destval;
196            u16 *srcreg;
197
198            destoffset = decode_rm00_address(rl);
199            DECODE_PRINTF(",");
200            destval = fetch_data_word(destoffset);
201            srcreg = DECODE_RM_WORD_REGISTER(rh);
202            DECODE_PRINTF("\n");
203            TRACE_AND_STEP();
204            destval = add_word(destval, *srcreg);
205            store_data_word(destoffset, destval);
206        }
207        break;
208    case 1:
209        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
210            u32 destval;
211            u32 *srcreg;
212
213            destoffset = decode_rm01_address(rl);
214            DECODE_PRINTF(",");
215            destval = fetch_data_long(destoffset);
216            srcreg = DECODE_RM_LONG_REGISTER(rh);
217            DECODE_PRINTF("\n");
218            TRACE_AND_STEP();
219            destval = add_long(destval, *srcreg);
220            store_data_long(destoffset, destval);
221        }
222        else {
223            u16 destval;
224            u16 *srcreg;
225
226            destoffset = decode_rm01_address(rl);
227            DECODE_PRINTF(",");
228            destval = fetch_data_word(destoffset);
229            srcreg = DECODE_RM_WORD_REGISTER(rh);
230            DECODE_PRINTF("\n");
231            TRACE_AND_STEP();
232            destval = add_word(destval, *srcreg);
233            store_data_word(destoffset, destval);
234        }
235        break;
236    case 2:
237        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
238            u32 destval;
239            u32 *srcreg;
240
241            destoffset = decode_rm10_address(rl);
242            DECODE_PRINTF(",");
243            destval = fetch_data_long(destoffset);
244            srcreg = DECODE_RM_LONG_REGISTER(rh);
245            DECODE_PRINTF("\n");
246            TRACE_AND_STEP();
247            destval = add_long(destval, *srcreg);
248            store_data_long(destoffset, destval);
249        }
250        else {
251            u16 destval;
252            u16 *srcreg;
253
254            destoffset = decode_rm10_address(rl);
255            DECODE_PRINTF(",");
256            destval = fetch_data_word(destoffset);
257            srcreg = DECODE_RM_WORD_REGISTER(rh);
258            DECODE_PRINTF("\n");
259            TRACE_AND_STEP();
260            destval = add_word(destval, *srcreg);
261            store_data_word(destoffset, destval);
262        }
263        break;
264    case 3:                    /* register to register */
265        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
266            u32 *destreg, *srcreg;
267
268            destreg = DECODE_RM_LONG_REGISTER(rl);
269            DECODE_PRINTF(",");
270            srcreg = DECODE_RM_LONG_REGISTER(rh);
271            DECODE_PRINTF("\n");
272            TRACE_AND_STEP();
273            *destreg = add_long(*destreg, *srcreg);
274        }
275        else {
276            u16 *destreg, *srcreg;
277
278            destreg = DECODE_RM_WORD_REGISTER(rl);
279            DECODE_PRINTF(",");
280            srcreg = DECODE_RM_WORD_REGISTER(rh);
281            DECODE_PRINTF("\n");
282            TRACE_AND_STEP();
283            *destreg = add_word(*destreg, *srcreg);
284        }
285        break;
286    }
287    DECODE_CLEAR_SEGOVR();
288    END_OF_INSTR();
289}
290
291/****************************************************************************
292REMARKS:
293Handles opcode 0x02
294****************************************************************************/
295static void
296x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
297{
298    int mod, rl, rh;
299    u8 *destreg, *srcreg;
300    uint srcoffset;
301    u8 srcval;
302
303    START_OF_INSTR();
304    DECODE_PRINTF("ADD\t");
305    FETCH_DECODE_MODRM(mod, rh, rl);
306    switch (mod) {
307    case 0:
308        destreg = DECODE_RM_BYTE_REGISTER(rh);
309        DECODE_PRINTF(",");
310        srcoffset = decode_rm00_address(rl);
311        srcval = fetch_data_byte(srcoffset);
312        DECODE_PRINTF("\n");
313        TRACE_AND_STEP();
314        *destreg = add_byte(*destreg, srcval);
315        break;
316    case 1:
317        destreg = DECODE_RM_BYTE_REGISTER(rh);
318        DECODE_PRINTF(",");
319        srcoffset = decode_rm01_address(rl);
320        srcval = fetch_data_byte(srcoffset);
321        DECODE_PRINTF("\n");
322        TRACE_AND_STEP();
323        *destreg = add_byte(*destreg, srcval);
324        break;
325    case 2:
326        destreg = DECODE_RM_BYTE_REGISTER(rh);
327        DECODE_PRINTF(",");
328        srcoffset = decode_rm10_address(rl);
329        srcval = fetch_data_byte(srcoffset);
330        DECODE_PRINTF("\n");
331        TRACE_AND_STEP();
332        *destreg = add_byte(*destreg, srcval);
333        break;
334    case 3:                    /* register to register */
335        destreg = DECODE_RM_BYTE_REGISTER(rh);
336        DECODE_PRINTF(",");
337        srcreg = DECODE_RM_BYTE_REGISTER(rl);
338        DECODE_PRINTF("\n");
339        TRACE_AND_STEP();
340        *destreg = add_byte(*destreg, *srcreg);
341        break;
342    }
343    DECODE_CLEAR_SEGOVR();
344    END_OF_INSTR();
345}
346
347/****************************************************************************
348REMARKS:
349Handles opcode 0x03
350****************************************************************************/
351static void
352x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
353{
354    int mod, rl, rh;
355    uint srcoffset;
356
357    START_OF_INSTR();
358    DECODE_PRINTF("ADD\t");
359    FETCH_DECODE_MODRM(mod, rh, rl);
360    switch (mod) {
361    case 0:
362        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
363            u32 *destreg;
364            u32 srcval;
365
366            destreg = DECODE_RM_LONG_REGISTER(rh);
367            DECODE_PRINTF(",");
368            srcoffset = decode_rm00_address(rl);
369            srcval = fetch_data_long(srcoffset);
370            DECODE_PRINTF("\n");
371            TRACE_AND_STEP();
372            *destreg = add_long(*destreg, srcval);
373        }
374        else {
375            u16 *destreg;
376            u16 srcval;
377
378            destreg = DECODE_RM_WORD_REGISTER(rh);
379            DECODE_PRINTF(",");
380            srcoffset = decode_rm00_address(rl);
381            srcval = fetch_data_word(srcoffset);
382            DECODE_PRINTF("\n");
383            TRACE_AND_STEP();
384            *destreg = add_word(*destreg, srcval);
385        }
386        break;
387    case 1:
388        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
389            u32 *destreg;
390            u32 srcval;
391
392            destreg = DECODE_RM_LONG_REGISTER(rh);
393            DECODE_PRINTF(",");
394            srcoffset = decode_rm01_address(rl);
395            srcval = fetch_data_long(srcoffset);
396            DECODE_PRINTF("\n");
397            TRACE_AND_STEP();
398            *destreg = add_long(*destreg, srcval);
399        }
400        else {
401            u16 *destreg;
402            u16 srcval;
403
404            destreg = DECODE_RM_WORD_REGISTER(rh);
405            DECODE_PRINTF(",");
406            srcoffset = decode_rm01_address(rl);
407            srcval = fetch_data_word(srcoffset);
408            DECODE_PRINTF("\n");
409            TRACE_AND_STEP();
410            *destreg = add_word(*destreg, srcval);
411        }
412        break;
413    case 2:
414        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
415            u32 *destreg;
416            u32 srcval;
417
418            destreg = DECODE_RM_LONG_REGISTER(rh);
419            DECODE_PRINTF(",");
420            srcoffset = decode_rm10_address(rl);
421            srcval = fetch_data_long(srcoffset);
422            DECODE_PRINTF("\n");
423            TRACE_AND_STEP();
424            *destreg = add_long(*destreg, srcval);
425        }
426        else {
427            u16 *destreg;
428            u16 srcval;
429
430            destreg = DECODE_RM_WORD_REGISTER(rh);
431            DECODE_PRINTF(",");
432            srcoffset = decode_rm10_address(rl);
433            srcval = fetch_data_word(srcoffset);
434            DECODE_PRINTF("\n");
435            TRACE_AND_STEP();
436            *destreg = add_word(*destreg, srcval);
437        }
438        break;
439    case 3:                    /* register to register */
440        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441            u32 *destreg, *srcreg;
442
443            destreg = DECODE_RM_LONG_REGISTER(rh);
444            DECODE_PRINTF(",");
445            srcreg = DECODE_RM_LONG_REGISTER(rl);
446            DECODE_PRINTF("\n");
447            TRACE_AND_STEP();
448            *destreg = add_long(*destreg, *srcreg);
449        }
450        else {
451            u16 *destreg, *srcreg;
452
453            destreg = DECODE_RM_WORD_REGISTER(rh);
454            DECODE_PRINTF(",");
455            srcreg = DECODE_RM_WORD_REGISTER(rl);
456            DECODE_PRINTF("\n");
457            TRACE_AND_STEP();
458            *destreg = add_word(*destreg, *srcreg);
459        }
460        break;
461    }
462    DECODE_CLEAR_SEGOVR();
463    END_OF_INSTR();
464}
465
466/****************************************************************************
467REMARKS:
468Handles opcode 0x04
469****************************************************************************/
470static void
471x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
472{
473    u8 srcval;
474
475    START_OF_INSTR();
476    DECODE_PRINTF("ADD\tAL,");
477    srcval = fetch_byte_imm();
478    DECODE_PRINTF2("%x\n", srcval);
479    TRACE_AND_STEP();
480    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
481    DECODE_CLEAR_SEGOVR();
482    END_OF_INSTR();
483}
484
485/****************************************************************************
486REMARKS:
487Handles opcode 0x05
488****************************************************************************/
489static void
490x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
491{
492    u32 srcval;
493
494    START_OF_INSTR();
495    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
496        DECODE_PRINTF("ADD\tEAX,");
497        srcval = fetch_long_imm();
498    }
499    else {
500        DECODE_PRINTF("ADD\tAX,");
501        srcval = fetch_word_imm();
502    }
503    DECODE_PRINTF2("%x\n", srcval);
504    TRACE_AND_STEP();
505    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
506        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
507    }
508    else {
509        M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
510    }
511    DECODE_CLEAR_SEGOVR();
512    END_OF_INSTR();
513}
514
515/****************************************************************************
516REMARKS:
517Handles opcode 0x06
518****************************************************************************/
519static void
520x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
521{
522    START_OF_INSTR();
523    DECODE_PRINTF("PUSH\tES\n");
524    TRACE_AND_STEP();
525    push_word(M.x86.R_ES);
526    DECODE_CLEAR_SEGOVR();
527    END_OF_INSTR();
528}
529
530/****************************************************************************
531REMARKS:
532Handles opcode 0x07
533****************************************************************************/
534static void
535x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
536{
537    START_OF_INSTR();
538    DECODE_PRINTF("POP\tES\n");
539    TRACE_AND_STEP();
540    M.x86.R_ES = pop_word();
541    DECODE_CLEAR_SEGOVR();
542    END_OF_INSTR();
543}
544
545/****************************************************************************
546REMARKS:
547Handles opcode 0x08
548****************************************************************************/
549static void
550x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
551{
552    int mod, rl, rh;
553    u8 *destreg, *srcreg;
554    uint destoffset;
555    u8 destval;
556
557    START_OF_INSTR();
558    DECODE_PRINTF("OR\t");
559    FETCH_DECODE_MODRM(mod, rh, rl);
560    switch (mod) {
561    case 0:
562        destoffset = decode_rm00_address(rl);
563        DECODE_PRINTF(",");
564        destval = fetch_data_byte(destoffset);
565        srcreg = DECODE_RM_BYTE_REGISTER(rh);
566        DECODE_PRINTF("\n");
567        TRACE_AND_STEP();
568        destval = or_byte(destval, *srcreg);
569        store_data_byte(destoffset, destval);
570        break;
571    case 1:
572        destoffset = decode_rm01_address(rl);
573        DECODE_PRINTF(",");
574        destval = fetch_data_byte(destoffset);
575        srcreg = DECODE_RM_BYTE_REGISTER(rh);
576        DECODE_PRINTF("\n");
577        TRACE_AND_STEP();
578        destval = or_byte(destval, *srcreg);
579        store_data_byte(destoffset, destval);
580        break;
581    case 2:
582        destoffset = decode_rm10_address(rl);
583        DECODE_PRINTF(",");
584        destval = fetch_data_byte(destoffset);
585        srcreg = DECODE_RM_BYTE_REGISTER(rh);
586        DECODE_PRINTF("\n");
587        TRACE_AND_STEP();
588        destval = or_byte(destval, *srcreg);
589        store_data_byte(destoffset, destval);
590        break;
591    case 3:                    /* register to register */
592        destreg = DECODE_RM_BYTE_REGISTER(rl);
593        DECODE_PRINTF(",");
594        srcreg = DECODE_RM_BYTE_REGISTER(rh);
595        DECODE_PRINTF("\n");
596        TRACE_AND_STEP();
597        *destreg = or_byte(*destreg, *srcreg);
598        break;
599    }
600    DECODE_CLEAR_SEGOVR();
601    END_OF_INSTR();
602}
603
604/****************************************************************************
605REMARKS:
606Handles opcode 0x09
607****************************************************************************/
608static void
609x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
610{
611    int mod, rl, rh;
612    uint destoffset;
613
614    START_OF_INSTR();
615    DECODE_PRINTF("OR\t");
616    FETCH_DECODE_MODRM(mod, rh, rl);
617    switch (mod) {
618    case 0:
619        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620            u32 destval;
621            u32 *srcreg;
622
623            destoffset = decode_rm00_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        }
632        else {
633            u16 destval;
634            u16 *srcreg;
635
636            destoffset = decode_rm00_address(rl);
637            DECODE_PRINTF(",");
638            destval = fetch_data_word(destoffset);
639            srcreg = DECODE_RM_WORD_REGISTER(rh);
640            DECODE_PRINTF("\n");
641            TRACE_AND_STEP();
642            destval = or_word(destval, *srcreg);
643            store_data_word(destoffset, destval);
644        }
645        break;
646    case 1:
647        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
648            u32 destval;
649            u32 *srcreg;
650
651            destoffset = decode_rm01_address(rl);
652            DECODE_PRINTF(",");
653            destval = fetch_data_long(destoffset);
654            srcreg = DECODE_RM_LONG_REGISTER(rh);
655            DECODE_PRINTF("\n");
656            TRACE_AND_STEP();
657            destval = or_long(destval, *srcreg);
658            store_data_long(destoffset, destval);
659        }
660        else {
661            u16 destval;
662            u16 *srcreg;
663
664            destoffset = decode_rm01_address(rl);
665            DECODE_PRINTF(",");
666            destval = fetch_data_word(destoffset);
667            srcreg = DECODE_RM_WORD_REGISTER(rh);
668            DECODE_PRINTF("\n");
669            TRACE_AND_STEP();
670            destval = or_word(destval, *srcreg);
671            store_data_word(destoffset, destval);
672        }
673        break;
674    case 2:
675        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
676            u32 destval;
677            u32 *srcreg;
678
679            destoffset = decode_rm10_address(rl);
680            DECODE_PRINTF(",");
681            destval = fetch_data_long(destoffset);
682            srcreg = DECODE_RM_LONG_REGISTER(rh);
683            DECODE_PRINTF("\n");
684            TRACE_AND_STEP();
685            destval = or_long(destval, *srcreg);
686            store_data_long(destoffset, destval);
687        }
688        else {
689            u16 destval;
690            u16 *srcreg;
691
692            destoffset = decode_rm10_address(rl);
693            DECODE_PRINTF(",");
694            destval = fetch_data_word(destoffset);
695            srcreg = DECODE_RM_WORD_REGISTER(rh);
696            DECODE_PRINTF("\n");
697            TRACE_AND_STEP();
698            destval = or_word(destval, *srcreg);
699            store_data_word(destoffset, destval);
700        }
701        break;
702    case 3:                    /* register to register */
703        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704            u32 *destreg, *srcreg;
705
706            destreg = DECODE_RM_LONG_REGISTER(rl);
707            DECODE_PRINTF(",");
708            srcreg = DECODE_RM_LONG_REGISTER(rh);
709            DECODE_PRINTF("\n");
710            TRACE_AND_STEP();
711            *destreg = or_long(*destreg, *srcreg);
712        }
713        else {
714            u16 *destreg, *srcreg;
715
716            destreg = DECODE_RM_WORD_REGISTER(rl);
717            DECODE_PRINTF(",");
718            srcreg = DECODE_RM_WORD_REGISTER(rh);
719            DECODE_PRINTF("\n");
720            TRACE_AND_STEP();
721            *destreg = or_word(*destreg, *srcreg);
722        }
723        break;
724    }
725    DECODE_CLEAR_SEGOVR();
726    END_OF_INSTR();
727}
728
729/****************************************************************************
730REMARKS:
731Handles opcode 0x0a
732****************************************************************************/
733static void
734x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
735{
736    int mod, rl, rh;
737    u8 *destreg, *srcreg;
738    uint srcoffset;
739    u8 srcval;
740
741    START_OF_INSTR();
742    DECODE_PRINTF("OR\t");
743    FETCH_DECODE_MODRM(mod, rh, rl);
744    switch (mod) {
745    case 0:
746        destreg = DECODE_RM_BYTE_REGISTER(rh);
747        DECODE_PRINTF(",");
748        srcoffset = decode_rm00_address(rl);
749        srcval = fetch_data_byte(srcoffset);
750        DECODE_PRINTF("\n");
751        TRACE_AND_STEP();
752        *destreg = or_byte(*destreg, srcval);
753        break;
754    case 1:
755        destreg = DECODE_RM_BYTE_REGISTER(rh);
756        DECODE_PRINTF(",");
757        srcoffset = decode_rm01_address(rl);
758        srcval = fetch_data_byte(srcoffset);
759        DECODE_PRINTF("\n");
760        TRACE_AND_STEP();
761        *destreg = or_byte(*destreg, srcval);
762        break;
763    case 2:
764        destreg = DECODE_RM_BYTE_REGISTER(rh);
765        DECODE_PRINTF(",");
766        srcoffset = decode_rm10_address(rl);
767        srcval = fetch_data_byte(srcoffset);
768        DECODE_PRINTF("\n");
769        TRACE_AND_STEP();
770        *destreg = or_byte(*destreg, srcval);
771        break;
772    case 3:                    /* register to register */
773        destreg = DECODE_RM_BYTE_REGISTER(rh);
774        DECODE_PRINTF(",");
775        srcreg = DECODE_RM_BYTE_REGISTER(rl);
776        DECODE_PRINTF("\n");
777        TRACE_AND_STEP();
778        *destreg = or_byte(*destreg, *srcreg);
779        break;
780    }
781    DECODE_CLEAR_SEGOVR();
782    END_OF_INSTR();
783}
784
785/****************************************************************************
786REMARKS:
787Handles opcode 0x0b
788****************************************************************************/
789static void
790x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
791{
792    int mod, rl, rh;
793    uint srcoffset;
794
795    START_OF_INSTR();
796    DECODE_PRINTF("OR\t");
797    FETCH_DECODE_MODRM(mod, rh, rl);
798    switch (mod) {
799    case 0:
800        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801            u32 *destreg;
802            u32 srcval;
803
804            destreg = DECODE_RM_LONG_REGISTER(rh);
805            DECODE_PRINTF(",");
806            srcoffset = decode_rm00_address(rl);
807            srcval = fetch_data_long(srcoffset);
808            DECODE_PRINTF("\n");
809            TRACE_AND_STEP();
810            *destreg = or_long(*destreg, srcval);
811        }
812        else {
813            u16 *destreg;
814            u16 srcval;
815
816            destreg = DECODE_RM_WORD_REGISTER(rh);
817            DECODE_PRINTF(",");
818            srcoffset = decode_rm00_address(rl);
819            srcval = fetch_data_word(srcoffset);
820            DECODE_PRINTF("\n");
821            TRACE_AND_STEP();
822            *destreg = or_word(*destreg, srcval);
823        }
824        break;
825    case 1:
826        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827            u32 *destreg;
828            u32 srcval;
829
830            destreg = DECODE_RM_LONG_REGISTER(rh);
831            DECODE_PRINTF(",");
832            srcoffset = decode_rm01_address(rl);
833            srcval = fetch_data_long(srcoffset);
834            DECODE_PRINTF("\n");
835            TRACE_AND_STEP();
836            *destreg = or_long(*destreg, srcval);
837        }
838        else {
839            u16 *destreg;
840            u16 srcval;
841
842            destreg = DECODE_RM_WORD_REGISTER(rh);
843            DECODE_PRINTF(",");
844            srcoffset = decode_rm01_address(rl);
845            srcval = fetch_data_word(srcoffset);
846            DECODE_PRINTF("\n");
847            TRACE_AND_STEP();
848            *destreg = or_word(*destreg, srcval);
849        }
850        break;
851    case 2:
852        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853            u32 *destreg;
854            u32 srcval;
855
856            destreg = DECODE_RM_LONG_REGISTER(rh);
857            DECODE_PRINTF(",");
858            srcoffset = decode_rm10_address(rl);
859            srcval = fetch_data_long(srcoffset);
860            DECODE_PRINTF("\n");
861            TRACE_AND_STEP();
862            *destreg = or_long(*destreg, srcval);
863        }
864        else {
865            u16 *destreg;
866            u16 srcval;
867
868            destreg = DECODE_RM_WORD_REGISTER(rh);
869            DECODE_PRINTF(",");
870            srcoffset = decode_rm10_address(rl);
871            srcval = fetch_data_word(srcoffset);
872            DECODE_PRINTF("\n");
873            TRACE_AND_STEP();
874            *destreg = or_word(*destreg, srcval);
875        }
876        break;
877    case 3:                    /* register to register */
878        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879            u32 *destreg, *srcreg;
880
881            destreg = DECODE_RM_LONG_REGISTER(rh);
882            DECODE_PRINTF(",");
883            srcreg = DECODE_RM_LONG_REGISTER(rl);
884            DECODE_PRINTF("\n");
885            TRACE_AND_STEP();
886            *destreg = or_long(*destreg, *srcreg);
887        }
888        else {
889            u16 *destreg, *srcreg;
890
891            destreg = DECODE_RM_WORD_REGISTER(rh);
892            DECODE_PRINTF(",");
893            srcreg = DECODE_RM_WORD_REGISTER(rl);
894            DECODE_PRINTF("\n");
895            TRACE_AND_STEP();
896            *destreg = or_word(*destreg, *srcreg);
897        }
898        break;
899    }
900    DECODE_CLEAR_SEGOVR();
901    END_OF_INSTR();
902}
903
904/****************************************************************************
905REMARKS:
906Handles opcode 0x0c
907****************************************************************************/
908static void
909x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
910{
911    u8 srcval;
912
913    START_OF_INSTR();
914    DECODE_PRINTF("OR\tAL,");
915    srcval = fetch_byte_imm();
916    DECODE_PRINTF2("%x\n", srcval);
917    TRACE_AND_STEP();
918    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
919    DECODE_CLEAR_SEGOVR();
920    END_OF_INSTR();
921}
922
923/****************************************************************************
924REMARKS:
925Handles opcode 0x0d
926****************************************************************************/
927static void
928x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
929{
930    u32 srcval;
931
932    START_OF_INSTR();
933    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
934        DECODE_PRINTF("OR\tEAX,");
935        srcval = fetch_long_imm();
936    }
937    else {
938        DECODE_PRINTF("OR\tAX,");
939        srcval = fetch_word_imm();
940    }
941    DECODE_PRINTF2("%x\n", srcval);
942    TRACE_AND_STEP();
943    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
944        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
945    }
946    else {
947        M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
948    }
949    DECODE_CLEAR_SEGOVR();
950    END_OF_INSTR();
951}
952
953/****************************************************************************
954REMARKS:
955Handles opcode 0x0e
956****************************************************************************/
957static void
958x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
959{
960    START_OF_INSTR();
961    DECODE_PRINTF("PUSH\tCS\n");
962    TRACE_AND_STEP();
963    push_word(M.x86.R_CS);
964    DECODE_CLEAR_SEGOVR();
965    END_OF_INSTR();
966}
967
968/****************************************************************************
969REMARKS:
970Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971****************************************************************************/
972static void
973x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
974{
975    u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
976
977    INC_DECODED_INST_LEN(1);
978    (*x86emu_optab2[op2]) (op2);
979}
980
981/****************************************************************************
982REMARKS:
983Handles opcode 0x10
984****************************************************************************/
985static void
986x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
987{
988    int mod, rl, rh;
989    u8 *destreg, *srcreg;
990    uint destoffset;
991    u8 destval;
992
993    START_OF_INSTR();
994    DECODE_PRINTF("ADC\t");
995    FETCH_DECODE_MODRM(mod, rh, rl);
996    switch (mod) {
997    case 0:
998        destoffset = decode_rm00_address(rl);
999        DECODE_PRINTF(",");
1000        destval = fetch_data_byte(destoffset);
1001        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002        DECODE_PRINTF("\n");
1003        TRACE_AND_STEP();
1004        destval = adc_byte(destval, *srcreg);
1005        store_data_byte(destoffset, destval);
1006        break;
1007    case 1:
1008        destoffset = decode_rm01_address(rl);
1009        DECODE_PRINTF(",");
1010        destval = fetch_data_byte(destoffset);
1011        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1012        DECODE_PRINTF("\n");
1013        TRACE_AND_STEP();
1014        destval = adc_byte(destval, *srcreg);
1015        store_data_byte(destoffset, destval);
1016        break;
1017    case 2:
1018        destoffset = decode_rm10_address(rl);
1019        DECODE_PRINTF(",");
1020        destval = fetch_data_byte(destoffset);
1021        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1022        DECODE_PRINTF("\n");
1023        TRACE_AND_STEP();
1024        destval = adc_byte(destval, *srcreg);
1025        store_data_byte(destoffset, destval);
1026        break;
1027    case 3:                    /* register to register */
1028        destreg = DECODE_RM_BYTE_REGISTER(rl);
1029        DECODE_PRINTF(",");
1030        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1031        DECODE_PRINTF("\n");
1032        TRACE_AND_STEP();
1033        *destreg = adc_byte(*destreg, *srcreg);
1034        break;
1035    }
1036    DECODE_CLEAR_SEGOVR();
1037    END_OF_INSTR();
1038}
1039
1040/****************************************************************************
1041REMARKS:
1042Handles opcode 0x11
1043****************************************************************************/
1044static void
1045x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1046{
1047    int mod, rl, rh;
1048    uint destoffset;
1049
1050    START_OF_INSTR();
1051    DECODE_PRINTF("ADC\t");
1052    FETCH_DECODE_MODRM(mod, rh, rl);
1053    switch (mod) {
1054    case 0:
1055        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1056            u32 destval;
1057            u32 *srcreg;
1058
1059            destoffset = decode_rm00_address(rl);
1060            DECODE_PRINTF(",");
1061            destval = fetch_data_long(destoffset);
1062            srcreg = DECODE_RM_LONG_REGISTER(rh);
1063            DECODE_PRINTF("\n");
1064            TRACE_AND_STEP();
1065            destval = adc_long(destval, *srcreg);
1066            store_data_long(destoffset, destval);
1067        }
1068        else {
1069            u16 destval;
1070            u16 *srcreg;
1071
1072            destoffset = decode_rm00_address(rl);
1073            DECODE_PRINTF(",");
1074            destval = fetch_data_word(destoffset);
1075            srcreg = DECODE_RM_WORD_REGISTER(rh);
1076            DECODE_PRINTF("\n");
1077            TRACE_AND_STEP();
1078            destval = adc_word(destval, *srcreg);
1079            store_data_word(destoffset, destval);
1080        }
1081        break;
1082    case 1:
1083        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1084            u32 destval;
1085            u32 *srcreg;
1086
1087            destoffset = decode_rm01_address(rl);
1088            DECODE_PRINTF(",");
1089            destval = fetch_data_long(destoffset);
1090            srcreg = DECODE_RM_LONG_REGISTER(rh);
1091            DECODE_PRINTF("\n");
1092            TRACE_AND_STEP();
1093            destval = adc_long(destval, *srcreg);
1094            store_data_long(destoffset, destval);
1095        }
1096        else {
1097            u16 destval;
1098            u16 *srcreg;
1099
1100            destoffset = decode_rm01_address(rl);
1101            DECODE_PRINTF(",");
1102            destval = fetch_data_word(destoffset);
1103            srcreg = DECODE_RM_WORD_REGISTER(rh);
1104            DECODE_PRINTF("\n");
1105            TRACE_AND_STEP();
1106            destval = adc_word(destval, *srcreg);
1107            store_data_word(destoffset, destval);
1108        }
1109        break;
1110    case 2:
1111        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112            u32 destval;
1113            u32 *srcreg;
1114
1115            destoffset = decode_rm10_address(rl);
1116            DECODE_PRINTF(",");
1117            destval = fetch_data_long(destoffset);
1118            srcreg = DECODE_RM_LONG_REGISTER(rh);
1119            DECODE_PRINTF("\n");
1120            TRACE_AND_STEP();
1121            destval = adc_long(destval, *srcreg);
1122            store_data_long(destoffset, destval);
1123        }
1124        else {
1125            u16 destval;
1126            u16 *srcreg;
1127
1128            destoffset = decode_rm10_address(rl);
1129            DECODE_PRINTF(",");
1130            destval = fetch_data_word(destoffset);
1131            srcreg = DECODE_RM_WORD_REGISTER(rh);
1132            DECODE_PRINTF("\n");
1133            TRACE_AND_STEP();
1134            destval = adc_word(destval, *srcreg);
1135            store_data_word(destoffset, destval);
1136        }
1137        break;
1138    case 3:                    /* register to register */
1139        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1140            u32 *destreg, *srcreg;
1141
1142            destreg = DECODE_RM_LONG_REGISTER(rl);
1143            DECODE_PRINTF(",");
1144            srcreg = DECODE_RM_LONG_REGISTER(rh);
1145            DECODE_PRINTF("\n");
1146            TRACE_AND_STEP();
1147            *destreg = adc_long(*destreg, *srcreg);
1148        }
1149        else {
1150            u16 *destreg, *srcreg;
1151
1152            destreg = DECODE_RM_WORD_REGISTER(rl);
1153            DECODE_PRINTF(",");
1154            srcreg = DECODE_RM_WORD_REGISTER(rh);
1155            DECODE_PRINTF("\n");
1156            TRACE_AND_STEP();
1157            *destreg = adc_word(*destreg, *srcreg);
1158        }
1159        break;
1160    }
1161    DECODE_CLEAR_SEGOVR();
1162    END_OF_INSTR();
1163}
1164
1165/****************************************************************************
1166REMARKS:
1167Handles opcode 0x12
1168****************************************************************************/
1169static void
1170x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1171{
1172    int mod, rl, rh;
1173    u8 *destreg, *srcreg;
1174    uint srcoffset;
1175    u8 srcval;
1176
1177    START_OF_INSTR();
1178    DECODE_PRINTF("ADC\t");
1179    FETCH_DECODE_MODRM(mod, rh, rl);
1180    switch (mod) {
1181    case 0:
1182        destreg = DECODE_RM_BYTE_REGISTER(rh);
1183        DECODE_PRINTF(",");
1184        srcoffset = decode_rm00_address(rl);
1185        srcval = fetch_data_byte(srcoffset);
1186        DECODE_PRINTF("\n");
1187        TRACE_AND_STEP();
1188        *destreg = adc_byte(*destreg, srcval);
1189        break;
1190    case 1:
1191        destreg = DECODE_RM_BYTE_REGISTER(rh);
1192        DECODE_PRINTF(",");
1193        srcoffset = decode_rm01_address(rl);
1194        srcval = fetch_data_byte(srcoffset);
1195        DECODE_PRINTF("\n");
1196        TRACE_AND_STEP();
1197        *destreg = adc_byte(*destreg, srcval);
1198        break;
1199    case 2:
1200        destreg = DECODE_RM_BYTE_REGISTER(rh);
1201        DECODE_PRINTF(",");
1202        srcoffset = decode_rm10_address(rl);
1203        srcval = fetch_data_byte(srcoffset);
1204        DECODE_PRINTF("\n");
1205        TRACE_AND_STEP();
1206        *destreg = adc_byte(*destreg, srcval);
1207        break;
1208    case 3:                    /* register to register */
1209        destreg = DECODE_RM_BYTE_REGISTER(rh);
1210        DECODE_PRINTF(",");
1211        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1212        DECODE_PRINTF("\n");
1213        TRACE_AND_STEP();
1214        *destreg = adc_byte(*destreg, *srcreg);
1215        break;
1216    }
1217    DECODE_CLEAR_SEGOVR();
1218    END_OF_INSTR();
1219}
1220
1221/****************************************************************************
1222REMARKS:
1223Handles opcode 0x13
1224****************************************************************************/
1225static void
1226x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1227{
1228    int mod, rl, rh;
1229    uint srcoffset;
1230
1231    START_OF_INSTR();
1232    DECODE_PRINTF("ADC\t");
1233    FETCH_DECODE_MODRM(mod, rh, rl);
1234    switch (mod) {
1235    case 0:
1236        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1237            u32 *destreg;
1238            u32 srcval;
1239
1240            destreg = DECODE_RM_LONG_REGISTER(rh);
1241            DECODE_PRINTF(",");
1242            srcoffset = decode_rm00_address(rl);
1243            srcval = fetch_data_long(srcoffset);
1244            DECODE_PRINTF("\n");
1245            TRACE_AND_STEP();
1246            *destreg = adc_long(*destreg, srcval);
1247        }
1248        else {
1249            u16 *destreg;
1250            u16 srcval;
1251
1252            destreg = DECODE_RM_WORD_REGISTER(rh);
1253            DECODE_PRINTF(",");
1254            srcoffset = decode_rm00_address(rl);
1255            srcval = fetch_data_word(srcoffset);
1256            DECODE_PRINTF("\n");
1257            TRACE_AND_STEP();
1258            *destreg = adc_word(*destreg, srcval);
1259        }
1260        break;
1261    case 1:
1262        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1263            u32 *destreg;
1264            u32 srcval;
1265
1266            destreg = DECODE_RM_LONG_REGISTER(rh);
1267            DECODE_PRINTF(",");
1268            srcoffset = decode_rm01_address(rl);
1269            srcval = fetch_data_long(srcoffset);
1270            DECODE_PRINTF("\n");
1271            TRACE_AND_STEP();
1272            *destreg = adc_long(*destreg, srcval);
1273        }
1274        else {
1275            u16 *destreg;
1276            u16 srcval;
1277
1278            destreg = DECODE_RM_WORD_REGISTER(rh);
1279            DECODE_PRINTF(",");
1280            srcoffset = decode_rm01_address(rl);
1281            srcval = fetch_data_word(srcoffset);
1282            DECODE_PRINTF("\n");
1283            TRACE_AND_STEP();
1284            *destreg = adc_word(*destreg, srcval);
1285        }
1286        break;
1287    case 2:
1288        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289            u32 *destreg;
1290            u32 srcval;
1291
1292            destreg = DECODE_RM_LONG_REGISTER(rh);
1293            DECODE_PRINTF(",");
1294            srcoffset = decode_rm10_address(rl);
1295            srcval = fetch_data_long(srcoffset);
1296            DECODE_PRINTF("\n");
1297            TRACE_AND_STEP();
1298            *destreg = adc_long(*destreg, srcval);
1299        }
1300        else {
1301            u16 *destreg;
1302            u16 srcval;
1303
1304            destreg = DECODE_RM_WORD_REGISTER(rh);
1305            DECODE_PRINTF(",");
1306            srcoffset = decode_rm10_address(rl);
1307            srcval = fetch_data_word(srcoffset);
1308            DECODE_PRINTF("\n");
1309            TRACE_AND_STEP();
1310            *destreg = adc_word(*destreg, srcval);
1311        }
1312        break;
1313    case 3:                    /* register to register */
1314        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1315            u32 *destreg, *srcreg;
1316
1317            destreg = DECODE_RM_LONG_REGISTER(rh);
1318            DECODE_PRINTF(",");
1319            srcreg = DECODE_RM_LONG_REGISTER(rl);
1320            DECODE_PRINTF("\n");
1321            TRACE_AND_STEP();
1322            *destreg = adc_long(*destreg, *srcreg);
1323        }
1324        else {
1325            u16 *destreg, *srcreg;
1326
1327            destreg = DECODE_RM_WORD_REGISTER(rh);
1328            DECODE_PRINTF(",");
1329            srcreg = DECODE_RM_WORD_REGISTER(rl);
1330            DECODE_PRINTF("\n");
1331            TRACE_AND_STEP();
1332            *destreg = adc_word(*destreg, *srcreg);
1333        }
1334        break;
1335    }
1336    DECODE_CLEAR_SEGOVR();
1337    END_OF_INSTR();
1338}
1339
1340/****************************************************************************
1341REMARKS:
1342Handles opcode 0x14
1343****************************************************************************/
1344static void
1345x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1346{
1347    u8 srcval;
1348
1349    START_OF_INSTR();
1350    DECODE_PRINTF("ADC\tAL,");
1351    srcval = fetch_byte_imm();
1352    DECODE_PRINTF2("%x\n", srcval);
1353    TRACE_AND_STEP();
1354    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1355    DECODE_CLEAR_SEGOVR();
1356    END_OF_INSTR();
1357}
1358
1359/****************************************************************************
1360REMARKS:
1361Handles opcode 0x15
1362****************************************************************************/
1363static void
1364x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1365{
1366    u32 srcval;
1367
1368    START_OF_INSTR();
1369    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370        DECODE_PRINTF("ADC\tEAX,");
1371        srcval = fetch_long_imm();
1372    }
1373    else {
1374        DECODE_PRINTF("ADC\tAX,");
1375        srcval = fetch_word_imm();
1376    }
1377    DECODE_PRINTF2("%x\n", srcval);
1378    TRACE_AND_STEP();
1379    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1380        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1381    }
1382    else {
1383        M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1384    }
1385    DECODE_CLEAR_SEGOVR();
1386    END_OF_INSTR();
1387}
1388
1389/****************************************************************************
1390REMARKS:
1391Handles opcode 0x16
1392****************************************************************************/
1393static void
1394x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1395{
1396    START_OF_INSTR();
1397    DECODE_PRINTF("PUSH\tSS\n");
1398    TRACE_AND_STEP();
1399    push_word(M.x86.R_SS);
1400    DECODE_CLEAR_SEGOVR();
1401    END_OF_INSTR();
1402}
1403
1404/****************************************************************************
1405REMARKS:
1406Handles opcode 0x17
1407****************************************************************************/
1408static void
1409x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1410{
1411    START_OF_INSTR();
1412    DECODE_PRINTF("POP\tSS\n");
1413    TRACE_AND_STEP();
1414    M.x86.R_SS = pop_word();
1415    DECODE_CLEAR_SEGOVR();
1416    END_OF_INSTR();
1417}
1418
1419/****************************************************************************
1420REMARKS:
1421Handles opcode 0x18
1422****************************************************************************/
1423static void
1424x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1425{
1426    int mod, rl, rh;
1427    u8 *destreg, *srcreg;
1428    uint destoffset;
1429    u8 destval;
1430
1431    START_OF_INSTR();
1432    DECODE_PRINTF("SBB\t");
1433    FETCH_DECODE_MODRM(mod, rh, rl);
1434    switch (mod) {
1435    case 0:
1436        destoffset = decode_rm00_address(rl);
1437        DECODE_PRINTF(",");
1438        destval = fetch_data_byte(destoffset);
1439        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1440        DECODE_PRINTF("\n");
1441        TRACE_AND_STEP();
1442        destval = sbb_byte(destval, *srcreg);
1443        store_data_byte(destoffset, destval);
1444        break;
1445    case 1:
1446        destoffset = decode_rm01_address(rl);
1447        DECODE_PRINTF(",");
1448        destval = fetch_data_byte(destoffset);
1449        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1450        DECODE_PRINTF("\n");
1451        TRACE_AND_STEP();
1452        destval = sbb_byte(destval, *srcreg);
1453        store_data_byte(destoffset, destval);
1454        break;
1455    case 2:
1456        destoffset = decode_rm10_address(rl);
1457        DECODE_PRINTF(",");
1458        destval = fetch_data_byte(destoffset);
1459        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1460        DECODE_PRINTF("\n");
1461        TRACE_AND_STEP();
1462        destval = sbb_byte(destval, *srcreg);
1463        store_data_byte(destoffset, destval);
1464        break;
1465    case 3:                    /* register to register */
1466        destreg = DECODE_RM_BYTE_REGISTER(rl);
1467        DECODE_PRINTF(",");
1468        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1469        DECODE_PRINTF("\n");
1470        TRACE_AND_STEP();
1471        *destreg = sbb_byte(*destreg, *srcreg);
1472        break;
1473    }
1474    DECODE_CLEAR_SEGOVR();
1475    END_OF_INSTR();
1476}
1477
1478/****************************************************************************
1479REMARKS:
1480Handles opcode 0x19
1481****************************************************************************/
1482static void
1483x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1484{
1485    int mod, rl, rh;
1486    uint destoffset;
1487
1488    START_OF_INSTR();
1489    DECODE_PRINTF("SBB\t");
1490    FETCH_DECODE_MODRM(mod, rh, rl);
1491    switch (mod) {
1492    case 0:
1493        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1494            u32 destval;
1495            u32 *srcreg;
1496
1497            destoffset = decode_rm00_address(rl);
1498            DECODE_PRINTF(",");
1499            destval = fetch_data_long(destoffset);
1500            srcreg = DECODE_RM_LONG_REGISTER(rh);
1501            DECODE_PRINTF("\n");
1502            TRACE_AND_STEP();
1503            destval = sbb_long(destval, *srcreg);
1504            store_data_long(destoffset, destval);
1505        }
1506        else {
1507            u16 destval;
1508            u16 *srcreg;
1509
1510            destoffset = decode_rm00_address(rl);
1511            DECODE_PRINTF(",");
1512            destval = fetch_data_word(destoffset);
1513            srcreg = DECODE_RM_WORD_REGISTER(rh);
1514            DECODE_PRINTF("\n");
1515            TRACE_AND_STEP();
1516            destval = sbb_word(destval, *srcreg);
1517            store_data_word(destoffset, destval);
1518        }
1519        break;
1520    case 1:
1521        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1522            u32 destval;
1523            u32 *srcreg;
1524
1525            destoffset = decode_rm01_address(rl);
1526            DECODE_PRINTF(",");
1527            destval = fetch_data_long(destoffset);
1528            srcreg = DECODE_RM_LONG_REGISTER(rh);
1529            DECODE_PRINTF("\n");
1530            TRACE_AND_STEP();
1531            destval = sbb_long(destval, *srcreg);
1532            store_data_long(destoffset, destval);
1533        }
1534        else {
1535            u16 destval;
1536            u16 *srcreg;
1537
1538            destoffset = decode_rm01_address(rl);
1539            DECODE_PRINTF(",");
1540            destval = fetch_data_word(destoffset);
1541            srcreg = DECODE_RM_WORD_REGISTER(rh);
1542            DECODE_PRINTF("\n");
1543            TRACE_AND_STEP();
1544            destval = sbb_word(destval, *srcreg);
1545            store_data_word(destoffset, destval);
1546        }
1547        break;
1548    case 2:
1549        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1550            u32 destval;
1551            u32 *srcreg;
1552
1553            destoffset = decode_rm10_address(rl);
1554            DECODE_PRINTF(",");
1555            destval = fetch_data_long(destoffset);
1556            srcreg = DECODE_RM_LONG_REGISTER(rh);
1557            DECODE_PRINTF("\n");
1558            TRACE_AND_STEP();
1559            destval = sbb_long(destval, *srcreg);
1560            store_data_long(destoffset, destval);
1561        }
1562        else {
1563            u16 destval;
1564            u16 *srcreg;
1565
1566            destoffset = decode_rm10_address(rl);
1567            DECODE_PRINTF(",");
1568            destval = fetch_data_word(destoffset);
1569            srcreg = DECODE_RM_WORD_REGISTER(rh);
1570            DECODE_PRINTF("\n");
1571            TRACE_AND_STEP();
1572            destval = sbb_word(destval, *srcreg);
1573            store_data_word(destoffset, destval);
1574        }
1575        break;
1576    case 3:                    /* register to register */
1577        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1578            u32 *destreg, *srcreg;
1579
1580            destreg = DECODE_RM_LONG_REGISTER(rl);
1581            DECODE_PRINTF(",");
1582            srcreg = DECODE_RM_LONG_REGISTER(rh);
1583            DECODE_PRINTF("\n");
1584            TRACE_AND_STEP();
1585            *destreg = sbb_long(*destreg, *srcreg);
1586        }
1587        else {
1588            u16 *destreg, *srcreg;
1589
1590            destreg = DECODE_RM_WORD_REGISTER(rl);
1591            DECODE_PRINTF(",");
1592            srcreg = DECODE_RM_WORD_REGISTER(rh);
1593            DECODE_PRINTF("\n");
1594            TRACE_AND_STEP();
1595            *destreg = sbb_word(*destreg, *srcreg);
1596        }
1597        break;
1598    }
1599    DECODE_CLEAR_SEGOVR();
1600    END_OF_INSTR();
1601}
1602
1603/****************************************************************************
1604REMARKS:
1605Handles opcode 0x1a
1606****************************************************************************/
1607static void
1608x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1609{
1610    int mod, rl, rh;
1611    u8 *destreg, *srcreg;
1612    uint srcoffset;
1613    u8 srcval;
1614
1615    START_OF_INSTR();
1616    DECODE_PRINTF("SBB\t");
1617    FETCH_DECODE_MODRM(mod, rh, rl);
1618    switch (mod) {
1619    case 0:
1620        destreg = DECODE_RM_BYTE_REGISTER(rh);
1621        DECODE_PRINTF(",");
1622        srcoffset = decode_rm00_address(rl);
1623        srcval = fetch_data_byte(srcoffset);
1624        DECODE_PRINTF("\n");
1625        TRACE_AND_STEP();
1626        *destreg = sbb_byte(*destreg, srcval);
1627        break;
1628    case 1:
1629        destreg = DECODE_RM_BYTE_REGISTER(rh);
1630        DECODE_PRINTF(",");
1631        srcoffset = decode_rm01_address(rl);
1632        srcval = fetch_data_byte(srcoffset);
1633        DECODE_PRINTF("\n");
1634        TRACE_AND_STEP();
1635        *destreg = sbb_byte(*destreg, srcval);
1636        break;
1637    case 2:
1638        destreg = DECODE_RM_BYTE_REGISTER(rh);
1639        DECODE_PRINTF(",");
1640        srcoffset = decode_rm10_address(rl);
1641        srcval = fetch_data_byte(srcoffset);
1642        DECODE_PRINTF("\n");
1643        TRACE_AND_STEP();
1644        *destreg = sbb_byte(*destreg, srcval);
1645        break;
1646    case 3:                    /* register to register */
1647        destreg = DECODE_RM_BYTE_REGISTER(rh);
1648        DECODE_PRINTF(",");
1649        srcreg = DECODE_RM_BYTE_REGISTER(rl);
1650        DECODE_PRINTF("\n");
1651        TRACE_AND_STEP();
1652        *destreg = sbb_byte(*destreg, *srcreg);
1653        break;
1654    }
1655    DECODE_CLEAR_SEGOVR();
1656    END_OF_INSTR();
1657}
1658
1659/****************************************************************************
1660REMARKS:
1661Handles opcode 0x1b
1662****************************************************************************/
1663static void
1664x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1665{
1666    int mod, rl, rh;
1667    uint srcoffset;
1668
1669    START_OF_INSTR();
1670    DECODE_PRINTF("SBB\t");
1671    FETCH_DECODE_MODRM(mod, rh, rl);
1672    switch (mod) {
1673    case 0:
1674        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1675            u32 *destreg;
1676            u32 srcval;
1677
1678            destreg = DECODE_RM_LONG_REGISTER(rh);
1679            DECODE_PRINTF(",");
1680            srcoffset = decode_rm00_address(rl);
1681            srcval = fetch_data_long(srcoffset);
1682            DECODE_PRINTF("\n");
1683            TRACE_AND_STEP();
1684            *destreg = sbb_long(*destreg, srcval);
1685        }
1686        else {
1687            u16 *destreg;
1688            u16 srcval;
1689
1690            destreg = DECODE_RM_WORD_REGISTER(rh);
1691            DECODE_PRINTF(",");
1692            srcoffset = decode_rm00_address(rl);
1693            srcval = fetch_data_word(srcoffset);
1694            DECODE_PRINTF("\n");
1695            TRACE_AND_STEP();
1696            *destreg = sbb_word(*destreg, srcval);
1697        }
1698        break;
1699    case 1:
1700        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1701            u32 *destreg;
1702            u32 srcval;
1703
1704            destreg = DECODE_RM_LONG_REGISTER(rh);
1705            DECODE_PRINTF(",");
1706            srcoffset = decode_rm01_address(rl);
1707            srcval = fetch_data_long(srcoffset);
1708            DECODE_PRINTF("\n");
1709            TRACE_AND_STEP();
1710            *destreg = sbb_long(*destreg, srcval);
1711        }
1712        else {
1713            u16 *destreg;
1714            u16 srcval;
1715
1716            destreg = DECODE_RM_WORD_REGISTER(rh);
1717            DECODE_PRINTF(",");
1718            srcoffset = decode_rm01_address(rl);
1719            srcval = fetch_data_word(srcoffset);
1720            DECODE_PRINTF("\n");
1721            TRACE_AND_STEP();
1722            *destreg = sbb_word(*destreg, srcval);
1723        }
1724        break;
1725    case 2:
1726        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1727            u32 *destreg;
1728            u32 srcval;
1729
1730            destreg = DECODE_RM_LONG_REGISTER(rh);
1731            DECODE_PRINTF(",");
1732            srcoffset = decode_rm10_address(rl);
1733            srcval = fetch_data_long(srcoffset);
1734            DECODE_PRINTF("\n");
1735            TRACE_AND_STEP();
1736            *destreg = sbb_long(*destreg, srcval);
1737        }
1738        else {
1739            u16 *destreg;
1740            u16 srcval;
1741
1742            destreg = DECODE_RM_WORD_REGISTER(rh);
1743            DECODE_PRINTF(",");
1744            srcoffset = decode_rm10_address(rl);
1745            srcval = fetch_data_word(srcoffset);
1746            DECODE_PRINTF("\n");
1747            TRACE_AND_STEP();
1748            *destreg = sbb_word(*destreg, srcval);
1749        }
1750        break;
1751    case 3:                    /* register to register */
1752        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753            u32 *destreg, *srcreg;
1754
1755            destreg = DECODE_RM_LONG_REGISTER(rh);
1756            DECODE_PRINTF(",");
1757            srcreg = DECODE_RM_LONG_REGISTER(rl);
1758            DECODE_PRINTF("\n");
1759            TRACE_AND_STEP();
1760            *destreg = sbb_long(*destreg, *srcreg);
1761        }
1762        else {
1763            u16 *destreg, *srcreg;
1764
1765            destreg = DECODE_RM_WORD_REGISTER(rh);
1766            DECODE_PRINTF(",");
1767            srcreg = DECODE_RM_WORD_REGISTER(rl);
1768            DECODE_PRINTF("\n");
1769            TRACE_AND_STEP();
1770            *destreg = sbb_word(*destreg, *srcreg);
1771        }
1772        break;
1773    }
1774    DECODE_CLEAR_SEGOVR();
1775    END_OF_INSTR();
1776}
1777
1778/****************************************************************************
1779REMARKS:
1780Handles opcode 0x1c
1781****************************************************************************/
1782static void
1783x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1784{
1785    u8 srcval;
1786
1787    START_OF_INSTR();
1788    DECODE_PRINTF("SBB\tAL,");
1789    srcval = fetch_byte_imm();
1790    DECODE_PRINTF2("%x\n", srcval);
1791    TRACE_AND_STEP();
1792    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1793    DECODE_CLEAR_SEGOVR();
1794    END_OF_INSTR();
1795}
1796
1797/****************************************************************************
1798REMARKS:
1799Handles opcode 0x1d
1800****************************************************************************/
1801static void
1802x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1803{
1804    u32 srcval;
1805
1806    START_OF_INSTR();
1807    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1808        DECODE_PRINTF("SBB\tEAX,");
1809        srcval = fetch_long_imm();
1810    }
1811    else {
1812        DECODE_PRINTF("SBB\tAX,");
1813        srcval = fetch_word_imm();
1814    }
1815    DECODE_PRINTF2("%x\n", srcval);
1816    TRACE_AND_STEP();
1817    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1818        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1819    }
1820    else {
1821        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1822    }
1823    DECODE_CLEAR_SEGOVR();
1824    END_OF_INSTR();
1825}
1826
1827/****************************************************************************
1828REMARKS:
1829Handles opcode 0x1e
1830****************************************************************************/
1831static void
1832x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1833{
1834    START_OF_INSTR();
1835    DECODE_PRINTF("PUSH\tDS\n");
1836    TRACE_AND_STEP();
1837    push_word(M.x86.R_DS);
1838    DECODE_CLEAR_SEGOVR();
1839    END_OF_INSTR();
1840}
1841
1842/****************************************************************************
1843REMARKS:
1844Handles opcode 0x1f
1845****************************************************************************/
1846static void
1847x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1848{
1849    START_OF_INSTR();
1850    DECODE_PRINTF("POP\tDS\n");
1851    TRACE_AND_STEP();
1852    M.x86.R_DS = pop_word();
1853    DECODE_CLEAR_SEGOVR();
1854    END_OF_INSTR();
1855}
1856
1857/****************************************************************************
1858REMARKS:
1859Handles opcode 0x20
1860****************************************************************************/
1861static void
1862x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1863{
1864    int mod, rl, rh;
1865    u8 *destreg, *srcreg;
1866    uint destoffset;
1867    u8 destval;
1868
1869    START_OF_INSTR();
1870    DECODE_PRINTF("AND\t");
1871    FETCH_DECODE_MODRM(mod, rh, rl);
1872
1873    switch (mod) {
1874    case 0:
1875        destoffset = decode_rm00_address(rl);
1876        DECODE_PRINTF(",");
1877        destval = fetch_data_byte(destoffset);
1878        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879        DECODE_PRINTF("\n");
1880        TRACE_AND_STEP();
1881        destval = and_byte(destval, *srcreg);
1882        store_data_byte(destoffset, destval);
1883        break;
1884
1885    case 1:
1886        destoffset = decode_rm01_address(rl);
1887        DECODE_PRINTF(",");
1888        destval = fetch_data_byte(destoffset);
1889        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1890        DECODE_PRINTF("\n");
1891        TRACE_AND_STEP();
1892        destval = and_byte(destval, *srcreg);
1893        store_data_byte(destoffset, destval);
1894        break;
1895
1896    case 2:
1897        destoffset = decode_rm10_address(rl);
1898        DECODE_PRINTF(",");
1899        destval = fetch_data_byte(destoffset);
1900        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1901        DECODE_PRINTF("\n");
1902        TRACE_AND_STEP();
1903        destval = and_byte(destval, *srcreg);
1904        store_data_byte(destoffset, destval);
1905        break;
1906
1907    case 3:                    /* register to register */
1908        destreg = DECODE_RM_BYTE_REGISTER(rl);
1909        DECODE_PRINTF(",");
1910        srcreg = DECODE_RM_BYTE_REGISTER(rh);
1911        DECODE_PRINTF("\n");
1912        TRACE_AND_STEP();
1913        *destreg = and_byte(*destreg, *srcreg);
1914        break;
1915    }
1916    DECODE_CLEAR_SEGOVR();
1917    END_OF_INSTR();
1918}
1919
1920/****************************************************************************
1921REMARKS:
1922Handles opcode 0x21
1923****************************************************************************/
1924static void
1925x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1926{
1927    int mod, rl, rh;
1928    uint destoffset;
1929
1930    START_OF_INSTR();
1931    DECODE_PRINTF("AND\t");
1932    FETCH_DECODE_MODRM(mod, rh, rl);
1933    switch (mod) {
1934    case 0:
1935        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1936            u32 destval;
1937            u32 *srcreg;
1938
1939            destoffset = decode_rm00_address(rl);
1940            DECODE_PRINTF(",");
1941            destval = fetch_data_long(destoffset);
1942            srcreg = DECODE_RM_LONG_REGISTER(rh);
1943            DECODE_PRINTF("\n");
1944            TRACE_AND_STEP();
1945            destval = and_long(destval, *srcreg);
1946            store_data_long(destoffset, destval);
1947        }
1948        else {
1949            u16 destval;
1950            u16 *srcreg;
1951
1952            destoffset = decode_rm00_address(rl);
1953            DECODE_PRINTF(",");
1954            destval = fetch_data_word(destoffset);
1955            srcreg = DECODE_RM_WORD_REGISTER(rh);
1956            DECODE_PRINTF("\n");
1957            TRACE_AND_STEP();
1958            destval = and_word(destval, *srcreg);
1959            store_data_word(destoffset, destval);
1960        }
1961        break;
1962    case 1:
1963        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1964            u32 destval;
1965            u32 *srcreg;
1966
1967            destoffset = decode_rm01_address(rl);
1968            DECODE_PRINTF(",");
1969            destval = fetch_data_long(destoffset);
1970            srcreg = DECODE_RM_LONG_REGISTER(rh);
1971            DECODE_PRINTF("\n");
1972            TRACE_AND_STEP();
1973            destval = and_long(destval, *srcreg);
1974            store_data_long(destoffset, destval);
1975        }
1976        else {
1977            u16 destval;
1978            u16 *srcreg;
1979
1980            destoffset = decode_rm01_address(rl);
1981            DECODE_PRINTF(",");
1982            destval = fetch_data_word(destoffset);
1983            srcreg = DECODE_RM_WORD_REGISTER(rh);
1984            DECODE_PRINTF("\n");
1985            TRACE_AND_STEP();
1986            destval = and_word(destval, *srcreg);
1987            store_data_word(destoffset, destval);
1988        }
1989        break;
1990    case 2:
1991        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1992            u32 destval;
1993            u32 *srcreg;
1994
1995            destoffset = decode_rm10_address(rl);
1996            DECODE_PRINTF(",");
1997            destval = fetch_data_long(destoffset);
1998            srcreg = DECODE_RM_LONG_REGISTER(rh);
1999            DECODE_PRINTF("\n");
2000            TRACE_AND_STEP();
2001            destval = and_long(destval, *srcreg);
2002            store_data_long(destoffset, destval);
2003        }
2004        else {
2005            u16 destval;
2006            u16 *srcreg;
2007
2008            destoffset = decode_rm10_address(rl);
2009            DECODE_PRINTF(",");
2010            destval = fetch_data_word(destoffset);
2011            srcreg = DECODE_RM_WORD_REGISTER(rh);
2012            DECODE_PRINTF("\n");
2013            TRACE_AND_STEP();
2014            destval = and_word(destval, *srcreg);
2015            store_data_word(destoffset, destval);
2016        }
2017        break;
2018    case 3:                    /* register to register */
2019        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2020            u32 *destreg, *srcreg;
2021
2022            destreg = DECODE_RM_LONG_REGISTER(rl);
2023            DECODE_PRINTF(",");
2024            srcreg = DECODE_RM_LONG_REGISTER(rh);
2025            DECODE_PRINTF("\n");
2026            TRACE_AND_STEP();
2027            *destreg = and_long(*destreg, *srcreg);
2028        }
2029        else {
2030            u16 *destreg, *srcreg;
2031
2032            destreg = DECODE_RM_WORD_REGISTER(rl);
2033            DECODE_PRINTF(",");
2034            srcreg = DECODE_RM_WORD_REGISTER(rh);
2035            DECODE_PRINTF("\n");
2036            TRACE_AND_STEP();
2037            *destreg = and_word(*destreg, *srcreg);
2038        }
2039        break;
2040    }
2041    DECODE_CLEAR_SEGOVR();
2042    END_OF_INSTR();
2043}
2044
2045/****************************************************************************
2046REMARKS:
2047Handles opcode 0x22
2048****************************************************************************/
2049static void
2050x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2051{
2052    int mod, rl, rh;
2053    u8 *destreg, *srcreg;
2054    uint srcoffset;
2055    u8 srcval;
2056
2057    START_OF_INSTR();
2058    DECODE_PRINTF("AND\t");
2059    FETCH_DECODE_MODRM(mod, rh, rl);
2060    switch (mod) {
2061    case 0:
2062        destreg = DECODE_RM_BYTE_REGISTER(rh);
2063        DECODE_PRINTF(",");
2064        srcoffset = decode_rm00_address(rl);
2065        srcval = fetch_data_byte(srcoffset);
2066        DECODE_PRINTF("\n");
2067        TRACE_AND_STEP();
2068        *destreg = and_byte(*destreg, srcval);
2069        break;
2070    case 1:
2071        destreg = DECODE_RM_BYTE_REGISTER(rh);
2072        DECODE_PRINTF(",");
2073        srcoffset = decode_rm01_address(rl);
2074        srcval = fetch_data_byte(srcoffset);
2075        DECODE_PRINTF("\n");
2076        TRACE_AND_STEP();
2077        *destreg = and_byte(*destreg, srcval);
2078        break;
2079    case 2:
2080        destreg = DECODE_RM_BYTE_REGISTER(rh);
2081        DECODE_PRINTF(",");
2082        srcoffset = decode_rm10_address(rl);
2083        srcval = fetch_data_byte(srcoffset);
2084        DECODE_PRINTF("\n");
2085        TRACE_AND_STEP();
2086        *destreg = and_byte(*destreg, srcval);
2087        break;
2088    case 3:                    /* register to register */
2089        destreg = DECODE_RM_BYTE_REGISTER(rh);
2090        DECODE_PRINTF(",");
2091        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2092        DECODE_PRINTF("\n");
2093        TRACE_AND_STEP();
2094        *destreg = and_byte(*destreg, *srcreg);
2095        break;
2096    }
2097    DECODE_CLEAR_SEGOVR();
2098    END_OF_INSTR();
2099}
2100
2101/****************************************************************************
2102REMARKS:
2103Handles opcode 0x23
2104****************************************************************************/
2105static void
2106x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2107{
2108    int mod, rl, rh;
2109    uint srcoffset;
2110
2111    START_OF_INSTR();
2112    DECODE_PRINTF("AND\t");
2113    FETCH_DECODE_MODRM(mod, rh, rl);
2114    switch (mod) {
2115    case 0:
2116        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2117            u32 *destreg;
2118            u32 srcval;
2119
2120            destreg = DECODE_RM_LONG_REGISTER(rh);
2121            DECODE_PRINTF(",");
2122            srcoffset = decode_rm00_address(rl);
2123            srcval = fetch_data_long(srcoffset);
2124            DECODE_PRINTF("\n");
2125            TRACE_AND_STEP();
2126            *destreg = and_long(*destreg, srcval);
2127        }
2128        else {
2129            u16 *destreg;
2130            u16 srcval;
2131
2132            destreg = DECODE_RM_WORD_REGISTER(rh);
2133            DECODE_PRINTF(",");
2134            srcoffset = decode_rm00_address(rl);
2135            srcval = fetch_data_word(srcoffset);
2136            DECODE_PRINTF("\n");
2137            TRACE_AND_STEP();
2138            *destreg = and_word(*destreg, srcval);
2139        }
2140        break;
2141    case 1:
2142        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2143            u32 *destreg;
2144            u32 srcval;
2145
2146            destreg = DECODE_RM_LONG_REGISTER(rh);
2147            DECODE_PRINTF(",");
2148            srcoffset = decode_rm01_address(rl);
2149            srcval = fetch_data_long(srcoffset);
2150            DECODE_PRINTF("\n");
2151            TRACE_AND_STEP();
2152            *destreg = and_long(*destreg, srcval);
2153            break;
2154        }
2155        else {
2156            u16 *destreg;
2157            u16 srcval;
2158
2159            destreg = DECODE_RM_WORD_REGISTER(rh);
2160            DECODE_PRINTF(",");
2161            srcoffset = decode_rm01_address(rl);
2162            srcval = fetch_data_word(srcoffset);
2163            DECODE_PRINTF("\n");
2164            TRACE_AND_STEP();
2165            *destreg = and_word(*destreg, srcval);
2166            break;
2167        }
2168    case 2:
2169        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2170            u32 *destreg;
2171            u32 srcval;
2172
2173            destreg = DECODE_RM_LONG_REGISTER(rh);
2174            DECODE_PRINTF(",");
2175            srcoffset = decode_rm10_address(rl);
2176            srcval = fetch_data_long(srcoffset);
2177            DECODE_PRINTF("\n");
2178            TRACE_AND_STEP();
2179            *destreg = and_long(*destreg, srcval);
2180        }
2181        else {
2182            u16 *destreg;
2183            u16 srcval;
2184
2185            destreg = DECODE_RM_WORD_REGISTER(rh);
2186            DECODE_PRINTF(",");
2187            srcoffset = decode_rm10_address(rl);
2188            srcval = fetch_data_word(srcoffset);
2189            DECODE_PRINTF("\n");
2190            TRACE_AND_STEP();
2191            *destreg = and_word(*destreg, srcval);
2192        }
2193        break;
2194    case 3:                    /* register to register */
2195        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2196            u32 *destreg, *srcreg;
2197
2198            destreg = DECODE_RM_LONG_REGISTER(rh);
2199            DECODE_PRINTF(",");
2200            srcreg = DECODE_RM_LONG_REGISTER(rl);
2201            DECODE_PRINTF("\n");
2202            TRACE_AND_STEP();
2203            *destreg = and_long(*destreg, *srcreg);
2204        }
2205        else {
2206            u16 *destreg, *srcreg;
2207
2208            destreg = DECODE_RM_WORD_REGISTER(rh);
2209            DECODE_PRINTF(",");
2210            srcreg = DECODE_RM_WORD_REGISTER(rl);
2211            DECODE_PRINTF("\n");
2212            TRACE_AND_STEP();
2213            *destreg = and_word(*destreg, *srcreg);
2214        }
2215        break;
2216    }
2217    DECODE_CLEAR_SEGOVR();
2218    END_OF_INSTR();
2219}
2220
2221/****************************************************************************
2222REMARKS:
2223Handles opcode 0x24
2224****************************************************************************/
2225static void
2226x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2227{
2228    u8 srcval;
2229
2230    START_OF_INSTR();
2231    DECODE_PRINTF("AND\tAL,");
2232    srcval = fetch_byte_imm();
2233    DECODE_PRINTF2("%x\n", srcval);
2234    TRACE_AND_STEP();
2235    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2236    DECODE_CLEAR_SEGOVR();
2237    END_OF_INSTR();
2238}
2239
2240/****************************************************************************
2241REMARKS:
2242Handles opcode 0x25
2243****************************************************************************/
2244static void
2245x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2246{
2247    u32 srcval;
2248
2249    START_OF_INSTR();
2250    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2251        DECODE_PRINTF("AND\tEAX,");
2252        srcval = fetch_long_imm();
2253    }
2254    else {
2255        DECODE_PRINTF("AND\tAX,");
2256        srcval = fetch_word_imm();
2257    }
2258    DECODE_PRINTF2("%x\n", srcval);
2259    TRACE_AND_STEP();
2260    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2261        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2262    }
2263    else {
2264        M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2265    }
2266    DECODE_CLEAR_SEGOVR();
2267    END_OF_INSTR();
2268}
2269
2270/****************************************************************************
2271REMARKS:
2272Handles opcode 0x26
2273****************************************************************************/
2274static void
2275x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2276{
2277    START_OF_INSTR();
2278    DECODE_PRINTF("ES:\n");
2279    TRACE_AND_STEP();
2280    M.x86.mode |= SYSMODE_SEGOVR_ES;
2281    /*
2282     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2283     * opcode subroutines we do not want to do this.
2284     */
2285    END_OF_INSTR();
2286}
2287
2288/****************************************************************************
2289REMARKS:
2290Handles opcode 0x27
2291****************************************************************************/
2292static void
2293x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2294{
2295    START_OF_INSTR();
2296    DECODE_PRINTF("DAA\n");
2297    TRACE_AND_STEP();
2298    M.x86.R_AL = daa_byte(M.x86.R_AL);
2299    DECODE_CLEAR_SEGOVR();
2300    END_OF_INSTR();
2301}
2302
2303/****************************************************************************
2304REMARKS:
2305Handles opcode 0x28
2306****************************************************************************/
2307static void
2308x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2309{
2310    int mod, rl, rh;
2311    u8 *destreg, *srcreg;
2312    uint destoffset;
2313    u8 destval;
2314
2315    START_OF_INSTR();
2316    DECODE_PRINTF("SUB\t");
2317    FETCH_DECODE_MODRM(mod, rh, rl);
2318    switch (mod) {
2319    case 0:
2320        destoffset = decode_rm00_address(rl);
2321        DECODE_PRINTF(",");
2322        destval = fetch_data_byte(destoffset);
2323        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2324        DECODE_PRINTF("\n");
2325        TRACE_AND_STEP();
2326        destval = sub_byte(destval, *srcreg);
2327        store_data_byte(destoffset, destval);
2328        break;
2329    case 1:
2330        destoffset = decode_rm01_address(rl);
2331        DECODE_PRINTF(",");
2332        destval = fetch_data_byte(destoffset);
2333        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2334        DECODE_PRINTF("\n");
2335        TRACE_AND_STEP();
2336        destval = sub_byte(destval, *srcreg);
2337        store_data_byte(destoffset, destval);
2338        break;
2339    case 2:
2340        destoffset = decode_rm10_address(rl);
2341        DECODE_PRINTF(",");
2342        destval = fetch_data_byte(destoffset);
2343        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2344        DECODE_PRINTF("\n");
2345        TRACE_AND_STEP();
2346        destval = sub_byte(destval, *srcreg);
2347        store_data_byte(destoffset, destval);
2348        break;
2349    case 3:                    /* register to register */
2350        destreg = DECODE_RM_BYTE_REGISTER(rl);
2351        DECODE_PRINTF(",");
2352        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2353        DECODE_PRINTF("\n");
2354        TRACE_AND_STEP();
2355        *destreg = sub_byte(*destreg, *srcreg);
2356        break;
2357    }
2358    DECODE_CLEAR_SEGOVR();
2359    END_OF_INSTR();
2360}
2361
2362/****************************************************************************
2363REMARKS:
2364Handles opcode 0x29
2365****************************************************************************/
2366static void
2367x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2368{
2369    int mod, rl, rh;
2370    uint destoffset;
2371
2372    START_OF_INSTR();
2373    DECODE_PRINTF("SUB\t");
2374    FETCH_DECODE_MODRM(mod, rh, rl);
2375    switch (mod) {
2376    case 0:
2377        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2378            u32 destval;
2379            u32 *srcreg;
2380
2381            destoffset = decode_rm00_address(rl);
2382            DECODE_PRINTF(",");
2383            destval = fetch_data_long(destoffset);
2384            srcreg = DECODE_RM_LONG_REGISTER(rh);
2385            DECODE_PRINTF("\n");
2386            TRACE_AND_STEP();
2387            destval = sub_long(destval, *srcreg);
2388            store_data_long(destoffset, destval);
2389        }
2390        else {
2391            u16 destval;
2392            u16 *srcreg;
2393
2394            destoffset = decode_rm00_address(rl);
2395            DECODE_PRINTF(",");
2396            destval = fetch_data_word(destoffset);
2397            srcreg = DECODE_RM_WORD_REGISTER(rh);
2398            DECODE_PRINTF("\n");
2399            TRACE_AND_STEP();
2400            destval = sub_word(destval, *srcreg);
2401            store_data_word(destoffset, destval);
2402        }
2403        break;
2404    case 1:
2405        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2406            u32 destval;
2407            u32 *srcreg;
2408
2409            destoffset = decode_rm01_address(rl);
2410            DECODE_PRINTF(",");
2411            destval = fetch_data_long(destoffset);
2412            srcreg = DECODE_RM_LONG_REGISTER(rh);
2413            DECODE_PRINTF("\n");
2414            TRACE_AND_STEP();
2415            destval = sub_long(destval, *srcreg);
2416            store_data_long(destoffset, destval);
2417        }
2418        else {
2419            u16 destval;
2420            u16 *srcreg;
2421
2422            destoffset = decode_rm01_address(rl);
2423            DECODE_PRINTF(",");
2424            destval = fetch_data_word(destoffset);
2425            srcreg = DECODE_RM_WORD_REGISTER(rh);
2426            DECODE_PRINTF("\n");
2427            TRACE_AND_STEP();
2428            destval = sub_word(destval, *srcreg);
2429            store_data_word(destoffset, destval);
2430        }
2431        break;
2432    case 2:
2433        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2434            u32 destval;
2435            u32 *srcreg;
2436
2437            destoffset = decode_rm10_address(rl);
2438            DECODE_PRINTF(",");
2439            destval = fetch_data_long(destoffset);
2440            srcreg = DECODE_RM_LONG_REGISTER(rh);
2441            DECODE_PRINTF("\n");
2442            TRACE_AND_STEP();
2443            destval = sub_long(destval, *srcreg);
2444            store_data_long(destoffset, destval);
2445        }
2446        else {
2447            u16 destval;
2448            u16 *srcreg;
2449
2450            destoffset = decode_rm10_address(rl);
2451            DECODE_PRINTF(",");
2452            destval = fetch_data_word(destoffset);
2453            srcreg = DECODE_RM_WORD_REGISTER(rh);
2454            DECODE_PRINTF("\n");
2455            TRACE_AND_STEP();
2456            destval = sub_word(destval, *srcreg);
2457            store_data_word(destoffset, destval);
2458        }
2459        break;
2460    case 3:                    /* register to register */
2461        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462            u32 *destreg, *srcreg;
2463
2464            destreg = DECODE_RM_LONG_REGISTER(rl);
2465            DECODE_PRINTF(",");
2466            srcreg = DECODE_RM_LONG_REGISTER(rh);
2467            DECODE_PRINTF("\n");
2468            TRACE_AND_STEP();
2469            *destreg = sub_long(*destreg, *srcreg);
2470        }
2471        else {
2472            u16 *destreg, *srcreg;
2473
2474            destreg = DECODE_RM_WORD_REGISTER(rl);
2475            DECODE_PRINTF(",");
2476            srcreg = DECODE_RM_WORD_REGISTER(rh);
2477            DECODE_PRINTF("\n");
2478            TRACE_AND_STEP();
2479            *destreg = sub_word(*destreg, *srcreg);
2480        }
2481        break;
2482    }
2483    DECODE_CLEAR_SEGOVR();
2484    END_OF_INSTR();
2485}
2486
2487/****************************************************************************
2488REMARKS:
2489Handles opcode 0x2a
2490****************************************************************************/
2491static void
2492x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2493{
2494    int mod, rl, rh;
2495    u8 *destreg, *srcreg;
2496    uint srcoffset;
2497    u8 srcval;
2498
2499    START_OF_INSTR();
2500    DECODE_PRINTF("SUB\t");
2501    FETCH_DECODE_MODRM(mod, rh, rl);
2502    switch (mod) {
2503    case 0:
2504        destreg = DECODE_RM_BYTE_REGISTER(rh);
2505        DECODE_PRINTF(",");
2506        srcoffset = decode_rm00_address(rl);
2507        srcval = fetch_data_byte(srcoffset);
2508        DECODE_PRINTF("\n");
2509        TRACE_AND_STEP();
2510        *destreg = sub_byte(*destreg, srcval);
2511        break;
2512    case 1:
2513        destreg = DECODE_RM_BYTE_REGISTER(rh);
2514        DECODE_PRINTF(",");
2515        srcoffset = decode_rm01_address(rl);
2516        srcval = fetch_data_byte(srcoffset);
2517        DECODE_PRINTF("\n");
2518        TRACE_AND_STEP();
2519        *destreg = sub_byte(*destreg, srcval);
2520        break;
2521    case 2:
2522        destreg = DECODE_RM_BYTE_REGISTER(rh);
2523        DECODE_PRINTF(",");
2524        srcoffset = decode_rm10_address(rl);
2525        srcval = fetch_data_byte(srcoffset);
2526        DECODE_PRINTF("\n");
2527        TRACE_AND_STEP();
2528        *destreg = sub_byte(*destreg, srcval);
2529        break;
2530    case 3:                    /* register to register */
2531        destreg = DECODE_RM_BYTE_REGISTER(rh);
2532        DECODE_PRINTF(",");
2533        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2534        DECODE_PRINTF("\n");
2535        TRACE_AND_STEP();
2536        *destreg = sub_byte(*destreg, *srcreg);
2537        break;
2538    }
2539    DECODE_CLEAR_SEGOVR();
2540    END_OF_INSTR();
2541}
2542
2543/****************************************************************************
2544REMARKS:
2545Handles opcode 0x2b
2546****************************************************************************/
2547static void
2548x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2549{
2550    int mod, rl, rh;
2551    uint srcoffset;
2552
2553    START_OF_INSTR();
2554    DECODE_PRINTF("SUB\t");
2555    FETCH_DECODE_MODRM(mod, rh, rl);
2556    switch (mod) {
2557    case 0:
2558        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2559            u32 *destreg;
2560            u32 srcval;
2561
2562            destreg = DECODE_RM_LONG_REGISTER(rh);
2563            DECODE_PRINTF(",");
2564            srcoffset = decode_rm00_address(rl);
2565            srcval = fetch_data_long(srcoffset);
2566            DECODE_PRINTF("\n");
2567            TRACE_AND_STEP();
2568            *destreg = sub_long(*destreg, srcval);
2569        }
2570        else {
2571            u16 *destreg;
2572            u16 srcval;
2573
2574            destreg = DECODE_RM_WORD_REGISTER(rh);
2575            DECODE_PRINTF(",");
2576            srcoffset = decode_rm00_address(rl);
2577            srcval = fetch_data_word(srcoffset);
2578            DECODE_PRINTF("\n");
2579            TRACE_AND_STEP();
2580            *destreg = sub_word(*destreg, srcval);
2581        }
2582        break;
2583    case 1:
2584        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585            u32 *destreg;
2586            u32 srcval;
2587
2588            destreg = DECODE_RM_LONG_REGISTER(rh);
2589            DECODE_PRINTF(",");
2590            srcoffset = decode_rm01_address(rl);
2591            srcval = fetch_data_long(srcoffset);
2592            DECODE_PRINTF("\n");
2593            TRACE_AND_STEP();
2594            *destreg = sub_long(*destreg, srcval);
2595        }
2596        else {
2597            u16 *destreg;
2598            u16 srcval;
2599
2600            destreg = DECODE_RM_WORD_REGISTER(rh);
2601            DECODE_PRINTF(",");
2602            srcoffset = decode_rm01_address(rl);
2603            srcval = fetch_data_word(srcoffset);
2604            DECODE_PRINTF("\n");
2605            TRACE_AND_STEP();
2606            *destreg = sub_word(*destreg, srcval);
2607        }
2608        break;
2609    case 2:
2610        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2611            u32 *destreg;
2612            u32 srcval;
2613
2614            destreg = DECODE_RM_LONG_REGISTER(rh);
2615            DECODE_PRINTF(",");
2616            srcoffset = decode_rm10_address(rl);
2617            srcval = fetch_data_long(srcoffset);
2618            DECODE_PRINTF("\n");
2619            TRACE_AND_STEP();
2620            *destreg = sub_long(*destreg, srcval);
2621        }
2622        else {
2623            u16 *destreg;
2624            u16 srcval;
2625
2626            destreg = DECODE_RM_WORD_REGISTER(rh);
2627            DECODE_PRINTF(",");
2628            srcoffset = decode_rm10_address(rl);
2629            srcval = fetch_data_word(srcoffset);
2630            DECODE_PRINTF("\n");
2631            TRACE_AND_STEP();
2632            *destreg = sub_word(*destreg, srcval);
2633        }
2634        break;
2635    case 3:                    /* register to register */
2636        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2637            u32 *destreg, *srcreg;
2638
2639            destreg = DECODE_RM_LONG_REGISTER(rh);
2640            DECODE_PRINTF(",");
2641            srcreg = DECODE_RM_LONG_REGISTER(rl);
2642            DECODE_PRINTF("\n");
2643            TRACE_AND_STEP();
2644            *destreg = sub_long(*destreg, *srcreg);
2645        }
2646        else {
2647            u16 *destreg, *srcreg;
2648
2649            destreg = DECODE_RM_WORD_REGISTER(rh);
2650            DECODE_PRINTF(",");
2651            srcreg = DECODE_RM_WORD_REGISTER(rl);
2652            DECODE_PRINTF("\n");
2653            TRACE_AND_STEP();
2654            *destreg = sub_word(*destreg, *srcreg);
2655        }
2656        break;
2657    }
2658    DECODE_CLEAR_SEGOVR();
2659    END_OF_INSTR();
2660}
2661
2662/****************************************************************************
2663REMARKS:
2664Handles opcode 0x2c
2665****************************************************************************/
2666static void
2667x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2668{
2669    u8 srcval;
2670
2671    START_OF_INSTR();
2672    DECODE_PRINTF("SUB\tAL,");
2673    srcval = fetch_byte_imm();
2674    DECODE_PRINTF2("%x\n", srcval);
2675    TRACE_AND_STEP();
2676    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2677    DECODE_CLEAR_SEGOVR();
2678    END_OF_INSTR();
2679}
2680
2681/****************************************************************************
2682REMARKS:
2683Handles opcode 0x2d
2684****************************************************************************/
2685static void
2686x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2687{
2688    u32 srcval;
2689
2690    START_OF_INSTR();
2691    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2692        DECODE_PRINTF("SUB\tEAX,");
2693        srcval = fetch_long_imm();
2694    }
2695    else {
2696        DECODE_PRINTF("SUB\tAX,");
2697        srcval = fetch_word_imm();
2698    }
2699    DECODE_PRINTF2("%x\n", srcval);
2700    TRACE_AND_STEP();
2701    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2702        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2703    }
2704    else {
2705        M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2706    }
2707    DECODE_CLEAR_SEGOVR();
2708    END_OF_INSTR();
2709}
2710
2711/****************************************************************************
2712REMARKS:
2713Handles opcode 0x2e
2714****************************************************************************/
2715static void
2716x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2717{
2718    START_OF_INSTR();
2719    DECODE_PRINTF("CS:\n");
2720    TRACE_AND_STEP();
2721    M.x86.mode |= SYSMODE_SEGOVR_CS;
2722    /* note no DECODE_CLEAR_SEGOVR here. */
2723    END_OF_INSTR();
2724}
2725
2726/****************************************************************************
2727REMARKS:
2728Handles opcode 0x2f
2729****************************************************************************/
2730static void
2731x86emuOp_das(u8 X86EMU_UNUSED(op1))
2732{
2733    START_OF_INSTR();
2734    DECODE_PRINTF("DAS\n");
2735    TRACE_AND_STEP();
2736    M.x86.R_AL = das_byte(M.x86.R_AL);
2737    DECODE_CLEAR_SEGOVR();
2738    END_OF_INSTR();
2739}
2740
2741/****************************************************************************
2742REMARKS:
2743Handles opcode 0x30
2744****************************************************************************/
2745static void
2746x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2747{
2748    int mod, rl, rh;
2749    u8 *destreg, *srcreg;
2750    uint destoffset;
2751    u8 destval;
2752
2753    START_OF_INSTR();
2754    DECODE_PRINTF("XOR\t");
2755    FETCH_DECODE_MODRM(mod, rh, rl);
2756    switch (mod) {
2757    case 0:
2758        destoffset = decode_rm00_address(rl);
2759        DECODE_PRINTF(",");
2760        destval = fetch_data_byte(destoffset);
2761        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2762        DECODE_PRINTF("\n");
2763        TRACE_AND_STEP();
2764        destval = xor_byte(destval, *srcreg);
2765        store_data_byte(destoffset, destval);
2766        break;
2767    case 1:
2768        destoffset = decode_rm01_address(rl);
2769        DECODE_PRINTF(",");
2770        destval = fetch_data_byte(destoffset);
2771        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2772        DECODE_PRINTF("\n");
2773        TRACE_AND_STEP();
2774        destval = xor_byte(destval, *srcreg);
2775        store_data_byte(destoffset, destval);
2776        break;
2777    case 2:
2778        destoffset = decode_rm10_address(rl);
2779        DECODE_PRINTF(",");
2780        destval = fetch_data_byte(destoffset);
2781        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2782        DECODE_PRINTF("\n");
2783        TRACE_AND_STEP();
2784        destval = xor_byte(destval, *srcreg);
2785        store_data_byte(destoffset, destval);
2786        break;
2787    case 3:                    /* register to register */
2788        destreg = DECODE_RM_BYTE_REGISTER(rl);
2789        DECODE_PRINTF(",");
2790        srcreg = DECODE_RM_BYTE_REGISTER(rh);
2791        DECODE_PRINTF("\n");
2792        TRACE_AND_STEP();
2793        *destreg = xor_byte(*destreg, *srcreg);
2794        break;
2795    }
2796    DECODE_CLEAR_SEGOVR();
2797    END_OF_INSTR();
2798}
2799
2800/****************************************************************************
2801REMARKS:
2802Handles opcode 0x31
2803****************************************************************************/
2804static void
2805x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2806{
2807    int mod, rl, rh;
2808    uint destoffset;
2809
2810    START_OF_INSTR();
2811    DECODE_PRINTF("XOR\t");
2812    FETCH_DECODE_MODRM(mod, rh, rl);
2813    switch (mod) {
2814    case 0:
2815        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2816            u32 destval;
2817            u32 *srcreg;
2818
2819            destoffset = decode_rm00_address(rl);
2820            DECODE_PRINTF(",");
2821            destval = fetch_data_long(destoffset);
2822            srcreg = DECODE_RM_LONG_REGISTER(rh);
2823            DECODE_PRINTF("\n");
2824            TRACE_AND_STEP();
2825            destval = xor_long(destval, *srcreg);
2826            store_data_long(destoffset, destval);
2827        }
2828        else {
2829            u16 destval;
2830            u16 *srcreg;
2831
2832            destoffset = decode_rm00_address(rl);
2833            DECODE_PRINTF(",");
2834            destval = fetch_data_word(destoffset);
2835            srcreg = DECODE_RM_WORD_REGISTER(rh);
2836            DECODE_PRINTF("\n");
2837            TRACE_AND_STEP();
2838            destval = xor_word(destval, *srcreg);
2839            store_data_word(destoffset, destval);
2840        }
2841        break;
2842    case 1:
2843        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2844            u32 destval;
2845            u32 *srcreg;
2846
2847            destoffset = decode_rm01_address(rl);
2848            DECODE_PRINTF(",");
2849            destval = fetch_data_long(destoffset);
2850            srcreg = DECODE_RM_LONG_REGISTER(rh);
2851            DECODE_PRINTF("\n");
2852            TRACE_AND_STEP();
2853            destval = xor_long(destval, *srcreg);
2854            store_data_long(destoffset, destval);
2855        }
2856        else {
2857            u16 destval;
2858            u16 *srcreg;
2859
2860            destoffset = decode_rm01_address(rl);
2861            DECODE_PRINTF(",");
2862            destval = fetch_data_word(destoffset);
2863            srcreg = DECODE_RM_WORD_REGISTER(rh);
2864            DECODE_PRINTF("\n");
2865            TRACE_AND_STEP();
2866            destval = xor_word(destval, *srcreg);
2867            store_data_word(destoffset, destval);
2868        }
2869        break;
2870    case 2:
2871        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2872            u32 destval;
2873            u32 *srcreg;
2874
2875            destoffset = decode_rm10_address(rl);
2876            DECODE_PRINTF(",");
2877            destval = fetch_data_long(destoffset);
2878            srcreg = DECODE_RM_LONG_REGISTER(rh);
2879            DECODE_PRINTF("\n");
2880            TRACE_AND_STEP();
2881            destval = xor_long(destval, *srcreg);
2882            store_data_long(destoffset, destval);
2883        }
2884        else {
2885            u16 destval;
2886            u16 *srcreg;
2887
2888            destoffset = decode_rm10_address(rl);
2889            DECODE_PRINTF(",");
2890            destval = fetch_data_word(destoffset);
2891            srcreg = DECODE_RM_WORD_REGISTER(rh);
2892            DECODE_PRINTF("\n");
2893            TRACE_AND_STEP();
2894            destval = xor_word(destval, *srcreg);
2895            store_data_word(destoffset, destval);
2896        }
2897        break;
2898    case 3:                    /* register to register */
2899        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2900            u32 *destreg, *srcreg;
2901
2902            destreg = DECODE_RM_LONG_REGISTER(rl);
2903            DECODE_PRINTF(",");
2904            srcreg = DECODE_RM_LONG_REGISTER(rh);
2905            DECODE_PRINTF("\n");
2906            TRACE_AND_STEP();
2907            *destreg = xor_long(*destreg, *srcreg);
2908        }
2909        else {
2910            u16 *destreg, *srcreg;
2911
2912            destreg = DECODE_RM_WORD_REGISTER(rl);
2913            DECODE_PRINTF(",");
2914            srcreg = DECODE_RM_WORD_REGISTER(rh);
2915            DECODE_PRINTF("\n");
2916            TRACE_AND_STEP();
2917            *destreg = xor_word(*destreg, *srcreg);
2918        }
2919        break;
2920    }
2921    DECODE_CLEAR_SEGOVR();
2922    END_OF_INSTR();
2923}
2924
2925/****************************************************************************
2926REMARKS:
2927Handles opcode 0x32
2928****************************************************************************/
2929static void
2930x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2931{
2932    int mod, rl, rh;
2933    u8 *destreg, *srcreg;
2934    uint srcoffset;
2935    u8 srcval;
2936
2937    START_OF_INSTR();
2938    DECODE_PRINTF("XOR\t");
2939    FETCH_DECODE_MODRM(mod, rh, rl);
2940    switch (mod) {
2941    case 0:
2942        destreg = DECODE_RM_BYTE_REGISTER(rh);
2943        DECODE_PRINTF(",");
2944        srcoffset = decode_rm00_address(rl);
2945        srcval = fetch_data_byte(srcoffset);
2946        DECODE_PRINTF("\n");
2947        TRACE_AND_STEP();
2948        *destreg = xor_byte(*destreg, srcval);
2949        break;
2950    case 1:
2951        destreg = DECODE_RM_BYTE_REGISTER(rh);
2952        DECODE_PRINTF(",");
2953        srcoffset = decode_rm01_address(rl);
2954        srcval = fetch_data_byte(srcoffset);
2955        DECODE_PRINTF("\n");
2956        TRACE_AND_STEP();
2957        *destreg = xor_byte(*destreg, srcval);
2958        break;
2959    case 2:
2960        destreg = DECODE_RM_BYTE_REGISTER(rh);
2961        DECODE_PRINTF(",");
2962        srcoffset = decode_rm10_address(rl);
2963        srcval = fetch_data_byte(srcoffset);
2964        DECODE_PRINTF("\n");
2965        TRACE_AND_STEP();
2966        *destreg = xor_byte(*destreg, srcval);
2967        break;
2968    case 3:                    /* register to register */
2969        destreg = DECODE_RM_BYTE_REGISTER(rh);
2970        DECODE_PRINTF(",");
2971        srcreg = DECODE_RM_BYTE_REGISTER(rl);
2972        DECODE_PRINTF("\n");
2973        TRACE_AND_STEP();
2974        *destreg = xor_byte(*destreg, *srcreg);
2975        break;
2976    }
2977    DECODE_CLEAR_SEGOVR();
2978    END_OF_INSTR();
2979}
2980
2981/****************************************************************************
2982REMARKS:
2983Handles opcode 0x33
2984****************************************************************************/
2985static void
2986x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2987{
2988    int mod, rl, rh;
2989    uint srcoffset;
2990
2991    START_OF_INSTR();
2992    DECODE_PRINTF("XOR\t");
2993    FETCH_DECODE_MODRM(mod, rh, rl);
2994    switch (mod) {
2995    case 0:
2996        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2997            u32 *destreg;
2998            u32 srcval;
2999
3000            destreg = DECODE_RM_LONG_REGISTER(rh);
3001            DECODE_PRINTF(",");
3002            srcoffset = decode_rm00_address(rl);
3003            srcval = fetch_data_long(srcoffset);
3004            DECODE_PRINTF("\n");
3005            TRACE_AND_STEP();
3006            *destreg = xor_long(*destreg, srcval);
3007        }
3008        else {
3009            u16 *destreg;
3010            u16 srcval;
3011
3012            destreg = DECODE_RM_WORD_REGISTER(rh);
3013            DECODE_PRINTF(",");
3014            srcoffset = decode_rm00_address(rl);
3015            srcval = fetch_data_word(srcoffset);
3016            DECODE_PRINTF("\n");
3017            TRACE_AND_STEP();
3018            *destreg = xor_word(*destreg, srcval);
3019        }
3020        break;
3021    case 1:
3022        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3023            u32 *destreg;
3024            u32 srcval;
3025
3026            destreg = DECODE_RM_LONG_REGISTER(rh);
3027            DECODE_PRINTF(",");
3028            srcoffset = decode_rm01_address(rl);
3029            srcval = fetch_data_long(srcoffset);
3030            DECODE_PRINTF("\n");
3031            TRACE_AND_STEP();
3032            *destreg = xor_long(*destreg, srcval);
3033        }
3034        else {
3035            u16 *destreg;
3036            u16 srcval;
3037
3038            destreg = DECODE_RM_WORD_REGISTER(rh);
3039            DECODE_PRINTF(",");
3040            srcoffset = decode_rm01_address(rl);
3041            srcval = fetch_data_word(srcoffset);
3042            DECODE_PRINTF("\n");
3043            TRACE_AND_STEP();
3044            *destreg = xor_word(*destreg, srcval);
3045        }
3046        break;
3047    case 2:
3048        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049            u32 *destreg;
3050            u32 srcval;
3051
3052            destreg = DECODE_RM_LONG_REGISTER(rh);
3053            DECODE_PRINTF(",");
3054            srcoffset = decode_rm10_address(rl);
3055            srcval = fetch_data_long(srcoffset);
3056            DECODE_PRINTF("\n");
3057            TRACE_AND_STEP();
3058            *destreg = xor_long(*destreg, srcval);
3059        }
3060        else {
3061            u16 *destreg;
3062            u16 srcval;
3063
3064            destreg = DECODE_RM_WORD_REGISTER(rh);
3065            DECODE_PRINTF(",");
3066            srcoffset = decode_rm10_address(rl);
3067            srcval = fetch_data_word(srcoffset);
3068            DECODE_PRINTF("\n");
3069            TRACE_AND_STEP();
3070            *destreg = xor_word(*destreg, srcval);
3071        }
3072        break;
3073    case 3:                    /* register to register */
3074        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3075            u32 *destreg, *srcreg;
3076
3077            destreg = DECODE_RM_LONG_REGISTER(rh);
3078            DECODE_PRINTF(",");
3079            srcreg = DECODE_RM_LONG_REGISTER(rl);
3080            DECODE_PRINTF("\n");
3081            TRACE_AND_STEP();
3082            *destreg = xor_long(*destreg, *srcreg);
3083        }
3084        else {
3085            u16 *destreg, *srcreg;
3086
3087            destreg = DECODE_RM_WORD_REGISTER(rh);
3088            DECODE_PRINTF(",");
3089            srcreg = DECODE_RM_WORD_REGISTER(rl);
3090            DECODE_PRINTF("\n");
3091            TRACE_AND_STEP();
3092            *destreg = xor_word(*destreg, *srcreg);
3093        }
3094        break;
3095    }
3096    DECODE_CLEAR_SEGOVR();
3097    END_OF_INSTR();
3098}
3099
3100/****************************************************************************
3101REMARKS:
3102Handles opcode 0x34
3103****************************************************************************/
3104static void
3105x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3106{
3107    u8 srcval;
3108
3109    START_OF_INSTR();
3110    DECODE_PRINTF("XOR\tAL,");
3111    srcval = fetch_byte_imm();
3112    DECODE_PRINTF2("%x\n", srcval);
3113    TRACE_AND_STEP();
3114    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3115    DECODE_CLEAR_SEGOVR();
3116    END_OF_INSTR();
3117}
3118
3119/****************************************************************************
3120REMARKS:
3121Handles opcode 0x35
3122****************************************************************************/
3123static void
3124x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3125{
3126    u32 srcval;
3127
3128    START_OF_INSTR();
3129    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3130        DECODE_PRINTF("XOR\tEAX,");
3131        srcval = fetch_long_imm();
3132    }
3133    else {
3134        DECODE_PRINTF("XOR\tAX,");
3135        srcval = fetch_word_imm();
3136    }
3137    DECODE_PRINTF2("%x\n", srcval);
3138    TRACE_AND_STEP();
3139    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3141    }
3142    else {
3143        M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3144    }
3145    DECODE_CLEAR_SEGOVR();
3146    END_OF_INSTR();
3147}
3148
3149/****************************************************************************
3150REMARKS:
3151Handles opcode 0x36
3152****************************************************************************/
3153static void
3154x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3155{
3156    START_OF_INSTR();
3157    DECODE_PRINTF("SS:\n");
3158    TRACE_AND_STEP();
3159    M.x86.mode |= SYSMODE_SEGOVR_SS;
3160    /* no DECODE_CLEAR_SEGOVR ! */
3161    END_OF_INSTR();
3162}
3163
3164/****************************************************************************
3165REMARKS:
3166Handles opcode 0x37
3167****************************************************************************/
3168static void
3169x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3170{
3171    START_OF_INSTR();
3172    DECODE_PRINTF("AAA\n");
3173    TRACE_AND_STEP();
3174    M.x86.R_AX = aaa_word(M.x86.R_AX);
3175    DECODE_CLEAR_SEGOVR();
3176    END_OF_INSTR();
3177}
3178
3179/****************************************************************************
3180REMARKS:
3181Handles opcode 0x38
3182****************************************************************************/
3183static void
3184x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3185{
3186    int mod, rl, rh;
3187    uint destoffset;
3188    u8 *destreg, *srcreg;
3189    u8 destval;
3190
3191    START_OF_INSTR();
3192    DECODE_PRINTF("CMP\t");
3193    FETCH_DECODE_MODRM(mod, rh, rl);
3194    switch (mod) {
3195    case 0:
3196        destoffset = decode_rm00_address(rl);
3197        DECODE_PRINTF(",");
3198        destval = fetch_data_byte(destoffset);
3199        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3200        DECODE_PRINTF("\n");
3201        TRACE_AND_STEP();
3202        cmp_byte(destval, *srcreg);
3203        break;
3204    case 1:
3205        destoffset = decode_rm01_address(rl);
3206        DECODE_PRINTF(",");
3207        destval = fetch_data_byte(destoffset);
3208        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3209        DECODE_PRINTF("\n");
3210        TRACE_AND_STEP();
3211        cmp_byte(destval, *srcreg);
3212        break;
3213    case 2:
3214        destoffset = decode_rm10_address(rl);
3215        DECODE_PRINTF(",");
3216        destval = fetch_data_byte(destoffset);
3217        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3218        DECODE_PRINTF("\n");
3219        TRACE_AND_STEP();
3220        cmp_byte(destval, *srcreg);
3221        break;
3222    case 3:                    /* register to register */
3223        destreg = DECODE_RM_BYTE_REGISTER(rl);
3224        DECODE_PRINTF(",");
3225        srcreg = DECODE_RM_BYTE_REGISTER(rh);
3226        DECODE_PRINTF("\n");
3227        TRACE_AND_STEP();
3228        cmp_byte(*destreg, *srcreg);
3229        break;
3230    }
3231    DECODE_CLEAR_SEGOVR();
3232    END_OF_INSTR();
3233}
3234
3235/****************************************************************************
3236REMARKS:
3237Handles opcode 0x39
3238****************************************************************************/
3239static void
3240x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3241{
3242    int mod, rl, rh;
3243    uint destoffset;
3244
3245    START_OF_INSTR();
3246    DECODE_PRINTF("CMP\t");
3247    FETCH_DECODE_MODRM(mod, rh, rl);
3248    switch (mod) {
3249    case 0:
3250        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3251            u32 destval;
3252            u32 *srcreg;
3253
3254            destoffset = decode_rm00_address(rl);
3255            DECODE_PRINTF(",");
3256            destval = fetch_data_long(destoffset);
3257            srcreg = DECODE_RM_LONG_REGISTER(rh);
3258            DECODE_PRINTF("\n");
3259            TRACE_AND_STEP();
3260            cmp_long(destval, *srcreg);
3261        }
3262        else {
3263            u16 destval;
3264            u16 *srcreg;
3265
3266            destoffset = decode_rm00_address(rl);
3267            DECODE_PRINTF(",");
3268            destval = fetch_data_word(destoffset);
3269            srcreg = DECODE_RM_WORD_REGISTER(rh);
3270            DECODE_PRINTF("\n");
3271            TRACE_AND_STEP();
3272            cmp_word(destval, *srcreg);
3273        }
3274        break;
3275    case 1:
3276        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3277            u32 destval;
3278            u32 *srcreg;
3279
3280            destoffset = decode_rm01_address(rl);
3281            DECODE_PRINTF(",");
3282            destval = fetch_data_long(destoffset);
3283            srcreg = DECODE_RM_LONG_REGISTER(rh);
3284            DECODE_PRINTF("\n");
3285            TRACE_AND_STEP();
3286            cmp_long(destval, *srcreg);
3287        }
3288        else {
3289            u16 destval;
3290            u16 *srcreg;
3291
3292            destoffset = decode_rm01_address(rl);
3293            DECODE_PRINTF(",");
3294            destval = fetch_data_word(destoffset);
3295            srcreg = DECODE_RM_WORD_REGISTER(rh);
3296            DECODE_PRINTF("\n");
3297            TRACE_AND_STEP();
3298            cmp_word(destval, *srcreg);
3299        }
3300        break;
3301    case 2:
3302        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3303            u32 destval;
3304            u32 *srcreg;
3305
3306            destoffset = decode_rm10_address(rl);
3307            DECODE_PRINTF(",");
3308            destval = fetch_data_long(destoffset);
3309            srcreg = DECODE_RM_LONG_REGISTER(rh);
3310            DECODE_PRINTF("\n");
3311            TRACE_AND_STEP();
3312            cmp_long(destval, *srcreg);
3313        }
3314        else {
3315            u16 destval;
3316            u16 *srcreg;
3317
3318            destoffset = decode_rm10_address(rl);
3319            DECODE_PRINTF(",");
3320            destval = fetch_data_word(destoffset);
3321            srcreg = DECODE_RM_WORD_REGISTER(rh);
3322            DECODE_PRINTF("\n");
3323            TRACE_AND_STEP();
3324            cmp_word(destval, *srcreg);
3325        }
3326        break;
3327    case 3:                    /* register to register */
3328        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3329            u32 *destreg, *srcreg;
3330
3331            destreg = DECODE_RM_LONG_REGISTER(rl);
3332            DECODE_PRINTF(",");
3333            srcreg = DECODE_RM_LONG_REGISTER(rh);
3334            DECODE_PRINTF("\n");
3335            TRACE_AND_STEP();
3336            cmp_long(*destreg, *srcreg);
3337        }
3338        else {
3339            u16 *destreg, *srcreg;
3340
3341            destreg = DECODE_RM_WORD_REGISTER(rl);
3342            DECODE_PRINTF(",");
3343            srcreg = DECODE_RM_WORD_REGISTER(rh);
3344            DECODE_PRINTF("\n");
3345            TRACE_AND_STEP();
3346            cmp_word(*destreg, *srcreg);
3347        }
3348        break;
3349    }
3350    DECODE_CLEAR_SEGOVR();
3351    END_OF_INSTR();
3352}
3353
3354/****************************************************************************
3355REMARKS:
3356Handles opcode 0x3a
3357****************************************************************************/
3358static void
3359x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3360{
3361    int mod, rl, rh;
3362    u8 *destreg, *srcreg;
3363    uint srcoffset;
3364    u8 srcval;
3365
3366    START_OF_INSTR();
3367    DECODE_PRINTF("CMP\t");
3368    FETCH_DECODE_MODRM(mod, rh, rl);
3369    switch (mod) {
3370    case 0:
3371        destreg = DECODE_RM_BYTE_REGISTER(rh);
3372        DECODE_PRINTF(",");
3373        srcoffset = decode_rm00_address(rl);
3374        srcval = fetch_data_byte(srcoffset);
3375        DECODE_PRINTF("\n");
3376        TRACE_AND_STEP();
3377        cmp_byte(*destreg, srcval);
3378        break;
3379    case 1:
3380        destreg = DECODE_RM_BYTE_REGISTER(rh);
3381        DECODE_PRINTF(",");
3382        srcoffset = decode_rm01_address(rl);
3383        srcval = fetch_data_byte(srcoffset);
3384        DECODE_PRINTF("\n");
3385        TRACE_AND_STEP();
3386        cmp_byte(*destreg, srcval);
3387        break;
3388    case 2:
3389        destreg = DECODE_RM_BYTE_REGISTER(rh);
3390        DECODE_PRINTF(",");
3391        srcoffset = decode_rm10_address(rl);
3392        srcval = fetch_data_byte(srcoffset);
3393        DECODE_PRINTF("\n");
3394        TRACE_AND_STEP();
3395        cmp_byte(*destreg, srcval);
3396        break;
3397    case 3:                    /* register to register */
3398        destreg = DECODE_RM_BYTE_REGISTER(rh);
3399        DECODE_PRINTF(",");
3400        srcreg = DECODE_RM_BYTE_REGISTER(rl);
3401        DECODE_PRINTF("\n");
3402        TRACE_AND_STEP();
3403        cmp_byte(*destreg, *srcreg);
3404        break;
3405    }
3406    DECODE_CLEAR_SEGOVR();
3407    END_OF_INSTR();
3408}
3409
3410/****************************************************************************
3411REMARKS:
3412Handles opcode 0x3b
3413****************************************************************************/
3414static void
3415x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3416{
3417    int mod, rl, rh;
3418    uint srcoffset;
3419
3420    START_OF_INSTR();
3421    DECODE_PRINTF("CMP\t");
3422    FETCH_DECODE_MODRM(mod, rh, rl);
3423    switch (mod) {
3424    case 0:
3425        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3426            u32 *destreg;
3427            u32 srcval;
3428
3429            destreg = DECODE_RM_LONG_REGISTER(rh);
3430            DECODE_PRINTF(",");
3431            srcoffset = decode_rm00_address(rl);
3432            srcval = fetch_data_long(srcoffset);
3433            DECODE_PRINTF("\n");
3434            TRACE_AND_STEP();
3435            cmp_long(*destreg, srcval);
3436        }
3437        else {
3438            u16 *destreg;
3439            u16 srcval;
3440
3441            destreg = DECODE_RM_WORD_REGISTER(rh);
3442            DECODE_PRINTF(",");
3443            srcoffset = decode_rm00_address(rl);
3444            srcval = fetch_data_word(srcoffset);
3445            DECODE_PRINTF("\n");
3446            TRACE_AND_STEP();
3447            cmp_word(*destreg, srcval);
3448        }
3449        break;
3450    case 1:
3451        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3452            u32 *destreg;
3453            u32 srcval;
3454
3455            destreg = DECODE_RM_LONG_REGISTER(rh);
3456            DECODE_PRINTF(",");
3457            srcoffset = decode_rm01_address(rl);
3458            srcval = fetch_data_long(srcoffset);
3459            DECODE_PRINTF("\n");
3460            TRACE_AND_STEP();
3461            cmp_long(*destreg, srcval);
3462        }
3463        else {
3464            u16 *destreg;
3465            u16 srcval;
3466
3467            destreg = DECODE_RM_WORD_REGISTER(rh);
3468            DECODE_PRINTF(",");
3469            srcoffset = decode_rm01_address(rl);
3470            srcval = fetch_data_word(srcoffset);
3471            DECODE_PRINTF("\n");
3472            TRACE_AND_STEP();
3473            cmp_word(*destreg, srcval);
3474        }
3475        break;
3476    case 2:
3477        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478            u32 *destreg;
3479            u32 srcval;
3480
3481            destreg = DECODE_RM_LONG_REGISTER(rh);
3482            DECODE_PRINTF(",");
3483            srcoffset = decode_rm10_address(rl);
3484            srcval = fetch_data_long(srcoffset);
3485            DECODE_PRINTF("\n");
3486            TRACE_AND_STEP();
3487            cmp_long(*destreg, srcval);
3488        }
3489        else {
3490            u16 *destreg;
3491            u16 srcval;
3492
3493            destreg = DECODE_RM_WORD_REGISTER(rh);
3494            DECODE_PRINTF(",");
3495            srcoffset = decode_rm10_address(rl);
3496            srcval = fetch_data_word(srcoffset);
3497            DECODE_PRINTF("\n");
3498            TRACE_AND_STEP();
3499            cmp_word(*destreg, srcval);
3500        }
3501        break;
3502    case 3:                    /* register to register */
3503        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504            u32 *destreg, *srcreg;
3505
3506            destreg = DECODE_RM_LONG_REGISTER(rh);
3507            DECODE_PRINTF(",");
3508            srcreg = DECODE_RM_LONG_REGISTER(rl);
3509            DECODE_PRINTF("\n");
3510            TRACE_AND_STEP();
3511            cmp_long(*destreg, *srcreg);
3512        }
3513        else {
3514            u16 *destreg, *srcreg;
3515
3516            destreg = DECODE_RM_WORD_REGISTER(rh);
3517            DECODE_PRINTF(",");
3518            srcreg = DECODE_RM_WORD_REGISTER(rl);
3519            DECODE_PRINTF("\n");
3520            TRACE_AND_STEP();
3521            cmp_word(*destreg, *srcreg);
3522        }
3523        break;
3524    }
3525    DECODE_CLEAR_SEGOVR();
3526    END_OF_INSTR();
3527}
3528
3529/****************************************************************************
3530REMARKS:
3531Handles opcode 0x3c
3532****************************************************************************/
3533static void
3534x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3535{
3536    u8 srcval;
3537
3538    START_OF_INSTR();
3539    DECODE_PRINTF("CMP\tAL,");
3540    srcval = fetch_byte_imm();
3541    DECODE_PRINTF2("%x\n", srcval);
3542    TRACE_AND_STEP();
3543    cmp_byte(M.x86.R_AL, srcval);
3544    DECODE_CLEAR_SEGOVR();
3545    END_OF_INSTR();
3546}
3547
3548/****************************************************************************
3549REMARKS:
3550Handles opcode 0x3d
3551****************************************************************************/
3552static void
3553x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3554{
3555    u32 srcval;
3556
3557    START_OF_INSTR();
3558    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559        DECODE_PRINTF("CMP\tEAX,");
3560        srcval = fetch_long_imm();
3561    }
3562    else {
3563        DECODE_PRINTF("CMP\tAX,");
3564        srcval = fetch_word_imm();
3565    }
3566    DECODE_PRINTF2("%x\n", srcval);
3567    TRACE_AND_STEP();
3568    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3569        cmp_long(M.x86.R_EAX, srcval);
3570    }
3571    else {
3572        cmp_word(M.x86.R_AX, (u16) srcval);
3573    }
3574    DECODE_CLEAR_SEGOVR();
3575    END_OF_INSTR();
3576}
3577
3578/****************************************************************************
3579REMARKS:
3580Handles opcode 0x3e
3581****************************************************************************/
3582static void
3583x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3584{
3585    START_OF_INSTR();
3586    DECODE_PRINTF("DS:\n");
3587    TRACE_AND_STEP();
3588    M.x86.mode |= SYSMODE_SEGOVR_DS;
3589    /* NO DECODE_CLEAR_SEGOVR! */
3590    END_OF_INSTR();
3591}
3592
3593/****************************************************************************
3594REMARKS:
3595Handles opcode 0x3f
3596****************************************************************************/
3597static void
3598x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3599{
3600    START_OF_INSTR();
3601    DECODE_PRINTF("AAS\n");
3602    TRACE_AND_STEP();
3603    M.x86.R_AX = aas_word(M.x86.R_AX);
3604    DECODE_CLEAR_SEGOVR();
3605    END_OF_INSTR();
3606}
3607
3608/****************************************************************************
3609REMARKS:
3610Handles opcode 0x40
3611****************************************************************************/
3612static void
3613x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3614{
3615    START_OF_INSTR();
3616    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3617        DECODE_PRINTF("INC\tEAX\n");
3618    }
3619    else {
3620        DECODE_PRINTF("INC\tAX\n");
3621    }
3622    TRACE_AND_STEP();
3623    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624        M.x86.R_EAX = inc_long(M.x86.R_EAX);
3625    }
3626    else {
3627        M.x86.R_AX = inc_word(M.x86.R_AX);
3628    }
3629    DECODE_CLEAR_SEGOVR();
3630    END_OF_INSTR();
3631}
3632
3633/****************************************************************************
3634REMARKS:
3635Handles opcode 0x41
3636****************************************************************************/
3637static void
3638x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3639{
3640    START_OF_INSTR();
3641    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642        DECODE_PRINTF("INC\tECX\n");
3643    }
3644    else {
3645        DECODE_PRINTF("INC\tCX\n");
3646    }
3647    TRACE_AND_STEP();
3648    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649        M.x86.R_ECX = inc_long(M.x86.R_ECX);
3650    }
3651    else {
3652        M.x86.R_CX = inc_word(M.x86.R_CX);
3653    }
3654    DECODE_CLEAR_SEGOVR();
3655    END_OF_INSTR();
3656}
3657
3658/****************************************************************************
3659REMARKS:
3660Handles opcode 0x42
3661****************************************************************************/
3662static void
3663x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3664{
3665    START_OF_INSTR();
3666    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3667        DECODE_PRINTF("INC\tEDX\n");
3668    }
3669    else {
3670        DECODE_PRINTF("INC\tDX\n");
3671    }
3672    TRACE_AND_STEP();
3673    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3674        M.x86.R_EDX = inc_long(M.x86.R_EDX);
3675    }
3676    else {
3677        M.x86.R_DX = inc_word(M.x86.R_DX);
3678    }
3679    DECODE_CLEAR_SEGOVR();
3680    END_OF_INSTR();
3681}
3682
3683/****************************************************************************
3684REMARKS:
3685Handles opcode 0x43
3686****************************************************************************/
3687static void
3688x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3689{
3690    START_OF_INSTR();
3691    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692        DECODE_PRINTF("INC\tEBX\n");
3693    }
3694    else {
3695        DECODE_PRINTF("INC\tBX\n");
3696    }
3697    TRACE_AND_STEP();
3698    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699        M.x86.R_EBX = inc_long(M.x86.R_EBX);
3700    }
3701    else {
3702        M.x86.R_BX = inc_word(M.x86.R_BX);
3703    }
3704    DECODE_CLEAR_SEGOVR();
3705    END_OF_INSTR();
3706}
3707
3708/****************************************************************************
3709REMARKS:
3710Handles opcode 0x44
3711****************************************************************************/
3712static void
3713x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3714{
3715    START_OF_INSTR();
3716    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3717        DECODE_PRINTF("INC\tESP\n");
3718    }
3719    else {
3720        DECODE_PRINTF("INC\tSP\n");
3721    }
3722    TRACE_AND_STEP();
3723    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724        M.x86.R_ESP = inc_long(M.x86.R_ESP);
3725    }
3726    else {
3727        M.x86.R_SP = inc_word(M.x86.R_SP);
3728    }
3729    DECODE_CLEAR_SEGOVR();
3730    END_OF_INSTR();
3731}
3732
3733/****************************************************************************
3734REMARKS:
3735Handles opcode 0x45
3736****************************************************************************/
3737static void
3738x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3739{
3740    START_OF_INSTR();
3741    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742        DECODE_PRINTF("INC\tEBP\n");
3743    }
3744    else {
3745        DECODE_PRINTF("INC\tBP\n");
3746    }
3747    TRACE_AND_STEP();
3748    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3749        M.x86.R_EBP = inc_long(M.x86.R_EBP);
3750    }
3751    else {
3752        M.x86.R_BP = inc_word(M.x86.R_BP);
3753    }
3754    DECODE_CLEAR_SEGOVR();
3755    END_OF_INSTR();
3756}
3757
3758/****************************************************************************
3759REMARKS:
3760Handles opcode 0x46
3761****************************************************************************/
3762static void
3763x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3764{
3765    START_OF_INSTR();
3766    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3767        DECODE_PRINTF("INC\tESI\n");
3768    }
3769    else {
3770        DECODE_PRINTF("INC\tSI\n");
3771    }
3772    TRACE_AND_STEP();
3773    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774        M.x86.R_ESI = inc_long(M.x86.R_ESI);
3775    }
3776    else {
3777        M.x86.R_SI = inc_word(M.x86.R_SI);
3778    }
3779    DECODE_CLEAR_SEGOVR();
3780    END_OF_INSTR();
3781}
3782
3783/****************************************************************************
3784REMARKS:
3785Handles opcode 0x47
3786****************************************************************************/
3787static void
3788x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3789{
3790    START_OF_INSTR();
3791    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3792        DECODE_PRINTF("INC\tEDI\n");
3793    }
3794    else {
3795        DECODE_PRINTF("INC\tDI\n");
3796    }
3797    TRACE_AND_STEP();
3798    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3799        M.x86.R_EDI = inc_long(M.x86.R_EDI);
3800    }
3801    else {
3802        M.x86.R_DI = inc_word(M.x86.R_DI);
3803    }
3804    DECODE_CLEAR_SEGOVR();
3805    END_OF_INSTR();
3806}
3807
3808/****************************************************************************
3809REMARKS:
3810Handles opcode 0x48
3811****************************************************************************/
3812static void
3813x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3814{
3815    START_OF_INSTR();
3816    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3817        DECODE_PRINTF("DEC\tEAX\n");
3818    }
3819    else {
3820        DECODE_PRINTF("DEC\tAX\n");
3821    }
3822    TRACE_AND_STEP();
3823    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824        M.x86.R_EAX = dec_long(M.x86.R_EAX);
3825    }
3826    else {
3827        M.x86.R_AX = dec_word(M.x86.R_AX);
3828    }
3829    DECODE_CLEAR_SEGOVR();
3830    END_OF_INSTR();
3831}
3832
3833/****************************************************************************
3834REMARKS:
3835Handles opcode 0x49
3836****************************************************************************/
3837static void
3838x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3839{
3840    START_OF_INSTR();
3841    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3842        DECODE_PRINTF("DEC\tECX\n");
3843    }
3844    else {
3845        DECODE_PRINTF("DEC\tCX\n");
3846    }
3847    TRACE_AND_STEP();
3848    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3849        M.x86.R_ECX = dec_long(M.x86.R_ECX);
3850    }
3851    else {
3852        M.x86.R_CX = dec_word(M.x86.R_CX);
3853    }
3854    DECODE_CLEAR_SEGOVR();
3855    END_OF_INSTR();
3856}
3857
3858/****************************************************************************
3859REMARKS:
3860Handles opcode 0x4a
3861****************************************************************************/
3862static void
3863x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3864{
3865    START_OF_INSTR();
3866    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867        DECODE_PRINTF("DEC\tEDX\n");
3868    }
3869    else {
3870        DECODE_PRINTF("DEC\tDX\n");
3871    }
3872    TRACE_AND_STEP();
3873    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874        M.x86.R_EDX = dec_long(M.x86.R_EDX);
3875    }
3876    else {
3877        M.x86.R_DX = dec_word(M.x86.R_DX);
3878    }
3879    DECODE_CLEAR_SEGOVR();
3880    END_OF_INSTR();
3881}
3882
3883/****************************************************************************
3884REMARKS:
3885Handles opcode 0x4b
3886****************************************************************************/
3887static void
3888x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3889{
3890    START_OF_INSTR();
3891    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3892        DECODE_PRINTF("DEC\tEBX\n");
3893    }
3894    else {
3895        DECODE_PRINTF("DEC\tBX\n");
3896    }
3897    TRACE_AND_STEP();
3898    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3899        M.x86.R_EBX = dec_long(M.x86.R_EBX);
3900    }
3901    else {
3902        M.x86.R_BX = dec_word(M.x86.R_BX);
3903    }
3904    DECODE_CLEAR_SEGOVR();
3905    END_OF_INSTR();
3906}
3907
3908/****************************************************************************
3909REMARKS:
3910Handles opcode 0x4c
3911****************************************************************************/
3912static void
3913x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3914{
3915    START_OF_INSTR();
3916    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3917        DECODE_PRINTF("DEC\tESP\n");
3918    }
3919    else {
3920        DECODE_PRINTF("DEC\tSP\n");
3921    }
3922    TRACE_AND_STEP();
3923    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3924        M.x86.R_ESP = dec_long(M.x86.R_ESP);
3925    }
3926    else {
3927        M.x86.R_SP = dec_word(M.x86.R_SP);
3928    }
3929    DECODE_CLEAR_SEGOVR();
3930    END_OF_INSTR();
3931}
3932
3933/****************************************************************************
3934REMARKS:
3935Handles opcode 0x4d
3936****************************************************************************/
3937static void
3938x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3939{
3940    START_OF_INSTR();
3941    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3942        DECODE_PRINTF("DEC\tEBP\n");
3943    }
3944    else {
3945        DECODE_PRINTF("DEC\tBP\n");
3946    }
3947    TRACE_AND_STEP();
3948    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3949        M.x86.R_EBP = dec_long(M.x86.R_EBP);
3950    }
3951    else {
3952        M.x86.R_BP = dec_word(M.x86.R_BP);
3953    }
3954    DECODE_CLEAR_SEGOVR();
3955    END_OF_INSTR();
3956}
3957
3958/****************************************************************************
3959REMARKS:
3960Handles opcode 0x4e
3961****************************************************************************/
3962static void
3963x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3964{
3965    START_OF_INSTR();
3966    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967        DECODE_PRINTF("DEC\tESI\n");
3968    }
3969    else {
3970        DECODE_PRINTF("DEC\tSI\n");
3971    }
3972    TRACE_AND_STEP();
3973    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974        M.x86.R_ESI = dec_long(M.x86.R_ESI);
3975    }
3976    else {
3977        M.x86.R_SI = dec_word(M.x86.R_SI);
3978    }
3979    DECODE_CLEAR_SEGOVR();
3980    END_OF_INSTR();
3981}
3982
3983/****************************************************************************
3984REMARKS:
3985Handles opcode 0x4f
3986****************************************************************************/
3987static void
3988x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3989{
3990    START_OF_INSTR();
3991    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992        DECODE_PRINTF("DEC\tEDI\n");
3993    }
3994    else {
3995        DECODE_PRINTF("DEC\tDI\n");
3996    }
3997    TRACE_AND_STEP();
3998    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3999        M.x86.R_EDI = dec_long(M.x86.R_EDI);
4000    }
4001    else {
4002        M.x86.R_DI = dec_word(M.x86.R_DI);
4003    }
4004    DECODE_CLEAR_SEGOVR();
4005    END_OF_INSTR();
4006}
4007
4008/****************************************************************************
4009REMARKS:
4010Handles opcode 0x50
4011****************************************************************************/
4012static void
4013x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4014{
4015    START_OF_INSTR();
4016    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4017        DECODE_PRINTF("PUSH\tEAX\n");
4018    }
4019    else {
4020        DECODE_PRINTF("PUSH\tAX\n");
4021    }
4022    TRACE_AND_STEP();
4023    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024        push_long(M.x86.R_EAX);
4025    }
4026    else {
4027        push_word(M.x86.R_AX);
4028    }
4029    DECODE_CLEAR_SEGOVR();
4030    END_OF_INSTR();
4031}
4032
4033/****************************************************************************
4034REMARKS:
4035Handles opcode 0x51
4036****************************************************************************/
4037static void
4038x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4039{
4040    START_OF_INSTR();
4041    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042        DECODE_PRINTF("PUSH\tECX\n");
4043    }
4044    else {
4045        DECODE_PRINTF("PUSH\tCX\n");
4046    }
4047    TRACE_AND_STEP();
4048    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049        push_long(M.x86.R_ECX);
4050    }
4051    else {
4052        push_word(M.x86.R_CX);
4053    }
4054    DECODE_CLEAR_SEGOVR();
4055    END_OF_INSTR();
4056}
4057
4058/****************************************************************************
4059REMARKS:
4060Handles opcode 0x52
4061****************************************************************************/
4062static void
4063x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4064{
4065    START_OF_INSTR();
4066    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4067        DECODE_PRINTF("PUSH\tEDX\n");
4068    }
4069    else {
4070        DECODE_PRINTF("PUSH\tDX\n");
4071    }
4072    TRACE_AND_STEP();
4073    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4074        push_long(M.x86.R_EDX);
4075    }
4076    else {
4077        push_word(M.x86.R_DX);
4078    }
4079    DECODE_CLEAR_SEGOVR();
4080    END_OF_INSTR();
4081}
4082
4083/****************************************************************************
4084REMARKS:
4085Handles opcode 0x53
4086****************************************************************************/
4087static void
4088x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4089{
4090    START_OF_INSTR();
4091    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092        DECODE_PRINTF("PUSH\tEBX\n");
4093    }
4094    else {
4095        DECODE_PRINTF("PUSH\tBX\n");
4096    }
4097    TRACE_AND_STEP();
4098    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099        push_long(M.x86.R_EBX);
4100    }
4101    else {
4102        push_word(M.x86.R_BX);
4103    }
4104    DECODE_CLEAR_SEGOVR();
4105    END_OF_INSTR();
4106}
4107
4108/****************************************************************************
4109REMARKS:
4110Handles opcode 0x54
4111****************************************************************************/
4112static void
4113x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4114{
4115    START_OF_INSTR();
4116    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4117        DECODE_PRINTF("PUSH\tESP\n");
4118    }
4119    else {
4120        DECODE_PRINTF("PUSH\tSP\n");
4121    }
4122    TRACE_AND_STEP();
4123    /* Always push (E)SP, since we are emulating an i386 and above
4124     * processor. This is necessary as some BIOS'es use this to check
4125     * what type of processor is in the system.
4126     */
4127    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128        push_long(M.x86.R_ESP);
4129    }
4130    else {
4131        push_word((u16) (M.x86.R_SP));
4132    }
4133    DECODE_CLEAR_SEGOVR();
4134    END_OF_INSTR();
4135}
4136
4137/****************************************************************************
4138REMARKS:
4139Handles opcode 0x55
4140****************************************************************************/
4141static void
4142x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4143{
4144    START_OF_INSTR();
4145    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146        DECODE_PRINTF("PUSH\tEBP\n");
4147    }
4148    else {
4149        DECODE_PRINTF("PUSH\tBP\n");
4150    }
4151    TRACE_AND_STEP();
4152    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4153        push_long(M.x86.R_EBP);
4154    }
4155    else {
4156        push_word(M.x86.R_BP);
4157    }
4158    DECODE_CLEAR_SEGOVR();
4159    END_OF_INSTR();
4160}
4161
4162/****************************************************************************
4163REMARKS:
4164Handles opcode 0x56
4165****************************************************************************/
4166static void
4167x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4168{
4169    START_OF_INSTR();
4170    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4171        DECODE_PRINTF("PUSH\tESI\n");
4172    }
4173    else {
4174        DECODE_PRINTF("PUSH\tSI\n");
4175    }
4176    TRACE_AND_STEP();
4177    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178        push_long(M.x86.R_ESI);
4179    }
4180    else {
4181        push_word(M.x86.R_SI);
4182    }
4183    DECODE_CLEAR_SEGOVR();
4184    END_OF_INSTR();
4185}
4186
4187/****************************************************************************
4188REMARKS:
4189Handles opcode 0x57
4190****************************************************************************/
4191static void
4192x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4193{
4194    START_OF_INSTR();
4195    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196        DECODE_PRINTF("PUSH\tEDI\n");
4197    }
4198    else {
4199        DECODE_PRINTF("PUSH\tDI\n");
4200    }
4201    TRACE_AND_STEP();
4202    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4203        push_long(M.x86.R_EDI);
4204    }
4205    else {
4206        push_word(M.x86.R_DI);
4207    }
4208    DECODE_CLEAR_SEGOVR();
4209    END_OF_INSTR();
4210}
4211
4212/****************************************************************************
4213REMARKS:
4214Handles opcode 0x58
4215****************************************************************************/
4216static void
4217x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4218{
4219    START_OF_INSTR();
4220    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221        DECODE_PRINTF("POP\tEAX\n");
4222    }
4223    else {
4224        DECODE_PRINTF("POP\tAX\n");
4225    }
4226    TRACE_AND_STEP();
4227    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4228        M.x86.R_EAX = pop_long();
4229    }
4230    else {
4231        M.x86.R_AX = pop_word();
4232    }
4233    DECODE_CLEAR_SEGOVR();
4234    END_OF_INSTR();
4235}
4236
4237/****************************************************************************
4238REMARKS:
4239Handles opcode 0x59
4240****************************************************************************/
4241static void
4242x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4243{
4244    START_OF_INSTR();
4245    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4246        DECODE_PRINTF("POP\tECX\n");
4247    }
4248    else {
4249        DECODE_PRINTF("POP\tCX\n");
4250    }
4251    TRACE_AND_STEP();
4252    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4253        M.x86.R_ECX = pop_long();
4254    }
4255    else {
4256        M.x86.R_CX = pop_word();
4257    }
4258    DECODE_CLEAR_SEGOVR();
4259    END_OF_INSTR();
4260}
4261
4262/****************************************************************************
4263REMARKS:
4264Handles opcode 0x5a
4265****************************************************************************/
4266static void
4267x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4268{
4269    START_OF_INSTR();
4270    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4271        DECODE_PRINTF("POP\tEDX\n");
4272    }
4273    else {
4274        DECODE_PRINTF("POP\tDX\n");
4275    }
4276    TRACE_AND_STEP();
4277    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4278        M.x86.R_EDX = pop_long();
4279    }
4280    else {
4281        M.x86.R_DX = pop_word();
4282    }
4283    DECODE_CLEAR_SEGOVR();
4284    END_OF_INSTR();
4285}
4286
4287/****************************************************************************
4288REMARKS:
4289Handles opcode 0x5b
4290****************************************************************************/
4291static void
4292x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4293{
4294    START_OF_INSTR();
4295    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4296        DECODE_PRINTF("POP\tEBX\n");
4297    }
4298    else {
4299        DECODE_PRINTF("POP\tBX\n");
4300    }
4301    TRACE_AND_STEP();
4302    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4303        M.x86.R_EBX = pop_long();
4304    }
4305    else {
4306        M.x86.R_BX = pop_word();
4307    }
4308    DECODE_CLEAR_SEGOVR();
4309    END_OF_INSTR();
4310}
4311
4312/****************************************************************************
4313REMARKS:
4314Handles opcode 0x5c
4315****************************************************************************/
4316static void
4317x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4318{
4319    START_OF_INSTR();
4320    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4321        DECODE_PRINTF("POP\tESP\n");
4322    }
4323    else {
4324        DECODE_PRINTF("POP\tSP\n");
4325    }
4326    TRACE_AND_STEP();
4327    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4328        M.x86.R_ESP = pop_long();
4329    }
4330    else {
4331        M.x86.R_SP = pop_word();
4332    }
4333    DECODE_CLEAR_SEGOVR();
4334    END_OF_INSTR();
4335}
4336
4337/****************************************************************************
4338REMARKS:
4339Handles opcode 0x5d
4340****************************************************************************/
4341static void
4342x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4343{
4344    START_OF_INSTR();
4345    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4346        DECODE_PRINTF("POP\tEBP\n");
4347    }
4348    else {
4349        DECODE_PRINTF("POP\tBP\n");
4350    }
4351    TRACE_AND_STEP();
4352    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353        M.x86.R_EBP = pop_long();
4354    }
4355    else {
4356        M.x86.R_BP = pop_word();
4357    }
4358    DECODE_CLEAR_SEGOVR();
4359    END_OF_INSTR();
4360}
4361
4362/****************************************************************************
4363REMARKS:
4364Handles opcode 0x5e
4365****************************************************************************/
4366static void
4367x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4368{
4369    START_OF_INSTR();
4370    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4371        DECODE_PRINTF("POP\tESI\n");
4372    }
4373    else {
4374        DECODE_PRINTF("POP\tSI\n");
4375    }
4376    TRACE_AND_STEP();
4377    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4378        M.x86.R_ESI = pop_long();
4379    }
4380    else {
4381        M.x86.R_SI = pop_word();
4382    }
4383    DECODE_CLEAR_SEGOVR();
4384    END_OF_INSTR();
4385}
4386
4387/****************************************************************************
4388REMARKS:
4389Handles opcode 0x5f
4390****************************************************************************/
4391static void
4392x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4393{
4394    START_OF_INSTR();
4395    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4396        DECODE_PRINTF("POP\tEDI\n");
4397    }
4398    else {
4399        DECODE_PRINTF("POP\tDI\n");
4400    }
4401    TRACE_AND_STEP();
4402    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4403        M.x86.R_EDI = pop_long();
4404    }
4405    else {
4406        M.x86.R_DI = pop_word();
4407    }
4408    DECODE_CLEAR_SEGOVR();
4409    END_OF_INSTR();
4410}
4411
4412/****************************************************************************
4413REMARKS:
4414Handles opcode 0x60
4415****************************************************************************/
4416static void
4417x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4418{
4419    START_OF_INSTR();
4420    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4421        DECODE_PRINTF("PUSHAD\n");
4422    }
4423    else {
4424        DECODE_PRINTF("PUSHA\n");
4425    }
4426    TRACE_AND_STEP();
4427    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4428        u32 old_sp = M.x86.R_ESP;
4429
4430        push_long(M.x86.R_EAX);
4431        push_long(M.x86.R_ECX);
4432        push_long(M.x86.R_EDX);
4433        push_long(M.x86.R_EBX);
4434        push_long(old_sp);
4435        push_long(M.x86.R_EBP);
4436        push_long(M.x86.R_ESI);
4437        push_long(M.x86.R_EDI);
4438    }
4439    else {
4440        u16 old_sp = M.x86.R_SP;
4441
4442        push_word(M.x86.R_AX);
4443        push_word(M.x86.R_CX);
4444        push_word(M.x86.R_DX);
4445        push_word(M.x86.R_BX);
4446        push_word(old_sp);
4447        push_word(M.x86.R_BP);
4448        push_word(M.x86.R_SI);
4449        push_word(M.x86.R_DI);
4450    }
4451    DECODE_CLEAR_SEGOVR();
4452    END_OF_INSTR();
4453}
4454
4455/****************************************************************************
4456REMARKS:
4457Handles opcode 0x61
4458****************************************************************************/
4459static void
4460x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4461{
4462    START_OF_INSTR();
4463    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4464        DECODE_PRINTF("POPAD\n");
4465    }
4466    else {
4467        DECODE_PRINTF("POPA\n");
4468    }
4469    TRACE_AND_STEP();
4470    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4471        M.x86.R_EDI = pop_long();
4472        M.x86.R_ESI = pop_long();
4473        M.x86.R_EBP = pop_long();
4474        M.x86.R_ESP += 4;       /* skip ESP */
4475        M.x86.R_EBX = pop_long();
4476        M.x86.R_EDX = pop_long();
4477        M.x86.R_ECX = pop_long();
4478        M.x86.R_EAX = pop_long();
4479    }
4480    else {
4481        M.x86.R_DI = pop_word();
4482        M.x86.R_SI = pop_word();
4483        M.x86.R_BP = pop_word();
4484        M.x86.R_SP += 2;        /* skip SP */
4485        M.x86.R_BX = pop_word();
4486        M.x86.R_DX = pop_word();
4487        M.x86.R_CX = pop_word();
4488        M.x86.R_AX = pop_word();
4489    }
4490    DECODE_CLEAR_SEGOVR();
4491    END_OF_INSTR();
4492}
4493
4494/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4495/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4496
4497/****************************************************************************
4498REMARKS:
4499Handles opcode 0x64
4500****************************************************************************/
4501static void
4502x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4503{
4504    START_OF_INSTR();
4505    DECODE_PRINTF("FS:\n");
4506    TRACE_AND_STEP();
4507    M.x86.mode |= SYSMODE_SEGOVR_FS;
4508    /*
4509     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4510     * opcode subroutines we do not want to do this.
4511     */
4512    END_OF_INSTR();
4513}
4514
4515/****************************************************************************
4516REMARKS:
4517Handles opcode 0x65
4518****************************************************************************/
4519static void
4520x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4521{
4522    START_OF_INSTR();
4523    DECODE_PRINTF("GS:\n");
4524    TRACE_AND_STEP();
4525    M.x86.mode |= SYSMODE_SEGOVR_GS;
4526    /*
4527     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4528     * opcode subroutines we do not want to do this.
4529     */
4530    END_OF_INSTR();
4531}
4532
4533/****************************************************************************
4534REMARKS:
4535Handles opcode 0x66 - prefix for 32-bit register
4536****************************************************************************/
4537static void
4538x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4539{
4540    START_OF_INSTR();
4541    DECODE_PRINTF("DATA:\n");
4542    TRACE_AND_STEP();
4543    M.x86.mode |= SYSMODE_PREFIX_DATA;
4544    /* note no DECODE_CLEAR_SEGOVR here. */
4545    END_OF_INSTR();
4546}
4547
4548/****************************************************************************
4549REMARKS:
4550Handles opcode 0x67 - prefix for 32-bit address
4551****************************************************************************/
4552static void
4553x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4554{
4555    START_OF_INSTR();
4556    DECODE_PRINTF("ADDR:\n");
4557    TRACE_AND_STEP();
4558    M.x86.mode |= SYSMODE_PREFIX_ADDR;
4559    /* note no DECODE_CLEAR_SEGOVR here. */
4560    END_OF_INSTR();
4561}
4562
4563/****************************************************************************
4564REMARKS:
4565Handles opcode 0x68
4566****************************************************************************/
4567static void
4568x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4569{
4570    u32 imm;
4571
4572    START_OF_INSTR();
4573    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4574        imm = fetch_long_imm();
4575    }
4576    else {
4577        imm = fetch_word_imm();
4578    }
4579    DECODE_PRINTF2("PUSH\t%x\n", imm);
4580    TRACE_AND_STEP();
4581    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4582        push_long(imm);
4583    }
4584    else {
4585        push_word((u16) imm);
4586    }
4587    DECODE_CLEAR_SEGOVR();
4588    END_OF_INSTR();
4589}
4590
4591/****************************************************************************
4592REMARKS:
4593Handles opcode 0x69
4594****************************************************************************/
4595static void
4596x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4597{
4598    int mod, rl, rh;
4599    uint srcoffset;
4600
4601    START_OF_INSTR();
4602    DECODE_PRINTF("IMUL\t");
4603    FETCH_DECODE_MODRM(mod, rh, rl);
4604    switch (mod) {
4605    case 0:
4606        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4607            u32 *destreg;
4608            u32 srcval;
4609            u32 res_lo, res_hi;
4610            s32 imm;
4611
4612            destreg = DECODE_RM_LONG_REGISTER(rh);
4613            DECODE_PRINTF(",");
4614            srcoffset = decode_rm00_address(rl);
4615            srcval = fetch_data_long(srcoffset);
4616            imm = fetch_long_imm();
4617            DECODE_PRINTF2(",%d\n", (s32) imm);
4618            TRACE_AND_STEP();
4619            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4620            if (res_hi != 0) {
4621                SET_FLAG(F_CF);
4622                SET_FLAG(F_OF);
4623            }
4624            else {
4625                CLEAR_FLAG(F_CF);
4626                CLEAR_FLAG(F_OF);
4627            }
4628            *destreg = (u32) res_lo;
4629        }
4630        else {
4631            u16 *destreg;
4632            u16 srcval;
4633            u32 res;
4634            s16 imm;
4635
4636            destreg = DECODE_RM_WORD_REGISTER(rh);
4637            DECODE_PRINTF(",");
4638            srcoffset = decode_rm00_address(rl);
4639            srcval = fetch_data_word(srcoffset);
4640            imm = fetch_word_imm();
4641            DECODE_PRINTF2(",%d\n", (s32) imm);
4642            TRACE_AND_STEP();
4643            res = (s16) srcval *(s16) imm;
4644
4645            if (res > 0xFFFF) {
4646                SET_FLAG(F_CF);
4647                SET_FLAG(F_OF);
4648            }
4649            else {
4650                CLEAR_FLAG(F_CF);
4651                CLEAR_FLAG(F_OF);
4652            }
4653            *destreg = (u16) res;
4654        }
4655        break;
4656    case 1:
4657        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4658            u32 *destreg;
4659            u32 srcval;
4660            u32 res_lo, res_hi;
4661            s32 imm;
4662
4663            destreg = DECODE_RM_LONG_REGISTER(rh);
4664            DECODE_PRINTF(",");
4665            srcoffset = decode_rm01_address(rl);
4666            srcval = fetch_data_long(srcoffset);
4667            imm = fetch_long_imm();
4668            DECODE_PRINTF2(",%d\n", (s32) imm);
4669            TRACE_AND_STEP();
4670            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4671            if (res_hi != 0) {
4672                SET_FLAG(F_CF);
4673                SET_FLAG(F_OF);
4674            }
4675            else {
4676                CLEAR_FLAG(F_CF);
4677                CLEAR_FLAG(F_OF);
4678            }
4679            *destreg = (u32) res_lo;
4680        }
4681        else {
4682            u16 *destreg;
4683            u16 srcval;
4684            u32 res;
4685            s16 imm;
4686
4687            destreg = DECODE_RM_WORD_REGISTER(rh);
4688            DECODE_PRINTF(",");
4689            srcoffset = decode_rm01_address(rl);
4690            srcval = fetch_data_word(srcoffset);
4691            imm = fetch_word_imm();
4692            DECODE_PRINTF2(",%d\n", (s32) imm);
4693            TRACE_AND_STEP();
4694            res = (s16) srcval *(s16) imm;
4695
4696            if (res > 0xFFFF) {
4697                SET_FLAG(F_CF);
4698                SET_FLAG(F_OF);
4699            }
4700            else {
4701                CLEAR_FLAG(F_CF);
4702                CLEAR_FLAG(F_OF);
4703            }
4704            *destreg = (u16) res;
4705        }
4706        break;
4707    case 2:
4708        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4709            u32 *destreg;
4710            u32 srcval;
4711            u32 res_lo, res_hi;
4712            s32 imm;
4713
4714            destreg = DECODE_RM_LONG_REGISTER(rh);
4715            DECODE_PRINTF(",");
4716            srcoffset = decode_rm10_address(rl);
4717            srcval = fetch_data_long(srcoffset);
4718            imm = fetch_long_imm();
4719            DECODE_PRINTF2(",%d\n", (s32) imm);
4720            TRACE_AND_STEP();
4721            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4722            if (res_hi != 0) {
4723                SET_FLAG(F_CF);
4724                SET_FLAG(F_OF);
4725            }
4726            else {
4727                CLEAR_FLAG(F_CF);
4728                CLEAR_FLAG(F_OF);
4729            }
4730            *destreg = (u32) res_lo;
4731        }
4732        else {
4733            u16 *destreg;
4734            u16 srcval;
4735            u32 res;
4736            s16 imm;
4737
4738            destreg = DECODE_RM_WORD_REGISTER(rh);
4739            DECODE_PRINTF(",");
4740            srcoffset = decode_rm10_address(rl);
4741            srcval = fetch_data_word(srcoffset);
4742            imm = fetch_word_imm();
4743            DECODE_PRINTF2(",%d\n", (s32) imm);
4744            TRACE_AND_STEP();
4745            res = (s16) srcval *(s16) imm;
4746
4747            if (res > 0xFFFF) {
4748                SET_FLAG(F_CF);
4749                SET_FLAG(F_OF);
4750            }
4751            else {
4752                CLEAR_FLAG(F_CF);
4753                CLEAR_FLAG(F_OF);
4754            }
4755            *destreg = (u16) res;
4756        }
4757        break;
4758    case 3:                    /* register to register */
4759        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760            u32 *destreg, *srcreg;
4761            u32 res_lo, res_hi;
4762            s32 imm;
4763
4764            destreg = DECODE_RM_LONG_REGISTER(rh);
4765            DECODE_PRINTF(",");
4766            srcreg = DECODE_RM_LONG_REGISTER(rl);
4767            imm = fetch_long_imm();
4768            DECODE_PRINTF2(",%d\n", (s32) imm);
4769            TRACE_AND_STEP();
4770            imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
4771            if (res_hi != 0) {
4772                SET_FLAG(F_CF);
4773                SET_FLAG(F_OF);
4774            }
4775            else {
4776                CLEAR_FLAG(F_CF);
4777                CLEAR_FLAG(F_OF);
4778            }
4779            *destreg = (u32) res_lo;
4780        }
4781        else {
4782            u16 *destreg, *srcreg;
4783            u32 res;
4784            s16 imm;
4785
4786            destreg = DECODE_RM_WORD_REGISTER(rh);
4787            DECODE_PRINTF(",");
4788            srcreg = DECODE_RM_WORD_REGISTER(rl);
4789            imm = fetch_word_imm();
4790            DECODE_PRINTF2(",%d\n", (s32) imm);
4791            res = (s16) * srcreg * (s16) imm;
4792            if (res > 0xFFFF) {
4793                SET_FLAG(F_CF);
4794                SET_FLAG(F_OF);
4795            }
4796            else {
4797                CLEAR_FLAG(F_CF);
4798                CLEAR_FLAG(F_OF);
4799            }
4800            *destreg = (u16) res;
4801        }
4802        break;
4803    }
4804    DECODE_CLEAR_SEGOVR();
4805    END_OF_INSTR();
4806}
4807
4808/****************************************************************************
4809REMARKS:
4810Handles opcode 0x6a
4811****************************************************************************/
4812static void
4813x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4814{
4815    s16 imm;
4816
4817    START_OF_INSTR();
4818    imm = (s8) fetch_byte_imm();
4819    DECODE_PRINTF2("PUSH\t%d\n", imm);
4820    TRACE_AND_STEP();
4821    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822        push_long((s32) imm);
4823    }
4824    else {
4825        push_word(imm);
4826    }
4827    DECODE_CLEAR_SEGOVR();
4828    END_OF_INSTR();
4829}
4830
4831/****************************************************************************
4832REMARKS:
4833Handles opcode 0x6b
4834****************************************************************************/
4835static void
4836x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4837{
4838    int mod, rl, rh;
4839    uint srcoffset;
4840    s8 imm;
4841
4842    START_OF_INSTR();
4843    DECODE_PRINTF("IMUL\t");
4844    FETCH_DECODE_MODRM(mod, rh, rl);
4845    switch (mod) {
4846    case 0:
4847        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4848            u32 *destreg;
4849            u32 srcval;
4850            u32 res_lo, res_hi;
4851
4852            destreg = DECODE_RM_LONG_REGISTER(rh);
4853            DECODE_PRINTF(",");
4854            srcoffset = decode_rm00_address(rl);
4855            srcval = fetch_data_long(srcoffset);
4856            imm = fetch_byte_imm();
4857            DECODE_PRINTF2(",%d\n", (s32) imm);
4858            TRACE_AND_STEP();
4859            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4860            if (res_hi != 0) {
4861                SET_FLAG(F_CF);
4862                SET_FLAG(F_OF);
4863            }
4864            else {
4865                CLEAR_FLAG(F_CF);
4866                CLEAR_FLAG(F_OF);
4867            }
4868            *destreg = (u32) res_lo;
4869        }
4870        else {
4871            u16 *destreg;
4872            u16 srcval;
4873            u32 res;
4874
4875            destreg = DECODE_RM_WORD_REGISTER(rh);
4876            DECODE_PRINTF(",");
4877            srcoffset = decode_rm00_address(rl);
4878            srcval = fetch_data_word(srcoffset);
4879            imm = fetch_byte_imm();
4880            DECODE_PRINTF2(",%d\n", (s32) imm);
4881            TRACE_AND_STEP();
4882            res = (s16) srcval *(s16) imm;
4883
4884            if (res > 0xFFFF) {
4885                SET_FLAG(F_CF);
4886                SET_FLAG(F_OF);
4887            }
4888            else {
4889                CLEAR_FLAG(F_CF);
4890                CLEAR_FLAG(F_OF);
4891            }
4892            *destreg = (u16) res;
4893        }
4894        break;
4895    case 1:
4896        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4897            u32 *destreg;
4898            u32 srcval;
4899            u32 res_lo, res_hi;
4900
4901            destreg = DECODE_RM_LONG_REGISTER(rh);
4902            DECODE_PRINTF(",");
4903            srcoffset = decode_rm01_address(rl);
4904            srcval = fetch_data_long(srcoffset);
4905            imm = fetch_byte_imm();
4906            DECODE_PRINTF2(",%d\n", (s32) imm);
4907            TRACE_AND_STEP();
4908            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4909            if (res_hi != 0) {
4910                SET_FLAG(F_CF);
4911                SET_FLAG(F_OF);
4912            }
4913            else {
4914                CLEAR_FLAG(F_CF);
4915                CLEAR_FLAG(F_OF);
4916            }
4917            *destreg = (u32) res_lo;
4918        }
4919        else {
4920            u16 *destreg;
4921            u16 srcval;
4922            u32 res;
4923
4924            destreg = DECODE_RM_WORD_REGISTER(rh);
4925            DECODE_PRINTF(",");
4926            srcoffset = decode_rm01_address(rl);
4927            srcval = fetch_data_word(srcoffset);
4928            imm = fetch_byte_imm();
4929            DECODE_PRINTF2(",%d\n", (s32) imm);
4930            TRACE_AND_STEP();
4931            res = (s16) srcval *(s16) imm;
4932
4933            if (res > 0xFFFF) {
4934                SET_FLAG(F_CF);
4935                SET_FLAG(F_OF);
4936            }
4937            else {
4938                CLEAR_FLAG(F_CF);
4939                CLEAR_FLAG(F_OF);
4940            }
4941            *destreg = (u16) res;
4942        }
4943        break;
4944    case 2:
4945        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4946            u32 *destreg;
4947            u32 srcval;
4948            u32 res_lo, res_hi;
4949
4950            destreg = DECODE_RM_LONG_REGISTER(rh);
4951            DECODE_PRINTF(",");
4952            srcoffset = decode_rm10_address(rl);
4953            srcval = fetch_data_long(srcoffset);
4954            imm = fetch_byte_imm();
4955            DECODE_PRINTF2(",%d\n", (s32) imm);
4956            TRACE_AND_STEP();
4957            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4958            if (res_hi != 0) {
4959                SET_FLAG(F_CF);
4960                SET_FLAG(F_OF);
4961            }
4962            else {
4963                CLEAR_FLAG(F_CF);
4964                CLEAR_FLAG(F_OF);
4965            }
4966            *destreg = (u32) res_lo;
4967        }
4968        else {
4969            u16 *destreg;
4970            u16 srcval;
4971            u32 res;
4972
4973            destreg = DECODE_RM_WORD_REGISTER(rh);
4974            DECODE_PRINTF(",");
4975            srcoffset = decode_rm10_address(rl);
4976            srcval = fetch_data_word(srcoffset);
4977            imm = fetch_byte_imm();
4978            DECODE_PRINTF2(",%d\n", (s32) imm);
4979            TRACE_AND_STEP();
4980            res = (s16) srcval *(s16) imm;
4981
4982            if (res > 0xFFFF) {
4983                SET_FLAG(F_CF);
4984                SET_FLAG(F_OF);
4985            }
4986            else {
4987                CLEAR_FLAG(F_CF);
4988                CLEAR_FLAG(F_OF);
4989            }
4990            *destreg = (u16) res;
4991        }
4992        break;
4993    case 3:                    /* register to register */
4994        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4995            u32 *destreg, *srcreg;
4996            u32 res_lo, res_hi;
4997
4998            destreg = DECODE_RM_LONG_REGISTER(rh);
4999            DECODE_PRINTF(",");
5000            srcreg = DECODE_RM_LONG_REGISTER(rl);
5001            imm = fetch_byte_imm();
5002            DECODE_PRINTF2(",%d\n", (s32) imm);
5003            TRACE_AND_STEP();
5004            imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
5005            if (res_hi != 0) {
5006                SET_FLAG(F_CF);
5007                SET_FLAG(F_OF);
5008            }
5009            else {
5010                CLEAR_FLAG(F_CF);
5011                CLEAR_FLAG(F_OF);
5012            }
5013            *destreg = (u32) res_lo;
5014        }
5015        else {
5016            u16 *destreg, *srcreg;
5017            u32 res;
5018
5019            destreg = DECODE_RM_WORD_REGISTER(rh);
5020            DECODE_PRINTF(",");
5021            srcreg = DECODE_RM_WORD_REGISTER(rl);
5022            imm = fetch_byte_imm();
5023            DECODE_PRINTF2(",%d\n", (s32) imm);
5024            res = (s16) * srcreg * (s16) imm;
5025            if (res > 0xFFFF) {
5026                SET_FLAG(F_CF);
5027                SET_FLAG(F_OF);
5028            }
5029            else {
5030                CLEAR_FLAG(F_CF);
5031                CLEAR_FLAG(F_OF);
5032            }
5033            *destreg = (u16) res;
5034        }
5035        break;
5036    }
5037    DECODE_CLEAR_SEGOVR();
5038    END_OF_INSTR();
5039}
5040
5041/****************************************************************************
5042REMARKS:
5043Handles opcode 0x6c
5044****************************************************************************/
5045static void
5046x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5047{
5048    START_OF_INSTR();
5049    DECODE_PRINTF("INSB\n");
5050    ins(1);
5051    TRACE_AND_STEP();
5052    DECODE_CLEAR_SEGOVR();
5053    END_OF_INSTR();
5054}
5055
5056/****************************************************************************
5057REMARKS:
5058Handles opcode 0x6d
5059****************************************************************************/
5060static void
5061x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5062{
5063    START_OF_INSTR();
5064    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5065        DECODE_PRINTF("INSD\n");
5066        ins(4);
5067    }
5068    else {
5069        DECODE_PRINTF("INSW\n");
5070        ins(2);
5071    }
5072    TRACE_AND_STEP();
5073    DECODE_CLEAR_SEGOVR();
5074    END_OF_INSTR();
5075}
5076
5077/****************************************************************************
5078REMARKS:
5079Handles opcode 0x6e
5080****************************************************************************/
5081static void
5082x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5083{
5084    START_OF_INSTR();
5085    DECODE_PRINTF("OUTSB\n");
5086    outs(1);
5087    TRACE_AND_STEP();
5088    DECODE_CLEAR_SEGOVR();
5089    END_OF_INSTR();
5090}
5091
5092/****************************************************************************
5093REMARKS:
5094Handles opcode 0x6f
5095****************************************************************************/
5096static void
5097x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5098{
5099    START_OF_INSTR();
5100    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5101        DECODE_PRINTF("OUTSD\n");
5102        outs(4);
5103    }
5104    else {
5105        DECODE_PRINTF("OUTSW\n");
5106        outs(2);
5107    }
5108    TRACE_AND_STEP();
5109    DECODE_CLEAR_SEGOVR();
5110    END_OF_INSTR();
5111}
5112
5113/****************************************************************************
5114REMARKS:
5115Handles opcode 0x70
5116****************************************************************************/
5117static void
5118x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5119{
5120    s8 offset;
5121    u16 target;
5122
5123    /* jump to byte offset if overflow flag is set */
5124    START_OF_INSTR();
5125    DECODE_PRINTF("JO\t");
5126    offset = (s8) fetch_byte_imm();
5127    target = (u16) (M.x86.R_IP + (s16) offset);
5128    DECODE_PRINTF2("%x\n", target);
5129    TRACE_AND_STEP();
5130    if (ACCESS_FLAG(F_OF))
5131        M.x86.R_IP = target;
5132    DECODE_CLEAR_SEGOVR();
5133    END_OF_INSTR();
5134}
5135
5136/****************************************************************************
5137REMARKS:
5138Handles opcode 0x71
5139****************************************************************************/
5140static void
5141x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5142{
5143    s8 offset;
5144    u16 target;
5145
5146    /* jump to byte offset if overflow is not set */
5147    START_OF_INSTR();
5148    DECODE_PRINTF("JNO\t");
5149    offset = (s8) fetch_byte_imm();
5150    target = (u16) (M.x86.R_IP + (s16) offset);
5151    DECODE_PRINTF2("%x\n", target);
5152    TRACE_AND_STEP();
5153    if (!ACCESS_FLAG(F_OF))
5154        M.x86.R_IP = target;
5155    DECODE_CLEAR_SEGOVR();
5156    END_OF_INSTR();
5157}
5158
5159/****************************************************************************
5160REMARKS:
5161Handles opcode 0x72
5162****************************************************************************/
5163static void
5164x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5165{
5166    s8 offset;
5167    u16 target;
5168
5169    /* jump to byte offset if carry flag is set. */
5170    START_OF_INSTR();
5171    DECODE_PRINTF("JB\t");
5172    offset = (s8) fetch_byte_imm();
5173    target = (u16) (M.x86.R_IP + (s16) offset);
5174    DECODE_PRINTF2("%x\n", target);
5175    TRACE_AND_STEP();
5176    if (ACCESS_FLAG(F_CF))
5177        M.x86.R_IP = target;
5178    DECODE_CLEAR_SEGOVR();
5179    END_OF_INSTR();
5180}
5181
5182/****************************************************************************
5183REMARKS:
5184Handles opcode 0x73
5185****************************************************************************/
5186static void
5187x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5188{
5189    s8 offset;
5190    u16 target;
5191
5192    /* jump to byte offset if carry flag is clear. */
5193    START_OF_INSTR();
5194    DECODE_PRINTF("JNB\t");
5195    offset = (s8) fetch_byte_imm();
5196    target = (u16) (M.x86.R_IP + (s16) offset);
5197    DECODE_PRINTF2("%x\n", target);
5198    TRACE_AND_STEP();
5199    if (!ACCESS_FLAG(F_CF))
5200        M.x86.R_IP = target;
5201    DECODE_CLEAR_SEGOVR();
5202    END_OF_INSTR();
5203}
5204
5205/****************************************************************************
5206REMARKS:
5207Handles opcode 0x74
5208****************************************************************************/
5209static void
5210x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5211{
5212    s8 offset;
5213    u16 target;
5214
5215    /* jump to byte offset if zero flag is set. */
5216    START_OF_INSTR();
5217    DECODE_PRINTF("JZ\t");
5218    offset = (s8) fetch_byte_imm();
5219    target = (u16) (M.x86.R_IP + (s16) offset);
5220    DECODE_PRINTF2("%x\n", target);
5221    TRACE_AND_STEP();
5222    if (ACCESS_FLAG(F_ZF))
5223        M.x86.R_IP = target;
5224    DECODE_CLEAR_SEGOVR();
5225    END_OF_INSTR();
5226}
5227
5228/****************************************************************************
5229REMARKS:
5230Handles opcode 0x75
5231****************************************************************************/
5232static void
5233x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5234{
5235    s8 offset;
5236    u16 target;
5237
5238    /* jump to byte offset if zero flag is clear. */
5239    START_OF_INSTR();
5240    DECODE_PRINTF("JNZ\t");
5241    offset = (s8) fetch_byte_imm();
5242    target = (u16) (M.x86.R_IP + (s16) offset);
5243    DECODE_PRINTF2("%x\n", target);
5244    TRACE_AND_STEP();
5245    if (!ACCESS_FLAG(F_ZF))
5246        M.x86.R_IP = target;
5247    DECODE_CLEAR_SEGOVR();
5248    END_OF_INSTR();
5249}
5250
5251/****************************************************************************
5252REMARKS:
5253Handles opcode 0x76
5254****************************************************************************/
5255static void
5256x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5257{
5258    s8 offset;
5259    u16 target;
5260
5261    /* jump to byte offset if carry flag is set or if the zero
5262       flag is set. */
5263    START_OF_INSTR();
5264    DECODE_PRINTF("JBE\t");
5265    offset = (s8) fetch_byte_imm();
5266    target = (u16) (M.x86.R_IP + (s16) offset);
5267    DECODE_PRINTF2("%x\n", target);
5268    TRACE_AND_STEP();
5269    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5270        M.x86.R_IP = target;
5271    DECODE_CLEAR_SEGOVR();
5272    END_OF_INSTR();
5273}
5274
5275/****************************************************************************
5276REMARKS:
5277Handles opcode 0x77
5278****************************************************************************/
5279static void
5280x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5281{
5282    s8 offset;
5283    u16 target;
5284
5285    /* jump to byte offset if carry flag is clear and if the zero
5286       flag is clear */
5287    START_OF_INSTR();
5288    DECODE_PRINTF("JNBE\t");
5289    offset = (s8) fetch_byte_imm();
5290    target = (u16) (M.x86.R_IP + (s16) offset);
5291    DECODE_PRINTF2("%x\n", target);
5292    TRACE_AND_STEP();
5293    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5294        M.x86.R_IP = target;
5295    DECODE_CLEAR_SEGOVR();
5296    END_OF_INSTR();
5297}
5298
5299/****************************************************************************
5300REMARKS:
5301Handles opcode 0x78
5302****************************************************************************/
5303static void
5304x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5305{
5306    s8 offset;
5307    u16 target;
5308
5309    /* jump to byte offset if sign flag is set */
5310    START_OF_INSTR();
5311    DECODE_PRINTF("JS\t");
5312    offset = (s8) fetch_byte_imm();
5313    target = (u16) (M.x86.R_IP + (s16) offset);
5314    DECODE_PRINTF2("%x\n", target);
5315    TRACE_AND_STEP();
5316    if (ACCESS_FLAG(F_SF))
5317        M.x86.R_IP = target;
5318    DECODE_CLEAR_SEGOVR();
5319    END_OF_INSTR();
5320}
5321
5322/****************************************************************************
5323REMARKS:
5324Handles opcode 0x79
5325****************************************************************************/
5326static void
5327x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5328{
5329    s8 offset;
5330    u16 target;
5331
5332    /* jump to byte offset if sign flag is clear */
5333    START_OF_INSTR();
5334    DECODE_PRINTF("JNS\t");
5335    offset = (s8) fetch_byte_imm();
5336    target = (u16) (M.x86.R_IP + (s16) offset);
5337    DECODE_PRINTF2("%x\n", target);
5338    TRACE_AND_STEP();
5339    if (!ACCESS_FLAG(F_SF))
5340        M.x86.R_IP = target;
5341    DECODE_CLEAR_SEGOVR();
5342    END_OF_INSTR();
5343}
5344
5345/****************************************************************************
5346REMARKS:
5347Handles opcode 0x7a
5348****************************************************************************/
5349static void
5350x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5351{
5352    s8 offset;
5353    u16 target;
5354
5355    /* jump to byte offset if parity flag is set (even parity) */
5356    START_OF_INSTR();
5357    DECODE_PRINTF("JP\t");
5358    offset = (s8) fetch_byte_imm();
5359    target = (u16) (M.x86.R_IP + (s16) offset);
5360    DECODE_PRINTF2("%x\n", target);
5361    TRACE_AND_STEP();
5362    if (ACCESS_FLAG(F_PF))
5363        M.x86.R_IP = target;
5364    DECODE_CLEAR_SEGOVR();
5365    END_OF_INSTR();
5366}
5367
5368/****************************************************************************
5369REMARKS:
5370Handles opcode 0x7b
5371****************************************************************************/
5372static void
5373x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5374{
5375    s8 offset;
5376    u16 target;
5377
5378    /* jump to byte offset if parity flag is clear (odd parity) */
5379    START_OF_INSTR();
5380    DECODE_PRINTF("JNP\t");
5381    offset = (s8) fetch_byte_imm();
5382    target = (u16) (M.x86.R_IP + (s16) offset);
5383    DECODE_PRINTF2("%x\n", target);
5384    TRACE_AND_STEP();
5385    if (!ACCESS_FLAG(F_PF))
5386        M.x86.R_IP = target;
5387    DECODE_CLEAR_SEGOVR();
5388    END_OF_INSTR();
5389}
5390
5391/****************************************************************************
5392REMARKS:
5393Handles opcode 0x7c
5394****************************************************************************/
5395static void
5396x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5397{
5398    s8 offset;
5399    u16 target;
5400    int sf, of;
5401
5402    /* jump to byte offset if sign flag not equal to overflow flag. */
5403    START_OF_INSTR();
5404    DECODE_PRINTF("JL\t");
5405    offset = (s8) fetch_byte_imm();
5406    target = (u16) (M.x86.R_IP + (s16) offset);
5407    DECODE_PRINTF2("%x\n", target);
5408    TRACE_AND_STEP();
5409    sf = ACCESS_FLAG(F_SF) != 0;
5410    of = ACCESS_FLAG(F_OF) != 0;
5411    if (sf ^ of)
5412        M.x86.R_IP = target;
5413    DECODE_CLEAR_SEGOVR();
5414    END_OF_INSTR();
5415}
5416
5417/****************************************************************************
5418REMARKS:
5419Handles opcode 0x7d
5420****************************************************************************/
5421static void
5422x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5423{
5424    s8 offset;
5425    u16 target;
5426    int sf, of;
5427
5428    /* jump to byte offset if sign flag not equal to overflow flag. */
5429    START_OF_INSTR();
5430    DECODE_PRINTF("JNL\t");
5431    offset = (s8) fetch_byte_imm();
5432    target = (u16) (M.x86.R_IP + (s16) offset);
5433    DECODE_PRINTF2("%x\n", target);
5434    TRACE_AND_STEP();
5435    sf = ACCESS_FLAG(F_SF) != 0;
5436    of = ACCESS_FLAG(F_OF) != 0;
5437    /* note: inverse of above, but using == instead of xor. */
5438    if (sf == of)
5439        M.x86.R_IP = target;
5440    DECODE_CLEAR_SEGOVR();
5441    END_OF_INSTR();
5442}
5443
5444/****************************************************************************
5445REMARKS:
5446Handles opcode 0x7e
5447****************************************************************************/
5448static void
5449x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5450{
5451    s8 offset;
5452    u16 target;
5453    int sf, of;
5454
5455    /* jump to byte offset if sign flag not equal to overflow flag
5456       or the zero flag is set */
5457    START_OF_INSTR();
5458    DECODE_PRINTF("JLE\t");
5459    offset = (s8) fetch_byte_imm();
5460    target = (u16) (M.x86.R_IP + (s16) offset);
5461    DECODE_PRINTF2("%x\n", target);
5462    TRACE_AND_STEP();
5463    sf = ACCESS_FLAG(F_SF) != 0;
5464    of = ACCESS_FLAG(F_OF) != 0;
5465    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5466        M.x86.R_IP = target;
5467    DECODE_CLEAR_SEGOVR();
5468    END_OF_INSTR();
5469}
5470
5471/****************************************************************************
5472REMARKS:
5473Handles opcode 0x7f
5474****************************************************************************/
5475static void
5476x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5477{
5478    s8 offset;
5479    u16 target;
5480    int sf, of;
5481
5482    /* jump to byte offset if sign flag equal to overflow flag.
5483       and the zero flag is clear */
5484    START_OF_INSTR();
5485    DECODE_PRINTF("JNLE\t");
5486    offset = (s8) fetch_byte_imm();
5487    target = (u16) (M.x86.R_IP + (s16) offset);
5488    DECODE_PRINTF2("%x\n", target);
5489    TRACE_AND_STEP();
5490    sf = ACCESS_FLAG(F_SF) != 0;
5491    of = ACCESS_FLAG(F_OF) != 0;
5492    if ((sf == of) && !ACCESS_FLAG(F_ZF))
5493        M.x86.R_IP = target;
5494    DECODE_CLEAR_SEGOVR();
5495    END_OF_INSTR();
5496}
5497
5498static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
5499    add_byte,                   /* 00 */
5500        or_byte,                /* 01 */
5501        adc_byte,               /* 02 */
5502        sbb_byte,               /* 03 */
5503        and_byte,               /* 04 */
5504        sub_byte,               /* 05 */
5505        xor_byte,               /* 06 */
5506        cmp_byte,               /* 07 */
5507};
5508
5509/****************************************************************************
5510REMARKS:
5511Handles opcode 0x80
5512****************************************************************************/
5513static void
5514x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5515{
5516    int mod, rl, rh;
5517    u8 *destreg;
5518    uint destoffset;
5519    u8 imm;
5520    u8 destval;
5521
5522    /*
5523     * Weirdo special case instruction format.  Part of the opcode
5524     * held below in "RH".  Doubly nested case would result, except
5525     * that the decoded instruction
5526     */
5527    START_OF_INSTR();
5528    FETCH_DECODE_MODRM(mod, rh, rl);
5529#ifdef DEBUG
5530    if (DEBUG_DECODE()) {
5531        /* XXX DECODE_PRINTF may be changed to something more
5532           general, so that it is important to leave the strings
5533           in the same format, even though the result is that the
5534           above test is done twice. */
5535
5536        switch (rh) {
5537        case 0:
5538            DECODE_PRINTF("ADD\t");
5539            break;
5540        case 1:
5541            DECODE_PRINTF("OR\t");
5542            break;
5543        case 2:
5544            DECODE_PRINTF("ADC\t");
5545            break;
5546        case 3:
5547            DECODE_PRINTF("SBB\t");
5548            break;
5549        case 4:
5550            DECODE_PRINTF("AND\t");
5551            break;
5552        case 5:
5553            DECODE_PRINTF("SUB\t");
5554            break;
5555        case 6:
5556            DECODE_PRINTF("XOR\t");
5557            break;
5558        case 7:
5559            DECODE_PRINTF("CMP\t");
5560            break;
5561        }
5562    }
5563#endif
5564    /* know operation, decode the mod byte to find the addressing
5565       mode. */
5566    switch (mod) {
5567    case 0:
5568        DECODE_PRINTF("BYTE PTR ");
5569        destoffset = decode_rm00_address(rl);
5570        DECODE_PRINTF(",");
5571        destval = fetch_data_byte(destoffset);
5572        imm = fetch_byte_imm();
5573        DECODE_PRINTF2("%x\n", imm);
5574        TRACE_AND_STEP();
5575        destval = (*opc80_byte_operation[rh]) (destval, imm);
5576        if (rh != 7)
5577            store_data_byte(destoffset, destval);
5578        break;
5579    case 1:
5580        DECODE_PRINTF("BYTE PTR ");
5581        destoffset = decode_rm01_address(rl);
5582        DECODE_PRINTF(",");
5583        destval = fetch_data_byte(destoffset);
5584        imm = fetch_byte_imm();
5585        DECODE_PRINTF2("%x\n", imm);
5586        TRACE_AND_STEP();
5587        destval = (*opc80_byte_operation[rh]) (destval, imm);
5588        if (rh != 7)
5589            store_data_byte(destoffset, destval);
5590        break;
5591    case 2:
5592        DECODE_PRINTF("BYTE PTR ");
5593        destoffset = decode_rm10_address(rl);
5594        DECODE_PRINTF(",");
5595        destval = fetch_data_byte(destoffset);
5596        imm = fetch_byte_imm();
5597        DECODE_PRINTF2("%x\n", imm);
5598        TRACE_AND_STEP();
5599        destval = (*opc80_byte_operation[rh]) (destval, imm);
5600        if (rh != 7)
5601            store_data_byte(destoffset, destval);
5602        break;
5603    case 3:                    /* register to register */
5604        destreg = DECODE_RM_BYTE_REGISTER(rl);
5605        DECODE_PRINTF(",");
5606        imm = fetch_byte_imm();
5607        DECODE_PRINTF2("%x\n", imm);
5608        TRACE_AND_STEP();
5609        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5610        if (rh != 7)
5611            *destreg = destval;
5612        break;
5613    }
5614    DECODE_CLEAR_SEGOVR();
5615    END_OF_INSTR();
5616}
5617
5618static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
5619    add_word,                   /*00 */
5620        or_word,                /*01 */
5621        adc_word,               /*02 */
5622        sbb_word,               /*03 */
5623        and_word,               /*04 */
5624        sub_word,               /*05 */
5625        xor_word,               /*06 */
5626        cmp_word,               /*07 */
5627};
5628
5629static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
5630    add_long,                   /*00 */
5631        or_long,                /*01 */
5632        adc_long,               /*02 */
5633        sbb_long,               /*03 */
5634        and_long,               /*04 */
5635        sub_long,               /*05 */
5636        xor_long,               /*06 */
5637        cmp_long,               /*07 */
5638};
5639
5640/****************************************************************************
5641REMARKS:
5642Handles opcode 0x81
5643****************************************************************************/
5644static void
5645x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5646{
5647    int mod, rl, rh;
5648    uint destoffset;
5649
5650    /*
5651     * Weirdo special case instruction format.  Part of the opcode
5652     * held below in "RH".  Doubly nested case would result, except
5653     * that the decoded instruction
5654     */
5655    START_OF_INSTR();
5656    FETCH_DECODE_MODRM(mod, rh, rl);
5657#ifdef DEBUG
5658    if (DEBUG_DECODE()) {
5659        /* XXX DECODE_PRINTF may be changed to something more
5660           general, so that it is important to leave the strings
5661           in the same format, even though the result is that the
5662           above test is done twice. */
5663
5664        switch (rh) {
5665        case 0:
5666            DECODE_PRINTF("ADD\t");
5667            break;
5668        case 1:
5669            DECODE_PRINTF("OR\t");
5670            break;
5671        case 2:
5672            DECODE_PRINTF("ADC\t");
5673            break;
5674        case 3:
5675            DECODE_PRINTF("SBB\t");
5676            break;
5677        case 4:
5678            DECODE_PRINTF("AND\t");
5679            break;
5680        case 5:
5681            DECODE_PRINTF("SUB\t");
5682            break;
5683        case 6:
5684            DECODE_PRINTF("XOR\t");
5685            break;
5686        case 7:
5687            DECODE_PRINTF("CMP\t");
5688            break;
5689        }
5690    }
5691#endif
5692    /*
5693     * Know operation, decode the mod byte to find the addressing
5694     * mode.
5695     */
5696    switch (mod) {
5697    case 0:
5698        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5699            u32 destval, imm;
5700
5701            DECODE_PRINTF("DWORD PTR ");
5702            destoffset = decode_rm00_address(rl);
5703            DECODE_PRINTF(",");
5704            destval = fetch_data_long(destoffset);
5705            imm = fetch_long_imm();
5706            DECODE_PRINTF2("%x\n", imm);
5707            TRACE_AND_STEP();
5708            destval = (*opc81_long_operation[rh]) (destval, imm);
5709            if (rh != 7)
5710                store_data_long(destoffset, destval);
5711        }
5712        else {
5713            u16 destval, imm;
5714
5715            DECODE_PRINTF("WORD PTR ");
5716            destoffset = decode_rm00_address(rl);
5717            DECODE_PRINTF(",");
5718            destval = fetch_data_word(destoffset);
5719            imm = fetch_word_imm();
5720            DECODE_PRINTF2("%x\n", imm);
5721            TRACE_AND_STEP();
5722            destval = (*opc81_word_operation[rh]) (destval, imm);
5723            if (rh != 7)
5724                store_data_word(destoffset, destval);
5725        }
5726        break;
5727    case 1:
5728        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5729            u32 destval, imm;
5730
5731            DECODE_PRINTF("DWORD PTR ");
5732            destoffset = decode_rm01_address(rl);
5733            DECODE_PRINTF(",");
5734            destval = fetch_data_long(destoffset);
5735            imm = fetch_long_imm();
5736            DECODE_PRINTF2("%x\n", imm);
5737            TRACE_AND_STEP();
5738            destval = (*opc81_long_operation[rh]) (destval, imm);
5739            if (rh != 7)
5740                store_data_long(destoffset, destval);
5741        }
5742        else {
5743            u16 destval, imm;
5744
5745            DECODE_PRINTF("WORD PTR ");
5746            destoffset = decode_rm01_address(rl);
5747            DECODE_PRINTF(",");
5748            destval = fetch_data_word(destoffset);
5749            imm = fetch_word_imm();
5750            DECODE_PRINTF2("%x\n", imm);
5751            TRACE_AND_STEP();
5752            destval = (*opc81_word_operation[rh]) (destval, imm);
5753            if (rh != 7)
5754                store_data_word(destoffset, destval);
5755        }
5756        break;
5757    case 2:
5758        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5759            u32 destval, imm;
5760
5761            DECODE_PRINTF("DWORD PTR ");
5762            destoffset = decode_rm10_address(rl);
5763            DECODE_PRINTF(",");
5764            destval = fetch_data_long(destoffset);
5765            imm = fetch_long_imm();
5766            DECODE_PRINTF2("%x\n", imm);
5767            TRACE_AND_STEP();
5768            destval = (*opc81_long_operation[rh]) (destval, imm);
5769            if (rh != 7)
5770                store_data_long(destoffset, destval);
5771        }
5772        else {
5773            u16 destval, imm;
5774
5775            DECODE_PRINTF("WORD PTR ");
5776            destoffset = decode_rm10_address(rl);
5777            DECODE_PRINTF(",");
5778            destval = fetch_data_word(destoffset);
5779            imm = fetch_word_imm();
5780            DECODE_PRINTF2("%x\n", imm);
5781            TRACE_AND_STEP();
5782            destval = (*opc81_word_operation[rh]) (destval, imm);
5783            if (rh != 7)
5784                store_data_word(destoffset, destval);
5785        }
5786        break;
5787    case 3:                    /* register to register */
5788        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5789            u32 *destreg;
5790            u32 destval, imm;
5791
5792            destreg = DECODE_RM_LONG_REGISTER(rl);
5793            DECODE_PRINTF(",");
5794            imm = fetch_long_imm();
5795            DECODE_PRINTF2("%x\n", imm);
5796            TRACE_AND_STEP();
5797            destval = (*opc81_long_operation[rh]) (*destreg, imm);
5798            if (rh != 7)
5799                *destreg = destval;
5800        }
5801        else {
5802            u16 *destreg;
5803            u16 destval, imm;
5804
5805            destreg = DECODE_RM_WORD_REGISTER(rl);
5806            DECODE_PRINTF(",");
5807            imm = fetch_word_imm();
5808            DECODE_PRINTF2("%x\n", imm);
5809            TRACE_AND_STEP();
5810            destval = (*opc81_word_operation[rh]) (*destreg, imm);
5811            if (rh != 7)
5812                *destreg = destval;
5813        }
5814        break;
5815    }
5816    DECODE_CLEAR_SEGOVR();
5817    END_OF_INSTR();
5818}
5819
5820static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
5821    add_byte,                   /*00 */
5822        or_byte,                /*01 *//*YYY UNUSED ???? */
5823        adc_byte,               /*02 */
5824        sbb_byte,               /*03 */
5825        and_byte,               /*04 *//*YYY UNUSED ???? */
5826        sub_byte,               /*05 */
5827        xor_byte,               /*06 *//*YYY UNUSED ???? */
5828        cmp_byte,               /*07 */
5829};
5830
5831/****************************************************************************
5832REMARKS:
5833Handles opcode 0x82
5834****************************************************************************/
5835static void
5836x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5837{
5838    int mod, rl, rh;
5839    u8 *destreg;
5840    uint destoffset;
5841    u8 imm;
5842    u8 destval;
5843
5844    /*
5845     * Weirdo special case instruction format.  Part of the opcode
5846     * held below in "RH".  Doubly nested case would result, except
5847     * that the decoded instruction Similar to opcode 81, except that
5848     * the immediate byte is sign extended to a word length.
5849     */
5850    START_OF_INSTR();
5851    FETCH_DECODE_MODRM(mod, rh, rl);
5852#ifdef DEBUG
5853    if (DEBUG_DECODE()) {
5854        /* XXX DECODE_PRINTF may be changed to something more
5855           general, so that it is important to leave the strings
5856           in the same format, even though the result is that the
5857           above test is done twice. */
5858        switch (rh) {
5859        case 0:
5860            DECODE_PRINTF("ADD\t");
5861            break;
5862        case 1:
5863            DECODE_PRINTF("OR\t");
5864            break;
5865        case 2:
5866            DECODE_PRINTF("ADC\t");
5867            break;
5868        case 3:
5869            DECODE_PRINTF("SBB\t");
5870            break;
5871        case 4:
5872            DECODE_PRINTF("AND\t");
5873            break;
5874        case 5:
5875            DECODE_PRINTF("SUB\t");
5876            break;
5877        case 6:
5878            DECODE_PRINTF("XOR\t");
5879            break;
5880        case 7:
5881            DECODE_PRINTF("CMP\t");
5882            break;
5883        }
5884    }
5885#endif
5886    /* know operation, decode the mod byte to find the addressing
5887       mode. */
5888    switch (mod) {
5889    case 0:
5890        DECODE_PRINTF("BYTE PTR ");
5891        destoffset = decode_rm00_address(rl);
5892        destval = fetch_data_byte(destoffset);
5893        imm = fetch_byte_imm();
5894        DECODE_PRINTF2(",%x\n", imm);
5895        TRACE_AND_STEP();
5896        destval = (*opc82_byte_operation[rh]) (destval, imm);
5897        if (rh != 7)
5898            store_data_byte(destoffset, destval);
5899        break;
5900    case 1:
5901        DECODE_PRINTF("BYTE PTR ");
5902        destoffset = decode_rm01_address(rl);
5903        destval = fetch_data_byte(destoffset);
5904        imm = fetch_byte_imm();
5905        DECODE_PRINTF2(",%x\n", imm);
5906        TRACE_AND_STEP();
5907        destval = (*opc82_byte_operation[rh]) (destval, imm);
5908        if (rh != 7)
5909            store_data_byte(destoffset, destval);
5910        break;
5911    case 2:
5912        DECODE_PRINTF("BYTE PTR ");
5913        destoffset = decode_rm10_address(rl);
5914        destval = fetch_data_byte(destoffset);
5915        imm = fetch_byte_imm();
5916        DECODE_PRINTF2(",%x\n", imm);
5917        TRACE_AND_STEP();
5918        destval = (*opc82_byte_operation[rh]) (destval, imm);
5919        if (rh != 7)
5920            store_data_byte(destoffset, destval);
5921        break;
5922    case 3:                    /* register to register */
5923        destreg = DECODE_RM_BYTE_REGISTER(rl);
5924        imm = fetch_byte_imm();
5925        DECODE_PRINTF2(",%x\n", imm);
5926        TRACE_AND_STEP();
5927        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5928        if (rh != 7)
5929            *destreg = destval;
5930        break;
5931    }
5932    DECODE_CLEAR_SEGOVR();
5933    END_OF_INSTR();
5934}
5935
5936static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
5937    add_word,                   /*00 */
5938        or_word,                /*01 *//*YYY UNUSED ???? */
5939        adc_word,               /*02 */
5940        sbb_word,               /*03 */
5941        and_word,               /*04 *//*YYY UNUSED ???? */
5942        sub_word,               /*05 */
5943        xor_word,               /*06 *//*YYY UNUSED ???? */
5944        cmp_word,               /*07 */
5945};
5946
5947static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
5948    add_long,                   /*00 */
5949        or_long,                /*01 *//*YYY UNUSED ???? */
5950        adc_long,               /*02 */
5951        sbb_long,               /*03 */
5952        and_long,               /*04 *//*YYY UNUSED ???? */
5953        sub_long,               /*05 */
5954        xor_long,               /*06 *//*YYY UNUSED ???? */
5955        cmp_long,               /*07 */
5956};
5957
5958/****************************************************************************
5959REMARKS:
5960Handles opcode 0x83
5961****************************************************************************/
5962static void
5963x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5964{
5965    int mod, rl, rh;
5966    uint destoffset;
5967
5968    /*
5969     * Weirdo special case instruction format.  Part of the opcode
5970     * held below in "RH".  Doubly nested case would result, except
5971     * that the decoded instruction Similar to opcode 81, except that
5972     * the immediate byte is sign extended to a word length.
5973     */
5974    START_OF_INSTR();
5975    FETCH_DECODE_MODRM(mod, rh, rl);
5976#ifdef DEBUG
5977    if (DEBUG_DECODE()) {
5978        /* XXX DECODE_PRINTF may be changed to something more
5979           general, so that it is important to leave the strings
5980           in the same format, even though the result is that the
5981           above test is done twice. */
5982        switch (rh) {
5983        case 0:
5984            DECODE_PRINTF("ADD\t");
5985            break;
5986        case 1:
5987            DECODE_PRINTF("OR\t");
5988            break;
5989        case 2:
5990            DECODE_PRINTF("ADC\t");
5991            break;
5992        case 3:
5993            DECODE_PRINTF("SBB\t");
5994            break;
5995        case 4:
5996            DECODE_PRINTF("AND\t");
5997            break;
5998        case 5:
5999            DECODE_PRINTF("SUB\t");
6000            break;
6001        case 6:
6002            DECODE_PRINTF("XOR\t");
6003            break;
6004        case 7:
6005            DECODE_PRINTF("CMP\t");
6006            break;
6007        }
6008    }
6009#endif
6010    /* know operation, decode the mod byte to find the addressing
6011       mode. */
6012    switch (mod) {
6013    case 0:
6014        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6015            u32 destval, imm;
6016
6017            DECODE_PRINTF("DWORD PTR ");
6018            destoffset = decode_rm00_address(rl);
6019            destval = fetch_data_long(destoffset);
6020            imm = (s8) fetch_byte_imm();
6021            DECODE_PRINTF2(",%x\n", imm);
6022            TRACE_AND_STEP();
6023            destval = (*opc83_long_operation[rh]) (destval, imm);
6024            if (rh != 7)
6025                store_data_long(destoffset, destval);
6026        }
6027        else {
6028            u16 destval, imm;
6029
6030            DECODE_PRINTF("WORD PTR ");
6031            destoffset = decode_rm00_address(rl);
6032            destval = fetch_data_word(destoffset);
6033            imm = (s8) fetch_byte_imm();
6034            DECODE_PRINTF2(",%x\n", imm);
6035            TRACE_AND_STEP();
6036            destval = (*opc83_word_operation[rh]) (destval, imm);
6037            if (rh != 7)
6038                store_data_word(destoffset, destval);
6039        }
6040        break;
6041    case 1:
6042        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6043            u32 destval, imm;
6044
6045            DECODE_PRINTF("DWORD PTR ");
6046            destoffset = decode_rm01_address(rl);
6047            destval = fetch_data_long(destoffset);
6048            imm = (s8) fetch_byte_imm();
6049            DECODE_PRINTF2(",%x\n", imm);
6050            TRACE_AND_STEP();
6051            destval = (*opc83_long_operation[rh]) (destval, imm);
6052            if (rh != 7)
6053                store_data_long(destoffset, destval);
6054        }
6055        else {
6056            u16 destval, imm;
6057
6058            DECODE_PRINTF("WORD PTR ");
6059            destoffset = decode_rm01_address(rl);
6060            destval = fetch_data_word(destoffset);
6061            imm = (s8) fetch_byte_imm();
6062            DECODE_PRINTF2(",%x\n", imm);
6063            TRACE_AND_STEP();
6064            destval = (*opc83_word_operation[rh]) (destval, imm);
6065            if (rh != 7)
6066                store_data_word(destoffset, destval);
6067        }
6068        break;
6069    case 2:
6070        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6071            u32 destval, imm;
6072
6073            DECODE_PRINTF("DWORD PTR ");
6074            destoffset = decode_rm10_address(rl);
6075            destval = fetch_data_long(destoffset);
6076            imm = (s8) fetch_byte_imm();
6077            DECODE_PRINTF2(",%x\n", imm);
6078            TRACE_AND_STEP();
6079            destval = (*opc83_long_operation[rh]) (destval, imm);
6080            if (rh != 7)
6081                store_data_long(destoffset, destval);
6082        }
6083        else {
6084            u16 destval, imm;
6085
6086            DECODE_PRINTF("WORD PTR ");
6087            destoffset = decode_rm10_address(rl);
6088            destval = fetch_data_word(destoffset);
6089            imm = (s8) fetch_byte_imm();
6090            DECODE_PRINTF2(",%x\n", imm);
6091            TRACE_AND_STEP();
6092            destval = (*opc83_word_operation[rh]) (destval, imm);
6093            if (rh != 7)
6094                store_data_word(destoffset, destval);
6095        }
6096        break;
6097    case 3:                    /* register to register */
6098        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6099            u32 *destreg;
6100            u32 destval, imm;
6101
6102            destreg = DECODE_RM_LONG_REGISTER(rl);
6103            imm = (s8) fetch_byte_imm();
6104            DECODE_PRINTF2(",%x\n", imm);
6105            TRACE_AND_STEP();
6106            destval = (*opc83_long_operation[rh]) (*destreg, imm);
6107            if (rh != 7)
6108                *destreg = destval;
6109        }
6110        else {
6111            u16 *destreg;
6112            u16 destval, imm;
6113
6114            destreg = DECODE_RM_WORD_REGISTER(rl);
6115            imm = (s8) fetch_byte_imm();
6116            DECODE_PRINTF2(",%x\n", imm);
6117            TRACE_AND_STEP();
6118            destval = (*opc83_word_operation[rh]) (*destreg, imm);
6119            if (rh != 7)
6120                *destreg = destval;
6121        }
6122        break;
6123    }
6124    DECODE_CLEAR_SEGOVR();
6125    END_OF_INSTR();
6126}
6127
6128/****************************************************************************
6129REMARKS:
6130Handles opcode 0x84
6131****************************************************************************/
6132static void
6133x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
6134{
6135    int mod, rl, rh;
6136    u8 *destreg, *srcreg;
6137    uint destoffset;
6138    u8 destval;
6139
6140    START_OF_INSTR();
6141    DECODE_PRINTF("TEST\t");
6142    FETCH_DECODE_MODRM(mod, rh, rl);
6143    switch (mod) {
6144    case 0:
6145        destoffset = decode_rm00_address(rl);
6146        DECODE_PRINTF(",");
6147        destval = fetch_data_byte(destoffset);
6148        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6149        DECODE_PRINTF("\n");
6150        TRACE_AND_STEP();
6151        test_byte(destval, *srcreg);
6152        break;
6153    case 1:
6154        destoffset = decode_rm01_address(rl);
6155        DECODE_PRINTF(",");
6156        destval = fetch_data_byte(destoffset);
6157        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6158        DECODE_PRINTF("\n");
6159        TRACE_AND_STEP();
6160        test_byte(destval, *srcreg);
6161        break;
6162    case 2:
6163        destoffset = decode_rm10_address(rl);
6164        DECODE_PRINTF(",");
6165        destval = fetch_data_byte(destoffset);
6166        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6167        DECODE_PRINTF("\n");
6168        TRACE_AND_STEP();
6169        test_byte(destval, *srcreg);
6170        break;
6171    case 3:                    /* register to register */
6172        destreg = DECODE_RM_BYTE_REGISTER(rl);
6173        DECODE_PRINTF(",");
6174        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6175        DECODE_PRINTF("\n");
6176        TRACE_AND_STEP();
6177        test_byte(*destreg, *srcreg);
6178        break;
6179    }
6180    DECODE_CLEAR_SEGOVR();
6181    END_OF_INSTR();
6182}
6183
6184/****************************************************************************
6185REMARKS:
6186Handles opcode 0x85
6187****************************************************************************/
6188static void
6189x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
6190{
6191    int mod, rl, rh;
6192    uint destoffset;
6193
6194    START_OF_INSTR();
6195    DECODE_PRINTF("TEST\t");
6196    FETCH_DECODE_MODRM(mod, rh, rl);
6197    switch (mod) {
6198    case 0:
6199        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6200            u32 destval;
6201            u32 *srcreg;
6202
6203            destoffset = decode_rm00_address(rl);
6204            DECODE_PRINTF(",");
6205            destval = fetch_data_long(destoffset);
6206            srcreg = DECODE_RM_LONG_REGISTER(rh);
6207            DECODE_PRINTF("\n");
6208            TRACE_AND_STEP();
6209            test_long(destval, *srcreg);
6210        }
6211        else {
6212            u16 destval;
6213            u16 *srcreg;
6214
6215            destoffset = decode_rm00_address(rl);
6216            DECODE_PRINTF(",");
6217            destval = fetch_data_word(destoffset);
6218            srcreg = DECODE_RM_WORD_REGISTER(rh);
6219            DECODE_PRINTF("\n");
6220            TRACE_AND_STEP();
6221            test_word(destval, *srcreg);
6222        }
6223        break;
6224    case 1:
6225        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6226            u32 destval;
6227            u32 *srcreg;
6228
6229            destoffset = decode_rm01_address(rl);
6230            DECODE_PRINTF(",");
6231            destval = fetch_data_long(destoffset);
6232            srcreg = DECODE_RM_LONG_REGISTER(rh);
6233            DECODE_PRINTF("\n");
6234            TRACE_AND_STEP();
6235            test_long(destval, *srcreg);
6236        }
6237        else {
6238            u16 destval;
6239            u16 *srcreg;
6240
6241            destoffset = decode_rm01_address(rl);
6242            DECODE_PRINTF(",");
6243            destval = fetch_data_word(destoffset);
6244            srcreg = DECODE_RM_WORD_REGISTER(rh);
6245            DECODE_PRINTF("\n");
6246            TRACE_AND_STEP();
6247            test_word(destval, *srcreg);
6248        }
6249        break;
6250    case 2:
6251        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252            u32 destval;
6253            u32 *srcreg;
6254
6255            destoffset = decode_rm10_address(rl);
6256            DECODE_PRINTF(",");
6257            destval = fetch_data_long(destoffset);
6258            srcreg = DECODE_RM_LONG_REGISTER(rh);
6259            DECODE_PRINTF("\n");
6260            TRACE_AND_STEP();
6261            test_long(destval, *srcreg);
6262        }
6263        else {
6264            u16 destval;
6265            u16 *srcreg;
6266
6267            destoffset = decode_rm10_address(rl);
6268            DECODE_PRINTF(",");
6269            destval = fetch_data_word(destoffset);
6270            srcreg = DECODE_RM_WORD_REGISTER(rh);
6271            DECODE_PRINTF("\n");
6272            TRACE_AND_STEP();
6273            test_word(destval, *srcreg);
6274        }
6275        break;
6276    case 3:                    /* register to register */
6277        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6278            u32 *destreg, *srcreg;
6279
6280            destreg = DECODE_RM_LONG_REGISTER(rl);
6281            DECODE_PRINTF(",");
6282            srcreg = DECODE_RM_LONG_REGISTER(rh);
6283            DECODE_PRINTF("\n");
6284            TRACE_AND_STEP();
6285            test_long(*destreg, *srcreg);
6286        }
6287        else {
6288            u16 *destreg, *srcreg;
6289
6290            destreg = DECODE_RM_WORD_REGISTER(rl);
6291            DECODE_PRINTF(",");
6292            srcreg = DECODE_RM_WORD_REGISTER(rh);
6293            DECODE_PRINTF("\n");
6294            TRACE_AND_STEP();
6295            test_word(*destreg, *srcreg);
6296        }
6297        break;
6298    }
6299    DECODE_CLEAR_SEGOVR();
6300    END_OF_INSTR();
6301}
6302
6303/****************************************************************************
6304REMARKS:
6305Handles opcode 0x86
6306****************************************************************************/
6307static void
6308x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6309{
6310    int mod, rl, rh;
6311    u8 *destreg, *srcreg;
6312    uint destoffset;
6313    u8 destval;
6314    u8 tmp;
6315
6316    START_OF_INSTR();
6317    DECODE_PRINTF("XCHG\t");
6318    FETCH_DECODE_MODRM(mod, rh, rl);
6319    switch (mod) {
6320    case 0:
6321        destoffset = decode_rm00_address(rl);
6322        DECODE_PRINTF(",");
6323        destval = fetch_data_byte(destoffset);
6324        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6325        DECODE_PRINTF("\n");
6326        TRACE_AND_STEP();
6327        tmp = *srcreg;
6328        *srcreg = destval;
6329        destval = tmp;
6330        store_data_byte(destoffset, destval);
6331        break;
6332    case 1:
6333        destoffset = decode_rm01_address(rl);
6334        DECODE_PRINTF(",");
6335        destval = fetch_data_byte(destoffset);
6336        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6337        DECODE_PRINTF("\n");
6338        TRACE_AND_STEP();
6339        tmp = *srcreg;
6340        *srcreg = destval;
6341        destval = tmp;
6342        store_data_byte(destoffset, destval);
6343        break;
6344    case 2:
6345        destoffset = decode_rm10_address(rl);
6346        DECODE_PRINTF(",");
6347        destval = fetch_data_byte(destoffset);
6348        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6349        DECODE_PRINTF("\n");
6350        TRACE_AND_STEP();
6351        tmp = *srcreg;
6352        *srcreg = destval;
6353        destval = tmp;
6354        store_data_byte(destoffset, destval);
6355        break;
6356    case 3:                    /* register to register */
6357        destreg = DECODE_RM_BYTE_REGISTER(rl);
6358        DECODE_PRINTF(",");
6359        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6360        DECODE_PRINTF("\n");
6361        TRACE_AND_STEP();
6362        tmp = *srcreg;
6363        *srcreg = *destreg;
6364        *destreg = tmp;
6365        break;
6366    }
6367    DECODE_CLEAR_SEGOVR();
6368    END_OF_INSTR();
6369}
6370
6371/****************************************************************************
6372REMARKS:
6373Handles opcode 0x87
6374****************************************************************************/
6375static void
6376x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6377{
6378    int mod, rl, rh;
6379    uint destoffset;
6380
6381    START_OF_INSTR();
6382    DECODE_PRINTF("XCHG\t");
6383    FETCH_DECODE_MODRM(mod, rh, rl);
6384    switch (mod) {
6385    case 0:
6386        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6387            u32 *srcreg;
6388            u32 destval, tmp;
6389
6390            destoffset = decode_rm00_address(rl);
6391            DECODE_PRINTF(",");
6392            destval = fetch_data_long(destoffset);
6393            srcreg = DECODE_RM_LONG_REGISTER(rh);
6394            DECODE_PRINTF("\n");
6395            TRACE_AND_STEP();
6396            tmp = *srcreg;
6397            *srcreg = destval;
6398            destval = tmp;
6399            store_data_long(destoffset, destval);
6400        }
6401        else {
6402            u16 *srcreg;
6403            u16 destval, tmp;
6404
6405            destoffset = decode_rm00_address(rl);
6406            DECODE_PRINTF(",");
6407            destval = fetch_data_word(destoffset);
6408            srcreg = DECODE_RM_WORD_REGISTER(rh);
6409            DECODE_PRINTF("\n");
6410            TRACE_AND_STEP();
6411            tmp = *srcreg;
6412            *srcreg = destval;
6413            destval = tmp;
6414            store_data_word(destoffset, destval);
6415        }
6416        break;
6417    case 1:
6418        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6419            u32 *srcreg;
6420            u32 destval, tmp;
6421
6422            destoffset = decode_rm01_address(rl);
6423            DECODE_PRINTF(",");
6424            destval = fetch_data_long(destoffset);
6425            srcreg = DECODE_RM_LONG_REGISTER(rh);
6426            DECODE_PRINTF("\n");
6427            TRACE_AND_STEP();
6428            tmp = *srcreg;
6429            *srcreg = destval;
6430            destval = tmp;
6431            store_data_long(destoffset, destval);
6432        }
6433        else {
6434            u16 *srcreg;
6435            u16 destval, tmp;
6436
6437            destoffset = decode_rm01_address(rl);
6438            DECODE_PRINTF(",");
6439            destval = fetch_data_word(destoffset);
6440            srcreg = DECODE_RM_WORD_REGISTER(rh);
6441            DECODE_PRINTF("\n");
6442            TRACE_AND_STEP();
6443            tmp = *srcreg;
6444            *srcreg = destval;
6445            destval = tmp;
6446            store_data_word(destoffset, destval);
6447        }
6448        break;
6449    case 2:
6450        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6451            u32 *srcreg;
6452            u32 destval, tmp;
6453
6454            destoffset = decode_rm10_address(rl);
6455            DECODE_PRINTF(",");
6456            destval = fetch_data_long(destoffset);
6457            srcreg = DECODE_RM_LONG_REGISTER(rh);
6458            DECODE_PRINTF("\n");
6459            TRACE_AND_STEP();
6460            tmp = *srcreg;
6461            *srcreg = destval;
6462            destval = tmp;
6463            store_data_long(destoffset, destval);
6464        }
6465        else {
6466            u16 *srcreg;
6467            u16 destval, tmp;
6468
6469            destoffset = decode_rm10_address(rl);
6470            DECODE_PRINTF(",");
6471            destval = fetch_data_word(destoffset);
6472            srcreg = DECODE_RM_WORD_REGISTER(rh);
6473            DECODE_PRINTF("\n");
6474            TRACE_AND_STEP();
6475            tmp = *srcreg;
6476            *srcreg = destval;
6477            destval = tmp;
6478            store_data_word(destoffset, destval);
6479        }
6480        break;
6481    case 3:                    /* register to register */
6482        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6483            u32 *destreg, *srcreg;
6484            u32 tmp;
6485
6486            destreg = DECODE_RM_LONG_REGISTER(rl);
6487            DECODE_PRINTF(",");
6488            srcreg = DECODE_RM_LONG_REGISTER(rh);
6489            DECODE_PRINTF("\n");
6490            TRACE_AND_STEP();
6491            tmp = *srcreg;
6492            *srcreg = *destreg;
6493            *destreg = tmp;
6494        }
6495        else {
6496            u16 *destreg, *srcreg;
6497            u16 tmp;
6498
6499            destreg = DECODE_RM_WORD_REGISTER(rl);
6500            DECODE_PRINTF(",");
6501            srcreg = DECODE_RM_WORD_REGISTER(rh);
6502            DECODE_PRINTF("\n");
6503            TRACE_AND_STEP();
6504            tmp = *srcreg;
6505            *srcreg = *destreg;
6506            *destreg = tmp;
6507        }
6508        break;
6509    }
6510    DECODE_CLEAR_SEGOVR();
6511    END_OF_INSTR();
6512}
6513
6514/****************************************************************************
6515REMARKS:
6516Handles opcode 0x88
6517****************************************************************************/
6518static void
6519x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6520{
6521    int mod, rl, rh;
6522    u8 *destreg, *srcreg;
6523    uint destoffset;
6524
6525    START_OF_INSTR();
6526    DECODE_PRINTF("MOV\t");
6527    FETCH_DECODE_MODRM(mod, rh, rl);
6528    switch (mod) {
6529    case 0:
6530        destoffset = decode_rm00_address(rl);
6531        DECODE_PRINTF(",");
6532        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6533        DECODE_PRINTF("\n");
6534        TRACE_AND_STEP();
6535        store_data_byte(destoffset, *srcreg);
6536        break;
6537    case 1:
6538        destoffset = decode_rm01_address(rl);
6539        DECODE_PRINTF(",");
6540        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6541        DECODE_PRINTF("\n");
6542        TRACE_AND_STEP();
6543        store_data_byte(destoffset, *srcreg);
6544        break;
6545    case 2:
6546        destoffset = decode_rm10_address(rl);
6547        DECODE_PRINTF(",");
6548        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6549        DECODE_PRINTF("\n");
6550        TRACE_AND_STEP();
6551        store_data_byte(destoffset, *srcreg);
6552        break;
6553    case 3:                    /* register to register */
6554        destreg = DECODE_RM_BYTE_REGISTER(rl);
6555        DECODE_PRINTF(",");
6556        srcreg = DECODE_RM_BYTE_REGISTER(rh);
6557        DECODE_PRINTF("\n");
6558        TRACE_AND_STEP();
6559        *destreg = *srcreg;
6560        break;
6561    }
6562    DECODE_CLEAR_SEGOVR();
6563    END_OF_INSTR();
6564}
6565
6566/****************************************************************************
6567REMARKS:
6568Handles opcode 0x89
6569****************************************************************************/
6570static void
6571x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6572{
6573    int mod, rl, rh;
6574    u32 destoffset;
6575
6576    START_OF_INSTR();
6577    DECODE_PRINTF("MOV\t");
6578    FETCH_DECODE_MODRM(mod, rh, rl);
6579    switch (mod) {
6580    case 0:
6581        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6582            u32 *srcreg;
6583
6584            destoffset = decode_rm00_address(rl);
6585            DECODE_PRINTF(",");
6586            srcreg = DECODE_RM_LONG_REGISTER(rh);
6587            DECODE_PRINTF("\n");
6588            TRACE_AND_STEP();
6589            store_data_long(destoffset, *srcreg);
6590        }
6591        else {
6592            u16 *srcreg;
6593
6594            destoffset = decode_rm00_address(rl);
6595            DECODE_PRINTF(",");
6596            srcreg = DECODE_RM_WORD_REGISTER(rh);
6597            DECODE_PRINTF("\n");
6598            TRACE_AND_STEP();
6599            store_data_word(destoffset, *srcreg);
6600        }
6601        break;
6602    case 1:
6603        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6604            u32 *srcreg;
6605
6606            destoffset = decode_rm01_address(rl);
6607            DECODE_PRINTF(",");
6608            srcreg = DECODE_RM_LONG_REGISTER(rh);
6609            DECODE_PRINTF("\n");
6610            TRACE_AND_STEP();
6611            store_data_long(destoffset, *srcreg);
6612        }
6613        else {
6614            u16 *srcreg;
6615
6616            destoffset = decode_rm01_address(rl);
6617            DECODE_PRINTF(",");
6618            srcreg = DECODE_RM_WORD_REGISTER(rh);
6619            DECODE_PRINTF("\n");
6620            TRACE_AND_STEP();
6621            store_data_word(destoffset, *srcreg);
6622        }
6623        break;
6624    case 2:
6625        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6626            u32 *srcreg;
6627
6628            destoffset = decode_rm10_address(rl);
6629            DECODE_PRINTF(",");
6630            srcreg = DECODE_RM_LONG_REGISTER(rh);
6631            DECODE_PRINTF("\n");
6632            TRACE_AND_STEP();
6633            store_data_long(destoffset, *srcreg);
6634        }
6635        else {
6636            u16 *srcreg;
6637
6638            destoffset = decode_rm10_address(rl);
6639            DECODE_PRINTF(",");
6640            srcreg = DECODE_RM_WORD_REGISTER(rh);
6641            DECODE_PRINTF("\n");
6642            TRACE_AND_STEP();
6643            store_data_word(destoffset, *srcreg);
6644        }
6645        break;
6646    case 3:                    /* register to register */
6647        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6648            u32 *destreg, *srcreg;
6649
6650            destreg = DECODE_RM_LONG_REGISTER(rl);
6651            DECODE_PRINTF(",");
6652            srcreg = DECODE_RM_LONG_REGISTER(rh);
6653            DECODE_PRINTF("\n");
6654            TRACE_AND_STEP();
6655            *destreg = *srcreg;
6656        }
6657        else {
6658            u16 *destreg, *srcreg;
6659
6660            destreg = DECODE_RM_WORD_REGISTER(rl);
6661            DECODE_PRINTF(",");
6662            srcreg = DECODE_RM_WORD_REGISTER(rh);
6663            DECODE_PRINTF("\n");
6664            TRACE_AND_STEP();
6665            *destreg = *srcreg;
6666        }
6667        break;
6668    }
6669    DECODE_CLEAR_SEGOVR();
6670    END_OF_INSTR();
6671}
6672
6673/****************************************************************************
6674REMARKS:
6675Handles opcode 0x8a
6676****************************************************************************/
6677static void
6678x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6679{
6680    int mod, rl, rh;
6681    u8 *destreg, *srcreg;
6682    uint srcoffset;
6683    u8 srcval;
6684
6685    START_OF_INSTR();
6686    DECODE_PRINTF("MOV\t");
6687    FETCH_DECODE_MODRM(mod, rh, rl);
6688    switch (mod) {
6689    case 0:
6690        destreg = DECODE_RM_BYTE_REGISTER(rh);
6691        DECODE_PRINTF(",");
6692        srcoffset = decode_rm00_address(rl);
6693        srcval = fetch_data_byte(srcoffset);
6694        DECODE_PRINTF("\n");
6695        TRACE_AND_STEP();
6696        *destreg = srcval;
6697        break;
6698    case 1:
6699        destreg = DECODE_RM_BYTE_REGISTER(rh);
6700        DECODE_PRINTF(",");
6701        srcoffset = decode_rm01_address(rl);
6702        srcval = fetch_data_byte(srcoffset);
6703        DECODE_PRINTF("\n");
6704        TRACE_AND_STEP();
6705        *destreg = srcval;
6706        break;
6707    case 2:
6708        destreg = DECODE_RM_BYTE_REGISTER(rh);
6709        DECODE_PRINTF(",");
6710        srcoffset = decode_rm10_address(rl);
6711        srcval = fetch_data_byte(srcoffset);
6712        DECODE_PRINTF("\n");
6713        TRACE_AND_STEP();
6714        *destreg = srcval;
6715        break;
6716    case 3:                    /* register to register */
6717        destreg = DECODE_RM_BYTE_REGISTER(rh);
6718        DECODE_PRINTF(",");
6719        srcreg = DECODE_RM_BYTE_REGISTER(rl);
6720        DECODE_PRINTF("\n");
6721        TRACE_AND_STEP();
6722        *destreg = *srcreg;
6723        break;
6724    }
6725    DECODE_CLEAR_SEGOVR();
6726    END_OF_INSTR();
6727}
6728
6729/****************************************************************************
6730REMARKS:
6731Handles opcode 0x8b
6732****************************************************************************/
6733static void
6734x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6735{
6736    int mod, rl, rh;
6737    uint srcoffset;
6738
6739    START_OF_INSTR();
6740    DECODE_PRINTF("MOV\t");
6741    FETCH_DECODE_MODRM(mod, rh, rl);
6742    switch (mod) {
6743    case 0:
6744        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6745            u32 *destreg;
6746            u32 srcval;
6747
6748            destreg = DECODE_RM_LONG_REGISTER(rh);
6749            DECODE_PRINTF(",");
6750            srcoffset = decode_rm00_address(rl);
6751            srcval = fetch_data_long(srcoffset);
6752            DECODE_PRINTF("\n");
6753            TRACE_AND_STEP();
6754            *destreg = srcval;
6755        }
6756        else {
6757            u16 *destreg;
6758            u16 srcval;
6759
6760            destreg = DECODE_RM_WORD_REGISTER(rh);
6761            DECODE_PRINTF(",");
6762            srcoffset = decode_rm00_address(rl);
6763            srcval = fetch_data_word(srcoffset);
6764            DECODE_PRINTF("\n");
6765            TRACE_AND_STEP();
6766            *destreg = srcval;
6767        }
6768        break;
6769    case 1:
6770        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6771            u32 *destreg;
6772            u32 srcval;
6773
6774            destreg = DECODE_RM_LONG_REGISTER(rh);
6775            DECODE_PRINTF(",");
6776            srcoffset = decode_rm01_address(rl);
6777            srcval = fetch_data_long(srcoffset);
6778            DECODE_PRINTF("\n");
6779            TRACE_AND_STEP();
6780            *destreg = srcval;
6781        }
6782        else {
6783            u16 *destreg;
6784            u16 srcval;
6785
6786            destreg = DECODE_RM_WORD_REGISTER(rh);
6787            DECODE_PRINTF(",");
6788            srcoffset = decode_rm01_address(rl);
6789            srcval = fetch_data_word(srcoffset);
6790            DECODE_PRINTF("\n");
6791            TRACE_AND_STEP();
6792            *destreg = srcval;
6793        }
6794        break;
6795    case 2:
6796        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6797            u32 *destreg;
6798            u32 srcval;
6799
6800            destreg = DECODE_RM_LONG_REGISTER(rh);
6801            DECODE_PRINTF(",");
6802            srcoffset = decode_rm10_address(rl);
6803            srcval = fetch_data_long(srcoffset);
6804            DECODE_PRINTF("\n");
6805            TRACE_AND_STEP();
6806            *destreg = srcval;
6807        }
6808        else {
6809            u16 *destreg;
6810            u16 srcval;
6811
6812            destreg = DECODE_RM_WORD_REGISTER(rh);
6813            DECODE_PRINTF(",");
6814            srcoffset = decode_rm10_address(rl);
6815            srcval = fetch_data_word(srcoffset);
6816            DECODE_PRINTF("\n");
6817            TRACE_AND_STEP();
6818            *destreg = srcval;
6819        }
6820        break;
6821    case 3:                    /* register to register */
6822        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6823            u32 *destreg, *srcreg;
6824
6825            destreg = DECODE_RM_LONG_REGISTER(rh);
6826            DECODE_PRINTF(",");
6827            srcreg = DECODE_RM_LONG_REGISTER(rl);
6828            DECODE_PRINTF("\n");
6829            TRACE_AND_STEP();
6830            *destreg = *srcreg;
6831        }
6832        else {
6833            u16 *destreg, *srcreg;
6834
6835            destreg = DECODE_RM_WORD_REGISTER(rh);
6836            DECODE_PRINTF(",");
6837            srcreg = DECODE_RM_WORD_REGISTER(rl);
6838            DECODE_PRINTF("\n");
6839            TRACE_AND_STEP();
6840            *destreg = *srcreg;
6841        }
6842        break;
6843    }
6844    DECODE_CLEAR_SEGOVR();
6845    END_OF_INSTR();
6846}
6847
6848/****************************************************************************
6849REMARKS:
6850Handles opcode 0x8c
6851****************************************************************************/
6852static void
6853x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6854{
6855    int mod, rl, rh;
6856    u16 *destreg, *srcreg;
6857    uint destoffset;
6858    u16 destval;
6859
6860    START_OF_INSTR();
6861    DECODE_PRINTF("MOV\t");
6862    FETCH_DECODE_MODRM(mod, rh, rl);
6863    switch (mod) {
6864    case 0:
6865        destoffset = decode_rm00_address(rl);
6866        DECODE_PRINTF(",");
6867        srcreg = decode_rm_seg_register(rh);
6868        DECODE_PRINTF("\n");
6869        TRACE_AND_STEP();
6870        destval = *srcreg;
6871        store_data_word(destoffset, destval);
6872        break;
6873    case 1:
6874        destoffset = decode_rm01_address(rl);
6875        DECODE_PRINTF(",");
6876        srcreg = decode_rm_seg_register(rh);
6877        DECODE_PRINTF("\n");
6878        TRACE_AND_STEP();
6879        destval = *srcreg;
6880        store_data_word(destoffset, destval);
6881        break;
6882    case 2:
6883        destoffset = decode_rm10_address(rl);
6884        DECODE_PRINTF(",");
6885        srcreg = decode_rm_seg_register(rh);
6886        DECODE_PRINTF("\n");
6887        TRACE_AND_STEP();
6888        destval = *srcreg;
6889        store_data_word(destoffset, destval);
6890        break;
6891    case 3:                    /* register to register */
6892        destreg = DECODE_RM_WORD_REGISTER(rl);
6893        DECODE_PRINTF(",");
6894        srcreg = decode_rm_seg_register(rh);
6895        DECODE_PRINTF("\n");
6896        TRACE_AND_STEP();
6897        *destreg = *srcreg;
6898        break;
6899    }
6900    DECODE_CLEAR_SEGOVR();
6901    END_OF_INSTR();
6902}
6903
6904/****************************************************************************
6905REMARKS:
6906Handles opcode 0x8d
6907****************************************************************************/
6908static void
6909x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6910{
6911    int mod, rl, rh;
6912    uint destoffset;
6913
6914    START_OF_INSTR();
6915    DECODE_PRINTF("LEA\t");
6916    FETCH_DECODE_MODRM(mod, rh, rl);
6917    switch (mod) {
6918    case 0:
6919        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6920            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6921
6922            DECODE_PRINTF(",");
6923            destoffset = decode_rm00_address(rl);
6924            DECODE_PRINTF("\n");
6925            TRACE_AND_STEP();
6926            *srcreg = (u32) destoffset;
6927        }
6928        else {
6929            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6930
6931            DECODE_PRINTF(",");
6932            destoffset = decode_rm00_address(rl);
6933            DECODE_PRINTF("\n");
6934            TRACE_AND_STEP();
6935            *srcreg = (u16) destoffset;
6936        }
6937        break;
6938    case 1:
6939        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6940            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6941
6942            DECODE_PRINTF(",");
6943            destoffset = decode_rm01_address(rl);
6944            DECODE_PRINTF("\n");
6945            TRACE_AND_STEP();
6946            *srcreg = (u32) destoffset;
6947        }
6948        else {
6949            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6950
6951            DECODE_PRINTF(",");
6952            destoffset = decode_rm01_address(rl);
6953            DECODE_PRINTF("\n");
6954            TRACE_AND_STEP();
6955            *srcreg = (u16) destoffset;
6956        }
6957        break;
6958    case 2:
6959        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6960            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6961
6962            DECODE_PRINTF(",");
6963            destoffset = decode_rm10_address(rl);
6964            DECODE_PRINTF("\n");
6965            TRACE_AND_STEP();
6966            *srcreg = (u32) destoffset;
6967        }
6968        else {
6969            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6970
6971            DECODE_PRINTF(",");
6972            destoffset = decode_rm10_address(rl);
6973            DECODE_PRINTF("\n");
6974            TRACE_AND_STEP();
6975            *srcreg = (u16) destoffset;
6976        }
6977        break;
6978    case 3:                    /* register to register */
6979        /* undefined.  Do nothing. */
6980        break;
6981    }
6982    DECODE_CLEAR_SEGOVR();
6983    END_OF_INSTR();
6984}
6985
6986/****************************************************************************
6987REMARKS:
6988Handles opcode 0x8e
6989****************************************************************************/
6990static void
6991x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6992{
6993    int mod, rl, rh;
6994    u16 *destreg, *srcreg;
6995    uint srcoffset;
6996    u16 srcval;
6997
6998    START_OF_INSTR();
6999    DECODE_PRINTF("MOV\t");
7000    FETCH_DECODE_MODRM(mod, rh, rl);
7001    switch (mod) {
7002    case 0:
7003        destreg = decode_rm_seg_register(rh);
7004        DECODE_PRINTF(",");
7005        srcoffset = decode_rm00_address(rl);
7006        srcval = fetch_data_word(srcoffset);
7007        DECODE_PRINTF("\n");
7008        TRACE_AND_STEP();
7009        *destreg = srcval;
7010        break;
7011    case 1:
7012        destreg = decode_rm_seg_register(rh);
7013        DECODE_PRINTF(",");
7014        srcoffset = decode_rm01_address(rl);
7015        srcval = fetch_data_word(srcoffset);
7016        DECODE_PRINTF("\n");
7017        TRACE_AND_STEP();
7018        *destreg = srcval;
7019        break;
7020    case 2:
7021        destreg = decode_rm_seg_register(rh);
7022        DECODE_PRINTF(",");
7023        srcoffset = decode_rm10_address(rl);
7024        srcval = fetch_data_word(srcoffset);
7025        DECODE_PRINTF("\n");
7026        TRACE_AND_STEP();
7027        *destreg = srcval;
7028        break;
7029    case 3:                    /* register to register */
7030        destreg = decode_rm_seg_register(rh);
7031        DECODE_PRINTF(",");
7032        srcreg = DECODE_RM_WORD_REGISTER(rl);
7033        DECODE_PRINTF("\n");
7034        TRACE_AND_STEP();
7035        *destreg = *srcreg;
7036        break;
7037    }
7038    /*
7039     * Clean up, and reset all the R_xSP pointers to the correct
7040     * locations.  This is about 3x too much overhead (doing all the
7041     * segreg ptrs when only one is needed, but this instruction
7042     * *cannot* be that common, and this isn't too much work anyway.
7043     */
7044    DECODE_CLEAR_SEGOVR();
7045    END_OF_INSTR();
7046}
7047
7048/****************************************************************************
7049REMARKS:
7050Handles opcode 0x8f
7051****************************************************************************/
7052static void
7053x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
7054{
7055    int mod, rl, rh;
7056    uint destoffset;
7057
7058    START_OF_INSTR();
7059    DECODE_PRINTF("POP\t");
7060    FETCH_DECODE_MODRM(mod, rh, rl);
7061    if (rh != 0) {
7062        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
7063        HALT_SYS();
7064    }
7065    switch (mod) {
7066    case 0:
7067        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7068            u32 destval;
7069
7070            destoffset = decode_rm00_address(rl);
7071            DECODE_PRINTF("\n");
7072            TRACE_AND_STEP();
7073            destval = pop_long();
7074            store_data_long(destoffset, destval);
7075        }
7076        else {
7077            u16 destval;
7078
7079            destoffset = decode_rm00_address(rl);
7080            DECODE_PRINTF("\n");
7081            TRACE_AND_STEP();
7082            destval = pop_word();
7083            store_data_word(destoffset, destval);
7084        }
7085        break;
7086    case 1:
7087        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7088            u32 destval;
7089
7090            destoffset = decode_rm01_address(rl);
7091            DECODE_PRINTF("\n");
7092            TRACE_AND_STEP();
7093            destval = pop_long();
7094            store_data_long(destoffset, destval);
7095        }
7096        else {
7097            u16 destval;
7098
7099            destoffset = decode_rm01_address(rl);
7100            DECODE_PRINTF("\n");
7101            TRACE_AND_STEP();
7102            destval = pop_word();
7103            store_data_word(destoffset, destval);
7104        }
7105        break;
7106    case 2:
7107        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7108            u32 destval;
7109
7110            destoffset = decode_rm10_address(rl);
7111            DECODE_PRINTF("\n");
7112            TRACE_AND_STEP();
7113            destval = pop_long();
7114            store_data_long(destoffset, destval);
7115        }
7116        else {
7117            u16 destval;
7118
7119            destoffset = decode_rm10_address(rl);
7120            DECODE_PRINTF("\n");
7121            TRACE_AND_STEP();
7122            destval = pop_word();
7123            store_data_word(destoffset, destval);
7124        }
7125        break;
7126    case 3:                    /* register to register */
7127        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7128            u32 *destreg;
7129
7130            destreg = DECODE_RM_LONG_REGISTER(rl);
7131            DECODE_PRINTF("\n");
7132            TRACE_AND_STEP();
7133            *destreg = pop_long();
7134        }
7135        else {
7136            u16 *destreg;
7137
7138            destreg = DECODE_RM_WORD_REGISTER(rl);
7139            DECODE_PRINTF("\n");
7140            TRACE_AND_STEP();
7141            *destreg = pop_word();
7142        }
7143        break;
7144    }
7145    DECODE_CLEAR_SEGOVR();
7146    END_OF_INSTR();
7147}
7148
7149/****************************************************************************
7150REMARKS:
7151Handles opcode 0x90
7152****************************************************************************/
7153static void
7154x86emuOp_nop(u8 X86EMU_UNUSED(op1))
7155{
7156    START_OF_INSTR();
7157    DECODE_PRINTF("NOP\n");
7158    TRACE_AND_STEP();
7159    DECODE_CLEAR_SEGOVR();
7160    END_OF_INSTR();
7161}
7162
7163/****************************************************************************
7164REMARKS:
7165Handles opcode 0x91
7166****************************************************************************/
7167static void
7168x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
7169{
7170    u32 tmp;
7171
7172    START_OF_INSTR();
7173    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7174        DECODE_PRINTF("XCHG\tEAX,ECX\n");
7175    }
7176    else {
7177        DECODE_PRINTF("XCHG\tAX,CX\n");
7178    }
7179    TRACE_AND_STEP();
7180    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7181        tmp = M.x86.R_EAX;
7182        M.x86.R_EAX = M.x86.R_ECX;
7183        M.x86.R_ECX = tmp;
7184    }
7185    else {
7186        tmp = M.x86.R_AX;
7187        M.x86.R_AX = M.x86.R_CX;
7188        M.x86.R_CX = (u16) tmp;
7189    }
7190    DECODE_CLEAR_SEGOVR();
7191    END_OF_INSTR();
7192}
7193
7194/****************************************************************************
7195REMARKS:
7196Handles opcode 0x92
7197****************************************************************************/
7198static void
7199x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
7200{
7201    u32 tmp;
7202
7203    START_OF_INSTR();
7204    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7205        DECODE_PRINTF("XCHG\tEAX,EDX\n");
7206    }
7207    else {
7208        DECODE_PRINTF("XCHG\tAX,DX\n");
7209    }
7210    TRACE_AND_STEP();
7211    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7212        tmp = M.x86.R_EAX;
7213        M.x86.R_EAX = M.x86.R_EDX;
7214        M.x86.R_EDX = tmp;
7215    }
7216    else {
7217        tmp = M.x86.R_AX;
7218        M.x86.R_AX = M.x86.R_DX;
7219        M.x86.R_DX = (u16) tmp;
7220    }
7221    DECODE_CLEAR_SEGOVR();
7222    END_OF_INSTR();
7223}
7224
7225/****************************************************************************
7226REMARKS:
7227Handles opcode 0x93
7228****************************************************************************/
7229static void
7230x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
7231{
7232    u32 tmp;
7233
7234    START_OF_INSTR();
7235    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7236        DECODE_PRINTF("XCHG\tEAX,EBX\n");
7237    }
7238    else {
7239        DECODE_PRINTF("XCHG\tAX,BX\n");
7240    }
7241    TRACE_AND_STEP();
7242    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7243        tmp = M.x86.R_EAX;
7244        M.x86.R_EAX = M.x86.R_EBX;
7245        M.x86.R_EBX = tmp;
7246    }
7247    else {
7248        tmp = M.x86.R_AX;
7249        M.x86.R_AX = M.x86.R_BX;
7250        M.x86.R_BX = (u16) tmp;
7251    }
7252    DECODE_CLEAR_SEGOVR();
7253    END_OF_INSTR();
7254}
7255
7256/****************************************************************************
7257REMARKS:
7258Handles opcode 0x94
7259****************************************************************************/
7260static void
7261x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
7262{
7263    u32 tmp;
7264
7265    START_OF_INSTR();
7266    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7267        DECODE_PRINTF("XCHG\tEAX,ESP\n");
7268    }
7269    else {
7270        DECODE_PRINTF("XCHG\tAX,SP\n");
7271    }
7272    TRACE_AND_STEP();
7273    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7274        tmp = M.x86.R_EAX;
7275        M.x86.R_EAX = M.x86.R_ESP;
7276        M.x86.R_ESP = tmp;
7277    }
7278    else {
7279        tmp = M.x86.R_AX;
7280        M.x86.R_AX = M.x86.R_SP;
7281        M.x86.R_SP = (u16) tmp;
7282    }
7283    DECODE_CLEAR_SEGOVR();
7284    END_OF_INSTR();
7285}
7286
7287/****************************************************************************
7288REMARKS:
7289Handles opcode 0x95
7290****************************************************************************/
7291static void
7292x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
7293{
7294    u32 tmp;
7295
7296    START_OF_INSTR();
7297    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7298        DECODE_PRINTF("XCHG\tEAX,EBP\n");
7299    }
7300    else {
7301        DECODE_PRINTF("XCHG\tAX,BP\n");
7302    }
7303    TRACE_AND_STEP();
7304    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7305        tmp = M.x86.R_EAX;
7306        M.x86.R_EAX = M.x86.R_EBP;
7307        M.x86.R_EBP = tmp;
7308    }
7309    else {
7310        tmp = M.x86.R_AX;
7311        M.x86.R_AX = M.x86.R_BP;
7312        M.x86.R_BP = (u16) tmp;
7313    }
7314    DECODE_CLEAR_SEGOVR();
7315    END_OF_INSTR();
7316}
7317
7318/****************************************************************************
7319REMARKS:
7320Handles opcode 0x96
7321****************************************************************************/
7322static void
7323x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
7324{
7325    u32 tmp;
7326
7327    START_OF_INSTR();
7328    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7329        DECODE_PRINTF("XCHG\tEAX,ESI\n");
7330    }
7331    else {
7332        DECODE_PRINTF("XCHG\tAX,SI\n");
7333    }
7334    TRACE_AND_STEP();
7335    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7336        tmp = M.x86.R_EAX;
7337        M.x86.R_EAX = M.x86.R_ESI;
7338        M.x86.R_ESI = tmp;
7339    }
7340    else {
7341        tmp = M.x86.R_AX;
7342        M.x86.R_AX = M.x86.R_SI;
7343        M.x86.R_SI = (u16) tmp;
7344    }
7345    DECODE_CLEAR_SEGOVR();
7346    END_OF_INSTR();
7347}
7348
7349/****************************************************************************
7350REMARKS:
7351Handles opcode 0x97
7352****************************************************************************/
7353static void
7354x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
7355{
7356    u32 tmp;
7357
7358    START_OF_INSTR();
7359    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7360        DECODE_PRINTF("XCHG\tEAX,EDI\n");
7361    }
7362    else {
7363        DECODE_PRINTF("XCHG\tAX,DI\n");
7364    }
7365    TRACE_AND_STEP();
7366    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7367        tmp = M.x86.R_EAX;
7368        M.x86.R_EAX = M.x86.R_EDI;
7369        M.x86.R_EDI = tmp;
7370    }
7371    else {
7372        tmp = M.x86.R_AX;
7373        M.x86.R_AX = M.x86.R_DI;
7374        M.x86.R_DI = (u16) tmp;
7375    }
7376    DECODE_CLEAR_SEGOVR();
7377    END_OF_INSTR();
7378}
7379
7380/****************************************************************************
7381REMARKS:
7382Handles opcode 0x98
7383****************************************************************************/
7384static void
7385x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7386{
7387    START_OF_INSTR();
7388    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7389        DECODE_PRINTF("CWDE\n");
7390    }
7391    else {
7392        DECODE_PRINTF("CBW\n");
7393    }
7394    TRACE_AND_STEP();
7395    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7396        if (M.x86.R_AX & 0x8000) {
7397            M.x86.R_EAX |= 0xffff0000;
7398        }
7399        else {
7400            M.x86.R_EAX &= 0x0000ffff;
7401        }
7402    }
7403    else {
7404        if (M.x86.R_AL & 0x80) {
7405            M.x86.R_AH = 0xff;
7406        }
7407        else {
7408            M.x86.R_AH = 0x0;
7409        }
7410    }
7411    DECODE_CLEAR_SEGOVR();
7412    END_OF_INSTR();
7413}
7414
7415/****************************************************************************
7416REMARKS:
7417Handles opcode 0x99
7418****************************************************************************/
7419static void
7420x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7421{
7422    START_OF_INSTR();
7423    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7424        DECODE_PRINTF("CDQ\n");
7425    }
7426    else {
7427        DECODE_PRINTF("CWD\n");
7428    }
7429    DECODE_PRINTF("CWD\n");
7430    TRACE_AND_STEP();
7431    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7432        if (M.x86.R_EAX & 0x80000000) {
7433            M.x86.R_EDX = 0xffffffff;
7434        }
7435        else {
7436            M.x86.R_EDX = 0x0;
7437        }
7438    }
7439    else {
7440        if (M.x86.R_AX & 0x8000) {
7441            M.x86.R_DX = 0xffff;
7442        }
7443        else {
7444            M.x86.R_DX = 0x0;
7445        }
7446    }
7447    DECODE_CLEAR_SEGOVR();
7448    END_OF_INSTR();
7449}
7450
7451/****************************************************************************
7452REMARKS:
7453Handles opcode 0x9a
7454****************************************************************************/
7455static void
7456x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7457{
7458    u32 farseg, faroff;
7459
7460    START_OF_INSTR();
7461    DECODE_PRINTF("CALL\t");
7462    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7463        faroff = fetch_long_imm();
7464        farseg = fetch_word_imm();
7465    }
7466    else {
7467        faroff = fetch_word_imm();
7468        farseg = fetch_word_imm();
7469    }
7470    DECODE_PRINTF2("%04x:", farseg);
7471    DECODE_PRINTF2("%04x\n", faroff);
7472    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7473
7474    /* XXX
7475     *
7476     * Hooked interrupt vectors calling into our "BIOS" will cause
7477     * problems unless all intersegment stuff is checked for BIOS
7478     * access.  Check needed here.  For moment, let it alone.
7479     */
7480    TRACE_AND_STEP();
7481    push_word(M.x86.R_CS);
7482    M.x86.R_CS = farseg;
7483    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7484        push_long(M.x86.R_EIP);
7485    }
7486    else {
7487        push_word(M.x86.R_IP);
7488    }
7489    M.x86.R_EIP = faroff & 0xffff;
7490    DECODE_CLEAR_SEGOVR();
7491    END_OF_INSTR();
7492}
7493
7494/****************************************************************************
7495REMARKS:
7496Handles opcode 0x9b
7497****************************************************************************/
7498static void
7499x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7500{
7501    START_OF_INSTR();
7502    DECODE_PRINTF("WAIT");
7503    TRACE_AND_STEP();
7504    /* NADA.  */
7505    DECODE_CLEAR_SEGOVR();
7506    END_OF_INSTR();
7507}
7508
7509/****************************************************************************
7510REMARKS:
7511Handles opcode 0x9c
7512****************************************************************************/
7513static void
7514x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7515{
7516    u32 flags;
7517
7518    START_OF_INSTR();
7519    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7520        DECODE_PRINTF("PUSHFD\n");
7521    }
7522    else {
7523        DECODE_PRINTF("PUSHF\n");
7524    }
7525    TRACE_AND_STEP();
7526
7527    /* clear out *all* bits not representing flags, and turn on real bits */
7528    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7529    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7530        push_long(flags);
7531    }
7532    else {
7533        push_word((u16) flags);
7534    }
7535    DECODE_CLEAR_SEGOVR();
7536    END_OF_INSTR();
7537}
7538
7539/****************************************************************************
7540REMARKS:
7541Handles opcode 0x9d
7542****************************************************************************/
7543static void
7544x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7545{
7546    START_OF_INSTR();
7547    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7548        DECODE_PRINTF("POPFD\n");
7549    }
7550    else {
7551        DECODE_PRINTF("POPF\n");
7552    }
7553    TRACE_AND_STEP();
7554    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7555        M.x86.R_EFLG = pop_long();
7556    }
7557    else {
7558        M.x86.R_FLG = pop_word();
7559    }
7560    DECODE_CLEAR_SEGOVR();
7561    END_OF_INSTR();
7562}
7563
7564/****************************************************************************
7565REMARKS:
7566Handles opcode 0x9e
7567****************************************************************************/
7568static void
7569x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7570{
7571    START_OF_INSTR();
7572    DECODE_PRINTF("SAHF\n");
7573    TRACE_AND_STEP();
7574    /* clear the lower bits of the flag register */
7575    M.x86.R_FLG &= 0xffffff00;
7576    /* or in the AH register into the flags register */
7577    M.x86.R_FLG |= M.x86.R_AH;
7578    DECODE_CLEAR_SEGOVR();
7579    END_OF_INSTR();
7580}
7581
7582/****************************************************************************
7583REMARKS:
7584Handles opcode 0x9f
7585****************************************************************************/
7586static void
7587x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7588{
7589    START_OF_INSTR();
7590    DECODE_PRINTF("LAHF\n");
7591    TRACE_AND_STEP();
7592    M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
7593    /* Undocumented TC++ behavior??? Nope.  It's documented, but
7594       you have to look real hard to notice it. */
7595    M.x86.R_AH |= 0x2;
7596    DECODE_CLEAR_SEGOVR();
7597    END_OF_INSTR();
7598}
7599
7600/****************************************************************************
7601REMARKS:
7602Handles opcode 0xa0
7603****************************************************************************/
7604static void
7605x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7606{
7607    u16 offset;
7608
7609    START_OF_INSTR();
7610    DECODE_PRINTF("MOV\tAL,");
7611    offset = fetch_word_imm();
7612    DECODE_PRINTF2("[%04x]\n", offset);
7613    TRACE_AND_STEP();
7614    M.x86.R_AL = fetch_data_byte(offset);
7615    DECODE_CLEAR_SEGOVR();
7616    END_OF_INSTR();
7617}
7618
7619/****************************************************************************
7620REMARKS:
7621Handles opcode 0xa1
7622****************************************************************************/
7623static void
7624x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7625{
7626    u16 offset;
7627
7628    START_OF_INSTR();
7629    offset = fetch_word_imm();
7630    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7631        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7632    }
7633    else {
7634        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7635    }
7636    TRACE_AND_STEP();
7637    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7638        M.x86.R_EAX = fetch_data_long(offset);
7639    }
7640    else {
7641        M.x86.R_AX = fetch_data_word(offset);
7642    }
7643    DECODE_CLEAR_SEGOVR();
7644    END_OF_INSTR();
7645}
7646
7647/****************************************************************************
7648REMARKS:
7649Handles opcode 0xa2
7650****************************************************************************/
7651static void
7652x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7653{
7654    u16 offset;
7655
7656    START_OF_INSTR();
7657    DECODE_PRINTF("MOV\t");
7658    offset = fetch_word_imm();
7659    DECODE_PRINTF2("[%04x],AL\n", offset);
7660    TRACE_AND_STEP();
7661    store_data_byte(offset, M.x86.R_AL);
7662    DECODE_CLEAR_SEGOVR();
7663    END_OF_INSTR();
7664}
7665
7666/****************************************************************************
7667REMARKS:
7668Handles opcode 0xa3
7669****************************************************************************/
7670static void
7671x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7672{
7673    u16 offset;
7674
7675    START_OF_INSTR();
7676    offset = fetch_word_imm();
7677    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7678        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7679    }
7680    else {
7681        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7682    }
7683    TRACE_AND_STEP();
7684    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7685        store_data_long(offset, M.x86.R_EAX);
7686    }
7687    else {
7688        store_data_word(offset, M.x86.R_AX);
7689    }
7690    DECODE_CLEAR_SEGOVR();
7691    END_OF_INSTR();
7692}
7693
7694/****************************************************************************
7695REMARKS:
7696Handles opcode 0xa4
7697****************************************************************************/
7698static void
7699x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7700{
7701    u8 val;
7702    u32 count;
7703    int inc;
7704
7705    START_OF_INSTR();
7706    DECODE_PRINTF("MOVS\tBYTE\n");
7707    if (ACCESS_FLAG(F_DF))      /* down */
7708        inc = -1;
7709    else
7710        inc = 1;
7711    TRACE_AND_STEP();
7712    count = 1;
7713    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7714        /* don't care whether REPE or REPNE */
7715        /* move them until CX is ZERO. */
7716        count = M.x86.R_CX;
7717        M.x86.R_CX = 0;
7718        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7719    }
7720    while (count--) {
7721        val = fetch_data_byte(M.x86.R_SI);
7722        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7723        M.x86.R_SI += inc;
7724        M.x86.R_DI += inc;
7725    }
7726    DECODE_CLEAR_SEGOVR();
7727    END_OF_INSTR();
7728}
7729
7730/****************************************************************************
7731REMARKS:
7732Handles opcode 0xa5
7733****************************************************************************/
7734static void
7735x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7736{
7737    u32 val;
7738    int inc;
7739    u32 count;
7740
7741    START_OF_INSTR();
7742    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7743        DECODE_PRINTF("MOVS\tDWORD\n");
7744        if (ACCESS_FLAG(F_DF))  /* down */
7745            inc = -4;
7746        else
7747            inc = 4;
7748    }
7749    else {
7750        DECODE_PRINTF("MOVS\tWORD\n");
7751        if (ACCESS_FLAG(F_DF))  /* down */
7752            inc = -2;
7753        else
7754            inc = 2;
7755    }
7756    TRACE_AND_STEP();
7757    count = 1;
7758    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7759        /* don't care whether REPE or REPNE */
7760        /* move them until CX is ZERO. */
7761        count = M.x86.R_CX;
7762        M.x86.R_CX = 0;
7763        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7764    }
7765    while (count--) {
7766        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7767            val = fetch_data_long(M.x86.R_SI);
7768            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7769        }
7770        else {
7771            val = fetch_data_word(M.x86.R_SI);
7772            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
7773        }
7774        M.x86.R_SI += inc;
7775        M.x86.R_DI += inc;
7776    }
7777    DECODE_CLEAR_SEGOVR();
7778    END_OF_INSTR();
7779}
7780
7781/****************************************************************************
7782REMARKS:
7783Handles opcode 0xa6
7784****************************************************************************/
7785static void
7786x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7787{
7788    s8 val1, val2;
7789    int inc;
7790
7791    START_OF_INSTR();
7792    DECODE_PRINTF("CMPS\tBYTE\n");
7793    TRACE_AND_STEP();
7794    if (ACCESS_FLAG(F_DF))      /* down */
7795        inc = -1;
7796    else
7797        inc = 1;
7798
7799    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7800        /* REPE  */
7801        /* move them until CX is ZERO. */
7802        while (M.x86.R_CX != 0) {
7803            val1 = fetch_data_byte(M.x86.R_SI);
7804            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7805            cmp_byte(val1, val2);
7806            M.x86.R_CX -= 1;
7807            M.x86.R_SI += inc;
7808            M.x86.R_DI += inc;
7809            if (ACCESS_FLAG(F_ZF) == 0)
7810                break;
7811        }
7812        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7813    }
7814    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7815        /* REPNE  */
7816        /* move them until CX is ZERO. */
7817        while (M.x86.R_CX != 0) {
7818            val1 = fetch_data_byte(M.x86.R_SI);
7819            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7820            cmp_byte(val1, val2);
7821            M.x86.R_CX -= 1;
7822            M.x86.R_SI += inc;
7823            M.x86.R_DI += inc;
7824            if (ACCESS_FLAG(F_ZF))
7825                break;          /* zero flag set means equal */
7826        }
7827        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7828    }
7829    else {
7830        val1 = fetch_data_byte(M.x86.R_SI);
7831        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7832        cmp_byte(val1, val2);
7833        M.x86.R_SI += inc;
7834        M.x86.R_DI += inc;
7835    }
7836    DECODE_CLEAR_SEGOVR();
7837    END_OF_INSTR();
7838}
7839
7840/****************************************************************************
7841REMARKS:
7842Handles opcode 0xa7
7843****************************************************************************/
7844static void
7845x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7846{
7847    u32 val1, val2;
7848    int inc;
7849
7850    START_OF_INSTR();
7851    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7852        DECODE_PRINTF("CMPS\tDWORD\n");
7853        if (ACCESS_FLAG(F_DF))  /* down */
7854            inc = -4;
7855        else
7856            inc = 4;
7857    }
7858    else {
7859        DECODE_PRINTF("CMPS\tWORD\n");
7860        if (ACCESS_FLAG(F_DF))  /* down */
7861            inc = -2;
7862        else
7863            inc = 2;
7864    }
7865    TRACE_AND_STEP();
7866    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7867        /* REPE  */
7868        /* move them until CX is ZERO. */
7869        while (M.x86.R_CX != 0) {
7870            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7871                val1 = fetch_data_long(M.x86.R_SI);
7872                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7873                cmp_long(val1, val2);
7874            }
7875            else {
7876                val1 = fetch_data_word(M.x86.R_SI);
7877                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7878                cmp_word((u16) val1, (u16) val2);
7879            }
7880            M.x86.R_CX -= 1;
7881            M.x86.R_SI += inc;
7882            M.x86.R_DI += inc;
7883            if (ACCESS_FLAG(F_ZF) == 0)
7884                break;
7885        }
7886        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7887    }
7888    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7889        /* REPNE  */
7890        /* move them until CX is ZERO. */
7891        while (M.x86.R_CX != 0) {
7892            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7893                val1 = fetch_data_long(M.x86.R_SI);
7894                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7895                cmp_long(val1, val2);
7896            }
7897            else {
7898                val1 = fetch_data_word(M.x86.R_SI);
7899                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7900                cmp_word((u16) val1, (u16) val2);
7901            }
7902            M.x86.R_CX -= 1;
7903            M.x86.R_SI += inc;
7904            M.x86.R_DI += inc;
7905            if (ACCESS_FLAG(F_ZF))
7906                break;          /* zero flag set means equal */
7907        }
7908        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7909    }
7910    else {
7911        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7912            val1 = fetch_data_long(M.x86.R_SI);
7913            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7914            cmp_long(val1, val2);
7915        }
7916        else {
7917            val1 = fetch_data_word(M.x86.R_SI);
7918            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7919            cmp_word((u16) val1, (u16) val2);
7920        }
7921        M.x86.R_SI += inc;
7922        M.x86.R_DI += inc;
7923    }
7924    DECODE_CLEAR_SEGOVR();
7925    END_OF_INSTR();
7926}
7927
7928/****************************************************************************
7929REMARKS:
7930Handles opcode 0xa8
7931****************************************************************************/
7932static void
7933x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7934{
7935    int imm;
7936
7937    START_OF_INSTR();
7938    DECODE_PRINTF("TEST\tAL,");
7939    imm = fetch_byte_imm();
7940    DECODE_PRINTF2("%04x\n", imm);
7941    TRACE_AND_STEP();
7942    test_byte(M.x86.R_AL, (u8) imm);
7943    DECODE_CLEAR_SEGOVR();
7944    END_OF_INSTR();
7945}
7946
7947/****************************************************************************
7948REMARKS:
7949Handles opcode 0xa9
7950****************************************************************************/
7951static void
7952x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7953{
7954    u32 srcval;
7955
7956    START_OF_INSTR();
7957    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7958        DECODE_PRINTF("TEST\tEAX,");
7959        srcval = fetch_long_imm();
7960    }
7961    else {
7962        DECODE_PRINTF("TEST\tAX,");
7963        srcval = fetch_word_imm();
7964    }
7965    DECODE_PRINTF2("%x\n", srcval);
7966    TRACE_AND_STEP();
7967    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7968        test_long(M.x86.R_EAX, srcval);
7969    }
7970    else {
7971        test_word(M.x86.R_AX, (u16) srcval);
7972    }
7973    DECODE_CLEAR_SEGOVR();
7974    END_OF_INSTR();
7975}
7976
7977/****************************************************************************
7978REMARKS:
7979Handles opcode 0xaa
7980****************************************************************************/
7981static void
7982x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7983{
7984    int inc;
7985
7986    START_OF_INSTR();
7987    DECODE_PRINTF("STOS\tBYTE\n");
7988    if (ACCESS_FLAG(F_DF))      /* down */
7989        inc = -1;
7990    else
7991        inc = 1;
7992    TRACE_AND_STEP();
7993    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7994        /* don't care whether REPE or REPNE */
7995        /* move them until CX is ZERO. */
7996        while (M.x86.R_CX != 0) {
7997            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7998            M.x86.R_CX -= 1;
7999            M.x86.R_DI += inc;
8000        }
8001        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8002    }
8003    else {
8004        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8005        M.x86.R_DI += inc;
8006    }
8007    DECODE_CLEAR_SEGOVR();
8008    END_OF_INSTR();
8009}
8010
8011/****************************************************************************
8012REMARKS:
8013Handles opcode 0xab
8014****************************************************************************/
8015static void
8016x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
8017{
8018    int inc;
8019    u32 count;
8020
8021    START_OF_INSTR();
8022    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023        DECODE_PRINTF("STOS\tDWORD\n");
8024        if (ACCESS_FLAG(F_DF))  /* down */
8025            inc = -4;
8026        else
8027            inc = 4;
8028    }
8029    else {
8030        DECODE_PRINTF("STOS\tWORD\n");
8031        if (ACCESS_FLAG(F_DF))  /* down */
8032            inc = -2;
8033        else
8034            inc = 2;
8035    }
8036    TRACE_AND_STEP();
8037    count = 1;
8038    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8039        /* don't care whether REPE or REPNE */
8040        /* move them until CX is ZERO. */
8041        count = M.x86.R_CX;
8042        M.x86.R_CX = 0;
8043        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8044    }
8045    while (count--) {
8046        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8047            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
8048        }
8049        else {
8050            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
8051        }
8052        M.x86.R_DI += inc;
8053    }
8054    DECODE_CLEAR_SEGOVR();
8055    END_OF_INSTR();
8056}
8057
8058/****************************************************************************
8059REMARKS:
8060Handles opcode 0xac
8061****************************************************************************/
8062static void
8063x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
8064{
8065    int inc;
8066
8067    START_OF_INSTR();
8068    DECODE_PRINTF("LODS\tBYTE\n");
8069    TRACE_AND_STEP();
8070    if (ACCESS_FLAG(F_DF))      /* down */
8071        inc = -1;
8072    else
8073        inc = 1;
8074    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8075        /* don't care whether REPE or REPNE */
8076        /* move them until CX is ZERO. */
8077        while (M.x86.R_CX != 0) {
8078            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8079            M.x86.R_CX -= 1;
8080            M.x86.R_SI += inc;
8081        }
8082        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8083    }
8084    else {
8085        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8086        M.x86.R_SI += inc;
8087    }
8088    DECODE_CLEAR_SEGOVR();
8089    END_OF_INSTR();
8090}
8091
8092/****************************************************************************
8093REMARKS:
8094Handles opcode 0xad
8095****************************************************************************/
8096static void
8097x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
8098{
8099    int inc;
8100    u32 count;
8101
8102    START_OF_INSTR();
8103    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104        DECODE_PRINTF("LODS\tDWORD\n");
8105        if (ACCESS_FLAG(F_DF))  /* down */
8106            inc = -4;
8107        else
8108            inc = 4;
8109    }
8110    else {
8111        DECODE_PRINTF("LODS\tWORD\n");
8112        if (ACCESS_FLAG(F_DF))  /* down */
8113            inc = -2;
8114        else
8115            inc = 2;
8116    }
8117    TRACE_AND_STEP();
8118    count = 1;
8119    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8120        /* don't care whether REPE or REPNE */
8121        /* move them until CX is ZERO. */
8122        count = M.x86.R_CX;
8123        M.x86.R_CX = 0;
8124        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8125    }
8126    while (count--) {
8127        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8128            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
8129        }
8130        else {
8131            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
8132        }
8133        M.x86.R_SI += inc;
8134    }
8135    DECODE_CLEAR_SEGOVR();
8136    END_OF_INSTR();
8137}
8138
8139/****************************************************************************
8140REMARKS:
8141Handles opcode 0xae
8142****************************************************************************/
8143static void
8144x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
8145{
8146    s8 val2;
8147    int inc;
8148
8149    START_OF_INSTR();
8150    DECODE_PRINTF("SCAS\tBYTE\n");
8151    TRACE_AND_STEP();
8152    if (ACCESS_FLAG(F_DF))      /* down */
8153        inc = -1;
8154    else
8155        inc = 1;
8156    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8157        /* REPE  */
8158        /* move them until CX is ZERO. */
8159        while (M.x86.R_CX != 0) {
8160            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8161            cmp_byte(M.x86.R_AL, val2);
8162            M.x86.R_CX -= 1;
8163            M.x86.R_DI += inc;
8164            if (ACCESS_FLAG(F_ZF) == 0)
8165                break;
8166        }
8167        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8168    }
8169    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8170        /* REPNE  */
8171        /* move them until CX is ZERO. */
8172        while (M.x86.R_CX != 0) {
8173            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8174            cmp_byte(M.x86.R_AL, val2);
8175            M.x86.R_CX -= 1;
8176            M.x86.R_DI += inc;
8177            if (ACCESS_FLAG(F_ZF))
8178                break;          /* zero flag set means equal */
8179        }
8180        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8181    }
8182    else {
8183        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8184        cmp_byte(M.x86.R_AL, val2);
8185        M.x86.R_DI += inc;
8186    }
8187    DECODE_CLEAR_SEGOVR();
8188    END_OF_INSTR();
8189}
8190
8191/****************************************************************************
8192REMARKS:
8193Handles opcode 0xaf
8194****************************************************************************/
8195static void
8196x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
8197{
8198    int inc;
8199    u32 val;
8200
8201    START_OF_INSTR();
8202    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8203        DECODE_PRINTF("SCAS\tDWORD\n");
8204        if (ACCESS_FLAG(F_DF))  /* down */
8205            inc = -4;
8206        else
8207            inc = 4;
8208    }
8209    else {
8210        DECODE_PRINTF("SCAS\tWORD\n");
8211        if (ACCESS_FLAG(F_DF))  /* down */
8212            inc = -2;
8213        else
8214            inc = 2;
8215    }
8216    TRACE_AND_STEP();
8217    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8218        /* REPE  */
8219        /* move them until CX is ZERO. */
8220        while (M.x86.R_CX != 0) {
8221            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8222                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8223                cmp_long(M.x86.R_EAX, val);
8224            }
8225            else {
8226                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8227                cmp_word(M.x86.R_AX, (u16) val);
8228            }
8229            M.x86.R_CX -= 1;
8230            M.x86.R_DI += inc;
8231            if (ACCESS_FLAG(F_ZF) == 0)
8232                break;
8233        }
8234        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8235    }
8236    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8237        /* REPNE  */
8238        /* move them until CX is ZERO. */
8239        while (M.x86.R_CX != 0) {
8240            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8241                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8242                cmp_long(M.x86.R_EAX, val);
8243            }
8244            else {
8245                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8246                cmp_word(M.x86.R_AX, (u16) val);
8247            }
8248            M.x86.R_CX -= 1;
8249            M.x86.R_DI += inc;
8250            if (ACCESS_FLAG(F_ZF))
8251                break;          /* zero flag set means equal */
8252        }
8253        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8254    }
8255    else {
8256        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8257            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8258            cmp_long(M.x86.R_EAX, val);
8259        }
8260        else {
8261            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8262            cmp_word(M.x86.R_AX, (u16) val);
8263        }
8264        M.x86.R_DI += inc;
8265    }
8266    DECODE_CLEAR_SEGOVR();
8267    END_OF_INSTR();
8268}
8269
8270/****************************************************************************
8271REMARKS:
8272Handles opcode 0xb0
8273****************************************************************************/
8274static void
8275x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
8276{
8277    u8 imm;
8278
8279    START_OF_INSTR();
8280    DECODE_PRINTF("MOV\tAL,");
8281    imm = fetch_byte_imm();
8282    DECODE_PRINTF2("%x\n", imm);
8283    TRACE_AND_STEP();
8284    M.x86.R_AL = imm;
8285    DECODE_CLEAR_SEGOVR();
8286    END_OF_INSTR();
8287}
8288
8289/****************************************************************************
8290REMARKS:
8291Handles opcode 0xb1
8292****************************************************************************/
8293static void
8294x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
8295{
8296    u8 imm;
8297
8298    START_OF_INSTR();
8299    DECODE_PRINTF("MOV\tCL,");
8300    imm = fetch_byte_imm();
8301    DECODE_PRINTF2("%x\n", imm);
8302    TRACE_AND_STEP();
8303    M.x86.R_CL = imm;
8304    DECODE_CLEAR_SEGOVR();
8305    END_OF_INSTR();
8306}
8307
8308/****************************************************************************
8309REMARKS:
8310Handles opcode 0xb2
8311****************************************************************************/
8312static void
8313x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
8314{
8315    u8 imm;
8316
8317    START_OF_INSTR();
8318    DECODE_PRINTF("MOV\tDL,");
8319    imm = fetch_byte_imm();
8320    DECODE_PRINTF2("%x\n", imm);
8321    TRACE_AND_STEP();
8322    M.x86.R_DL = imm;
8323    DECODE_CLEAR_SEGOVR();
8324    END_OF_INSTR();
8325}
8326
8327/****************************************************************************
8328REMARKS:
8329Handles opcode 0xb3
8330****************************************************************************/
8331static void
8332x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
8333{
8334    u8 imm;
8335
8336    START_OF_INSTR();
8337    DECODE_PRINTF("MOV\tBL,");
8338    imm = fetch_byte_imm();
8339    DECODE_PRINTF2("%x\n", imm);
8340    TRACE_AND_STEP();
8341    M.x86.R_BL = imm;
8342    DECODE_CLEAR_SEGOVR();
8343    END_OF_INSTR();
8344}
8345
8346/****************************************************************************
8347REMARKS:
8348Handles opcode 0xb4
8349****************************************************************************/
8350static void
8351x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
8352{
8353    u8 imm;
8354
8355    START_OF_INSTR();
8356    DECODE_PRINTF("MOV\tAH,");
8357    imm = fetch_byte_imm();
8358    DECODE_PRINTF2("%x\n", imm);
8359    TRACE_AND_STEP();
8360    M.x86.R_AH = imm;
8361    DECODE_CLEAR_SEGOVR();
8362    END_OF_INSTR();
8363}
8364
8365/****************************************************************************
8366REMARKS:
8367Handles opcode 0xb5
8368****************************************************************************/
8369static void
8370x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
8371{
8372    u8 imm;
8373
8374    START_OF_INSTR();
8375    DECODE_PRINTF("MOV\tCH,");
8376    imm = fetch_byte_imm();
8377    DECODE_PRINTF2("%x\n", imm);
8378    TRACE_AND_STEP();
8379    M.x86.R_CH = imm;
8380    DECODE_CLEAR_SEGOVR();
8381    END_OF_INSTR();
8382}
8383
8384/****************************************************************************
8385REMARKS:
8386Handles opcode 0xb6
8387****************************************************************************/
8388static void
8389x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
8390{
8391    u8 imm;
8392
8393    START_OF_INSTR();
8394    DECODE_PRINTF("MOV\tDH,");
8395    imm = fetch_byte_imm();
8396    DECODE_PRINTF2("%x\n", imm);
8397    TRACE_AND_STEP();
8398    M.x86.R_DH = imm;
8399    DECODE_CLEAR_SEGOVR();
8400    END_OF_INSTR();
8401}
8402
8403/****************************************************************************
8404REMARKS:
8405Handles opcode 0xb7
8406****************************************************************************/
8407static void
8408x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
8409{
8410    u8 imm;
8411
8412    START_OF_INSTR();
8413    DECODE_PRINTF("MOV\tBH,");
8414    imm = fetch_byte_imm();
8415    DECODE_PRINTF2("%x\n", imm);
8416    TRACE_AND_STEP();
8417    M.x86.R_BH = imm;
8418    DECODE_CLEAR_SEGOVR();
8419    END_OF_INSTR();
8420}
8421
8422/****************************************************************************
8423REMARKS:
8424Handles opcode 0xb8
8425****************************************************************************/
8426static void
8427x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
8428{
8429    u32 srcval;
8430
8431    START_OF_INSTR();
8432    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8433        DECODE_PRINTF("MOV\tEAX,");
8434        srcval = fetch_long_imm();
8435    }
8436    else {
8437        DECODE_PRINTF("MOV\tAX,");
8438        srcval = fetch_word_imm();
8439    }
8440    DECODE_PRINTF2("%x\n", srcval);
8441    TRACE_AND_STEP();
8442    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8443        M.x86.R_EAX = srcval;
8444    }
8445    else {
8446        M.x86.R_AX = (u16) srcval;
8447    }
8448    DECODE_CLEAR_SEGOVR();
8449    END_OF_INSTR();
8450}
8451
8452/****************************************************************************
8453REMARKS:
8454Handles opcode 0xb9
8455****************************************************************************/
8456static void
8457x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8458{
8459    u32 srcval;
8460
8461    START_OF_INSTR();
8462    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8463        DECODE_PRINTF("MOV\tECX,");
8464        srcval = fetch_long_imm();
8465    }
8466    else {
8467        DECODE_PRINTF("MOV\tCX,");
8468        srcval = fetch_word_imm();
8469    }
8470    DECODE_PRINTF2("%x\n", srcval);
8471    TRACE_AND_STEP();
8472    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8473        M.x86.R_ECX = srcval;
8474    }
8475    else {
8476        M.x86.R_CX = (u16) srcval;
8477    }
8478    DECODE_CLEAR_SEGOVR();
8479    END_OF_INSTR();
8480}
8481
8482/****************************************************************************
8483REMARKS:
8484Handles opcode 0xba
8485****************************************************************************/
8486static void
8487x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8488{
8489    u32 srcval;
8490
8491    START_OF_INSTR();
8492    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8493        DECODE_PRINTF("MOV\tEDX,");
8494        srcval = fetch_long_imm();
8495    }
8496    else {
8497        DECODE_PRINTF("MOV\tDX,");
8498        srcval = fetch_word_imm();
8499    }
8500    DECODE_PRINTF2("%x\n", srcval);
8501    TRACE_AND_STEP();
8502    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8503        M.x86.R_EDX = srcval;
8504    }
8505    else {
8506        M.x86.R_DX = (u16) srcval;
8507    }
8508    DECODE_CLEAR_SEGOVR();
8509    END_OF_INSTR();
8510}
8511
8512/****************************************************************************
8513REMARKS:
8514Handles opcode 0xbb
8515****************************************************************************/
8516static void
8517x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8518{
8519    u32 srcval;
8520
8521    START_OF_INSTR();
8522    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8523        DECODE_PRINTF("MOV\tEBX,");
8524        srcval = fetch_long_imm();
8525    }
8526    else {
8527        DECODE_PRINTF("MOV\tBX,");
8528        srcval = fetch_word_imm();
8529    }
8530    DECODE_PRINTF2("%x\n", srcval);
8531    TRACE_AND_STEP();
8532    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8533        M.x86.R_EBX = srcval;
8534    }
8535    else {
8536        M.x86.R_BX = (u16) srcval;
8537    }
8538    DECODE_CLEAR_SEGOVR();
8539    END_OF_INSTR();
8540}
8541
8542/****************************************************************************
8543REMARKS:
8544Handles opcode 0xbc
8545****************************************************************************/
8546static void
8547x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8548{
8549    u32 srcval;
8550
8551    START_OF_INSTR();
8552    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8553        DECODE_PRINTF("MOV\tESP,");
8554        srcval = fetch_long_imm();
8555    }
8556    else {
8557        DECODE_PRINTF("MOV\tSP,");
8558        srcval = fetch_word_imm();
8559    }
8560    DECODE_PRINTF2("%x\n", srcval);
8561    TRACE_AND_STEP();
8562    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8563        M.x86.R_ESP = srcval;
8564    }
8565    else {
8566        M.x86.R_SP = (u16) srcval;
8567    }
8568    DECODE_CLEAR_SEGOVR();
8569    END_OF_INSTR();
8570}
8571
8572/****************************************************************************
8573REMARKS:
8574Handles opcode 0xbd
8575****************************************************************************/
8576static void
8577x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8578{
8579    u32 srcval;
8580
8581    START_OF_INSTR();
8582    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8583        DECODE_PRINTF("MOV\tEBP,");
8584        srcval = fetch_long_imm();
8585    }
8586    else {
8587        DECODE_PRINTF("MOV\tBP,");
8588        srcval = fetch_word_imm();
8589    }
8590    DECODE_PRINTF2("%x\n", srcval);
8591    TRACE_AND_STEP();
8592    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8593        M.x86.R_EBP = srcval;
8594    }
8595    else {
8596        M.x86.R_BP = (u16) srcval;
8597    }
8598    DECODE_CLEAR_SEGOVR();
8599    END_OF_INSTR();
8600}
8601
8602/****************************************************************************
8603REMARKS:
8604Handles opcode 0xbe
8605****************************************************************************/
8606static void
8607x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8608{
8609    u32 srcval;
8610
8611    START_OF_INSTR();
8612    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613        DECODE_PRINTF("MOV\tESI,");
8614        srcval = fetch_long_imm();
8615    }
8616    else {
8617        DECODE_PRINTF("MOV\tSI,");
8618        srcval = fetch_word_imm();
8619    }
8620    DECODE_PRINTF2("%x\n", srcval);
8621    TRACE_AND_STEP();
8622    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8623        M.x86.R_ESI = srcval;
8624    }
8625    else {
8626        M.x86.R_SI = (u16) srcval;
8627    }
8628    DECODE_CLEAR_SEGOVR();
8629    END_OF_INSTR();
8630}
8631
8632/****************************************************************************
8633REMARKS:
8634Handles opcode 0xbf
8635****************************************************************************/
8636static void
8637x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8638{
8639    u32 srcval;
8640
8641    START_OF_INSTR();
8642    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8643        DECODE_PRINTF("MOV\tEDI,");
8644        srcval = fetch_long_imm();
8645    }
8646    else {
8647        DECODE_PRINTF("MOV\tDI,");
8648        srcval = fetch_word_imm();
8649    }
8650    DECODE_PRINTF2("%x\n", srcval);
8651    TRACE_AND_STEP();
8652    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8653        M.x86.R_EDI = srcval;
8654    }
8655    else {
8656        M.x86.R_DI = (u16) srcval;
8657    }
8658    DECODE_CLEAR_SEGOVR();
8659    END_OF_INSTR();
8660}
8661
8662/* used by opcodes c0, d0, and d2. */
8663static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
8664    rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte,       /* sal_byte === shl_byte  by definition */
8665sar_byte,};
8666
8667/****************************************************************************
8668REMARKS:
8669Handles opcode 0xc0
8670****************************************************************************/
8671static void
8672x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8673{
8674    int mod, rl, rh;
8675    u8 *destreg;
8676    uint destoffset;
8677    u8 destval;
8678    u8 amt;
8679
8680    /*
8681     * Yet another weirdo special case instruction format.  Part of
8682     * the opcode held below in "RH".  Doubly nested case would
8683     * result, except that the decoded instruction
8684     */
8685    START_OF_INSTR();
8686    FETCH_DECODE_MODRM(mod, rh, rl);
8687#ifdef DEBUG
8688    if (DEBUG_DECODE()) {
8689        /* XXX DECODE_PRINTF may be changed to something more
8690           general, so that it is important to leave the strings
8691           in the same format, even though the result is that the
8692           above test is done twice. */
8693
8694        switch (rh) {
8695        case 0:
8696            DECODE_PRINTF("ROL\t");
8697            break;
8698        case 1:
8699            DECODE_PRINTF("ROR\t");
8700            break;
8701        case 2:
8702            DECODE_PRINTF("RCL\t");
8703            break;
8704        case 3:
8705            DECODE_PRINTF("RCR\t");
8706            break;
8707        case 4:
8708            DECODE_PRINTF("SHL\t");
8709            break;
8710        case 5:
8711            DECODE_PRINTF("SHR\t");
8712            break;
8713        case 6:
8714            DECODE_PRINTF("SAL\t");
8715            break;
8716        case 7:
8717            DECODE_PRINTF("SAR\t");
8718            break;
8719        }
8720    }
8721#endif
8722    /* know operation, decode the mod byte to find the addressing
8723       mode. */
8724    switch (mod) {
8725    case 0:
8726        DECODE_PRINTF("BYTE PTR ");
8727        destoffset = decode_rm00_address(rl);
8728        amt = fetch_byte_imm();
8729        DECODE_PRINTF2(",%x\n", amt);
8730        destval = fetch_data_byte(destoffset);
8731        TRACE_AND_STEP();
8732        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8733        store_data_byte(destoffset, destval);
8734        break;
8735    case 1:
8736        DECODE_PRINTF("BYTE PTR ");
8737        destoffset = decode_rm01_address(rl);
8738        amt = fetch_byte_imm();
8739        DECODE_PRINTF2(",%x\n", amt);
8740        destval = fetch_data_byte(destoffset);
8741        TRACE_AND_STEP();
8742        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8743        store_data_byte(destoffset, destval);
8744        break;
8745    case 2:
8746        DECODE_PRINTF("BYTE PTR ");
8747        destoffset = decode_rm10_address(rl);
8748        amt = fetch_byte_imm();
8749        DECODE_PRINTF2(",%x\n", amt);
8750        destval = fetch_data_byte(destoffset);
8751        TRACE_AND_STEP();
8752        destval = (*opcD0_byte_operation[rh]) (destval, amt);
8753        store_data_byte(destoffset, destval);
8754        break;
8755    case 3:                    /* register to register */
8756        destreg = DECODE_RM_BYTE_REGISTER(rl);
8757        amt = fetch_byte_imm();
8758        DECODE_PRINTF2(",%x\n", amt);
8759        TRACE_AND_STEP();
8760        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8761        *destreg = destval;
8762        break;
8763    }
8764    DECODE_CLEAR_SEGOVR();
8765    END_OF_INSTR();
8766}
8767
8768/* used by opcodes c1, d1, and d3. */
8769static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
8770    rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word,       /* sal_byte === shl_byte  by definition */
8771sar_word,};
8772
8773/* used by opcodes c1, d1, and d3. */
8774static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
8775    rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long,       /* sal_byte === shl_byte  by definition */
8776sar_long,};
8777
8778/****************************************************************************
8779REMARKS:
8780Handles opcode 0xc1
8781****************************************************************************/
8782static void
8783x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8784{
8785    int mod, rl, rh;
8786    uint destoffset;
8787    u8 amt;
8788
8789    /*
8790     * Yet another weirdo special case instruction format.  Part of
8791     * the opcode held below in "RH".  Doubly nested case would
8792     * result, except that the decoded instruction
8793     */
8794    START_OF_INSTR();
8795    FETCH_DECODE_MODRM(mod, rh, rl);
8796#ifdef DEBUG
8797    if (DEBUG_DECODE()) {
8798        /* XXX DECODE_PRINTF may be changed to something more
8799           general, so that it is important to leave the strings
8800           in the same format, even though the result is that the
8801           above test is done twice. */
8802
8803        switch (rh) {
8804        case 0:
8805            DECODE_PRINTF("ROL\t");
8806            break;
8807        case 1:
8808            DECODE_PRINTF("ROR\t");
8809            break;
8810        case 2:
8811            DECODE_PRINTF("RCL\t");
8812            break;
8813        case 3:
8814            DECODE_PRINTF("RCR\t");
8815            break;
8816        case 4:
8817            DECODE_PRINTF("SHL\t");
8818            break;
8819        case 5:
8820            DECODE_PRINTF("SHR\t");
8821            break;
8822        case 6:
8823            DECODE_PRINTF("SAL\t");
8824            break;
8825        case 7:
8826            DECODE_PRINTF("SAR\t");
8827            break;
8828        }
8829    }
8830#endif
8831    /* know operation, decode the mod byte to find the addressing
8832       mode. */
8833    switch (mod) {
8834    case 0:
8835        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8836            u32 destval;
8837
8838            DECODE_PRINTF("DWORD PTR ");
8839            destoffset = decode_rm00_address(rl);
8840            amt = fetch_byte_imm();
8841            DECODE_PRINTF2(",%x\n", amt);
8842            destval = fetch_data_long(destoffset);
8843            TRACE_AND_STEP();
8844            destval = (*opcD1_long_operation[rh]) (destval, amt);
8845            store_data_long(destoffset, destval);
8846        }
8847        else {
8848            u16 destval;
8849
8850            DECODE_PRINTF("WORD PTR ");
8851            destoffset = decode_rm00_address(rl);
8852            amt = fetch_byte_imm();
8853            DECODE_PRINTF2(",%x\n", amt);
8854            destval = fetch_data_word(destoffset);
8855            TRACE_AND_STEP();
8856            destval = (*opcD1_word_operation[rh]) (destval, amt);
8857            store_data_word(destoffset, destval);
8858        }
8859        break;
8860    case 1:
8861        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8862            u32 destval;
8863
8864            DECODE_PRINTF("DWORD PTR ");
8865            destoffset = decode_rm01_address(rl);
8866            amt = fetch_byte_imm();
8867            DECODE_PRINTF2(",%x\n", amt);
8868            destval = fetch_data_long(destoffset);
8869            TRACE_AND_STEP();
8870            destval = (*opcD1_long_operation[rh]) (destval, amt);
8871            store_data_long(destoffset, destval);
8872        }
8873        else {
8874            u16 destval;
8875
8876            DECODE_PRINTF("WORD PTR ");
8877            destoffset = decode_rm01_address(rl);
8878            amt = fetch_byte_imm();
8879            DECODE_PRINTF2(",%x\n", amt);
8880            destval = fetch_data_word(destoffset);
8881            TRACE_AND_STEP();
8882            destval = (*opcD1_word_operation[rh]) (destval, amt);
8883            store_data_word(destoffset, destval);
8884        }
8885        break;
8886    case 2:
8887        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8888            u32 destval;
8889
8890            DECODE_PRINTF("DWORD PTR ");
8891            destoffset = decode_rm10_address(rl);
8892            amt = fetch_byte_imm();
8893            DECODE_PRINTF2(",%x\n", amt);
8894            destval = fetch_data_long(destoffset);
8895            TRACE_AND_STEP();
8896            destval = (*opcD1_long_operation[rh]) (destval, amt);
8897            store_data_long(destoffset, destval);
8898        }
8899        else {
8900            u16 destval;
8901
8902            DECODE_PRINTF("WORD PTR ");
8903            destoffset = decode_rm10_address(rl);
8904            amt = fetch_byte_imm();
8905            DECODE_PRINTF2(",%x\n", amt);
8906            destval = fetch_data_word(destoffset);
8907            TRACE_AND_STEP();
8908            destval = (*opcD1_word_operation[rh]) (destval, amt);
8909            store_data_word(destoffset, destval);
8910        }
8911        break;
8912    case 3:                    /* register to register */
8913        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8914            u32 *destreg;
8915
8916            destreg = DECODE_RM_LONG_REGISTER(rl);
8917            amt = fetch_byte_imm();
8918            DECODE_PRINTF2(",%x\n", amt);
8919            TRACE_AND_STEP();
8920            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8921        }
8922        else {
8923            u16 *destreg;
8924
8925            destreg = DECODE_RM_WORD_REGISTER(rl);
8926            amt = fetch_byte_imm();
8927            DECODE_PRINTF2(",%x\n", amt);
8928            TRACE_AND_STEP();
8929            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8930        }
8931        break;
8932    }
8933    DECODE_CLEAR_SEGOVR();
8934    END_OF_INSTR();
8935}
8936
8937/****************************************************************************
8938REMARKS:
8939Handles opcode 0xc2
8940****************************************************************************/
8941static void
8942x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8943{
8944    u16 imm;
8945
8946    START_OF_INSTR();
8947    DECODE_PRINTF("RET\t");
8948    imm = fetch_word_imm();
8949    DECODE_PRINTF2("%x\n", imm);
8950    RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8951    TRACE_AND_STEP();
8952    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8953        M.x86.R_EIP = pop_long();
8954    } else {
8955        M.x86.R_IP = pop_word();
8956    }
8957    M.x86.R_SP += imm;
8958    DECODE_CLEAR_SEGOVR();
8959    END_OF_INSTR();
8960}
8961
8962/****************************************************************************
8963REMARKS:
8964Handles opcode 0xc3
8965****************************************************************************/
8966static void
8967x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8968{
8969    START_OF_INSTR();
8970    DECODE_PRINTF("RET\n");
8971    RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8972    TRACE_AND_STEP();
8973    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8974        M.x86.R_EIP = pop_long();
8975    } else {
8976        M.x86.R_IP = pop_word();
8977    }
8978    DECODE_CLEAR_SEGOVR();
8979    END_OF_INSTR();
8980}
8981
8982/****************************************************************************
8983REMARKS:
8984Handles opcode 0xc4
8985****************************************************************************/
8986static void
8987x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8988{
8989    int mod, rh, rl;
8990    u16 *dstreg;
8991    uint srcoffset;
8992
8993    START_OF_INSTR();
8994    DECODE_PRINTF("LES\t");
8995    FETCH_DECODE_MODRM(mod, rh, rl);
8996    switch (mod) {
8997    case 0:
8998        dstreg = DECODE_RM_WORD_REGISTER(rh);
8999        DECODE_PRINTF(",");
9000        srcoffset = decode_rm00_address(rl);
9001        DECODE_PRINTF("\n");
9002        TRACE_AND_STEP();
9003        *dstreg = fetch_data_word(srcoffset);
9004        M.x86.R_ES = fetch_data_word(srcoffset + 2);
9005        break;
9006    case 1:
9007        dstreg = DECODE_RM_WORD_REGISTER(rh);
9008        DECODE_PRINTF(",");
9009        srcoffset = decode_rm01_address(rl);
9010        DECODE_PRINTF("\n");
9011        TRACE_AND_STEP();
9012        *dstreg = fetch_data_word(srcoffset);
9013        M.x86.R_ES = fetch_data_word(srcoffset + 2);
9014        break;
9015    case 2:
9016        dstreg = DECODE_RM_WORD_REGISTER(rh);
9017        DECODE_PRINTF(",");
9018        srcoffset = decode_rm10_address(rl);
9019        DECODE_PRINTF("\n");
9020        TRACE_AND_STEP();
9021        *dstreg = fetch_data_word(srcoffset);
9022        M.x86.R_ES = fetch_data_word(srcoffset + 2);
9023        break;
9024    case 3:                    /* register to register */
9025        /* UNDEFINED! */
9026        TRACE_AND_STEP();
9027    }
9028    DECODE_CLEAR_SEGOVR();
9029    END_OF_INSTR();
9030}
9031
9032/****************************************************************************
9033REMARKS:
9034Handles opcode 0xc5
9035****************************************************************************/
9036static void
9037x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9038{
9039    int mod, rh, rl;
9040    u16 *dstreg;
9041    uint srcoffset;
9042
9043    START_OF_INSTR();
9044    DECODE_PRINTF("LDS\t");
9045    FETCH_DECODE_MODRM(mod, rh, rl);
9046    switch (mod) {
9047    case 0:
9048        dstreg = DECODE_RM_WORD_REGISTER(rh);
9049        DECODE_PRINTF(",");
9050        srcoffset = decode_rm00_address(rl);
9051        DECODE_PRINTF("\n");
9052        TRACE_AND_STEP();
9053        *dstreg = fetch_data_word(srcoffset);
9054        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9055        break;
9056    case 1:
9057        dstreg = DECODE_RM_WORD_REGISTER(rh);
9058        DECODE_PRINTF(",");
9059        srcoffset = decode_rm01_address(rl);
9060        DECODE_PRINTF("\n");
9061        TRACE_AND_STEP();
9062        *dstreg = fetch_data_word(srcoffset);
9063        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9064        break;
9065    case 2:
9066        dstreg = DECODE_RM_WORD_REGISTER(rh);
9067        DECODE_PRINTF(",");
9068        srcoffset = decode_rm10_address(rl);
9069        DECODE_PRINTF("\n");
9070        TRACE_AND_STEP();
9071        *dstreg = fetch_data_word(srcoffset);
9072        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9073        break;
9074    case 3:                    /* register to register */
9075        /* UNDEFINED! */
9076        TRACE_AND_STEP();
9077    }
9078    DECODE_CLEAR_SEGOVR();
9079    END_OF_INSTR();
9080}
9081
9082/****************************************************************************
9083REMARKS:
9084Handles opcode 0xc6
9085****************************************************************************/
9086static void
9087x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9088{
9089    int mod, rl, rh;
9090    u8 *destreg;
9091    uint destoffset;
9092    u8 imm;
9093
9094    START_OF_INSTR();
9095    DECODE_PRINTF("MOV\t");
9096    FETCH_DECODE_MODRM(mod, rh, rl);
9097    if (rh != 0) {
9098        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9099        HALT_SYS();
9100    }
9101    switch (mod) {
9102    case 0:
9103        DECODE_PRINTF("BYTE PTR ");
9104        destoffset = decode_rm00_address(rl);
9105        imm = fetch_byte_imm();
9106        DECODE_PRINTF2(",%2x\n", imm);
9107        TRACE_AND_STEP();
9108        store_data_byte(destoffset, imm);
9109        break;
9110    case 1:
9111        DECODE_PRINTF("BYTE PTR ");
9112        destoffset = decode_rm01_address(rl);
9113        imm = fetch_byte_imm();
9114        DECODE_PRINTF2(",%2x\n", imm);
9115        TRACE_AND_STEP();
9116        store_data_byte(destoffset, imm);
9117        break;
9118    case 2:
9119        DECODE_PRINTF("BYTE PTR ");
9120        destoffset = decode_rm10_address(rl);
9121        imm = fetch_byte_imm();
9122        DECODE_PRINTF2(",%2x\n", imm);
9123        TRACE_AND_STEP();
9124        store_data_byte(destoffset, imm);
9125        break;
9126    case 3:                    /* register to register */
9127        destreg = DECODE_RM_BYTE_REGISTER(rl);
9128        imm = fetch_byte_imm();
9129        DECODE_PRINTF2(",%2x\n", imm);
9130        TRACE_AND_STEP();
9131        *destreg = imm;
9132        break;
9133    }
9134    DECODE_CLEAR_SEGOVR();
9135    END_OF_INSTR();
9136}
9137
9138/****************************************************************************
9139REMARKS:
9140Handles opcode 0xc7
9141****************************************************************************/
9142static void
9143x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9144{
9145    int mod, rl, rh;
9146    uint destoffset;
9147
9148    START_OF_INSTR();
9149    DECODE_PRINTF("MOV\t");
9150    FETCH_DECODE_MODRM(mod, rh, rl);
9151    if (rh != 0) {
9152        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9153        HALT_SYS();
9154    }
9155    switch (mod) {
9156    case 0:
9157        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9158            u32 imm;
9159
9160            DECODE_PRINTF("DWORD PTR ");
9161            destoffset = decode_rm00_address(rl);
9162            imm = fetch_long_imm();
9163            DECODE_PRINTF2(",%x\n", imm);
9164            TRACE_AND_STEP();
9165            store_data_long(destoffset, imm);
9166        }
9167        else {
9168            u16 imm;
9169
9170            DECODE_PRINTF("WORD PTR ");
9171            destoffset = decode_rm00_address(rl);
9172            imm = fetch_word_imm();
9173            DECODE_PRINTF2(",%x\n", imm);
9174            TRACE_AND_STEP();
9175            store_data_word(destoffset, imm);
9176        }
9177        break;
9178    case 1:
9179        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9180            u32 imm;
9181
9182            DECODE_PRINTF("DWORD PTR ");
9183            destoffset = decode_rm01_address(rl);
9184            imm = fetch_long_imm();
9185            DECODE_PRINTF2(",%x\n", imm);
9186            TRACE_AND_STEP();
9187            store_data_long(destoffset, imm);
9188        }
9189        else {
9190            u16 imm;
9191
9192            DECODE_PRINTF("WORD PTR ");
9193            destoffset = decode_rm01_address(rl);
9194            imm = fetch_word_imm();
9195            DECODE_PRINTF2(",%x\n", imm);
9196            TRACE_AND_STEP();
9197            store_data_word(destoffset, imm);
9198        }
9199        break;
9200    case 2:
9201        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9202            u32 imm;
9203
9204            DECODE_PRINTF("DWORD PTR ");
9205            destoffset = decode_rm10_address(rl);
9206            imm = fetch_long_imm();
9207            DECODE_PRINTF2(",%x\n", imm);
9208            TRACE_AND_STEP();
9209            store_data_long(destoffset, imm);
9210        }
9211        else {
9212            u16 imm;
9213
9214            DECODE_PRINTF("WORD PTR ");
9215            destoffset = decode_rm10_address(rl);
9216            imm = fetch_word_imm();
9217            DECODE_PRINTF2(",%x\n", imm);
9218            TRACE_AND_STEP();
9219            store_data_word(destoffset, imm);
9220        }
9221        break;
9222    case 3:                    /* register to register */
9223        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9224            u32 *destreg;
9225            u32 imm;
9226
9227            destreg = DECODE_RM_LONG_REGISTER(rl);
9228            imm = fetch_long_imm();
9229            DECODE_PRINTF2(",%x\n", imm);
9230            TRACE_AND_STEP();
9231            *destreg = imm;
9232        }
9233        else {
9234            u16 *destreg;
9235            u16 imm;
9236
9237            destreg = DECODE_RM_WORD_REGISTER(rl);
9238            imm = fetch_word_imm();
9239            DECODE_PRINTF2(",%x\n", imm);
9240            TRACE_AND_STEP();
9241            *destreg = imm;
9242        }
9243        break;
9244    }
9245    DECODE_CLEAR_SEGOVR();
9246    END_OF_INSTR();
9247}
9248
9249/****************************************************************************
9250REMARKS:
9251Handles opcode 0xc8
9252****************************************************************************/
9253static void
9254x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9255{
9256    u16 local, frame_pointer;
9257    u8 nesting;
9258    int i;
9259
9260    START_OF_INSTR();
9261    local = fetch_word_imm();
9262    nesting = fetch_byte_imm();
9263    DECODE_PRINTF2("ENTER %x\n", local);
9264    DECODE_PRINTF2(",%x\n", nesting);
9265    TRACE_AND_STEP();
9266    push_word(M.x86.R_BP);
9267    frame_pointer = M.x86.R_SP;
9268    if (nesting > 0) {
9269        for (i = 1; i < nesting; i++) {
9270            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9271                M.x86.R_BP -= 4;
9272                push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
9273            } else {
9274                M.x86.R_BP -= 2;
9275                push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9276            }
9277        }
9278        push_word(frame_pointer);
9279    }
9280    M.x86.R_BP = frame_pointer;
9281    M.x86.R_SP = (u16) (M.x86.R_SP - local);
9282    DECODE_CLEAR_SEGOVR();
9283    END_OF_INSTR();
9284}
9285
9286/****************************************************************************
9287REMARKS:
9288Handles opcode 0xc9
9289****************************************************************************/
9290static void
9291x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9292{
9293    START_OF_INSTR();
9294    DECODE_PRINTF("LEAVE\n");
9295    TRACE_AND_STEP();
9296    M.x86.R_SP = M.x86.R_BP;
9297    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9298        M.x86.R_EBP = pop_long();
9299    } else {
9300        M.x86.R_BP = pop_word();
9301    }
9302    DECODE_CLEAR_SEGOVR();
9303    END_OF_INSTR();
9304}
9305
9306/****************************************************************************
9307REMARKS:
9308Handles opcode 0xca
9309****************************************************************************/
9310static void
9311x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9312{
9313    u16 imm;
9314
9315    START_OF_INSTR();
9316    DECODE_PRINTF("RETF\t");
9317    imm = fetch_word_imm();
9318    DECODE_PRINTF2("%x\n", imm);
9319    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9320    TRACE_AND_STEP();
9321    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9322        M.x86.R_EIP = pop_long();
9323        M.x86.R_CS = pop_long() & 0xffff;
9324    } else {
9325        M.x86.R_IP = pop_word();
9326        M.x86.R_CS = pop_word();
9327    }
9328    M.x86.R_SP += imm;
9329    DECODE_CLEAR_SEGOVR();
9330    END_OF_INSTR();
9331}
9332
9333/****************************************************************************
9334REMARKS:
9335Handles opcode 0xcb
9336****************************************************************************/
9337static void
9338x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9339{
9340    START_OF_INSTR();
9341    DECODE_PRINTF("RETF\n");
9342    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9343    TRACE_AND_STEP();
9344    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9345        M.x86.R_EIP = pop_long();
9346        M.x86.R_CS = pop_long() & 0xffff;
9347    } else {
9348        M.x86.R_IP = pop_word();
9349        M.x86.R_CS = pop_word();
9350    }
9351    DECODE_CLEAR_SEGOVR();
9352    END_OF_INSTR();
9353}
9354
9355/****************************************************************************
9356REMARKS:
9357Handles opcode 0xcc
9358****************************************************************************/
9359static void
9360x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9361{
9362    START_OF_INSTR();
9363    DECODE_PRINTF("INT 3\n");
9364    TRACE_AND_STEP();
9365    if (_X86EMU_intrTab[3]) {
9366        (*_X86EMU_intrTab[3]) (3);
9367    }
9368    else {
9369        push_word((u16) M.x86.R_FLG);
9370        CLEAR_FLAG(F_IF);
9371        CLEAR_FLAG(F_TF);
9372        push_word(M.x86.R_CS);
9373        M.x86.R_CS = mem_access_word(3 * 4 + 2);
9374        push_word(M.x86.R_IP);
9375        M.x86.R_IP = mem_access_word(3 * 4);
9376    }
9377    DECODE_CLEAR_SEGOVR();
9378    END_OF_INSTR();
9379}
9380
9381/****************************************************************************
9382REMARKS:
9383Handles opcode 0xcd
9384****************************************************************************/
9385static void
9386x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9387{
9388    u8 intnum;
9389
9390    START_OF_INSTR();
9391    DECODE_PRINTF("INT\t");
9392    intnum = fetch_byte_imm();
9393    DECODE_PRINTF2("%x\n", intnum);
9394    TRACE_AND_STEP();
9395    if (_X86EMU_intrTab[intnum]) {
9396        (*_X86EMU_intrTab[intnum]) (intnum);
9397    }
9398    else {
9399        push_word((u16) M.x86.R_FLG);
9400        CLEAR_FLAG(F_IF);
9401        CLEAR_FLAG(F_TF);
9402        push_word(M.x86.R_CS);
9403        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9404        push_word(M.x86.R_IP);
9405        M.x86.R_IP = mem_access_word(intnum * 4);
9406    }
9407    DECODE_CLEAR_SEGOVR();
9408    END_OF_INSTR();
9409}
9410
9411/****************************************************************************
9412REMARKS:
9413Handles opcode 0xce
9414****************************************************************************/
9415static void
9416x86emuOp_into(u8 X86EMU_UNUSED(op1))
9417{
9418    START_OF_INSTR();
9419    DECODE_PRINTF("INTO\n");
9420    TRACE_AND_STEP();
9421    if (ACCESS_FLAG(F_OF)) {
9422        if (_X86EMU_intrTab[4]) {
9423            (*_X86EMU_intrTab[4]) (4);
9424        }
9425        else {
9426            push_word((u16) M.x86.R_FLG);
9427            CLEAR_FLAG(F_IF);
9428            CLEAR_FLAG(F_TF);
9429            push_word(M.x86.R_CS);
9430            M.x86.R_CS = mem_access_word(4 * 4 + 2);
9431            push_word(M.x86.R_IP);
9432            M.x86.R_IP = mem_access_word(4 * 4);
9433        }
9434    }
9435    DECODE_CLEAR_SEGOVR();
9436    END_OF_INSTR();
9437}
9438
9439/****************************************************************************
9440REMARKS:
9441Handles opcode 0xcf
9442****************************************************************************/
9443static void
9444x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9445{
9446    START_OF_INSTR();
9447    DECODE_PRINTF("IRET\n");
9448
9449    TRACE_AND_STEP();
9450
9451    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9452        M.x86.R_EIP = pop_long();
9453        M.x86.R_CS = pop_long() & 0xffff;
9454        M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
9455    } else {
9456        M.x86.R_IP = pop_word();
9457        M.x86.R_CS = pop_word();
9458        M.x86.R_FLG = pop_word();
9459    }
9460    DECODE_CLEAR_SEGOVR();
9461    END_OF_INSTR();
9462}
9463
9464/****************************************************************************
9465REMARKS:
9466Handles opcode 0xd0
9467****************************************************************************/
9468static void
9469x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9470{
9471    int mod, rl, rh;
9472    u8 *destreg;
9473    uint destoffset;
9474    u8 destval;
9475
9476    /*
9477     * Yet another weirdo special case instruction format.  Part of
9478     * the opcode held below in "RH".  Doubly nested case would
9479     * result, except that the decoded instruction
9480     */
9481    START_OF_INSTR();
9482    FETCH_DECODE_MODRM(mod, rh, rl);
9483#ifdef DEBUG
9484    if (DEBUG_DECODE()) {
9485        /* XXX DECODE_PRINTF may be changed to something more
9486           general, so that it is important to leave the strings
9487           in the same format, even though the result is that the
9488           above test is done twice. */
9489        switch (rh) {
9490        case 0:
9491            DECODE_PRINTF("ROL\t");
9492            break;
9493        case 1:
9494            DECODE_PRINTF("ROR\t");
9495            break;
9496        case 2:
9497            DECODE_PRINTF("RCL\t");
9498            break;
9499        case 3:
9500            DECODE_PRINTF("RCR\t");
9501            break;
9502        case 4:
9503            DECODE_PRINTF("SHL\t");
9504            break;
9505        case 5:
9506            DECODE_PRINTF("SHR\t");
9507            break;
9508        case 6:
9509            DECODE_PRINTF("SAL\t");
9510            break;
9511        case 7:
9512            DECODE_PRINTF("SAR\t");
9513            break;
9514        }
9515    }
9516#endif
9517    /* know operation, decode the mod byte to find the addressing
9518       mode. */
9519    switch (mod) {
9520    case 0:
9521        DECODE_PRINTF("BYTE PTR ");
9522        destoffset = decode_rm00_address(rl);
9523        DECODE_PRINTF(",1\n");
9524        destval = fetch_data_byte(destoffset);
9525        TRACE_AND_STEP();
9526        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9527        store_data_byte(destoffset, destval);
9528        break;
9529    case 1:
9530        DECODE_PRINTF("BYTE PTR ");
9531        destoffset = decode_rm01_address(rl);
9532        DECODE_PRINTF(",1\n");
9533        destval = fetch_data_byte(destoffset);
9534        TRACE_AND_STEP();
9535        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9536        store_data_byte(destoffset, destval);
9537        break;
9538    case 2:
9539        DECODE_PRINTF("BYTE PTR ");
9540        destoffset = decode_rm10_address(rl);
9541        DECODE_PRINTF(",1\n");
9542        destval = fetch_data_byte(destoffset);
9543        TRACE_AND_STEP();
9544        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9545        store_data_byte(destoffset, destval);
9546        break;
9547    case 3:                    /* register to register */
9548        destreg = DECODE_RM_BYTE_REGISTER(rl);
9549        DECODE_PRINTF(",1\n");
9550        TRACE_AND_STEP();
9551        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9552        *destreg = destval;
9553        break;
9554    }
9555    DECODE_CLEAR_SEGOVR();
9556    END_OF_INSTR();
9557}
9558
9559/****************************************************************************
9560REMARKS:
9561Handles opcode 0xd1
9562****************************************************************************/
9563static void
9564x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9565{
9566    int mod, rl, rh;
9567    uint destoffset;
9568
9569    /*
9570     * Yet another weirdo special case instruction format.  Part of
9571     * the opcode held below in "RH".  Doubly nested case would
9572     * result, except that the decoded instruction
9573     */
9574    START_OF_INSTR();
9575    FETCH_DECODE_MODRM(mod, rh, rl);
9576#ifdef DEBUG
9577    if (DEBUG_DECODE()) {
9578        /* XXX DECODE_PRINTF may be changed to something more
9579           general, so that it is important to leave the strings
9580           in the same format, even though the result is that the
9581           above test is done twice. */
9582        switch (rh) {
9583        case 0:
9584            DECODE_PRINTF("ROL\t");
9585            break;
9586        case 1:
9587            DECODE_PRINTF("ROR\t");
9588            break;
9589        case 2:
9590            DECODE_PRINTF("RCL\t");
9591            break;
9592        case 3:
9593            DECODE_PRINTF("RCR\t");
9594            break;
9595        case 4:
9596            DECODE_PRINTF("SHL\t");
9597            break;
9598        case 5:
9599            DECODE_PRINTF("SHR\t");
9600            break;
9601        case 6:
9602            DECODE_PRINTF("SAL\t");
9603            break;
9604        case 7:
9605            DECODE_PRINTF("SAR\t");
9606            break;
9607        }
9608    }
9609#endif
9610    /* know operation, decode the mod byte to find the addressing
9611       mode. */
9612    switch (mod) {
9613    case 0:
9614        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9615            u32 destval;
9616
9617            DECODE_PRINTF("DWORD PTR ");
9618            destoffset = decode_rm00_address(rl);
9619            DECODE_PRINTF(",1\n");
9620            destval = fetch_data_long(destoffset);
9621            TRACE_AND_STEP();
9622            destval = (*opcD1_long_operation[rh]) (destval, 1);
9623            store_data_long(destoffset, destval);
9624        }
9625        else {
9626            u16 destval;
9627
9628            DECODE_PRINTF("WORD PTR ");
9629            destoffset = decode_rm00_address(rl);
9630            DECODE_PRINTF(",1\n");
9631            destval = fetch_data_word(destoffset);
9632            TRACE_AND_STEP();
9633            destval = (*opcD1_word_operation[rh]) (destval, 1);
9634            store_data_word(destoffset, destval);
9635        }
9636        break;
9637    case 1:
9638        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9639            u32 destval;
9640
9641            DECODE_PRINTF("DWORD PTR ");
9642            destoffset = decode_rm01_address(rl);
9643            DECODE_PRINTF(",1\n");
9644            destval = fetch_data_long(destoffset);
9645            TRACE_AND_STEP();
9646            destval = (*opcD1_long_operation[rh]) (destval, 1);
9647            store_data_long(destoffset, destval);
9648        }
9649        else {
9650            u16 destval;
9651
9652            DECODE_PRINTF("WORD PTR ");
9653            destoffset = decode_rm01_address(rl);
9654            DECODE_PRINTF(",1\n");
9655            destval = fetch_data_word(destoffset);
9656            TRACE_AND_STEP();
9657            destval = (*opcD1_word_operation[rh]) (destval, 1);
9658            store_data_word(destoffset, destval);
9659        }
9660        break;
9661    case 2:
9662        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9663            u32 destval;
9664
9665            DECODE_PRINTF("DWORD PTR ");
9666            destoffset = decode_rm10_address(rl);
9667            DECODE_PRINTF(",1\n");
9668            destval = fetch_data_long(destoffset);
9669            TRACE_AND_STEP();
9670            destval = (*opcD1_long_operation[rh]) (destval, 1);
9671            store_data_long(destoffset, destval);
9672        }
9673        else {
9674            u16 destval;
9675
9676            DECODE_PRINTF("BYTE PTR ");
9677            destoffset = decode_rm10_address(rl);
9678            DECODE_PRINTF(",1\n");
9679            destval = fetch_data_word(destoffset);
9680            TRACE_AND_STEP();
9681            destval = (*opcD1_word_operation[rh]) (destval, 1);
9682            store_data_word(destoffset, destval);
9683        }
9684        break;
9685    case 3:                    /* register to register */
9686        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9687            u32 destval;
9688            u32 *destreg;
9689
9690            destreg = DECODE_RM_LONG_REGISTER(rl);
9691            DECODE_PRINTF(",1\n");
9692            TRACE_AND_STEP();
9693            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9694            *destreg = destval;
9695        }
9696        else {
9697            u16 destval;
9698            u16 *destreg;
9699
9700            destreg = DECODE_RM_WORD_REGISTER(rl);
9701            DECODE_PRINTF(",1\n");
9702            TRACE_AND_STEP();
9703            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9704            *destreg = destval;
9705        }
9706        break;
9707    }
9708    DECODE_CLEAR_SEGOVR();
9709    END_OF_INSTR();
9710}
9711
9712/****************************************************************************
9713REMARKS:
9714Handles opcode 0xd2
9715****************************************************************************/
9716static void
9717x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9718{
9719    int mod, rl, rh;
9720    u8 *destreg;
9721    uint destoffset;
9722    u8 destval;
9723    u8 amt;
9724
9725    /*
9726     * Yet another weirdo special case instruction format.  Part of
9727     * the opcode held below in "RH".  Doubly nested case would
9728     * result, except that the decoded instruction
9729     */
9730    START_OF_INSTR();
9731    FETCH_DECODE_MODRM(mod, rh, rl);
9732#ifdef DEBUG
9733    if (DEBUG_DECODE()) {
9734        /* XXX DECODE_PRINTF may be changed to something more
9735           general, so that it is important to leave the strings
9736           in the same format, even though the result is that the
9737           above test is done twice. */
9738        switch (rh) {
9739        case 0:
9740            DECODE_PRINTF("ROL\t");
9741            break;
9742        case 1:
9743            DECODE_PRINTF("ROR\t");
9744            break;
9745        case 2:
9746            DECODE_PRINTF("RCL\t");
9747            break;
9748        case 3:
9749            DECODE_PRINTF("RCR\t");
9750            break;
9751        case 4:
9752            DECODE_PRINTF("SHL\t");
9753            break;
9754        case 5:
9755            DECODE_PRINTF("SHR\t");
9756            break;
9757        case 6:
9758            DECODE_PRINTF("SAL\t");
9759            break;
9760        case 7:
9761            DECODE_PRINTF("SAR\t");
9762            break;
9763        }
9764    }
9765#endif
9766    /* know operation, decode the mod byte to find the addressing
9767       mode. */
9768    amt = M.x86.R_CL;
9769    switch (mod) {
9770    case 0:
9771        DECODE_PRINTF("BYTE PTR ");
9772        destoffset = decode_rm00_address(rl);
9773        DECODE_PRINTF(",CL\n");
9774        destval = fetch_data_byte(destoffset);
9775        TRACE_AND_STEP();
9776        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9777        store_data_byte(destoffset, destval);
9778        break;
9779    case 1:
9780        DECODE_PRINTF("BYTE PTR ");
9781        destoffset = decode_rm01_address(rl);
9782        DECODE_PRINTF(",CL\n");
9783        destval = fetch_data_byte(destoffset);
9784        TRACE_AND_STEP();
9785        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9786        store_data_byte(destoffset, destval);
9787        break;
9788    case 2:
9789        DECODE_PRINTF("BYTE PTR ");
9790        destoffset = decode_rm10_address(rl);
9791        DECODE_PRINTF(",CL\n");
9792        destval = fetch_data_byte(destoffset);
9793        TRACE_AND_STEP();
9794        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9795        store_data_byte(destoffset, destval);
9796        break;
9797    case 3:                    /* register to register */
9798        destreg = DECODE_RM_BYTE_REGISTER(rl);
9799        DECODE_PRINTF(",CL\n");
9800        TRACE_AND_STEP();
9801        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9802        *destreg = destval;
9803        break;
9804    }
9805    DECODE_CLEAR_SEGOVR();
9806    END_OF_INSTR();
9807}
9808
9809/****************************************************************************
9810REMARKS:
9811Handles opcode 0xd3
9812****************************************************************************/
9813static void
9814x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9815{
9816    int mod, rl, rh;
9817    uint destoffset;
9818    u8 amt;
9819
9820    /*
9821     * Yet another weirdo special case instruction format.  Part of
9822     * the opcode held below in "RH".  Doubly nested case would
9823     * result, except that the decoded instruction
9824     */
9825    START_OF_INSTR();
9826    FETCH_DECODE_MODRM(mod, rh, rl);
9827#ifdef DEBUG
9828    if (DEBUG_DECODE()) {
9829        /* XXX DECODE_PRINTF may be changed to something more
9830           general, so that it is important to leave the strings
9831           in the same format, even though the result is that the
9832           above test is done twice. */
9833        switch (rh) {
9834        case 0:
9835            DECODE_PRINTF("ROL\t");
9836            break;
9837        case 1:
9838            DECODE_PRINTF("ROR\t");
9839            break;
9840        case 2:
9841            DECODE_PRINTF("RCL\t");
9842            break;
9843        case 3:
9844            DECODE_PRINTF("RCR\t");
9845            break;
9846        case 4:
9847            DECODE_PRINTF("SHL\t");
9848            break;
9849        case 5:
9850            DECODE_PRINTF("SHR\t");
9851            break;
9852        case 6:
9853            DECODE_PRINTF("SAL\t");
9854            break;
9855        case 7:
9856            DECODE_PRINTF("SAR\t");
9857            break;
9858        }
9859    }
9860#endif
9861    /* know operation, decode the mod byte to find the addressing
9862       mode. */
9863    amt = M.x86.R_CL;
9864    switch (mod) {
9865    case 0:
9866        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9867            u32 destval;
9868
9869            DECODE_PRINTF("DWORD PTR ");
9870            destoffset = decode_rm00_address(rl);
9871            DECODE_PRINTF(",CL\n");
9872            destval = fetch_data_long(destoffset);
9873            TRACE_AND_STEP();
9874            destval = (*opcD1_long_operation[rh]) (destval, amt);
9875            store_data_long(destoffset, destval);
9876        }
9877        else {
9878            u16 destval;
9879
9880            DECODE_PRINTF("WORD PTR ");
9881            destoffset = decode_rm00_address(rl);
9882            DECODE_PRINTF(",CL\n");
9883            destval = fetch_data_word(destoffset);
9884            TRACE_AND_STEP();
9885            destval = (*opcD1_word_operation[rh]) (destval, amt);
9886            store_data_word(destoffset, destval);
9887        }
9888        break;
9889    case 1:
9890        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9891            u32 destval;
9892
9893            DECODE_PRINTF("DWORD PTR ");
9894            destoffset = decode_rm01_address(rl);
9895            DECODE_PRINTF(",CL\n");
9896            destval = fetch_data_long(destoffset);
9897            TRACE_AND_STEP();
9898            destval = (*opcD1_long_operation[rh]) (destval, amt);
9899            store_data_long(destoffset, destval);
9900        }
9901        else {
9902            u16 destval;
9903
9904            DECODE_PRINTF("WORD PTR ");
9905            destoffset = decode_rm01_address(rl);
9906            DECODE_PRINTF(",CL\n");
9907            destval = fetch_data_word(destoffset);
9908            TRACE_AND_STEP();
9909            destval = (*opcD1_word_operation[rh]) (destval, amt);
9910            store_data_word(destoffset, destval);
9911        }
9912        break;
9913    case 2:
9914        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9915            u32 destval;
9916
9917            DECODE_PRINTF("DWORD PTR ");
9918            destoffset = decode_rm10_address(rl);
9919            DECODE_PRINTF(",CL\n");
9920            destval = fetch_data_long(destoffset);
9921            TRACE_AND_STEP();
9922            destval = (*opcD1_long_operation[rh]) (destval, amt);
9923            store_data_long(destoffset, destval);
9924        }
9925        else {
9926            u16 destval;
9927
9928            DECODE_PRINTF("WORD PTR ");
9929            destoffset = decode_rm10_address(rl);
9930            DECODE_PRINTF(",CL\n");
9931            destval = fetch_data_word(destoffset);
9932            TRACE_AND_STEP();
9933            destval = (*opcD1_word_operation[rh]) (destval, amt);
9934            store_data_word(destoffset, destval);
9935        }
9936        break;
9937    case 3:                    /* register to register */
9938        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9939            u32 *destreg;
9940
9941            destreg = DECODE_RM_LONG_REGISTER(rl);
9942            DECODE_PRINTF(",CL\n");
9943            TRACE_AND_STEP();
9944            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9945        }
9946        else {
9947            u16 *destreg;
9948
9949            destreg = DECODE_RM_WORD_REGISTER(rl);
9950            DECODE_PRINTF(",CL\n");
9951            TRACE_AND_STEP();
9952            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9953        }
9954        break;
9955    }
9956    DECODE_CLEAR_SEGOVR();
9957    END_OF_INSTR();
9958}
9959
9960/****************************************************************************
9961REMARKS:
9962Handles opcode 0xd4
9963****************************************************************************/
9964static void
9965x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9966{
9967    u8 a;
9968
9969    START_OF_INSTR();
9970    DECODE_PRINTF("AAM\n");
9971    a = fetch_byte_imm();       /* this is a stupid encoding. */
9972    if (a != 10) {
9973        /* fix: add base decoding
9974           aam_word(u8 val, int base a) */
9975        DECODE_PRINTF("ERROR DECODING AAM\n");
9976        TRACE_REGS();
9977        HALT_SYS();
9978    }
9979    TRACE_AND_STEP();
9980    /* note the type change here --- returning AL and AH in AX. */
9981    M.x86.R_AX = aam_word(M.x86.R_AL);
9982    DECODE_CLEAR_SEGOVR();
9983    END_OF_INSTR();
9984}
9985
9986/****************************************************************************
9987REMARKS:
9988Handles opcode 0xd5
9989****************************************************************************/
9990static void
9991x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9992{
9993    u8 a;
9994
9995    START_OF_INSTR();
9996    DECODE_PRINTF("AAD\n");
9997    a = fetch_byte_imm();
9998    if (a != 10) {
9999        /* fix: add base decoding
10000           aad_word(u16 val, int base a) */
10001        DECODE_PRINTF("ERROR DECODING AAM\n");
10002        TRACE_REGS();
10003        HALT_SYS();
10004    }
10005    TRACE_AND_STEP();
10006    M.x86.R_AX = aad_word(M.x86.R_AX);
10007    DECODE_CLEAR_SEGOVR();
10008    END_OF_INSTR();
10009}
10010
10011/* opcode 0xd6 ILLEGAL OPCODE */
10012
10013/****************************************************************************
10014REMARKS:
10015Handles opcode 0xd7
10016****************************************************************************/
10017static void
10018x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
10019{
10020    u16 addr;
10021
10022    START_OF_INSTR();
10023    DECODE_PRINTF("XLAT\n");
10024    TRACE_AND_STEP();
10025    addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
10026    M.x86.R_AL = fetch_data_byte(addr);
10027    DECODE_CLEAR_SEGOVR();
10028    END_OF_INSTR();
10029}
10030
10031/* instuctions  D8 .. DF are in i87_ops.c */
10032
10033/****************************************************************************
10034REMARKS:
10035Handles opcode 0xe0
10036****************************************************************************/
10037static void
10038x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10039{
10040    s16 ip;
10041
10042    START_OF_INSTR();
10043    DECODE_PRINTF("LOOPNE\t");
10044    ip = (s8) fetch_byte_imm();
10045    ip += (s16) M.x86.R_IP;
10046    DECODE_PRINTF2("%04x\n", ip);
10047    TRACE_AND_STEP();
10048    M.x86.R_CX -= 1;
10049    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
10050        M.x86.R_IP = ip;
10051    DECODE_CLEAR_SEGOVR();
10052    END_OF_INSTR();
10053}
10054
10055/****************************************************************************
10056REMARKS:
10057Handles opcode 0xe1
10058****************************************************************************/
10059static void
10060x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10061{
10062    s16 ip;
10063
10064    START_OF_INSTR();
10065    DECODE_PRINTF("LOOPE\t");
10066    ip = (s8) fetch_byte_imm();
10067    ip += (s16) M.x86.R_IP;
10068    DECODE_PRINTF2("%04x\n", ip);
10069    TRACE_AND_STEP();
10070    M.x86.R_CX -= 1;
10071    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
10072        M.x86.R_IP = ip;
10073    DECODE_CLEAR_SEGOVR();
10074    END_OF_INSTR();
10075}
10076
10077/****************************************************************************
10078REMARKS:
10079Handles opcode 0xe2
10080****************************************************************************/
10081static void
10082x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10083{
10084    s16 ip;
10085
10086    START_OF_INSTR();
10087    DECODE_PRINTF("LOOP\t");
10088    ip = (s8) fetch_byte_imm();
10089    ip += (s16) M.x86.R_IP;
10090    DECODE_PRINTF2("%04x\n", ip);
10091    TRACE_AND_STEP();
10092    M.x86.R_CX -= 1;
10093    if (M.x86.R_CX != 0)
10094        M.x86.R_IP = ip;
10095    DECODE_CLEAR_SEGOVR();
10096    END_OF_INSTR();
10097}
10098
10099/****************************************************************************
10100REMARKS:
10101Handles opcode 0xe3
10102****************************************************************************/
10103static void
10104x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10105{
10106    u16 target;
10107    s8 offset;
10108
10109    /* jump to byte offset if overflow flag is set */
10110    START_OF_INSTR();
10111    DECODE_PRINTF("JCXZ\t");
10112    offset = (s8) fetch_byte_imm();
10113    target = (u16) (M.x86.R_IP + offset);
10114    DECODE_PRINTF2("%x\n", target);
10115    TRACE_AND_STEP();
10116    if (M.x86.R_CX == 0)
10117        M.x86.R_IP = target;
10118    DECODE_CLEAR_SEGOVR();
10119    END_OF_INSTR();
10120}
10121
10122/****************************************************************************
10123REMARKS:
10124Handles opcode 0xe4
10125****************************************************************************/
10126static void
10127x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10128{
10129    u8 port;
10130
10131    START_OF_INSTR();
10132    DECODE_PRINTF("IN\t");
10133    port = (u8) fetch_byte_imm();
10134    DECODE_PRINTF2("%x,AL\n", port);
10135    TRACE_AND_STEP();
10136    M.x86.R_AL = (*sys_inb) (port);
10137    DECODE_CLEAR_SEGOVR();
10138    END_OF_INSTR();
10139}
10140
10141/****************************************************************************
10142REMARKS:
10143Handles opcode 0xe5
10144****************************************************************************/
10145static void
10146x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10147{
10148    u8 port;
10149
10150    START_OF_INSTR();
10151    DECODE_PRINTF("IN\t");
10152    port = (u8) fetch_byte_imm();
10153    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10154        DECODE_PRINTF2("EAX,%x\n", port);
10155    }
10156    else {
10157        DECODE_PRINTF2("AX,%x\n", port);
10158    }
10159    TRACE_AND_STEP();
10160    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10161        M.x86.R_EAX = (*sys_inl) (port);
10162    }
10163    else {
10164        M.x86.R_AX = (*sys_inw) (port);
10165    }
10166    DECODE_CLEAR_SEGOVR();
10167    END_OF_INSTR();
10168}
10169
10170/****************************************************************************
10171REMARKS:
10172Handles opcode 0xe6
10173****************************************************************************/
10174static void
10175x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10176{
10177    u8 port;
10178
10179    START_OF_INSTR();
10180    DECODE_PRINTF("OUT\t");
10181    port = (u8) fetch_byte_imm();
10182    DECODE_PRINTF2("%x,AL\n", port);
10183    TRACE_AND_STEP();
10184    (*sys_outb) (port, M.x86.R_AL);
10185    DECODE_CLEAR_SEGOVR();
10186    END_OF_INSTR();
10187}
10188
10189/****************************************************************************
10190REMARKS:
10191Handles opcode 0xe7
10192****************************************************************************/
10193static void
10194x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10195{
10196    u8 port;
10197
10198    START_OF_INSTR();
10199    DECODE_PRINTF("OUT\t");
10200    port = (u8) fetch_byte_imm();
10201    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10202        DECODE_PRINTF2("%x,EAX\n", port);
10203    }
10204    else {
10205        DECODE_PRINTF2("%x,AX\n", port);
10206    }
10207    TRACE_AND_STEP();
10208    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10209        (*sys_outl) (port, M.x86.R_EAX);
10210    }
10211    else {
10212        (*sys_outw) (port, M.x86.R_AX);
10213    }
10214    DECODE_CLEAR_SEGOVR();
10215    END_OF_INSTR();
10216}
10217
10218/****************************************************************************
10219REMARKS:
10220Handles opcode 0xe8
10221****************************************************************************/
10222static void
10223x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10224{
10225    s16 ip16 = 0;
10226    s32 ip32 = 0;
10227
10228    START_OF_INSTR();
10229    DECODE_PRINTF("CALL\t");
10230    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10231        ip32 = (s32) fetch_long_imm();
10232        ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10233        DECODE_PRINTF2("%04x\n", (u16) ip32);
10234        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10235    }
10236    else {
10237        ip16 = (s16) fetch_word_imm();
10238        ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10239        DECODE_PRINTF2("%04x\n", (u16) ip16);
10240        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10241    }
10242    TRACE_AND_STEP();
10243    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10244        push_long(M.x86.R_EIP);
10245        M.x86.R_EIP = ip32 & 0xffff;
10246    }
10247    else {
10248        push_word(M.x86.R_IP);
10249        M.x86.R_EIP = ip16;
10250    }
10251    DECODE_CLEAR_SEGOVR();
10252    END_OF_INSTR();
10253}
10254
10255/****************************************************************************
10256REMARKS:
10257Handles opcode 0xe9
10258****************************************************************************/
10259static void
10260x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10261{
10262    u32 ip;
10263
10264    START_OF_INSTR();
10265    DECODE_PRINTF("JMP\t");
10266    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10267        ip = (u32) fetch_long_imm();
10268        ip += (u32) M.x86.R_EIP;
10269        DECODE_PRINTF2("%08x\n", (u32) ip);
10270        TRACE_AND_STEP();
10271        M.x86.R_EIP = (u32) ip;
10272    }
10273    else {
10274        ip = (s16) fetch_word_imm();
10275        ip += (s16) M.x86.R_IP;
10276        DECODE_PRINTF2("%04x\n", (u16) ip);
10277        TRACE_AND_STEP();
10278        M.x86.R_IP = (u16) ip;
10279    }
10280    DECODE_CLEAR_SEGOVR();
10281    END_OF_INSTR();
10282}
10283
10284/****************************************************************************
10285REMARKS:
10286Handles opcode 0xea
10287****************************************************************************/
10288static void
10289x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10290{
10291    u16 cs;
10292    u32 ip;
10293
10294    START_OF_INSTR();
10295    DECODE_PRINTF("JMP\tFAR ");
10296    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10297        ip = fetch_long_imm();
10298    }
10299    else {
10300        ip = fetch_word_imm();
10301    }
10302    cs = fetch_word_imm();
10303    DECODE_PRINTF2("%04x:", cs);
10304    DECODE_PRINTF2("%04x\n", ip);
10305    TRACE_AND_STEP();
10306    M.x86.R_EIP = ip & 0xffff;
10307    M.x86.R_CS = cs;
10308    DECODE_CLEAR_SEGOVR();
10309    END_OF_INSTR();
10310}
10311
10312/****************************************************************************
10313REMARKS:
10314Handles opcode 0xeb
10315****************************************************************************/
10316static void
10317x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10318{
10319    u16 target;
10320    s8 offset;
10321
10322    START_OF_INSTR();
10323    DECODE_PRINTF("JMP\t");
10324    offset = (s8) fetch_byte_imm();
10325    target = (u16) (M.x86.R_IP + offset);
10326    DECODE_PRINTF2("%x\n", target);
10327    TRACE_AND_STEP();
10328    M.x86.R_IP = target;
10329    DECODE_CLEAR_SEGOVR();
10330    END_OF_INSTR();
10331}
10332
10333/****************************************************************************
10334REMARKS:
10335Handles opcode 0xec
10336****************************************************************************/
10337static void
10338x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10339{
10340    START_OF_INSTR();
10341    DECODE_PRINTF("IN\tAL,DX\n");
10342    TRACE_AND_STEP();
10343    M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10344    DECODE_CLEAR_SEGOVR();
10345    END_OF_INSTR();
10346}
10347
10348/****************************************************************************
10349REMARKS:
10350Handles opcode 0xed
10351****************************************************************************/
10352static void
10353x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10354{
10355    START_OF_INSTR();
10356    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10357        DECODE_PRINTF("IN\tEAX,DX\n");
10358    }
10359    else {
10360        DECODE_PRINTF("IN\tAX,DX\n");
10361    }
10362    TRACE_AND_STEP();
10363    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364        M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10365    }
10366    else {
10367        M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10368    }
10369    DECODE_CLEAR_SEGOVR();
10370    END_OF_INSTR();
10371}
10372
10373/****************************************************************************
10374REMARKS:
10375Handles opcode 0xee
10376****************************************************************************/
10377static void
10378x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10379{
10380    START_OF_INSTR();
10381    DECODE_PRINTF("OUT\tDX,AL\n");
10382    TRACE_AND_STEP();
10383    (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10384    DECODE_CLEAR_SEGOVR();
10385    END_OF_INSTR();
10386}
10387
10388/****************************************************************************
10389REMARKS:
10390Handles opcode 0xef
10391****************************************************************************/
10392static void
10393x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10394{
10395    START_OF_INSTR();
10396    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397        DECODE_PRINTF("OUT\tDX,EAX\n");
10398    }
10399    else {
10400        DECODE_PRINTF("OUT\tDX,AX\n");
10401    }
10402    TRACE_AND_STEP();
10403    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10404        (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10405    }
10406    else {
10407        (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10408    }
10409    DECODE_CLEAR_SEGOVR();
10410    END_OF_INSTR();
10411}
10412
10413/****************************************************************************
10414REMARKS:
10415Handles opcode 0xf0
10416****************************************************************************/
10417static void
10418x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10419{
10420    START_OF_INSTR();
10421    DECODE_PRINTF("LOCK:\n");
10422    TRACE_AND_STEP();
10423    DECODE_CLEAR_SEGOVR();
10424    END_OF_INSTR();
10425}
10426
10427/*opcode 0xf1 ILLEGAL OPERATION */
10428
10429/****************************************************************************
10430REMARKS:
10431Handles opcode 0xf2
10432****************************************************************************/
10433static void
10434x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10435{
10436    START_OF_INSTR();
10437    DECODE_PRINTF("REPNE\n");
10438    TRACE_AND_STEP();
10439    M.x86.mode |= SYSMODE_PREFIX_REPNE;
10440    DECODE_CLEAR_SEGOVR();
10441    END_OF_INSTR();
10442}
10443
10444/****************************************************************************
10445REMARKS:
10446Handles opcode 0xf3
10447****************************************************************************/
10448static void
10449x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10450{
10451    START_OF_INSTR();
10452    DECODE_PRINTF("REPE\n");
10453    TRACE_AND_STEP();
10454    M.x86.mode |= SYSMODE_PREFIX_REPE;
10455    DECODE_CLEAR_SEGOVR();
10456    END_OF_INSTR();
10457}
10458
10459/****************************************************************************
10460REMARKS:
10461Handles opcode 0xf4
10462****************************************************************************/
10463static void
10464x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10465{
10466    START_OF_INSTR();
10467    DECODE_PRINTF("HALT\n");
10468    TRACE_AND_STEP();
10469    HALT_SYS();
10470    DECODE_CLEAR_SEGOVR();
10471    END_OF_INSTR();
10472}
10473
10474/****************************************************************************
10475REMARKS:
10476Handles opcode 0xf5
10477****************************************************************************/
10478static void
10479x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10480{
10481    /* complement the carry flag. */
10482    START_OF_INSTR();
10483    DECODE_PRINTF("CMC\n");
10484    TRACE_AND_STEP();
10485    TOGGLE_FLAG(F_CF);
10486    DECODE_CLEAR_SEGOVR();
10487    END_OF_INSTR();
10488}
10489
10490/****************************************************************************
10491REMARKS:
10492Handles opcode 0xf6
10493****************************************************************************/
10494static void
10495x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10496{
10497    int mod, rl, rh;
10498    u8 *destreg;
10499    uint destoffset;
10500    u8 destval, srcval;
10501
10502    /* long, drawn out code follows.  Double switch for a total
10503       of 32 cases.  */
10504    START_OF_INSTR();
10505    FETCH_DECODE_MODRM(mod, rh, rl);
10506    switch (mod) {
10507    case 0:                    /* mod=00 */
10508        switch (rh) {
10509        case 0:                /* test byte imm */
10510            DECODE_PRINTF("TEST\tBYTE PTR ");
10511            destoffset = decode_rm00_address(rl);
10512            DECODE_PRINTF(",");
10513            srcval = fetch_byte_imm();
10514            DECODE_PRINTF2("%02x\n", srcval);
10515            destval = fetch_data_byte(destoffset);
10516            TRACE_AND_STEP();
10517            test_byte(destval, srcval);
10518            break;
10519        case 1:
10520            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10521            HALT_SYS();
10522            break;
10523        case 2:
10524            DECODE_PRINTF("NOT\tBYTE PTR ");
10525            destoffset = decode_rm00_address(rl);
10526            DECODE_PRINTF("\n");
10527            destval = fetch_data_byte(destoffset);
10528            TRACE_AND_STEP();
10529            destval = not_byte(destval);
10530            store_data_byte(destoffset, destval);
10531            break;
10532        case 3:
10533            DECODE_PRINTF("NEG\tBYTE PTR ");
10534            destoffset = decode_rm00_address(rl);
10535            DECODE_PRINTF("\n");
10536            destval = fetch_data_byte(destoffset);
10537            TRACE_AND_STEP();
10538            destval = neg_byte(destval);
10539            store_data_byte(destoffset, destval);
10540            break;
10541        case 4:
10542            DECODE_PRINTF("MUL\tBYTE PTR ");
10543            destoffset = decode_rm00_address(rl);
10544            DECODE_PRINTF("\n");
10545            destval = fetch_data_byte(destoffset);
10546            TRACE_AND_STEP();
10547            mul_byte(destval);
10548            break;
10549        case 5:
10550            DECODE_PRINTF("IMUL\tBYTE PTR ");
10551            destoffset = decode_rm00_address(rl);
10552            DECODE_PRINTF("\n");
10553            destval = fetch_data_byte(destoffset);
10554            TRACE_AND_STEP();
10555            imul_byte(destval);
10556            break;
10557        case 6:
10558            DECODE_PRINTF("DIV\tBYTE PTR ");
10559            destoffset = decode_rm00_address(rl);
10560            DECODE_PRINTF("\n");
10561            destval = fetch_data_byte(destoffset);
10562            TRACE_AND_STEP();
10563            div_byte(destval);
10564            break;
10565        case 7:
10566            DECODE_PRINTF("IDIV\tBYTE PTR ");
10567            destoffset = decode_rm00_address(rl);
10568            DECODE_PRINTF("\n");
10569            destval = fetch_data_byte(destoffset);
10570            TRACE_AND_STEP();
10571            idiv_byte(destval);
10572            break;
10573        }
10574        break;                  /* end mod==00 */
10575    case 1:                    /* mod=01 */
10576        switch (rh) {
10577        case 0:                /* test byte imm */
10578            DECODE_PRINTF("TEST\tBYTE PTR ");
10579            destoffset = decode_rm01_address(rl);
10580            DECODE_PRINTF(",");
10581            srcval = fetch_byte_imm();
10582            DECODE_PRINTF2("%02x\n", srcval);
10583            destval = fetch_data_byte(destoffset);
10584            TRACE_AND_STEP();
10585            test_byte(destval, srcval);
10586            break;
10587        case 1:
10588            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10589            HALT_SYS();
10590            break;
10591        case 2:
10592            DECODE_PRINTF("NOT\tBYTE PTR ");
10593            destoffset = decode_rm01_address(rl);
10594            DECODE_PRINTF("\n");
10595            destval = fetch_data_byte(destoffset);
10596            TRACE_AND_STEP();
10597            destval = not_byte(destval);
10598            store_data_byte(destoffset, destval);
10599            break;
10600        case 3:
10601            DECODE_PRINTF("NEG\tBYTE PTR ");
10602            destoffset = decode_rm01_address(rl);
10603            DECODE_PRINTF("\n");
10604            destval = fetch_data_byte(destoffset);
10605            TRACE_AND_STEP();
10606            destval = neg_byte(destval);
10607            store_data_byte(destoffset, destval);
10608            break;
10609        case 4:
10610            DECODE_PRINTF("MUL\tBYTE PTR ");
10611            destoffset = decode_rm01_address(rl);
10612            DECODE_PRINTF("\n");
10613            destval = fetch_data_byte(destoffset);
10614            TRACE_AND_STEP();
10615            mul_byte(destval);
10616            break;
10617        case 5:
10618            DECODE_PRINTF("IMUL\tBYTE PTR ");
10619            destoffset = decode_rm01_address(rl);
10620            DECODE_PRINTF("\n");
10621            destval = fetch_data_byte(destoffset);
10622            TRACE_AND_STEP();
10623            imul_byte(destval);
10624            break;
10625        case 6:
10626            DECODE_PRINTF("DIV\tBYTE PTR ");
10627            destoffset = decode_rm01_address(rl);
10628            DECODE_PRINTF("\n");
10629            destval = fetch_data_byte(destoffset);
10630            TRACE_AND_STEP();
10631            div_byte(destval);
10632            break;
10633        case 7:
10634            DECODE_PRINTF("IDIV\tBYTE PTR ");
10635            destoffset = decode_rm01_address(rl);
10636            DECODE_PRINTF("\n");
10637            destval = fetch_data_byte(destoffset);
10638            TRACE_AND_STEP();
10639            idiv_byte(destval);
10640            break;
10641        }
10642        break;                  /* end mod==01 */
10643    case 2:                    /* mod=10 */
10644        switch (rh) {
10645        case 0:                /* test byte imm */
10646            DECODE_PRINTF("TEST\tBYTE PTR ");
10647            destoffset = decode_rm10_address(rl);
10648            DECODE_PRINTF(",");
10649            srcval = fetch_byte_imm();
10650            DECODE_PRINTF2("%02x\n", srcval);
10651            destval = fetch_data_byte(destoffset);
10652            TRACE_AND_STEP();
10653            test_byte(destval, srcval);
10654            break;
10655        case 1:
10656            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10657            HALT_SYS();
10658            break;
10659        case 2:
10660            DECODE_PRINTF("NOT\tBYTE PTR ");
10661            destoffset = decode_rm10_address(rl);
10662            DECODE_PRINTF("\n");
10663            destval = fetch_data_byte(destoffset);
10664            TRACE_AND_STEP();
10665            destval = not_byte(destval);
10666            store_data_byte(destoffset, destval);
10667            break;
10668        case 3:
10669            DECODE_PRINTF("NEG\tBYTE PTR ");
10670            destoffset = decode_rm10_address(rl);
10671            DECODE_PRINTF("\n");
10672            destval = fetch_data_byte(destoffset);
10673            TRACE_AND_STEP();
10674            destval = neg_byte(destval);
10675            store_data_byte(destoffset, destval);
10676            break;
10677        case 4:
10678            DECODE_PRINTF("MUL\tBYTE PTR ");
10679            destoffset = decode_rm10_address(rl);
10680            DECODE_PRINTF("\n");
10681            destval = fetch_data_byte(destoffset);
10682            TRACE_AND_STEP();
10683            mul_byte(destval);
10684            break;
10685        case 5:
10686            DECODE_PRINTF("IMUL\tBYTE PTR ");
10687            destoffset = decode_rm10_address(rl);
10688            DECODE_PRINTF("\n");
10689            destval = fetch_data_byte(destoffset);
10690            TRACE_AND_STEP();
10691            imul_byte(destval);
10692            break;
10693        case 6:
10694            DECODE_PRINTF("DIV\tBYTE PTR ");
10695            destoffset = decode_rm10_address(rl);
10696            DECODE_PRINTF("\n");
10697            destval = fetch_data_byte(destoffset);
10698            TRACE_AND_STEP();
10699            div_byte(destval);
10700            break;
10701        case 7:
10702            DECODE_PRINTF("IDIV\tBYTE PTR ");
10703            destoffset = decode_rm10_address(rl);
10704            DECODE_PRINTF("\n");
10705            destval = fetch_data_byte(destoffset);
10706            TRACE_AND_STEP();
10707            idiv_byte(destval);
10708            break;
10709        }
10710        break;                  /* end mod==10 */
10711    case 3:                    /* mod=11 */
10712        switch (rh) {
10713        case 0:                /* test byte imm */
10714            DECODE_PRINTF("TEST\t");
10715            destreg = DECODE_RM_BYTE_REGISTER(rl);
10716            DECODE_PRINTF(",");
10717            srcval = fetch_byte_imm();
10718            DECODE_PRINTF2("%02x\n", srcval);
10719            TRACE_AND_STEP();
10720            test_byte(*destreg, srcval);
10721            break;
10722        case 1:
10723            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10724            HALT_SYS();
10725            break;
10726        case 2:
10727            DECODE_PRINTF("NOT\t");
10728            destreg = DECODE_RM_BYTE_REGISTER(rl);
10729            DECODE_PRINTF("\n");
10730            TRACE_AND_STEP();
10731            *destreg = not_byte(*destreg);
10732            break;
10733        case 3:
10734            DECODE_PRINTF("NEG\t");
10735            destreg = DECODE_RM_BYTE_REGISTER(rl);
10736            DECODE_PRINTF("\n");
10737            TRACE_AND_STEP();
10738            *destreg = neg_byte(*destreg);
10739            break;
10740        case 4:
10741            DECODE_PRINTF("MUL\t");
10742            destreg = DECODE_RM_BYTE_REGISTER(rl);
10743            DECODE_PRINTF("\n");
10744            TRACE_AND_STEP();
10745            mul_byte(*destreg); /*!!!  */
10746            break;
10747        case 5:
10748            DECODE_PRINTF("IMUL\t");
10749            destreg = DECODE_RM_BYTE_REGISTER(rl);
10750            DECODE_PRINTF("\n");
10751            TRACE_AND_STEP();
10752            imul_byte(*destreg);
10753            break;
10754        case 6:
10755            DECODE_PRINTF("DIV\t");
10756            destreg = DECODE_RM_BYTE_REGISTER(rl);
10757            DECODE_PRINTF("\n");
10758            TRACE_AND_STEP();
10759            div_byte(*destreg);
10760            break;
10761        case 7:
10762            DECODE_PRINTF("IDIV\t");
10763            destreg = DECODE_RM_BYTE_REGISTER(rl);
10764            DECODE_PRINTF("\n");
10765            TRACE_AND_STEP();
10766            idiv_byte(*destreg);
10767            break;
10768        }
10769        break;                  /* end mod==11 */
10770    }
10771    DECODE_CLEAR_SEGOVR();
10772    END_OF_INSTR();
10773}
10774
10775/****************************************************************************
10776REMARKS:
10777Handles opcode 0xf7
10778****************************************************************************/
10779static void
10780x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10781{
10782    int mod, rl, rh;
10783    uint destoffset;
10784
10785    /* long, drawn out code follows.  Double switch for a total
10786       of 32 cases.  */
10787    START_OF_INSTR();
10788    FETCH_DECODE_MODRM(mod, rh, rl);
10789    switch (mod) {
10790    case 0:                    /* mod=00 */
10791        switch (rh) {
10792        case 0:                /* test word imm */
10793            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10794                u32 destval, srcval;
10795
10796                DECODE_PRINTF("TEST\tDWORD PTR ");
10797                destoffset = decode_rm00_address(rl);
10798                DECODE_PRINTF(",");
10799                srcval = fetch_long_imm();
10800                DECODE_PRINTF2("%x\n", srcval);
10801                destval = fetch_data_long(destoffset);
10802                TRACE_AND_STEP();
10803                test_long(destval, srcval);
10804            }
10805            else {
10806                u16 destval, srcval;
10807
10808                DECODE_PRINTF("TEST\tWORD PTR ");
10809                destoffset = decode_rm00_address(rl);
10810                DECODE_PRINTF(",");
10811                srcval = fetch_word_imm();
10812                DECODE_PRINTF2("%x\n", srcval);
10813                destval = fetch_data_word(destoffset);
10814                TRACE_AND_STEP();
10815                test_word(destval, srcval);
10816            }
10817            break;
10818        case 1:
10819            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10820            HALT_SYS();
10821            break;
10822        case 2:
10823            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10824                u32 destval;
10825
10826                DECODE_PRINTF("NOT\tDWORD PTR ");
10827                destoffset = decode_rm00_address(rl);
10828                DECODE_PRINTF("\n");
10829                destval = fetch_data_long(destoffset);
10830                TRACE_AND_STEP();
10831                destval = not_long(destval);
10832                store_data_long(destoffset, destval);
10833            }
10834            else {
10835                u16 destval;
10836
10837                DECODE_PRINTF("NOT\tWORD PTR ");
10838                destoffset = decode_rm00_address(rl);
10839                DECODE_PRINTF("\n");
10840                destval = fetch_data_word(destoffset);
10841                TRACE_AND_STEP();
10842                destval = not_word(destval);
10843                store_data_word(destoffset, destval);
10844            }
10845            break;
10846        case 3:
10847            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10848                u32 destval;
10849
10850                DECODE_PRINTF("NEG\tDWORD PTR ");
10851                destoffset = decode_rm00_address(rl);
10852                DECODE_PRINTF("\n");
10853                destval = fetch_data_long(destoffset);
10854                TRACE_AND_STEP();
10855                destval = neg_long(destval);
10856                store_data_long(destoffset, destval);
10857            }
10858            else {
10859                u16 destval;
10860
10861                DECODE_PRINTF("NEG\tWORD PTR ");
10862                destoffset = decode_rm00_address(rl);
10863                DECODE_PRINTF("\n");
10864                destval = fetch_data_word(destoffset);
10865                TRACE_AND_STEP();
10866                destval = neg_word(destval);
10867                store_data_word(destoffset, destval);
10868            }
10869            break;
10870        case 4:
10871            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10872                u32 destval;
10873
10874                DECODE_PRINTF("MUL\tDWORD PTR ");
10875                destoffset = decode_rm00_address(rl);
10876                DECODE_PRINTF("\n");
10877                destval = fetch_data_long(destoffset);
10878                TRACE_AND_STEP();
10879                mul_long(destval);
10880            }
10881            else {
10882                u16 destval;
10883
10884                DECODE_PRINTF("MUL\tWORD PTR ");
10885                destoffset = decode_rm00_address(rl);
10886                DECODE_PRINTF("\n");
10887                destval = fetch_data_word(destoffset);
10888                TRACE_AND_STEP();
10889                mul_word(destval);
10890            }
10891            break;
10892        case 5:
10893            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10894                u32 destval;
10895
10896                DECODE_PRINTF("IMUL\tDWORD PTR ");
10897                destoffset = decode_rm00_address(rl);
10898                DECODE_PRINTF("\n");
10899                destval = fetch_data_long(destoffset);
10900                TRACE_AND_STEP();
10901                imul_long(destval);
10902            }
10903            else {
10904                u16 destval;
10905
10906                DECODE_PRINTF("IMUL\tWORD PTR ");
10907                destoffset = decode_rm00_address(rl);
10908                DECODE_PRINTF("\n");
10909                destval = fetch_data_word(destoffset);
10910                TRACE_AND_STEP();
10911                imul_word(destval);
10912            }
10913            break;
10914        case 6:
10915            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10916                u32 destval;
10917
10918                DECODE_PRINTF("DIV\tDWORD PTR ");
10919                destoffset = decode_rm00_address(rl);
10920                DECODE_PRINTF("\n");
10921                destval = fetch_data_long(destoffset);
10922                TRACE_AND_STEP();
10923                div_long(destval);
10924            }
10925            else {
10926                u16 destval;
10927
10928                DECODE_PRINTF("DIV\tWORD PTR ");
10929                destoffset = decode_rm00_address(rl);
10930                DECODE_PRINTF("\n");
10931                destval = fetch_data_word(destoffset);
10932                TRACE_AND_STEP();
10933                div_word(destval);
10934            }
10935            break;
10936        case 7:
10937            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10938                u32 destval;
10939
10940                DECODE_PRINTF("IDIV\tDWORD PTR ");
10941                destoffset = decode_rm00_address(rl);
10942                DECODE_PRINTF("\n");
10943                destval = fetch_data_long(destoffset);
10944                TRACE_AND_STEP();
10945                idiv_long(destval);
10946            }
10947            else {
10948                u16 destval;
10949
10950                DECODE_PRINTF("IDIV\tWORD PTR ");
10951                destoffset = decode_rm00_address(rl);
10952                DECODE_PRINTF("\n");
10953                destval = fetch_data_word(destoffset);
10954                TRACE_AND_STEP();
10955                idiv_word(destval);
10956            }
10957            break;
10958        }
10959        break;                  /* end mod==00 */
10960    case 1:                    /* mod=01 */
10961        switch (rh) {
10962        case 0:                /* test word imm */
10963            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10964                u32 destval, srcval;
10965
10966                DECODE_PRINTF("TEST\tDWORD PTR ");
10967                destoffset = decode_rm01_address(rl);
10968                DECODE_PRINTF(",");
10969                srcval = fetch_long_imm();
10970                DECODE_PRINTF2("%x\n", srcval);
10971                destval = fetch_data_long(destoffset);
10972                TRACE_AND_STEP();
10973                test_long(destval, srcval);
10974            }
10975            else {
10976                u16 destval, srcval;
10977
10978                DECODE_PRINTF("TEST\tWORD PTR ");
10979                destoffset = decode_rm01_address(rl);
10980                DECODE_PRINTF(",");
10981                srcval = fetch_word_imm();
10982                DECODE_PRINTF2("%x\n", srcval);
10983                destval = fetch_data_word(destoffset);
10984                TRACE_AND_STEP();
10985                test_word(destval, srcval);
10986            }
10987            break;
10988        case 1:
10989            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10990            HALT_SYS();
10991            break;
10992        case 2:
10993            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10994                u32 destval;
10995
10996                DECODE_PRINTF("NOT\tDWORD PTR ");
10997                destoffset = decode_rm01_address(rl);
10998                DECODE_PRINTF("\n");
10999                destval = fetch_data_long(destoffset);
11000                TRACE_AND_STEP();
11001                destval = not_long(destval);
11002                store_data_long(destoffset, destval);
11003            }
11004            else {
11005                u16 destval;
11006
11007                DECODE_PRINTF("NOT\tWORD PTR ");
11008                destoffset = decode_rm01_address(rl);
11009                DECODE_PRINTF("\n");
11010                destval = fetch_data_word(destoffset);
11011                TRACE_AND_STEP();
11012                destval = not_word(destval);
11013                store_data_word(destoffset, destval);
11014            }
11015            break;
11016        case 3:
11017            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018                u32 destval;
11019
11020                DECODE_PRINTF("NEG\tDWORD PTR ");
11021                destoffset = decode_rm01_address(rl);
11022                DECODE_PRINTF("\n");
11023                destval = fetch_data_long(destoffset);
11024                TRACE_AND_STEP();
11025                destval = neg_long(destval);
11026                store_data_long(destoffset, destval);
11027            }
11028            else {
11029                u16 destval;
11030
11031                DECODE_PRINTF("NEG\tWORD PTR ");
11032                destoffset = decode_rm01_address(rl);
11033                DECODE_PRINTF("\n");
11034                destval = fetch_data_word(destoffset);
11035                TRACE_AND_STEP();
11036                destval = neg_word(destval);
11037                store_data_word(destoffset, destval);
11038            }
11039            break;
11040        case 4:
11041            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11042                u32 destval;
11043
11044                DECODE_PRINTF("MUL\tDWORD PTR ");
11045                destoffset = decode_rm01_address(rl);
11046                DECODE_PRINTF("\n");
11047                destval = fetch_data_long(destoffset);
11048                TRACE_AND_STEP();
11049                mul_long(destval);
11050            }
11051            else {
11052                u16 destval;
11053
11054                DECODE_PRINTF("MUL\tWORD PTR ");
11055                destoffset = decode_rm01_address(rl);
11056                DECODE_PRINTF("\n");
11057                destval = fetch_data_word(destoffset);
11058                TRACE_AND_STEP();
11059                mul_word(destval);
11060            }
11061            break;
11062        case 5:
11063            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11064                u32 destval;
11065
11066                DECODE_PRINTF("IMUL\tDWORD PTR ");
11067                destoffset = decode_rm01_address(rl);
11068                DECODE_PRINTF("\n");
11069                destval = fetch_data_long(destoffset);
11070                TRACE_AND_STEP();
11071                imul_long(destval);
11072            }
11073            else {
11074                u16 destval;
11075
11076                DECODE_PRINTF("IMUL\tWORD PTR ");
11077                destoffset = decode_rm01_address(rl);
11078                DECODE_PRINTF("\n");
11079                destval = fetch_data_word(destoffset);
11080                TRACE_AND_STEP();
11081                imul_word(destval);
11082            }
11083            break;
11084        case 6:
11085            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11086                u32 destval;
11087
11088                DECODE_PRINTF("DIV\tDWORD PTR ");
11089                destoffset = decode_rm01_address(rl);
11090                DECODE_PRINTF("\n");
11091                destval = fetch_data_long(destoffset);
11092                TRACE_AND_STEP();
11093                div_long(destval);
11094            }
11095            else {
11096                u16 destval;
11097
11098                DECODE_PRINTF("DIV\tWORD PTR ");
11099                destoffset = decode_rm01_address(rl);
11100                DECODE_PRINTF("\n");
11101                destval = fetch_data_word(destoffset);
11102                TRACE_AND_STEP();
11103                div_word(destval);
11104            }
11105            break;
11106        case 7:
11107            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11108                u32 destval;
11109
11110                DECODE_PRINTF("IDIV\tDWORD PTR ");
11111                destoffset = decode_rm01_address(rl);
11112                DECODE_PRINTF("\n");
11113                destval = fetch_data_long(destoffset);
11114                TRACE_AND_STEP();
11115                idiv_long(destval);
11116            }
11117            else {
11118                u16 destval;
11119
11120                DECODE_PRINTF("IDIV\tWORD PTR ");
11121                destoffset = decode_rm01_address(rl);
11122                DECODE_PRINTF("\n");
11123                destval = fetch_data_word(destoffset);
11124                TRACE_AND_STEP();
11125                idiv_word(destval);
11126            }
11127            break;
11128        }
11129        break;                  /* end mod==01 */
11130    case 2:                    /* mod=10 */
11131        switch (rh) {
11132        case 0:                /* test word imm */
11133            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11134                u32 destval, srcval;
11135
11136                DECODE_PRINTF("TEST\tDWORD PTR ");
11137                destoffset = decode_rm10_address(rl);
11138                DECODE_PRINTF(",");
11139                srcval = fetch_long_imm();
11140                DECODE_PRINTF2("%x\n", srcval);
11141                destval = fetch_data_long(destoffset);
11142                TRACE_AND_STEP();
11143                test_long(destval, srcval);
11144            }
11145            else {
11146                u16 destval, srcval;
11147
11148                DECODE_PRINTF("TEST\tWORD PTR ");
11149                destoffset = decode_rm10_address(rl);
11150                DECODE_PRINTF(",");
11151                srcval = fetch_word_imm();
11152                DECODE_PRINTF2("%x\n", srcval);
11153                destval = fetch_data_word(destoffset);
11154                TRACE_AND_STEP();
11155                test_word(destval, srcval);
11156            }
11157            break;
11158        case 1:
11159            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11160            HALT_SYS();
11161            break;
11162        case 2:
11163            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11164                u32 destval;
11165
11166                DECODE_PRINTF("NOT\tDWORD PTR ");
11167                destoffset = decode_rm10_address(rl);
11168                DECODE_PRINTF("\n");
11169                destval = fetch_data_long(destoffset);
11170                TRACE_AND_STEP();
11171                destval = not_long(destval);
11172                store_data_long(destoffset, destval);
11173            }
11174            else {
11175                u16 destval;
11176
11177                DECODE_PRINTF("NOT\tWORD PTR ");
11178                destoffset = decode_rm10_address(rl);
11179                DECODE_PRINTF("\n");
11180                destval = fetch_data_word(destoffset);
11181                TRACE_AND_STEP();
11182                destval = not_word(destval);
11183                store_data_word(destoffset, destval);
11184            }
11185            break;
11186        case 3:
11187            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11188                u32 destval;
11189
11190                DECODE_PRINTF("NEG\tDWORD PTR ");
11191                destoffset = decode_rm10_address(rl);
11192                DECODE_PRINTF("\n");
11193                destval = fetch_data_long(destoffset);
11194                TRACE_AND_STEP();
11195                destval = neg_long(destval);
11196                store_data_long(destoffset, destval);
11197            }
11198            else {
11199                u16 destval;
11200
11201                DECODE_PRINTF("NEG\tWORD PTR ");
11202                destoffset = decode_rm10_address(rl);
11203                DECODE_PRINTF("\n");
11204                destval = fetch_data_word(destoffset);
11205                TRACE_AND_STEP();
11206                destval = neg_word(destval);
11207                store_data_word(destoffset, destval);
11208            }
11209            break;
11210        case 4:
11211            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11212                u32 destval;
11213
11214                DECODE_PRINTF("MUL\tDWORD PTR ");
11215                destoffset = decode_rm10_address(rl);
11216                DECODE_PRINTF("\n");
11217                destval = fetch_data_long(destoffset);
11218                TRACE_AND_STEP();
11219                mul_long(destval);
11220            }
11221            else {
11222                u16 destval;
11223
11224                DECODE_PRINTF("MUL\tWORD PTR ");
11225                destoffset = decode_rm10_address(rl);
11226                DECODE_PRINTF("\n");
11227                destval = fetch_data_word(destoffset);
11228                TRACE_AND_STEP();
11229                mul_word(destval);
11230            }
11231            break;
11232        case 5:
11233            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11234                u32 destval;
11235
11236                DECODE_PRINTF("IMUL\tDWORD PTR ");
11237                destoffset = decode_rm10_address(rl);
11238                DECODE_PRINTF("\n");
11239                destval = fetch_data_long(destoffset);
11240                TRACE_AND_STEP();
11241                imul_long(destval);
11242            }
11243            else {
11244                u16 destval;
11245
11246                DECODE_PRINTF("IMUL\tWORD PTR ");
11247                destoffset = decode_rm10_address(rl);
11248                DECODE_PRINTF("\n");
11249                destval = fetch_data_word(destoffset);
11250                TRACE_AND_STEP();
11251                imul_word(destval);
11252            }
11253            break;
11254        case 6:
11255            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11256                u32 destval;
11257
11258                DECODE_PRINTF("DIV\tDWORD PTR ");
11259                destoffset = decode_rm10_address(rl);
11260                DECODE_PRINTF("\n");
11261                destval = fetch_data_long(destoffset);
11262                TRACE_AND_STEP();
11263                div_long(destval);
11264            }
11265            else {
11266                u16 destval;
11267
11268                DECODE_PRINTF("DIV\tWORD PTR ");
11269                destoffset = decode_rm10_address(rl);
11270                DECODE_PRINTF("\n");
11271                destval = fetch_data_word(destoffset);
11272                TRACE_AND_STEP();
11273                div_word(destval);
11274            }
11275            break;
11276        case 7:
11277            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11278                u32 destval;
11279
11280                DECODE_PRINTF("IDIV\tDWORD PTR ");
11281                destoffset = decode_rm10_address(rl);
11282                DECODE_PRINTF("\n");
11283                destval = fetch_data_long(destoffset);
11284                TRACE_AND_STEP();
11285                idiv_long(destval);
11286            }
11287            else {
11288                u16 destval;
11289
11290                DECODE_PRINTF("IDIV\tWORD PTR ");
11291                destoffset = decode_rm10_address(rl);
11292                DECODE_PRINTF("\n");
11293                destval = fetch_data_word(destoffset);
11294                TRACE_AND_STEP();
11295                idiv_word(destval);
11296            }
11297            break;
11298        }
11299        break;                  /* end mod==10 */
11300    case 3:                    /* mod=11 */
11301        switch (rh) {
11302        case 0:                /* test word imm */
11303            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11304                u32 *destreg;
11305                u32 srcval;
11306
11307                DECODE_PRINTF("TEST\t");
11308                destreg = DECODE_RM_LONG_REGISTER(rl);
11309                DECODE_PRINTF(",");
11310                srcval = fetch_long_imm();
11311                DECODE_PRINTF2("%x\n", srcval);
11312                TRACE_AND_STEP();
11313                test_long(*destreg, srcval);
11314            }
11315            else {
11316                u16 *destreg;
11317                u16 srcval;
11318
11319                DECODE_PRINTF("TEST\t");
11320                destreg = DECODE_RM_WORD_REGISTER(rl);
11321                DECODE_PRINTF(",");
11322                srcval = fetch_word_imm();
11323                DECODE_PRINTF2("%x\n", srcval);
11324                TRACE_AND_STEP();
11325                test_word(*destreg, srcval);
11326            }
11327            break;
11328        case 1:
11329            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11330            HALT_SYS();
11331            break;
11332        case 2:
11333            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11334                u32 *destreg;
11335
11336                DECODE_PRINTF("NOT\t");
11337                destreg = DECODE_RM_LONG_REGISTER(rl);
11338                DECODE_PRINTF("\n");
11339                TRACE_AND_STEP();
11340                *destreg = not_long(*destreg);
11341            }
11342            else {
11343                u16 *destreg;
11344
11345                DECODE_PRINTF("NOT\t");
11346                destreg = DECODE_RM_WORD_REGISTER(rl);
11347                DECODE_PRINTF("\n");
11348                TRACE_AND_STEP();
11349                *destreg = not_word(*destreg);
11350            }
11351            break;
11352        case 3:
11353            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11354                u32 *destreg;
11355
11356                DECODE_PRINTF("NEG\t");
11357                destreg = DECODE_RM_LONG_REGISTER(rl);
11358                DECODE_PRINTF("\n");
11359                TRACE_AND_STEP();
11360                *destreg = neg_long(*destreg);
11361            }
11362            else {
11363                u16 *destreg;
11364
11365                DECODE_PRINTF("NEG\t");
11366                destreg = DECODE_RM_WORD_REGISTER(rl);
11367                DECODE_PRINTF("\n");
11368                TRACE_AND_STEP();
11369                *destreg = neg_word(*destreg);
11370            }
11371            break;
11372        case 4:
11373            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11374                u32 *destreg;
11375
11376                DECODE_PRINTF("MUL\t");
11377                destreg = DECODE_RM_LONG_REGISTER(rl);
11378                DECODE_PRINTF("\n");
11379                TRACE_AND_STEP();
11380                mul_long(*destreg);     /*!!!  */
11381            }
11382            else {
11383                u16 *destreg;
11384
11385                DECODE_PRINTF("MUL\t");
11386                destreg = DECODE_RM_WORD_REGISTER(rl);
11387                DECODE_PRINTF("\n");
11388                TRACE_AND_STEP();
11389                mul_word(*destreg);     /*!!!  */
11390            }
11391            break;
11392        case 5:
11393            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11394                u32 *destreg;
11395
11396                DECODE_PRINTF("IMUL\t");
11397                destreg = DECODE_RM_LONG_REGISTER(rl);
11398                DECODE_PRINTF("\n");
11399                TRACE_AND_STEP();
11400                imul_long(*destreg);
11401            }
11402            else {
11403                u16 *destreg;
11404
11405                DECODE_PRINTF("IMUL\t");
11406                destreg = DECODE_RM_WORD_REGISTER(rl);
11407                DECODE_PRINTF("\n");
11408                TRACE_AND_STEP();
11409                imul_word(*destreg);
11410            }
11411            break;
11412        case 6:
11413            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11414                u32 *destreg;
11415
11416                DECODE_PRINTF("DIV\t");
11417                destreg = DECODE_RM_LONG_REGISTER(rl);
11418                DECODE_PRINTF("\n");
11419                TRACE_AND_STEP();
11420                div_long(*destreg);
11421            }
11422            else {
11423                u16 *destreg;
11424
11425                DECODE_PRINTF("DIV\t");
11426                destreg = DECODE_RM_WORD_REGISTER(rl);
11427                DECODE_PRINTF("\n");
11428                TRACE_AND_STEP();
11429                div_word(*destreg);
11430            }
11431            break;
11432        case 7:
11433            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11434                u32 *destreg;
11435
11436                DECODE_PRINTF("IDIV\t");
11437                destreg = DECODE_RM_LONG_REGISTER(rl);
11438                DECODE_PRINTF("\n");
11439                TRACE_AND_STEP();
11440                idiv_long(*destreg);
11441            }
11442            else {
11443                u16 *destreg;
11444
11445                DECODE_PRINTF("IDIV\t");
11446                destreg = DECODE_RM_WORD_REGISTER(rl);
11447                DECODE_PRINTF("\n");
11448                TRACE_AND_STEP();
11449                idiv_word(*destreg);
11450            }
11451            break;
11452        }
11453        break;                  /* end mod==11 */
11454    }
11455    DECODE_CLEAR_SEGOVR();
11456    END_OF_INSTR();
11457}
11458
11459/****************************************************************************
11460REMARKS:
11461Handles opcode 0xf8
11462****************************************************************************/
11463static void
11464x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11465{
11466    /* clear the carry flag. */
11467    START_OF_INSTR();
11468    DECODE_PRINTF("CLC\n");
11469    TRACE_AND_STEP();
11470    CLEAR_FLAG(F_CF);
11471    DECODE_CLEAR_SEGOVR();
11472    END_OF_INSTR();
11473}
11474
11475/****************************************************************************
11476REMARKS:
11477Handles opcode 0xf9
11478****************************************************************************/
11479static void
11480x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11481{
11482    /* set the carry flag. */
11483    START_OF_INSTR();
11484    DECODE_PRINTF("STC\n");
11485    TRACE_AND_STEP();
11486    SET_FLAG(F_CF);
11487    DECODE_CLEAR_SEGOVR();
11488    END_OF_INSTR();
11489}
11490
11491/****************************************************************************
11492REMARKS:
11493Handles opcode 0xfa
11494****************************************************************************/
11495static void
11496x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11497{
11498    /* clear interrupts. */
11499    START_OF_INSTR();
11500    DECODE_PRINTF("CLI\n");
11501    TRACE_AND_STEP();
11502    CLEAR_FLAG(F_IF);
11503    DECODE_CLEAR_SEGOVR();
11504    END_OF_INSTR();
11505}
11506
11507/****************************************************************************
11508REMARKS:
11509Handles opcode 0xfb
11510****************************************************************************/
11511static void
11512x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11513{
11514    /* enable  interrupts. */
11515    START_OF_INSTR();
11516    DECODE_PRINTF("STI\n");
11517    TRACE_AND_STEP();
11518    SET_FLAG(F_IF);
11519    DECODE_CLEAR_SEGOVR();
11520    END_OF_INSTR();
11521}
11522
11523/****************************************************************************
11524REMARKS:
11525Handles opcode 0xfc
11526****************************************************************************/
11527static void
11528x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11529{
11530    /* clear interrupts. */
11531    START_OF_INSTR();
11532    DECODE_PRINTF("CLD\n");
11533    TRACE_AND_STEP();
11534    CLEAR_FLAG(F_DF);
11535    DECODE_CLEAR_SEGOVR();
11536    END_OF_INSTR();
11537}
11538
11539/****************************************************************************
11540REMARKS:
11541Handles opcode 0xfd
11542****************************************************************************/
11543static void
11544x86emuOp_std(u8 X86EMU_UNUSED(op1))
11545{
11546    /* clear interrupts. */
11547    START_OF_INSTR();
11548    DECODE_PRINTF("STD\n");
11549    TRACE_AND_STEP();
11550    SET_FLAG(F_DF);
11551    DECODE_CLEAR_SEGOVR();
11552    END_OF_INSTR();
11553}
11554
11555/****************************************************************************
11556REMARKS:
11557Handles opcode 0xfe
11558****************************************************************************/
11559static void
11560x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11561{
11562    int mod, rh, rl;
11563    u8 destval;
11564    uint destoffset;
11565    u8 *destreg;
11566
11567    /* Yet another special case instruction. */
11568    START_OF_INSTR();
11569    FETCH_DECODE_MODRM(mod, rh, rl);
11570#ifdef DEBUG
11571    if (DEBUG_DECODE()) {
11572        /* XXX DECODE_PRINTF may be changed to something more
11573           general, so that it is important to leave the strings
11574           in the same format, even though the result is that the
11575           above test is done twice. */
11576
11577        switch (rh) {
11578        case 0:
11579            DECODE_PRINTF("INC\t");
11580            break;
11581        case 1:
11582            DECODE_PRINTF("DEC\t");
11583            break;
11584        case 2:
11585        case 3:
11586        case 4:
11587        case 5:
11588        case 6:
11589        case 7:
11590            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11591            HALT_SYS();
11592            break;
11593        }
11594    }
11595#endif
11596    switch (mod) {
11597    case 0:
11598        DECODE_PRINTF("BYTE PTR ");
11599        destoffset = decode_rm00_address(rl);
11600        DECODE_PRINTF("\n");
11601        switch (rh) {
11602        case 0:                /* inc word ptr ... */
11603            destval = fetch_data_byte(destoffset);
11604            TRACE_AND_STEP();
11605            destval = inc_byte(destval);
11606            store_data_byte(destoffset, destval);
11607            break;
11608        case 1:                /* dec word ptr ... */
11609            destval = fetch_data_byte(destoffset);
11610            TRACE_AND_STEP();
11611            destval = dec_byte(destval);
11612            store_data_byte(destoffset, destval);
11613            break;
11614        }
11615        break;
11616    case 1:
11617        DECODE_PRINTF("BYTE PTR ");
11618        destoffset = decode_rm01_address(rl);
11619        DECODE_PRINTF("\n");
11620        switch (rh) {
11621        case 0:
11622            destval = fetch_data_byte(destoffset);
11623            TRACE_AND_STEP();
11624            destval = inc_byte(destval);
11625            store_data_byte(destoffset, destval);
11626            break;
11627        case 1:
11628            destval = fetch_data_byte(destoffset);
11629            TRACE_AND_STEP();
11630            destval = dec_byte(destval);
11631            store_data_byte(destoffset, destval);
11632            break;
11633        }
11634        break;
11635    case 2:
11636        DECODE_PRINTF("BYTE PTR ");
11637        destoffset = decode_rm10_address(rl);
11638        DECODE_PRINTF("\n");
11639        switch (rh) {
11640        case 0:
11641            destval = fetch_data_byte(destoffset);
11642            TRACE_AND_STEP();
11643            destval = inc_byte(destval);
11644            store_data_byte(destoffset, destval);
11645            break;
11646        case 1:
11647            destval = fetch_data_byte(destoffset);
11648            TRACE_AND_STEP();
11649            destval = dec_byte(destval);
11650            store_data_byte(destoffset, destval);
11651            break;
11652        }
11653        break;
11654    case 3:
11655        destreg = DECODE_RM_BYTE_REGISTER(rl);
11656        DECODE_PRINTF("\n");
11657        switch (rh) {
11658        case 0:
11659            TRACE_AND_STEP();
11660            *destreg = inc_byte(*destreg);
11661            break;
11662        case 1:
11663            TRACE_AND_STEP();
11664            *destreg = dec_byte(*destreg);
11665            break;
11666        }
11667        break;
11668    }
11669    DECODE_CLEAR_SEGOVR();
11670    END_OF_INSTR();
11671}
11672
11673/****************************************************************************
11674REMARKS:
11675Handles opcode 0xff
11676****************************************************************************/
11677static void
11678x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11679{
11680    int mod, rh, rl;
11681    uint destoffset = 0;
11682    u16 *destreg;
11683    u16 destval, destval2;
11684
11685    /* Yet another special case instruction. */
11686    START_OF_INSTR();
11687    FETCH_DECODE_MODRM(mod, rh, rl);
11688#ifdef DEBUG
11689    if (DEBUG_DECODE()) {
11690        /* XXX DECODE_PRINTF may be changed to something more
11691           general, so that it is important to leave the strings
11692           in the same format, even though the result is that the
11693           above test is done twice. */
11694
11695        switch (rh) {
11696        case 0:
11697            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11698                DECODE_PRINTF("INC\tDWORD PTR ");
11699            }
11700            else {
11701                DECODE_PRINTF("INC\tWORD PTR ");
11702            }
11703            break;
11704        case 1:
11705            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11706                DECODE_PRINTF("DEC\tDWORD PTR ");
11707            }
11708            else {
11709                DECODE_PRINTF("DEC\tWORD PTR ");
11710            }
11711            break;
11712        case 2:
11713            DECODE_PRINTF("CALL\t");
11714            break;
11715        case 3:
11716            DECODE_PRINTF("CALL\tFAR ");
11717            break;
11718        case 4:
11719            DECODE_PRINTF("JMP\t");
11720            break;
11721        case 5:
11722            DECODE_PRINTF("JMP\tFAR ");
11723            break;
11724        case 6:
11725            DECODE_PRINTF("PUSH\t");
11726            break;
11727        case 7:
11728            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11729            HALT_SYS();
11730            break;
11731        }
11732    }
11733#endif
11734    switch (mod) {
11735    case 0:
11736        destoffset = decode_rm00_address(rl);
11737        DECODE_PRINTF("\n");
11738        switch (rh) {
11739        case 0:                /* inc word ptr ... */
11740            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11741                u32 destval32;
11742
11743                destval32 = fetch_data_long(destoffset);
11744                TRACE_AND_STEP();
11745                destval32 = inc_long(destval32);
11746                store_data_long(destoffset, destval32);
11747            }
11748            else {
11749                u16 destval16;
11750
11751                destval16 = fetch_data_word(destoffset);
11752                TRACE_AND_STEP();
11753                destval16 = inc_word(destval16);
11754                store_data_word(destoffset, destval16);
11755            }
11756            break;
11757        case 1:                /* dec word ptr ... */
11758            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11759                u32 destval32;
11760
11761                destval32 = fetch_data_long(destoffset);
11762                TRACE_AND_STEP();
11763                destval32 = dec_long(destval32);
11764                store_data_long(destoffset, destval32);
11765            }
11766            else {
11767                u16 destval16;
11768
11769                destval16 = fetch_data_word(destoffset);
11770                TRACE_AND_STEP();
11771                destval16 = dec_word(destval16);
11772                store_data_word(destoffset, destval16);
11773            }
11774            break;
11775        case 2:                /* call word ptr ... */
11776            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11777                destval = fetch_data_long(destoffset);
11778                TRACE_AND_STEP();
11779                push_long(M.x86.R_EIP);
11780                M.x86.R_EIP = destval;
11781            } else {
11782                destval = fetch_data_word(destoffset);
11783                TRACE_AND_STEP();
11784                push_word(M.x86.R_IP);
11785                M.x86.R_IP = destval;
11786            }
11787            break;
11788        case 3:                /* call far ptr ... */
11789            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11790                destval = fetch_data_long(destoffset);
11791                destval2 = fetch_data_word(destoffset + 4);
11792                TRACE_AND_STEP();
11793                push_long(M.x86.R_CS);
11794                M.x86.R_CS = destval2;
11795                push_long(M.x86.R_EIP);
11796                M.x86.R_EIP = destval;
11797            } else {
11798                destval = fetch_data_word(destoffset);
11799                destval2 = fetch_data_word(destoffset + 2);
11800                TRACE_AND_STEP();
11801                push_word(M.x86.R_CS);
11802                M.x86.R_CS = destval2;
11803                push_word(M.x86.R_IP);
11804                M.x86.R_IP = destval;
11805            }
11806            break;
11807        case 4:                /* jmp word ptr ... */
11808            destval = fetch_data_word(destoffset);
11809            TRACE_AND_STEP();
11810            M.x86.R_IP = destval;
11811            break;
11812        case 5:                /* jmp far ptr ... */
11813            destval = fetch_data_word(destoffset);
11814            destval2 = fetch_data_word(destoffset + 2);
11815            TRACE_AND_STEP();
11816            M.x86.R_IP = destval;
11817            M.x86.R_CS = destval2;
11818            break;
11819        case 6:                /*  push word ptr ... */
11820            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11821                u32 destval32;
11822
11823                destval32 = fetch_data_long(destoffset);
11824                TRACE_AND_STEP();
11825                push_long(destval32);
11826            }
11827            else {
11828                u16 destval16;
11829
11830                destval16 = fetch_data_word(destoffset);
11831                TRACE_AND_STEP();
11832                push_word(destval16);
11833            }
11834            break;
11835        }
11836        break;
11837    case 1:
11838        destoffset = decode_rm01_address(rl);
11839        DECODE_PRINTF("\n");
11840        switch (rh) {
11841        case 0:
11842            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11843                u32 destval32;
11844
11845                destval32 = fetch_data_long(destoffset);
11846                TRACE_AND_STEP();
11847                destval32 = inc_long(destval32);
11848                store_data_long(destoffset, destval32);
11849            }
11850            else {
11851                u16 destval16;
11852
11853                destval16 = fetch_data_word(destoffset);
11854                TRACE_AND_STEP();
11855                destval16 = inc_word(destval16);
11856                store_data_word(destoffset, destval16);
11857            }
11858            break;
11859        case 1:
11860            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11861                u32 destval32;
11862
11863                destval32 = fetch_data_long(destoffset);
11864                TRACE_AND_STEP();
11865                destval32 = dec_long(destval32);
11866                store_data_long(destoffset, destval32);
11867            }
11868            else {
11869                u16 destval16;
11870
11871                destval16 = fetch_data_word(destoffset);
11872                TRACE_AND_STEP();
11873                destval16 = dec_word(destval16);
11874                store_data_word(destoffset, destval16);
11875            }
11876            break;
11877        case 2:                /* call word ptr ... */
11878            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11879                destval = fetch_data_long(destoffset);
11880                TRACE_AND_STEP();
11881                push_long(M.x86.R_EIP);
11882                M.x86.R_EIP = destval;
11883            } else {
11884                destval = fetch_data_word(destoffset);
11885                TRACE_AND_STEP();
11886                push_word(M.x86.R_IP);
11887                M.x86.R_IP = destval;
11888            }
11889            break;
11890        case 3:                /* call far ptr ... */
11891            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11892                destval = fetch_data_long(destoffset);
11893                destval2 = fetch_data_word(destoffset + 4);
11894                TRACE_AND_STEP();
11895                push_long(M.x86.R_CS);
11896                M.x86.R_CS = destval2;
11897                push_long(M.x86.R_EIP);
11898                M.x86.R_EIP = destval;
11899            } else {
11900                destval = fetch_data_word(destoffset);
11901                destval2 = fetch_data_word(destoffset + 2);
11902                TRACE_AND_STEP();
11903                push_word(M.x86.R_CS);
11904                M.x86.R_CS = destval2;
11905                push_word(M.x86.R_IP);
11906                M.x86.R_IP = destval;
11907            }
11908            break;
11909        case 4:                /* jmp word ptr ... */
11910            destval = fetch_data_word(destoffset);
11911            TRACE_AND_STEP();
11912            M.x86.R_IP = destval;
11913            break;
11914        case 5:                /* jmp far ptr ... */
11915            destval = fetch_data_word(destoffset);
11916            destval2 = fetch_data_word(destoffset + 2);
11917            TRACE_AND_STEP();
11918            M.x86.R_IP = destval;
11919            M.x86.R_CS = destval2;
11920            break;
11921        case 6:                /*  push word ptr ... */
11922            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11923                u32 destval32;
11924
11925                destval32 = fetch_data_long(destoffset);
11926                TRACE_AND_STEP();
11927                push_long(destval32);
11928            }
11929            else {
11930                u16 destval16;
11931
11932                destval16 = fetch_data_word(destoffset);
11933                TRACE_AND_STEP();
11934                push_word(destval16);
11935            }
11936            break;
11937        }
11938        break;
11939    case 2:
11940        destoffset = decode_rm10_address(rl);
11941        DECODE_PRINTF("\n");
11942        switch (rh) {
11943        case 0:
11944            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11945                u32 destval32;
11946
11947                destval32 = fetch_data_long(destoffset);
11948                TRACE_AND_STEP();
11949                destval32 = inc_long(destval32);
11950                store_data_long(destoffset, destval32);
11951            }
11952            else {
11953                u16 destval16;
11954
11955                destval16 = fetch_data_word(destoffset);
11956                TRACE_AND_STEP();
11957                destval16 = inc_word(destval16);
11958                store_data_word(destoffset, destval16);
11959            }
11960            break;
11961        case 1:
11962            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11963                u32 destval32;
11964
11965                destval32 = fetch_data_long(destoffset);
11966                TRACE_AND_STEP();
11967                destval32 = dec_long(destval32);
11968                store_data_long(destoffset, destval32);
11969            }
11970            else {
11971                u16 destval16;
11972
11973                destval16 = fetch_data_word(destoffset);
11974                TRACE_AND_STEP();
11975                destval16 = dec_word(destval16);
11976                store_data_word(destoffset, destval16);
11977            }
11978            break;
11979        case 2:                /* call word ptr ... */
11980            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11981                destval = fetch_data_long(destoffset);
11982                TRACE_AND_STEP();
11983                push_long(M.x86.R_EIP);
11984                M.x86.R_EIP = destval;
11985            } else {
11986                destval = fetch_data_word(destoffset);
11987                TRACE_AND_STEP();
11988                push_word(M.x86.R_IP);
11989                M.x86.R_IP = destval;
11990            }
11991            break;
11992        case 3:                /* call far ptr ... */
11993            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11994                destval = fetch_data_long(destoffset);
11995                destval2 = fetch_data_word(destoffset + 4);
11996                TRACE_AND_STEP();
11997                push_long(M.x86.R_CS);
11998                M.x86.R_CS = destval2;
11999                push_long(M.x86.R_EIP);
12000                M.x86.R_EIP = destval;
12001            } else {
12002                destval = fetch_data_word(destoffset);
12003                destval2 = fetch_data_word(destoffset + 2);
12004                TRACE_AND_STEP();
12005                push_word(M.x86.R_CS);
12006                M.x86.R_CS = destval2;
12007                push_word(M.x86.R_IP);
12008                M.x86.R_IP = destval;
12009            }
12010            break;
12011        case 4:                /* jmp word ptr ... */
12012            destval = fetch_data_word(destoffset);
12013            TRACE_AND_STEP();
12014            M.x86.R_IP = destval;
12015            break;
12016        case 5:                /* jmp far ptr ... */
12017            destval = fetch_data_word(destoffset);
12018            destval2 = fetch_data_word(destoffset + 2);
12019            TRACE_AND_STEP();
12020            M.x86.R_IP = destval;
12021            M.x86.R_CS = destval2;
12022            break;
12023        case 6:                /*  push word ptr ... */
12024            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12025                u32 destval32;
12026
12027                destval32 = fetch_data_long(destoffset);
12028                TRACE_AND_STEP();
12029                push_long(destval32);
12030            }
12031            else {
12032                u16 destval16;
12033
12034                destval16 = fetch_data_word(destoffset);
12035                TRACE_AND_STEP();
12036                push_word(destval16);
12037            }
12038            break;
12039        }
12040        break;
12041    case 3:
12042        switch (rh) {
12043        case 0:
12044            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12045                u32 *destreg32;
12046
12047                destreg32 = DECODE_RM_LONG_REGISTER(rl);
12048                DECODE_PRINTF("\n");
12049                TRACE_AND_STEP();
12050                *destreg32 = inc_long(*destreg32);
12051            }
12052            else {
12053                u16 *destreg16;
12054
12055                destreg16 = DECODE_RM_WORD_REGISTER(rl);
12056                DECODE_PRINTF("\n");
12057                TRACE_AND_STEP();
12058                *destreg16 = inc_word(*destreg16);
12059            }
12060            break;
12061        case 1:
12062            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12063                u32 *destreg32;
12064
12065                destreg32 = DECODE_RM_LONG_REGISTER(rl);
12066                DECODE_PRINTF("\n");
12067                TRACE_AND_STEP();
12068                *destreg32 = dec_long(*destreg32);
12069            }
12070            else {
12071                u16 *destreg16;
12072
12073                destreg16 = DECODE_RM_WORD_REGISTER(rl);
12074                DECODE_PRINTF("\n");
12075                TRACE_AND_STEP();
12076                *destreg16 = dec_word(*destreg16);
12077            }
12078            break;
12079        case 2:                /* call word ptr ... */
12080            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12081                destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
12082                DECODE_PRINTF("\n");
12083                TRACE_AND_STEP();
12084                push_long(M.x86.R_EIP);
12085                M.x86.R_EIP = *destreg;
12086            } else {
12087                destreg = DECODE_RM_WORD_REGISTER(rl);
12088                DECODE_PRINTF("\n");
12089                TRACE_AND_STEP();
12090                push_word(M.x86.R_IP);
12091                M.x86.R_IP = *destreg;
12092            }
12093            break;
12094        case 3:                /* jmp far ptr ... */
12095            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12096            TRACE_AND_STEP();
12097            HALT_SYS();
12098            break;
12099
12100        case 4:                /* jmp  ... */
12101            destreg = DECODE_RM_WORD_REGISTER(rl);
12102            DECODE_PRINTF("\n");
12103            TRACE_AND_STEP();
12104            M.x86.R_IP = (u16) (*destreg);
12105            break;
12106        case 5:                /* jmp far ptr ... */
12107            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12108            TRACE_AND_STEP();
12109            HALT_SYS();
12110            break;
12111        case 6:
12112            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12113                u32 *destreg32;
12114
12115                destreg32 = DECODE_RM_LONG_REGISTER(rl);
12116                DECODE_PRINTF("\n");
12117                TRACE_AND_STEP();
12118                push_long(*destreg32);
12119            }
12120            else {
12121                u16 *destreg16;
12122
12123                destreg16 = DECODE_RM_WORD_REGISTER(rl);
12124                DECODE_PRINTF("\n");
12125                TRACE_AND_STEP();
12126                push_word(*destreg16);
12127            }
12128            break;
12129        }
12130        break;
12131    }
12132    DECODE_CLEAR_SEGOVR();
12133    END_OF_INSTR();
12134}
12135
12136/***************************************************************************
12137 * Single byte operation code table:
12138 **************************************************************************/
12139void (*x86emu_optab[256]) (u8) = {
12140/*  0x00 */ x86emuOp_add_byte_RM_R,
12141/*  0x01 */ x86emuOp_add_word_RM_R,
12142/*  0x02 */ x86emuOp_add_byte_R_RM,
12143/*  0x03 */ x86emuOp_add_word_R_RM,
12144/*  0x04 */ x86emuOp_add_byte_AL_IMM,
12145/*  0x05 */ x86emuOp_add_word_AX_IMM,
12146/*  0x06 */ x86emuOp_push_ES,
12147/*  0x07 */ x86emuOp_pop_ES,
12148/*  0x08 */ x86emuOp_or_byte_RM_R,
12149/*  0x09 */ x86emuOp_or_word_RM_R,
12150/*  0x0a */ x86emuOp_or_byte_R_RM,
12151/*  0x0b */ x86emuOp_or_word_R_RM,
12152/*  0x0c */ x86emuOp_or_byte_AL_IMM,
12153/*  0x0d */ x86emuOp_or_word_AX_IMM,
12154/*  0x0e */ x86emuOp_push_CS,
12155/*  0x0f */ x86emuOp_two_byte,
12156/*  0x10 */ x86emuOp_adc_byte_RM_R,
12157/*  0x11 */ x86emuOp_adc_word_RM_R,
12158/*  0x12 */ x86emuOp_adc_byte_R_RM,
12159/*  0x13 */ x86emuOp_adc_word_R_RM,
12160/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
12161/*  0x15 */ x86emuOp_adc_word_AX_IMM,
12162/*  0x16 */ x86emuOp_push_SS,
12163/*  0x17 */ x86emuOp_pop_SS,
12164/*  0x18 */ x86emuOp_sbb_byte_RM_R,
12165/*  0x19 */ x86emuOp_sbb_word_RM_R,
12166/*  0x1a */ x86emuOp_sbb_byte_R_RM,
12167/*  0x1b */ x86emuOp_sbb_word_R_RM,
12168/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
12169/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
12170/*  0x1e */ x86emuOp_push_DS,
12171/*  0x1f */ x86emuOp_pop_DS,
12172/*  0x20 */ x86emuOp_and_byte_RM_R,
12173/*  0x21 */ x86emuOp_and_word_RM_R,
12174/*  0x22 */ x86emuOp_and_byte_R_RM,
12175/*  0x23 */ x86emuOp_and_word_R_RM,
12176/*  0x24 */ x86emuOp_and_byte_AL_IMM,
12177/*  0x25 */ x86emuOp_and_word_AX_IMM,
12178/*  0x26 */ x86emuOp_segovr_ES,
12179/*  0x27 */ x86emuOp_daa,
12180/*  0x28 */ x86emuOp_sub_byte_RM_R,
12181/*  0x29 */ x86emuOp_sub_word_RM_R,
12182/*  0x2a */ x86emuOp_sub_byte_R_RM,
12183/*  0x2b */ x86emuOp_sub_word_R_RM,
12184/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
12185/*  0x2d */ x86emuOp_sub_word_AX_IMM,
12186/*  0x2e */ x86emuOp_segovr_CS,
12187/*  0x2f */ x86emuOp_das,
12188/*  0x30 */ x86emuOp_xor_byte_RM_R,
12189/*  0x31 */ x86emuOp_xor_word_RM_R,
12190/*  0x32 */ x86emuOp_xor_byte_R_RM,
12191/*  0x33 */ x86emuOp_xor_word_R_RM,
12192/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
12193/*  0x35 */ x86emuOp_xor_word_AX_IMM,
12194/*  0x36 */ x86emuOp_segovr_SS,
12195/*  0x37 */ x86emuOp_aaa,
12196/*  0x38 */ x86emuOp_cmp_byte_RM_R,
12197/*  0x39 */ x86emuOp_cmp_word_RM_R,
12198/*  0x3a */ x86emuOp_cmp_byte_R_RM,
12199/*  0x3b */ x86emuOp_cmp_word_R_RM,
12200/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
12201/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
12202/*  0x3e */ x86emuOp_segovr_DS,
12203/*  0x3f */ x86emuOp_aas,
12204/*  0x40 */ x86emuOp_inc_AX,
12205/*  0x41 */ x86emuOp_inc_CX,
12206/*  0x42 */ x86emuOp_inc_DX,
12207/*  0x43 */ x86emuOp_inc_BX,
12208/*  0x44 */ x86emuOp_inc_SP,
12209/*  0x45 */ x86emuOp_inc_BP,
12210/*  0x46 */ x86emuOp_inc_SI,
12211/*  0x47 */ x86emuOp_inc_DI,
12212/*  0x48 */ x86emuOp_dec_AX,
12213/*  0x49 */ x86emuOp_dec_CX,
12214/*  0x4a */ x86emuOp_dec_DX,
12215/*  0x4b */ x86emuOp_dec_BX,
12216/*  0x4c */ x86emuOp_dec_SP,
12217/*  0x4d */ x86emuOp_dec_BP,
12218/*  0x4e */ x86emuOp_dec_SI,
12219/*  0x4f */ x86emuOp_dec_DI,
12220/*  0x50 */ x86emuOp_push_AX,
12221/*  0x51 */ x86emuOp_push_CX,
12222/*  0x52 */ x86emuOp_push_DX,
12223/*  0x53 */ x86emuOp_push_BX,
12224/*  0x54 */ x86emuOp_push_SP,
12225/*  0x55 */ x86emuOp_push_BP,
12226/*  0x56 */ x86emuOp_push_SI,
12227/*  0x57 */ x86emuOp_push_DI,
12228/*  0x58 */ x86emuOp_pop_AX,
12229/*  0x59 */ x86emuOp_pop_CX,
12230/*  0x5a */ x86emuOp_pop_DX,
12231/*  0x5b */ x86emuOp_pop_BX,
12232/*  0x5c */ x86emuOp_pop_SP,
12233/*  0x5d */ x86emuOp_pop_BP,
12234/*  0x5e */ x86emuOp_pop_SI,
12235/*  0x5f */ x86emuOp_pop_DI,
12236/*  0x60 */ x86emuOp_push_all,
12237/*  0x61 */ x86emuOp_pop_all,
12238                                                /*  0x62 */ x86emuOp_illegal_op,
12239                                                /* bound */
12240                                                /*  0x63 */ x86emuOp_illegal_op,
12241                                                /* arpl */
12242/*  0x64 */ x86emuOp_segovr_FS,
12243/*  0x65 */ x86emuOp_segovr_GS,
12244/*  0x66 */ x86emuOp_prefix_data,
12245/*  0x67 */ x86emuOp_prefix_addr,
12246/*  0x68 */ x86emuOp_push_word_IMM,
12247/*  0x69 */ x86emuOp_imul_word_IMM,
12248/*  0x6a */ x86emuOp_push_byte_IMM,
12249/*  0x6b */ x86emuOp_imul_byte_IMM,
12250/*  0x6c */ x86emuOp_ins_byte,
12251/*  0x6d */ x86emuOp_ins_word,
12252/*  0x6e */ x86emuOp_outs_byte,
12253/*  0x6f */ x86emuOp_outs_word,
12254/*  0x70 */ x86emuOp_jump_near_O,
12255/*  0x71 */ x86emuOp_jump_near_NO,
12256/*  0x72 */ x86emuOp_jump_near_B,
12257/*  0x73 */ x86emuOp_jump_near_NB,
12258/*  0x74 */ x86emuOp_jump_near_Z,
12259/*  0x75 */ x86emuOp_jump_near_NZ,
12260/*  0x76 */ x86emuOp_jump_near_BE,
12261/*  0x77 */ x86emuOp_jump_near_NBE,
12262/*  0x78 */ x86emuOp_jump_near_S,
12263/*  0x79 */ x86emuOp_jump_near_NS,
12264/*  0x7a */ x86emuOp_jump_near_P,
12265/*  0x7b */ x86emuOp_jump_near_NP,
12266/*  0x7c */ x86emuOp_jump_near_L,
12267/*  0x7d */ x86emuOp_jump_near_NL,
12268/*  0x7e */ x86emuOp_jump_near_LE,
12269/*  0x7f */ x86emuOp_jump_near_NLE,
12270/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
12271/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
12272/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
12273/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
12274/*  0x84 */ x86emuOp_test_byte_RM_R,
12275/*  0x85 */ x86emuOp_test_word_RM_R,
12276/*  0x86 */ x86emuOp_xchg_byte_RM_R,
12277/*  0x87 */ x86emuOp_xchg_word_RM_R,
12278/*  0x88 */ x86emuOp_mov_byte_RM_R,
12279/*  0x89 */ x86emuOp_mov_word_RM_R,
12280/*  0x8a */ x86emuOp_mov_byte_R_RM,
12281/*  0x8b */ x86emuOp_mov_word_R_RM,
12282/*  0x8c */ x86emuOp_mov_word_RM_SR,
12283/*  0x8d */ x86emuOp_lea_word_R_M,
12284/*  0x8e */ x86emuOp_mov_word_SR_RM,
12285/*  0x8f */ x86emuOp_pop_RM,
12286/*  0x90 */ x86emuOp_nop,
12287/*  0x91 */ x86emuOp_xchg_word_AX_CX,
12288/*  0x92 */ x86emuOp_xchg_word_AX_DX,
12289/*  0x93 */ x86emuOp_xchg_word_AX_BX,
12290/*  0x94 */ x86emuOp_xchg_word_AX_SP,
12291/*  0x95 */ x86emuOp_xchg_word_AX_BP,
12292/*  0x96 */ x86emuOp_xchg_word_AX_SI,
12293/*  0x97 */ x86emuOp_xchg_word_AX_DI,
12294/*  0x98 */ x86emuOp_cbw,
12295/*  0x99 */ x86emuOp_cwd,
12296/*  0x9a */ x86emuOp_call_far_IMM,
12297/*  0x9b */ x86emuOp_wait,
12298/*  0x9c */ x86emuOp_pushf_word,
12299/*  0x9d */ x86emuOp_popf_word,
12300/*  0x9e */ x86emuOp_sahf,
12301/*  0x9f */ x86emuOp_lahf,
12302/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
12303/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
12304/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
12305/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
12306/*  0xa4 */ x86emuOp_movs_byte,
12307/*  0xa5 */ x86emuOp_movs_word,
12308/*  0xa6 */ x86emuOp_cmps_byte,
12309/*  0xa7 */ x86emuOp_cmps_word,
12310/*  0xa8 */ x86emuOp_test_AL_IMM,
12311/*  0xa9 */ x86emuOp_test_AX_IMM,
12312/*  0xaa */ x86emuOp_stos_byte,
12313/*  0xab */ x86emuOp_stos_word,
12314/*  0xac */ x86emuOp_lods_byte,
12315/*  0xad */ x86emuOp_lods_word,
12316/*  0xac */ x86emuOp_scas_byte,
12317/*  0xad */ x86emuOp_scas_word,
12318/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
12319/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
12320/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
12321/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
12322/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
12323/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
12324/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
12325/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
12326/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
12327/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
12328/*  0xba */ x86emuOp_mov_word_DX_IMM,
12329/*  0xbb */ x86emuOp_mov_word_BX_IMM,
12330/*  0xbc */ x86emuOp_mov_word_SP_IMM,
12331/*  0xbd */ x86emuOp_mov_word_BP_IMM,
12332/*  0xbe */ x86emuOp_mov_word_SI_IMM,
12333/*  0xbf */ x86emuOp_mov_word_DI_IMM,
12334/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12335/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12336/*  0xc2 */ x86emuOp_ret_near_IMM,
12337/*  0xc3 */ x86emuOp_ret_near,
12338/*  0xc4 */ x86emuOp_les_R_IMM,
12339/*  0xc5 */ x86emuOp_lds_R_IMM,
12340/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
12341/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
12342/*  0xc8 */ x86emuOp_enter,
12343/*  0xc9 */ x86emuOp_leave,
12344/*  0xca */ x86emuOp_ret_far_IMM,
12345/*  0xcb */ x86emuOp_ret_far,
12346/*  0xcc */ x86emuOp_int3,
12347/*  0xcd */ x86emuOp_int_IMM,
12348/*  0xce */ x86emuOp_into,
12349/*  0xcf */ x86emuOp_iret,
12350/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
12351/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
12352/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12353/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
12354/*  0xd4 */ x86emuOp_aam,
12355/*  0xd5 */ x86emuOp_aad,
12356                                                /*  0xd6 */ x86emuOp_illegal_op,
12357                                                /* Undocumented SETALC instruction */
12358/*  0xd7 */ x86emuOp_xlat,
12359/*  0xd8 */ x86emuOp_esc_coprocess_d8,
12360/*  0xd9 */ x86emuOp_esc_coprocess_d9,
12361/*  0xda */ x86emuOp_esc_coprocess_da,
12362/*  0xdb */ x86emuOp_esc_coprocess_db,
12363/*  0xdc */ x86emuOp_esc_coprocess_dc,
12364/*  0xdd */ x86emuOp_esc_coprocess_dd,
12365/*  0xde */ x86emuOp_esc_coprocess_de,
12366/*  0xdf */ x86emuOp_esc_coprocess_df,
12367/*  0xe0 */ x86emuOp_loopne,
12368/*  0xe1 */ x86emuOp_loope,
12369/*  0xe2 */ x86emuOp_loop,
12370/*  0xe3 */ x86emuOp_jcxz,
12371/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
12372/*  0xe5 */ x86emuOp_in_word_AX_IMM,
12373/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
12374/*  0xe7 */ x86emuOp_out_word_IMM_AX,
12375/*  0xe8 */ x86emuOp_call_near_IMM,
12376/*  0xe9 */ x86emuOp_jump_near_IMM,
12377/*  0xea */ x86emuOp_jump_far_IMM,
12378/*  0xeb */ x86emuOp_jump_byte_IMM,
12379/*  0xec */ x86emuOp_in_byte_AL_DX,
12380/*  0xed */ x86emuOp_in_word_AX_DX,
12381/*  0xee */ x86emuOp_out_byte_DX_AL,
12382/*  0xef */ x86emuOp_out_word_DX_AX,
12383/*  0xf0 */ x86emuOp_lock,
12384/*  0xf1 */ x86emuOp_illegal_op,
12385/*  0xf2 */ x86emuOp_repne,
12386/*  0xf3 */ x86emuOp_repe,
12387/*  0xf4 */ x86emuOp_halt,
12388/*  0xf5 */ x86emuOp_cmc,
12389/*  0xf6 */ x86emuOp_opcF6_byte_RM,
12390/*  0xf7 */ x86emuOp_opcF7_word_RM,
12391/*  0xf8 */ x86emuOp_clc,
12392/*  0xf9 */ x86emuOp_stc,
12393/*  0xfa */ x86emuOp_cli,
12394/*  0xfb */ x86emuOp_sti,
12395/*  0xfc */ x86emuOp_cld,
12396/*  0xfd */ x86emuOp_std,
12397/*  0xfe */ x86emuOp_opcFE_byte_RM,
12398/*  0xff */ x86emuOp_opcFF_word_RM,
12399};
12400