1/****************************************************************************
2*
3*						Realmode X86 Emulator Library
4*
5*            	Copyright (C) 1996-1999 SciTech Software, Inc.
6* 				     Copyright (C) David Mosberger-Tang
7* 					   Copyright (C) 1999 Egbert Eich
8*
9*  ========================================================================
10*
11*  Permission to use, copy, modify, distribute, and sell this software and
12*  its documentation for any purpose is hereby granted without fee,
13*  provided that the above copyright notice appear in all copies and that
14*  both that copyright notice and this permission notice appear in
15*  supporting documentation, and that the name of the authors not be used
16*  in advertising or publicity pertaining to distribution of the software
17*  without specific, written prior permission.  The authors makes no
18*  representations about the suitability of this software for any purpose.
19*  It is provided "as is" without express or implied warranty.
20*
21*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27*  PERFORMANCE OF THIS SOFTWARE.
28*
29*  ========================================================================
30*
31* Language:		ANSI C
32* Environment:	Any
33* Developer:    Kendall Bennett
34*
35* Description:  This file includes subroutines to implement the decoding
36*               and emulation of all the x86 processor instructions.
37*
38* There are approximately 250 subroutines in here, which correspond
39* to the 256 byte-"opcodes" found on the 8086.  The table which
40* dispatches this is found in the files optab.[ch].
41*
42* Each opcode proc has a comment preceeding it which gives it's table
43* address.  Several opcodes are missing (undefined) in the table.
44*
45* Each proc includes information for decoding (DECODE_PRINTF and
46* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47* functions (START_OF_INSTR, END_OF_INSTR).
48*
49* Many of the procedures are *VERY* similar in coding.  This has
50* allowed for a very large amount of code to be generated in a fairly
51* short amount of time (i.e. cut, paste, and modify).  The result is
52* that much of the code below could have been folded into subroutines
53* for a large reduction in size of this file.  The downside would be
54* that there would be a penalty in execution speed.  The file could
55* also have been *MUCH* larger by inlining certain functions which
56* were called.  This could have resulted even faster execution.  The
57* prime directive I used to decide whether to inline the code or to
58* modularize it, was basically: 1) no unnecessary subroutine calls,
59* 2) no routines more than about 200 lines in size, and 3) modularize
60* any code that I might not get right the first time.  The fetch_*
61* subroutines fall into the latter category.  The The decode_* fall
62* into the second category.  The coding of the "switch(mod){ .... }"
63* in many of the subroutines below falls into the first category.
64* Especially, the coding of {add,and,or,sub,...}_{byte,word}
65* subroutines are an especially glaring case of the third guideline.
66* Since so much of the code is cloned from other modules (compare
67* opcode #00 to opcode #01), making the basic operations subroutine
68* calls is especially important; otherwise mistakes in coding an
69* "add" would represent a nightmare in maintenance.
70*
71****************************************************************************/
72
73#include "x86emu/x86emui.h"
74
75/*----------------------------- Implementation ----------------------------*/
76
77/****************************************************************************
78PARAMETERS:
79op1 - Instruction op code
80
81REMARKS:
82Handles illegal opcodes.
83****************************************************************************/
84static void
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 too 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        /* dont 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        /* dont 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        /* dont 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        /* dont 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        /* dont 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        /* dont 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    M.x86.R_IP = pop_word();
8953    M.x86.R_SP += imm;
8954    DECODE_CLEAR_SEGOVR();
8955    END_OF_INSTR();
8956}
8957
8958/****************************************************************************
8959REMARKS:
8960Handles opcode 0xc3
8961****************************************************************************/
8962static void
8963x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8964{
8965    START_OF_INSTR();
8966    DECODE_PRINTF("RET\n");
8967    RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8968    TRACE_AND_STEP();
8969    M.x86.R_IP = pop_word();
8970    DECODE_CLEAR_SEGOVR();
8971    END_OF_INSTR();
8972}
8973
8974/****************************************************************************
8975REMARKS:
8976Handles opcode 0xc4
8977****************************************************************************/
8978static void
8979x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8980{
8981    int mod, rh, rl;
8982    u16 *dstreg;
8983    uint srcoffset;
8984
8985    START_OF_INSTR();
8986    DECODE_PRINTF("LES\t");
8987    FETCH_DECODE_MODRM(mod, rh, rl);
8988    switch (mod) {
8989    case 0:
8990        dstreg = DECODE_RM_WORD_REGISTER(rh);
8991        DECODE_PRINTF(",");
8992        srcoffset = decode_rm00_address(rl);
8993        DECODE_PRINTF("\n");
8994        TRACE_AND_STEP();
8995        *dstreg = fetch_data_word(srcoffset);
8996        M.x86.R_ES = fetch_data_word(srcoffset + 2);
8997        break;
8998    case 1:
8999        dstreg = DECODE_RM_WORD_REGISTER(rh);
9000        DECODE_PRINTF(",");
9001        srcoffset = decode_rm01_address(rl);
9002        DECODE_PRINTF("\n");
9003        TRACE_AND_STEP();
9004        *dstreg = fetch_data_word(srcoffset);
9005        M.x86.R_ES = fetch_data_word(srcoffset + 2);
9006        break;
9007    case 2:
9008        dstreg = DECODE_RM_WORD_REGISTER(rh);
9009        DECODE_PRINTF(",");
9010        srcoffset = decode_rm10_address(rl);
9011        DECODE_PRINTF("\n");
9012        TRACE_AND_STEP();
9013        *dstreg = fetch_data_word(srcoffset);
9014        M.x86.R_ES = fetch_data_word(srcoffset + 2);
9015        break;
9016    case 3:                    /* register to register */
9017        /* UNDEFINED! */
9018        TRACE_AND_STEP();
9019    }
9020    DECODE_CLEAR_SEGOVR();
9021    END_OF_INSTR();
9022}
9023
9024/****************************************************************************
9025REMARKS:
9026Handles opcode 0xc5
9027****************************************************************************/
9028static void
9029x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9030{
9031    int mod, rh, rl;
9032    u16 *dstreg;
9033    uint srcoffset;
9034
9035    START_OF_INSTR();
9036    DECODE_PRINTF("LDS\t");
9037    FETCH_DECODE_MODRM(mod, rh, rl);
9038    switch (mod) {
9039    case 0:
9040        dstreg = DECODE_RM_WORD_REGISTER(rh);
9041        DECODE_PRINTF(",");
9042        srcoffset = decode_rm00_address(rl);
9043        DECODE_PRINTF("\n");
9044        TRACE_AND_STEP();
9045        *dstreg = fetch_data_word(srcoffset);
9046        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9047        break;
9048    case 1:
9049        dstreg = DECODE_RM_WORD_REGISTER(rh);
9050        DECODE_PRINTF(",");
9051        srcoffset = decode_rm01_address(rl);
9052        DECODE_PRINTF("\n");
9053        TRACE_AND_STEP();
9054        *dstreg = fetch_data_word(srcoffset);
9055        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9056        break;
9057    case 2:
9058        dstreg = DECODE_RM_WORD_REGISTER(rh);
9059        DECODE_PRINTF(",");
9060        srcoffset = decode_rm10_address(rl);
9061        DECODE_PRINTF("\n");
9062        TRACE_AND_STEP();
9063        *dstreg = fetch_data_word(srcoffset);
9064        M.x86.R_DS = fetch_data_word(srcoffset + 2);
9065        break;
9066    case 3:                    /* register to register */
9067        /* UNDEFINED! */
9068        TRACE_AND_STEP();
9069    }
9070    DECODE_CLEAR_SEGOVR();
9071    END_OF_INSTR();
9072}
9073
9074/****************************************************************************
9075REMARKS:
9076Handles opcode 0xc6
9077****************************************************************************/
9078static void
9079x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9080{
9081    int mod, rl, rh;
9082    u8 *destreg;
9083    uint destoffset;
9084    u8 imm;
9085
9086    START_OF_INSTR();
9087    DECODE_PRINTF("MOV\t");
9088    FETCH_DECODE_MODRM(mod, rh, rl);
9089    if (rh != 0) {
9090        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9091        HALT_SYS();
9092    }
9093    switch (mod) {
9094    case 0:
9095        DECODE_PRINTF("BYTE PTR ");
9096        destoffset = decode_rm00_address(rl);
9097        imm = fetch_byte_imm();
9098        DECODE_PRINTF2(",%2x\n", imm);
9099        TRACE_AND_STEP();
9100        store_data_byte(destoffset, imm);
9101        break;
9102    case 1:
9103        DECODE_PRINTF("BYTE PTR ");
9104        destoffset = decode_rm01_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 2:
9111        DECODE_PRINTF("BYTE PTR ");
9112        destoffset = decode_rm10_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 3:                    /* register to register */
9119        destreg = DECODE_RM_BYTE_REGISTER(rl);
9120        imm = fetch_byte_imm();
9121        DECODE_PRINTF2(",%2x\n", imm);
9122        TRACE_AND_STEP();
9123        *destreg = imm;
9124        break;
9125    }
9126    DECODE_CLEAR_SEGOVR();
9127    END_OF_INSTR();
9128}
9129
9130/****************************************************************************
9131REMARKS:
9132Handles opcode 0xc7
9133****************************************************************************/
9134static void
9135x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9136{
9137    int mod, rl, rh;
9138    uint destoffset;
9139
9140    START_OF_INSTR();
9141    DECODE_PRINTF("MOV\t");
9142    FETCH_DECODE_MODRM(mod, rh, rl);
9143    if (rh != 0) {
9144        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9145        HALT_SYS();
9146    }
9147    switch (mod) {
9148    case 0:
9149        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9150            u32 imm;
9151
9152            DECODE_PRINTF("DWORD PTR ");
9153            destoffset = decode_rm00_address(rl);
9154            imm = fetch_long_imm();
9155            DECODE_PRINTF2(",%x\n", imm);
9156            TRACE_AND_STEP();
9157            store_data_long(destoffset, imm);
9158        }
9159        else {
9160            u16 imm;
9161
9162            DECODE_PRINTF("WORD PTR ");
9163            destoffset = decode_rm00_address(rl);
9164            imm = fetch_word_imm();
9165            DECODE_PRINTF2(",%x\n", imm);
9166            TRACE_AND_STEP();
9167            store_data_word(destoffset, imm);
9168        }
9169        break;
9170    case 1:
9171        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9172            u32 imm;
9173
9174            DECODE_PRINTF("DWORD PTR ");
9175            destoffset = decode_rm01_address(rl);
9176            imm = fetch_long_imm();
9177            DECODE_PRINTF2(",%x\n", imm);
9178            TRACE_AND_STEP();
9179            store_data_long(destoffset, imm);
9180        }
9181        else {
9182            u16 imm;
9183
9184            DECODE_PRINTF("WORD PTR ");
9185            destoffset = decode_rm01_address(rl);
9186            imm = fetch_word_imm();
9187            DECODE_PRINTF2(",%x\n", imm);
9188            TRACE_AND_STEP();
9189            store_data_word(destoffset, imm);
9190        }
9191        break;
9192    case 2:
9193        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9194            u32 imm;
9195
9196            DECODE_PRINTF("DWORD PTR ");
9197            destoffset = decode_rm10_address(rl);
9198            imm = fetch_long_imm();
9199            DECODE_PRINTF2(",%x\n", imm);
9200            TRACE_AND_STEP();
9201            store_data_long(destoffset, imm);
9202        }
9203        else {
9204            u16 imm;
9205
9206            DECODE_PRINTF("WORD PTR ");
9207            destoffset = decode_rm10_address(rl);
9208            imm = fetch_word_imm();
9209            DECODE_PRINTF2(",%x\n", imm);
9210            TRACE_AND_STEP();
9211            store_data_word(destoffset, imm);
9212        }
9213        break;
9214    case 3:                    /* register to register */
9215        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9216            u32 *destreg;
9217            u32 imm;
9218
9219            destreg = DECODE_RM_LONG_REGISTER(rl);
9220            imm = fetch_long_imm();
9221            DECODE_PRINTF2(",%x\n", imm);
9222            TRACE_AND_STEP();
9223            *destreg = imm;
9224        }
9225        else {
9226            u16 *destreg;
9227            u16 imm;
9228
9229            destreg = DECODE_RM_WORD_REGISTER(rl);
9230            imm = fetch_word_imm();
9231            DECODE_PRINTF2(",%x\n", imm);
9232            TRACE_AND_STEP();
9233            *destreg = imm;
9234        }
9235        break;
9236    }
9237    DECODE_CLEAR_SEGOVR();
9238    END_OF_INSTR();
9239}
9240
9241/****************************************************************************
9242REMARKS:
9243Handles opcode 0xc8
9244****************************************************************************/
9245static void
9246x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9247{
9248    u16 local, frame_pointer;
9249    u8 nesting;
9250    int i;
9251
9252    START_OF_INSTR();
9253    local = fetch_word_imm();
9254    nesting = fetch_byte_imm();
9255    DECODE_PRINTF2("ENTER %x\n", local);
9256    DECODE_PRINTF2(",%x\n", nesting);
9257    TRACE_AND_STEP();
9258    push_word(M.x86.R_BP);
9259    frame_pointer = M.x86.R_SP;
9260    if (nesting > 0) {
9261        for (i = 1; i < nesting; i++) {
9262            M.x86.R_BP -= 2;
9263            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9264        }
9265        push_word(frame_pointer);
9266    }
9267    M.x86.R_BP = frame_pointer;
9268    M.x86.R_SP = (u16) (M.x86.R_SP - local);
9269    DECODE_CLEAR_SEGOVR();
9270    END_OF_INSTR();
9271}
9272
9273/****************************************************************************
9274REMARKS:
9275Handles opcode 0xc9
9276****************************************************************************/
9277static void
9278x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9279{
9280    START_OF_INSTR();
9281    DECODE_PRINTF("LEAVE\n");
9282    TRACE_AND_STEP();
9283    M.x86.R_SP = M.x86.R_BP;
9284    M.x86.R_BP = pop_word();
9285    DECODE_CLEAR_SEGOVR();
9286    END_OF_INSTR();
9287}
9288
9289/****************************************************************************
9290REMARKS:
9291Handles opcode 0xca
9292****************************************************************************/
9293static void
9294x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9295{
9296    u16 imm;
9297
9298    START_OF_INSTR();
9299    DECODE_PRINTF("RETF\t");
9300    imm = fetch_word_imm();
9301    DECODE_PRINTF2("%x\n", imm);
9302    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9303    TRACE_AND_STEP();
9304    M.x86.R_IP = pop_word();
9305    M.x86.R_CS = pop_word();
9306    M.x86.R_SP += imm;
9307    DECODE_CLEAR_SEGOVR();
9308    END_OF_INSTR();
9309}
9310
9311/****************************************************************************
9312REMARKS:
9313Handles opcode 0xcb
9314****************************************************************************/
9315static void
9316x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9317{
9318    START_OF_INSTR();
9319    DECODE_PRINTF("RETF\n");
9320    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9321    TRACE_AND_STEP();
9322    M.x86.R_IP = pop_word();
9323    M.x86.R_CS = pop_word();
9324    DECODE_CLEAR_SEGOVR();
9325    END_OF_INSTR();
9326}
9327
9328/****************************************************************************
9329REMARKS:
9330Handles opcode 0xcc
9331****************************************************************************/
9332static void
9333x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9334{
9335    START_OF_INSTR();
9336    DECODE_PRINTF("INT 3\n");
9337    TRACE_AND_STEP();
9338    if (_X86EMU_intrTab[3]) {
9339        (*_X86EMU_intrTab[3]) (3);
9340    }
9341    else {
9342        push_word((u16) M.x86.R_FLG);
9343        CLEAR_FLAG(F_IF);
9344        CLEAR_FLAG(F_TF);
9345        push_word(M.x86.R_CS);
9346        M.x86.R_CS = mem_access_word(3 * 4 + 2);
9347        push_word(M.x86.R_IP);
9348        M.x86.R_IP = mem_access_word(3 * 4);
9349    }
9350    DECODE_CLEAR_SEGOVR();
9351    END_OF_INSTR();
9352}
9353
9354/****************************************************************************
9355REMARKS:
9356Handles opcode 0xcd
9357****************************************************************************/
9358static void
9359x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9360{
9361    u8 intnum;
9362
9363    START_OF_INSTR();
9364    DECODE_PRINTF("INT\t");
9365    intnum = fetch_byte_imm();
9366    DECODE_PRINTF2("%x\n", intnum);
9367    TRACE_AND_STEP();
9368    if (_X86EMU_intrTab[intnum]) {
9369        (*_X86EMU_intrTab[intnum]) (intnum);
9370    }
9371    else {
9372        push_word((u16) M.x86.R_FLG);
9373        CLEAR_FLAG(F_IF);
9374        CLEAR_FLAG(F_TF);
9375        push_word(M.x86.R_CS);
9376        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9377        push_word(M.x86.R_IP);
9378        M.x86.R_IP = mem_access_word(intnum * 4);
9379    }
9380    DECODE_CLEAR_SEGOVR();
9381    END_OF_INSTR();
9382}
9383
9384/****************************************************************************
9385REMARKS:
9386Handles opcode 0xce
9387****************************************************************************/
9388static void
9389x86emuOp_into(u8 X86EMU_UNUSED(op1))
9390{
9391    START_OF_INSTR();
9392    DECODE_PRINTF("INTO\n");
9393    TRACE_AND_STEP();
9394    if (ACCESS_FLAG(F_OF)) {
9395        if (_X86EMU_intrTab[4]) {
9396            (*_X86EMU_intrTab[4]) (4);
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(4 * 4 + 2);
9404            push_word(M.x86.R_IP);
9405            M.x86.R_IP = mem_access_word(4 * 4);
9406        }
9407    }
9408    DECODE_CLEAR_SEGOVR();
9409    END_OF_INSTR();
9410}
9411
9412/****************************************************************************
9413REMARKS:
9414Handles opcode 0xcf
9415****************************************************************************/
9416static void
9417x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9418{
9419    START_OF_INSTR();
9420    DECODE_PRINTF("IRET\n");
9421
9422    TRACE_AND_STEP();
9423
9424    M.x86.R_IP = pop_word();
9425    M.x86.R_CS = pop_word();
9426    M.x86.R_FLG = pop_word();
9427    DECODE_CLEAR_SEGOVR();
9428    END_OF_INSTR();
9429}
9430
9431/****************************************************************************
9432REMARKS:
9433Handles opcode 0xd0
9434****************************************************************************/
9435static void
9436x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9437{
9438    int mod, rl, rh;
9439    u8 *destreg;
9440    uint destoffset;
9441    u8 destval;
9442
9443    /*
9444     * Yet another weirdo special case instruction format.  Part of
9445     * the opcode held below in "RH".  Doubly nested case would
9446     * result, except that the decoded instruction
9447     */
9448    START_OF_INSTR();
9449    FETCH_DECODE_MODRM(mod, rh, rl);
9450#ifdef DEBUG
9451    if (DEBUG_DECODE()) {
9452        /* XXX DECODE_PRINTF may be changed to something more
9453           general, so that it is important to leave the strings
9454           in the same format, even though the result is that the
9455           above test is done twice. */
9456        switch (rh) {
9457        case 0:
9458            DECODE_PRINTF("ROL\t");
9459            break;
9460        case 1:
9461            DECODE_PRINTF("ROR\t");
9462            break;
9463        case 2:
9464            DECODE_PRINTF("RCL\t");
9465            break;
9466        case 3:
9467            DECODE_PRINTF("RCR\t");
9468            break;
9469        case 4:
9470            DECODE_PRINTF("SHL\t");
9471            break;
9472        case 5:
9473            DECODE_PRINTF("SHR\t");
9474            break;
9475        case 6:
9476            DECODE_PRINTF("SAL\t");
9477            break;
9478        case 7:
9479            DECODE_PRINTF("SAR\t");
9480            break;
9481        }
9482    }
9483#endif
9484    /* know operation, decode the mod byte to find the addressing
9485       mode. */
9486    switch (mod) {
9487    case 0:
9488        DECODE_PRINTF("BYTE PTR ");
9489        destoffset = decode_rm00_address(rl);
9490        DECODE_PRINTF(",1\n");
9491        destval = fetch_data_byte(destoffset);
9492        TRACE_AND_STEP();
9493        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9494        store_data_byte(destoffset, destval);
9495        break;
9496    case 1:
9497        DECODE_PRINTF("BYTE PTR ");
9498        destoffset = decode_rm01_address(rl);
9499        DECODE_PRINTF(",1\n");
9500        destval = fetch_data_byte(destoffset);
9501        TRACE_AND_STEP();
9502        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9503        store_data_byte(destoffset, destval);
9504        break;
9505    case 2:
9506        DECODE_PRINTF("BYTE PTR ");
9507        destoffset = decode_rm10_address(rl);
9508        DECODE_PRINTF(",1\n");
9509        destval = fetch_data_byte(destoffset);
9510        TRACE_AND_STEP();
9511        destval = (*opcD0_byte_operation[rh]) (destval, 1);
9512        store_data_byte(destoffset, destval);
9513        break;
9514    case 3:                    /* register to register */
9515        destreg = DECODE_RM_BYTE_REGISTER(rl);
9516        DECODE_PRINTF(",1\n");
9517        TRACE_AND_STEP();
9518        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9519        *destreg = destval;
9520        break;
9521    }
9522    DECODE_CLEAR_SEGOVR();
9523    END_OF_INSTR();
9524}
9525
9526/****************************************************************************
9527REMARKS:
9528Handles opcode 0xd1
9529****************************************************************************/
9530static void
9531x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9532{
9533    int mod, rl, rh;
9534    uint destoffset;
9535
9536    /*
9537     * Yet another weirdo special case instruction format.  Part of
9538     * the opcode held below in "RH".  Doubly nested case would
9539     * result, except that the decoded instruction
9540     */
9541    START_OF_INSTR();
9542    FETCH_DECODE_MODRM(mod, rh, rl);
9543#ifdef DEBUG
9544    if (DEBUG_DECODE()) {
9545        /* XXX DECODE_PRINTF may be changed to something more
9546           general, so that it is important to leave the strings
9547           in the same format, even though the result is that the
9548           above test is done twice. */
9549        switch (rh) {
9550        case 0:
9551            DECODE_PRINTF("ROL\t");
9552            break;
9553        case 1:
9554            DECODE_PRINTF("ROR\t");
9555            break;
9556        case 2:
9557            DECODE_PRINTF("RCL\t");
9558            break;
9559        case 3:
9560            DECODE_PRINTF("RCR\t");
9561            break;
9562        case 4:
9563            DECODE_PRINTF("SHL\t");
9564            break;
9565        case 5:
9566            DECODE_PRINTF("SHR\t");
9567            break;
9568        case 6:
9569            DECODE_PRINTF("SAL\t");
9570            break;
9571        case 7:
9572            DECODE_PRINTF("SAR\t");
9573            break;
9574        }
9575    }
9576#endif
9577    /* know operation, decode the mod byte to find the addressing
9578       mode. */
9579    switch (mod) {
9580    case 0:
9581        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9582            u32 destval;
9583
9584            DECODE_PRINTF("DWORD PTR ");
9585            destoffset = decode_rm00_address(rl);
9586            DECODE_PRINTF(",1\n");
9587            destval = fetch_data_long(destoffset);
9588            TRACE_AND_STEP();
9589            destval = (*opcD1_long_operation[rh]) (destval, 1);
9590            store_data_long(destoffset, destval);
9591        }
9592        else {
9593            u16 destval;
9594
9595            DECODE_PRINTF("WORD PTR ");
9596            destoffset = decode_rm00_address(rl);
9597            DECODE_PRINTF(",1\n");
9598            destval = fetch_data_word(destoffset);
9599            TRACE_AND_STEP();
9600            destval = (*opcD1_word_operation[rh]) (destval, 1);
9601            store_data_word(destoffset, destval);
9602        }
9603        break;
9604    case 1:
9605        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9606            u32 destval;
9607
9608            DECODE_PRINTF("DWORD PTR ");
9609            destoffset = decode_rm01_address(rl);
9610            DECODE_PRINTF(",1\n");
9611            destval = fetch_data_long(destoffset);
9612            TRACE_AND_STEP();
9613            destval = (*opcD1_long_operation[rh]) (destval, 1);
9614            store_data_long(destoffset, destval);
9615        }
9616        else {
9617            u16 destval;
9618
9619            DECODE_PRINTF("WORD PTR ");
9620            destoffset = decode_rm01_address(rl);
9621            DECODE_PRINTF(",1\n");
9622            destval = fetch_data_word(destoffset);
9623            TRACE_AND_STEP();
9624            destval = (*opcD1_word_operation[rh]) (destval, 1);
9625            store_data_word(destoffset, destval);
9626        }
9627        break;
9628    case 2:
9629        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9630            u32 destval;
9631
9632            DECODE_PRINTF("DWORD PTR ");
9633            destoffset = decode_rm10_address(rl);
9634            DECODE_PRINTF(",1\n");
9635            destval = fetch_data_long(destoffset);
9636            TRACE_AND_STEP();
9637            destval = (*opcD1_long_operation[rh]) (destval, 1);
9638            store_data_long(destoffset, destval);
9639        }
9640        else {
9641            u16 destval;
9642
9643            DECODE_PRINTF("BYTE PTR ");
9644            destoffset = decode_rm10_address(rl);
9645            DECODE_PRINTF(",1\n");
9646            destval = fetch_data_word(destoffset);
9647            TRACE_AND_STEP();
9648            destval = (*opcD1_word_operation[rh]) (destval, 1);
9649            store_data_word(destoffset, destval);
9650        }
9651        break;
9652    case 3:                    /* register to register */
9653        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9654            u32 destval;
9655            u32 *destreg;
9656
9657            destreg = DECODE_RM_LONG_REGISTER(rl);
9658            DECODE_PRINTF(",1\n");
9659            TRACE_AND_STEP();
9660            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9661            *destreg = destval;
9662        }
9663        else {
9664            u16 destval;
9665            u16 *destreg;
9666
9667            destreg = DECODE_RM_WORD_REGISTER(rl);
9668            DECODE_PRINTF(",1\n");
9669            TRACE_AND_STEP();
9670            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9671            *destreg = destval;
9672        }
9673        break;
9674    }
9675    DECODE_CLEAR_SEGOVR();
9676    END_OF_INSTR();
9677}
9678
9679/****************************************************************************
9680REMARKS:
9681Handles opcode 0xd2
9682****************************************************************************/
9683static void
9684x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9685{
9686    int mod, rl, rh;
9687    u8 *destreg;
9688    uint destoffset;
9689    u8 destval;
9690    u8 amt;
9691
9692    /*
9693     * Yet another weirdo special case instruction format.  Part of
9694     * the opcode held below in "RH".  Doubly nested case would
9695     * result, except that the decoded instruction
9696     */
9697    START_OF_INSTR();
9698    FETCH_DECODE_MODRM(mod, rh, rl);
9699#ifdef DEBUG
9700    if (DEBUG_DECODE()) {
9701        /* XXX DECODE_PRINTF may be changed to something more
9702           general, so that it is important to leave the strings
9703           in the same format, even though the result is that the
9704           above test is done twice. */
9705        switch (rh) {
9706        case 0:
9707            DECODE_PRINTF("ROL\t");
9708            break;
9709        case 1:
9710            DECODE_PRINTF("ROR\t");
9711            break;
9712        case 2:
9713            DECODE_PRINTF("RCL\t");
9714            break;
9715        case 3:
9716            DECODE_PRINTF("RCR\t");
9717            break;
9718        case 4:
9719            DECODE_PRINTF("SHL\t");
9720            break;
9721        case 5:
9722            DECODE_PRINTF("SHR\t");
9723            break;
9724        case 6:
9725            DECODE_PRINTF("SAL\t");
9726            break;
9727        case 7:
9728            DECODE_PRINTF("SAR\t");
9729            break;
9730        }
9731    }
9732#endif
9733    /* know operation, decode the mod byte to find the addressing
9734       mode. */
9735    amt = M.x86.R_CL;
9736    switch (mod) {
9737    case 0:
9738        DECODE_PRINTF("BYTE PTR ");
9739        destoffset = decode_rm00_address(rl);
9740        DECODE_PRINTF(",CL\n");
9741        destval = fetch_data_byte(destoffset);
9742        TRACE_AND_STEP();
9743        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9744        store_data_byte(destoffset, destval);
9745        break;
9746    case 1:
9747        DECODE_PRINTF("BYTE PTR ");
9748        destoffset = decode_rm01_address(rl);
9749        DECODE_PRINTF(",CL\n");
9750        destval = fetch_data_byte(destoffset);
9751        TRACE_AND_STEP();
9752        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9753        store_data_byte(destoffset, destval);
9754        break;
9755    case 2:
9756        DECODE_PRINTF("BYTE PTR ");
9757        destoffset = decode_rm10_address(rl);
9758        DECODE_PRINTF(",CL\n");
9759        destval = fetch_data_byte(destoffset);
9760        TRACE_AND_STEP();
9761        destval = (*opcD0_byte_operation[rh]) (destval, amt);
9762        store_data_byte(destoffset, destval);
9763        break;
9764    case 3:                    /* register to register */
9765        destreg = DECODE_RM_BYTE_REGISTER(rl);
9766        DECODE_PRINTF(",CL\n");
9767        TRACE_AND_STEP();
9768        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9769        *destreg = destval;
9770        break;
9771    }
9772    DECODE_CLEAR_SEGOVR();
9773    END_OF_INSTR();
9774}
9775
9776/****************************************************************************
9777REMARKS:
9778Handles opcode 0xd3
9779****************************************************************************/
9780static void
9781x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9782{
9783    int mod, rl, rh;
9784    uint destoffset;
9785    u8 amt;
9786
9787    /*
9788     * Yet another weirdo special case instruction format.  Part of
9789     * the opcode held below in "RH".  Doubly nested case would
9790     * result, except that the decoded instruction
9791     */
9792    START_OF_INSTR();
9793    FETCH_DECODE_MODRM(mod, rh, rl);
9794#ifdef DEBUG
9795    if (DEBUG_DECODE()) {
9796        /* XXX DECODE_PRINTF may be changed to something more
9797           general, so that it is important to leave the strings
9798           in the same format, even though the result is that the
9799           above test is done twice. */
9800        switch (rh) {
9801        case 0:
9802            DECODE_PRINTF("ROL\t");
9803            break;
9804        case 1:
9805            DECODE_PRINTF("ROR\t");
9806            break;
9807        case 2:
9808            DECODE_PRINTF("RCL\t");
9809            break;
9810        case 3:
9811            DECODE_PRINTF("RCR\t");
9812            break;
9813        case 4:
9814            DECODE_PRINTF("SHL\t");
9815            break;
9816        case 5:
9817            DECODE_PRINTF("SHR\t");
9818            break;
9819        case 6:
9820            DECODE_PRINTF("SAL\t");
9821            break;
9822        case 7:
9823            DECODE_PRINTF("SAR\t");
9824            break;
9825        }
9826    }
9827#endif
9828    /* know operation, decode the mod byte to find the addressing
9829       mode. */
9830    amt = M.x86.R_CL;
9831    switch (mod) {
9832    case 0:
9833        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9834            u32 destval;
9835
9836            DECODE_PRINTF("DWORD PTR ");
9837            destoffset = decode_rm00_address(rl);
9838            DECODE_PRINTF(",CL\n");
9839            destval = fetch_data_long(destoffset);
9840            TRACE_AND_STEP();
9841            destval = (*opcD1_long_operation[rh]) (destval, amt);
9842            store_data_long(destoffset, destval);
9843        }
9844        else {
9845            u16 destval;
9846
9847            DECODE_PRINTF("WORD PTR ");
9848            destoffset = decode_rm00_address(rl);
9849            DECODE_PRINTF(",CL\n");
9850            destval = fetch_data_word(destoffset);
9851            TRACE_AND_STEP();
9852            destval = (*opcD1_word_operation[rh]) (destval, amt);
9853            store_data_word(destoffset, destval);
9854        }
9855        break;
9856    case 1:
9857        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9858            u32 destval;
9859
9860            DECODE_PRINTF("DWORD PTR ");
9861            destoffset = decode_rm01_address(rl);
9862            DECODE_PRINTF(",CL\n");
9863            destval = fetch_data_long(destoffset);
9864            TRACE_AND_STEP();
9865            destval = (*opcD1_long_operation[rh]) (destval, amt);
9866            store_data_long(destoffset, destval);
9867        }
9868        else {
9869            u16 destval;
9870
9871            DECODE_PRINTF("WORD PTR ");
9872            destoffset = decode_rm01_address(rl);
9873            DECODE_PRINTF(",CL\n");
9874            destval = fetch_data_word(destoffset);
9875            TRACE_AND_STEP();
9876            destval = (*opcD1_word_operation[rh]) (destval, amt);
9877            store_data_word(destoffset, destval);
9878        }
9879        break;
9880    case 2:
9881        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9882            u32 destval;
9883
9884            DECODE_PRINTF("DWORD PTR ");
9885            destoffset = decode_rm10_address(rl);
9886            DECODE_PRINTF(",CL\n");
9887            destval = fetch_data_long(destoffset);
9888            TRACE_AND_STEP();
9889            destval = (*opcD1_long_operation[rh]) (destval, amt);
9890            store_data_long(destoffset, destval);
9891        }
9892        else {
9893            u16 destval;
9894
9895            DECODE_PRINTF("WORD PTR ");
9896            destoffset = decode_rm10_address(rl);
9897            DECODE_PRINTF(",CL\n");
9898            destval = fetch_data_word(destoffset);
9899            TRACE_AND_STEP();
9900            destval = (*opcD1_word_operation[rh]) (destval, amt);
9901            store_data_word(destoffset, destval);
9902        }
9903        break;
9904    case 3:                    /* register to register */
9905        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9906            u32 *destreg;
9907
9908            destreg = DECODE_RM_LONG_REGISTER(rl);
9909            DECODE_PRINTF(",CL\n");
9910            TRACE_AND_STEP();
9911            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9912        }
9913        else {
9914            u16 *destreg;
9915
9916            destreg = DECODE_RM_WORD_REGISTER(rl);
9917            DECODE_PRINTF(",CL\n");
9918            TRACE_AND_STEP();
9919            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9920        }
9921        break;
9922    }
9923    DECODE_CLEAR_SEGOVR();
9924    END_OF_INSTR();
9925}
9926
9927/****************************************************************************
9928REMARKS:
9929Handles opcode 0xd4
9930****************************************************************************/
9931static void
9932x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9933{
9934    u8 a;
9935
9936    START_OF_INSTR();
9937    DECODE_PRINTF("AAM\n");
9938    a = fetch_byte_imm();       /* this is a stupid encoding. */
9939    if (a != 10) {
9940        /* fix: add base decoding
9941           aam_word(u8 val, int base a) */
9942        DECODE_PRINTF("ERROR DECODING AAM\n");
9943        TRACE_REGS();
9944        HALT_SYS();
9945    }
9946    TRACE_AND_STEP();
9947    /* note the type change here --- returning AL and AH in AX. */
9948    M.x86.R_AX = aam_word(M.x86.R_AL);
9949    DECODE_CLEAR_SEGOVR();
9950    END_OF_INSTR();
9951}
9952
9953/****************************************************************************
9954REMARKS:
9955Handles opcode 0xd5
9956****************************************************************************/
9957static void
9958x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9959{
9960    u8 a;
9961
9962    START_OF_INSTR();
9963    DECODE_PRINTF("AAD\n");
9964    a = fetch_byte_imm();
9965    if (a != 10) {
9966        /* fix: add base decoding
9967           aad_word(u16 val, int base a) */
9968        DECODE_PRINTF("ERROR DECODING AAM\n");
9969        TRACE_REGS();
9970        HALT_SYS();
9971    }
9972    TRACE_AND_STEP();
9973    M.x86.R_AX = aad_word(M.x86.R_AX);
9974    DECODE_CLEAR_SEGOVR();
9975    END_OF_INSTR();
9976}
9977
9978/* opcode 0xd6 ILLEGAL OPCODE */
9979
9980/****************************************************************************
9981REMARKS:
9982Handles opcode 0xd7
9983****************************************************************************/
9984static void
9985x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9986{
9987    u16 addr;
9988
9989    START_OF_INSTR();
9990    DECODE_PRINTF("XLAT\n");
9991    TRACE_AND_STEP();
9992    addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
9993    M.x86.R_AL = fetch_data_byte(addr);
9994    DECODE_CLEAR_SEGOVR();
9995    END_OF_INSTR();
9996}
9997
9998/* instuctions  D8 .. DF are in i87_ops.c */
9999
10000/****************************************************************************
10001REMARKS:
10002Handles opcode 0xe0
10003****************************************************************************/
10004static void
10005x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10006{
10007    s16 ip;
10008
10009    START_OF_INSTR();
10010    DECODE_PRINTF("LOOPNE\t");
10011    ip = (s8) fetch_byte_imm();
10012    ip += (s16) M.x86.R_IP;
10013    DECODE_PRINTF2("%04x\n", ip);
10014    TRACE_AND_STEP();
10015    M.x86.R_CX -= 1;
10016    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
10017        M.x86.R_IP = ip;
10018    DECODE_CLEAR_SEGOVR();
10019    END_OF_INSTR();
10020}
10021
10022/****************************************************************************
10023REMARKS:
10024Handles opcode 0xe1
10025****************************************************************************/
10026static void
10027x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10028{
10029    s16 ip;
10030
10031    START_OF_INSTR();
10032    DECODE_PRINTF("LOOPE\t");
10033    ip = (s8) fetch_byte_imm();
10034    ip += (s16) M.x86.R_IP;
10035    DECODE_PRINTF2("%04x\n", ip);
10036    TRACE_AND_STEP();
10037    M.x86.R_CX -= 1;
10038    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
10039        M.x86.R_IP = ip;
10040    DECODE_CLEAR_SEGOVR();
10041    END_OF_INSTR();
10042}
10043
10044/****************************************************************************
10045REMARKS:
10046Handles opcode 0xe2
10047****************************************************************************/
10048static void
10049x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10050{
10051    s16 ip;
10052
10053    START_OF_INSTR();
10054    DECODE_PRINTF("LOOP\t");
10055    ip = (s8) fetch_byte_imm();
10056    ip += (s16) M.x86.R_IP;
10057    DECODE_PRINTF2("%04x\n", ip);
10058    TRACE_AND_STEP();
10059    M.x86.R_CX -= 1;
10060    if (M.x86.R_CX != 0)
10061        M.x86.R_IP = ip;
10062    DECODE_CLEAR_SEGOVR();
10063    END_OF_INSTR();
10064}
10065
10066/****************************************************************************
10067REMARKS:
10068Handles opcode 0xe3
10069****************************************************************************/
10070static void
10071x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10072{
10073    u16 target;
10074    s8 offset;
10075
10076    /* jump to byte offset if overflow flag is set */
10077    START_OF_INSTR();
10078    DECODE_PRINTF("JCXZ\t");
10079    offset = (s8) fetch_byte_imm();
10080    target = (u16) (M.x86.R_IP + offset);
10081    DECODE_PRINTF2("%x\n", target);
10082    TRACE_AND_STEP();
10083    if (M.x86.R_CX == 0)
10084        M.x86.R_IP = target;
10085    DECODE_CLEAR_SEGOVR();
10086    END_OF_INSTR();
10087}
10088
10089/****************************************************************************
10090REMARKS:
10091Handles opcode 0xe4
10092****************************************************************************/
10093static void
10094x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10095{
10096    u8 port;
10097
10098    START_OF_INSTR();
10099    DECODE_PRINTF("IN\t");
10100    port = (u8) fetch_byte_imm();
10101    DECODE_PRINTF2("%x,AL\n", port);
10102    TRACE_AND_STEP();
10103    M.x86.R_AL = (*sys_inb) (port);
10104    DECODE_CLEAR_SEGOVR();
10105    END_OF_INSTR();
10106}
10107
10108/****************************************************************************
10109REMARKS:
10110Handles opcode 0xe5
10111****************************************************************************/
10112static void
10113x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10114{
10115    u8 port;
10116
10117    START_OF_INSTR();
10118    DECODE_PRINTF("IN\t");
10119    port = (u8) fetch_byte_imm();
10120    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10121        DECODE_PRINTF2("EAX,%x\n", port);
10122    }
10123    else {
10124        DECODE_PRINTF2("AX,%x\n", port);
10125    }
10126    TRACE_AND_STEP();
10127    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10128        M.x86.R_EAX = (*sys_inl) (port);
10129    }
10130    else {
10131        M.x86.R_AX = (*sys_inw) (port);
10132    }
10133    DECODE_CLEAR_SEGOVR();
10134    END_OF_INSTR();
10135}
10136
10137/****************************************************************************
10138REMARKS:
10139Handles opcode 0xe6
10140****************************************************************************/
10141static void
10142x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10143{
10144    u8 port;
10145
10146    START_OF_INSTR();
10147    DECODE_PRINTF("OUT\t");
10148    port = (u8) fetch_byte_imm();
10149    DECODE_PRINTF2("%x,AL\n", port);
10150    TRACE_AND_STEP();
10151    (*sys_outb) (port, M.x86.R_AL);
10152    DECODE_CLEAR_SEGOVR();
10153    END_OF_INSTR();
10154}
10155
10156/****************************************************************************
10157REMARKS:
10158Handles opcode 0xe7
10159****************************************************************************/
10160static void
10161x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10162{
10163    u8 port;
10164
10165    START_OF_INSTR();
10166    DECODE_PRINTF("OUT\t");
10167    port = (u8) fetch_byte_imm();
10168    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10169        DECODE_PRINTF2("%x,EAX\n", port);
10170    }
10171    else {
10172        DECODE_PRINTF2("%x,AX\n", port);
10173    }
10174    TRACE_AND_STEP();
10175    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10176        (*sys_outl) (port, M.x86.R_EAX);
10177    }
10178    else {
10179        (*sys_outw) (port, M.x86.R_AX);
10180    }
10181    DECODE_CLEAR_SEGOVR();
10182    END_OF_INSTR();
10183}
10184
10185/****************************************************************************
10186REMARKS:
10187Handles opcode 0xe8
10188****************************************************************************/
10189static void
10190x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10191{
10192    s16 ip16 = 0;
10193    s32 ip32 = 0;
10194
10195    START_OF_INSTR();
10196    DECODE_PRINTF("CALL\t");
10197    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10198        ip32 = (s32) fetch_long_imm();
10199        ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10200        DECODE_PRINTF2("%04x\n", (u16) ip32);
10201        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10202    }
10203    else {
10204        ip16 = (s16) fetch_word_imm();
10205        ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10206        DECODE_PRINTF2("%04x\n", (u16) ip16);
10207        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10208    }
10209    TRACE_AND_STEP();
10210    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10211        push_long(M.x86.R_EIP);
10212        M.x86.R_EIP = ip32 & 0xffff;
10213    }
10214    else {
10215        push_word(M.x86.R_IP);
10216        M.x86.R_EIP = ip16;
10217    }
10218    DECODE_CLEAR_SEGOVR();
10219    END_OF_INSTR();
10220}
10221
10222/****************************************************************************
10223REMARKS:
10224Handles opcode 0xe9
10225****************************************************************************/
10226static void
10227x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10228{
10229    u32 ip;
10230
10231    START_OF_INSTR();
10232    DECODE_PRINTF("JMP\t");
10233    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234        ip = (u32) fetch_long_imm();
10235        ip += (u32) M.x86.R_EIP;
10236        DECODE_PRINTF2("%08x\n", (u32) ip);
10237        TRACE_AND_STEP();
10238        M.x86.R_EIP = (u32) ip;
10239    }
10240    else {
10241        ip = (s16) fetch_word_imm();
10242        ip += (s16) M.x86.R_IP;
10243        DECODE_PRINTF2("%04x\n", (u16) ip);
10244        TRACE_AND_STEP();
10245        M.x86.R_IP = (u16) ip;
10246    }
10247    DECODE_CLEAR_SEGOVR();
10248    END_OF_INSTR();
10249}
10250
10251/****************************************************************************
10252REMARKS:
10253Handles opcode 0xea
10254****************************************************************************/
10255static void
10256x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10257{
10258    u16 cs;
10259    u32 ip;
10260
10261    START_OF_INSTR();
10262    DECODE_PRINTF("JMP\tFAR ");
10263    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10264        ip = fetch_long_imm();
10265    }
10266    else {
10267        ip = fetch_word_imm();
10268    }
10269    cs = fetch_word_imm();
10270    DECODE_PRINTF2("%04x:", cs);
10271    DECODE_PRINTF2("%04x\n", ip);
10272    TRACE_AND_STEP();
10273    M.x86.R_EIP = ip & 0xffff;
10274    M.x86.R_CS = cs;
10275    DECODE_CLEAR_SEGOVR();
10276    END_OF_INSTR();
10277}
10278
10279/****************************************************************************
10280REMARKS:
10281Handles opcode 0xeb
10282****************************************************************************/
10283static void
10284x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10285{
10286    u16 target;
10287    s8 offset;
10288
10289    START_OF_INSTR();
10290    DECODE_PRINTF("JMP\t");
10291    offset = (s8) fetch_byte_imm();
10292    target = (u16) (M.x86.R_IP + offset);
10293    DECODE_PRINTF2("%x\n", target);
10294    TRACE_AND_STEP();
10295    M.x86.R_IP = target;
10296    DECODE_CLEAR_SEGOVR();
10297    END_OF_INSTR();
10298}
10299
10300/****************************************************************************
10301REMARKS:
10302Handles opcode 0xec
10303****************************************************************************/
10304static void
10305x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10306{
10307    START_OF_INSTR();
10308    DECODE_PRINTF("IN\tAL,DX\n");
10309    TRACE_AND_STEP();
10310    M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10311    DECODE_CLEAR_SEGOVR();
10312    END_OF_INSTR();
10313}
10314
10315/****************************************************************************
10316REMARKS:
10317Handles opcode 0xed
10318****************************************************************************/
10319static void
10320x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10321{
10322    START_OF_INSTR();
10323    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10324        DECODE_PRINTF("IN\tEAX,DX\n");
10325    }
10326    else {
10327        DECODE_PRINTF("IN\tAX,DX\n");
10328    }
10329    TRACE_AND_STEP();
10330    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10331        M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10332    }
10333    else {
10334        M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10335    }
10336    DECODE_CLEAR_SEGOVR();
10337    END_OF_INSTR();
10338}
10339
10340/****************************************************************************
10341REMARKS:
10342Handles opcode 0xee
10343****************************************************************************/
10344static void
10345x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10346{
10347    START_OF_INSTR();
10348    DECODE_PRINTF("OUT\tDX,AL\n");
10349    TRACE_AND_STEP();
10350    (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10351    DECODE_CLEAR_SEGOVR();
10352    END_OF_INSTR();
10353}
10354
10355/****************************************************************************
10356REMARKS:
10357Handles opcode 0xef
10358****************************************************************************/
10359static void
10360x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10361{
10362    START_OF_INSTR();
10363    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364        DECODE_PRINTF("OUT\tDX,EAX\n");
10365    }
10366    else {
10367        DECODE_PRINTF("OUT\tDX,AX\n");
10368    }
10369    TRACE_AND_STEP();
10370    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10371        (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10372    }
10373    else {
10374        (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10375    }
10376    DECODE_CLEAR_SEGOVR();
10377    END_OF_INSTR();
10378}
10379
10380/****************************************************************************
10381REMARKS:
10382Handles opcode 0xf0
10383****************************************************************************/
10384static void
10385x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10386{
10387    START_OF_INSTR();
10388    DECODE_PRINTF("LOCK:\n");
10389    TRACE_AND_STEP();
10390    DECODE_CLEAR_SEGOVR();
10391    END_OF_INSTR();
10392}
10393
10394/*opcode 0xf1 ILLEGAL OPERATION */
10395
10396/****************************************************************************
10397REMARKS:
10398Handles opcode 0xf2
10399****************************************************************************/
10400static void
10401x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10402{
10403    START_OF_INSTR();
10404    DECODE_PRINTF("REPNE\n");
10405    TRACE_AND_STEP();
10406    M.x86.mode |= SYSMODE_PREFIX_REPNE;
10407    DECODE_CLEAR_SEGOVR();
10408    END_OF_INSTR();
10409}
10410
10411/****************************************************************************
10412REMARKS:
10413Handles opcode 0xf3
10414****************************************************************************/
10415static void
10416x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10417{
10418    START_OF_INSTR();
10419    DECODE_PRINTF("REPE\n");
10420    TRACE_AND_STEP();
10421    M.x86.mode |= SYSMODE_PREFIX_REPE;
10422    DECODE_CLEAR_SEGOVR();
10423    END_OF_INSTR();
10424}
10425
10426/****************************************************************************
10427REMARKS:
10428Handles opcode 0xf4
10429****************************************************************************/
10430static void
10431x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10432{
10433    START_OF_INSTR();
10434    DECODE_PRINTF("HALT\n");
10435    TRACE_AND_STEP();
10436    HALT_SYS();
10437    DECODE_CLEAR_SEGOVR();
10438    END_OF_INSTR();
10439}
10440
10441/****************************************************************************
10442REMARKS:
10443Handles opcode 0xf5
10444****************************************************************************/
10445static void
10446x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10447{
10448    /* complement the carry flag. */
10449    START_OF_INSTR();
10450    DECODE_PRINTF("CMC\n");
10451    TRACE_AND_STEP();
10452    TOGGLE_FLAG(F_CF);
10453    DECODE_CLEAR_SEGOVR();
10454    END_OF_INSTR();
10455}
10456
10457/****************************************************************************
10458REMARKS:
10459Handles opcode 0xf6
10460****************************************************************************/
10461static void
10462x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10463{
10464    int mod, rl, rh;
10465    u8 *destreg;
10466    uint destoffset;
10467    u8 destval, srcval;
10468
10469    /* long, drawn out code follows.  Double switch for a total
10470       of 32 cases.  */
10471    START_OF_INSTR();
10472    FETCH_DECODE_MODRM(mod, rh, rl);
10473    switch (mod) {
10474    case 0:                    /* mod=00 */
10475        switch (rh) {
10476        case 0:                /* test byte imm */
10477            DECODE_PRINTF("TEST\tBYTE PTR ");
10478            destoffset = decode_rm00_address(rl);
10479            DECODE_PRINTF(",");
10480            srcval = fetch_byte_imm();
10481            DECODE_PRINTF2("%02x\n", srcval);
10482            destval = fetch_data_byte(destoffset);
10483            TRACE_AND_STEP();
10484            test_byte(destval, srcval);
10485            break;
10486        case 1:
10487            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10488            HALT_SYS();
10489            break;
10490        case 2:
10491            DECODE_PRINTF("NOT\tBYTE PTR ");
10492            destoffset = decode_rm00_address(rl);
10493            DECODE_PRINTF("\n");
10494            destval = fetch_data_byte(destoffset);
10495            TRACE_AND_STEP();
10496            destval = not_byte(destval);
10497            store_data_byte(destoffset, destval);
10498            break;
10499        case 3:
10500            DECODE_PRINTF("NEG\tBYTE PTR ");
10501            destoffset = decode_rm00_address(rl);
10502            DECODE_PRINTF("\n");
10503            destval = fetch_data_byte(destoffset);
10504            TRACE_AND_STEP();
10505            destval = neg_byte(destval);
10506            store_data_byte(destoffset, destval);
10507            break;
10508        case 4:
10509            DECODE_PRINTF("MUL\tBYTE PTR ");
10510            destoffset = decode_rm00_address(rl);
10511            DECODE_PRINTF("\n");
10512            destval = fetch_data_byte(destoffset);
10513            TRACE_AND_STEP();
10514            mul_byte(destval);
10515            break;
10516        case 5:
10517            DECODE_PRINTF("IMUL\tBYTE PTR ");
10518            destoffset = decode_rm00_address(rl);
10519            DECODE_PRINTF("\n");
10520            destval = fetch_data_byte(destoffset);
10521            TRACE_AND_STEP();
10522            imul_byte(destval);
10523            break;
10524        case 6:
10525            DECODE_PRINTF("DIV\tBYTE PTR ");
10526            destoffset = decode_rm00_address(rl);
10527            DECODE_PRINTF("\n");
10528            destval = fetch_data_byte(destoffset);
10529            TRACE_AND_STEP();
10530            div_byte(destval);
10531            break;
10532        case 7:
10533            DECODE_PRINTF("IDIV\tBYTE PTR ");
10534            destoffset = decode_rm00_address(rl);
10535            DECODE_PRINTF("\n");
10536            destval = fetch_data_byte(destoffset);
10537            TRACE_AND_STEP();
10538            idiv_byte(destval);
10539            break;
10540        }
10541        break;                  /* end mod==00 */
10542    case 1:                    /* mod=01 */
10543        switch (rh) {
10544        case 0:                /* test byte imm */
10545            DECODE_PRINTF("TEST\tBYTE PTR ");
10546            destoffset = decode_rm01_address(rl);
10547            DECODE_PRINTF(",");
10548            srcval = fetch_byte_imm();
10549            DECODE_PRINTF2("%02x\n", srcval);
10550            destval = fetch_data_byte(destoffset);
10551            TRACE_AND_STEP();
10552            test_byte(destval, srcval);
10553            break;
10554        case 1:
10555            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10556            HALT_SYS();
10557            break;
10558        case 2:
10559            DECODE_PRINTF("NOT\tBYTE PTR ");
10560            destoffset = decode_rm01_address(rl);
10561            DECODE_PRINTF("\n");
10562            destval = fetch_data_byte(destoffset);
10563            TRACE_AND_STEP();
10564            destval = not_byte(destval);
10565            store_data_byte(destoffset, destval);
10566            break;
10567        case 3:
10568            DECODE_PRINTF("NEG\tBYTE PTR ");
10569            destoffset = decode_rm01_address(rl);
10570            DECODE_PRINTF("\n");
10571            destval = fetch_data_byte(destoffset);
10572            TRACE_AND_STEP();
10573            destval = neg_byte(destval);
10574            store_data_byte(destoffset, destval);
10575            break;
10576        case 4:
10577            DECODE_PRINTF("MUL\tBYTE PTR ");
10578            destoffset = decode_rm01_address(rl);
10579            DECODE_PRINTF("\n");
10580            destval = fetch_data_byte(destoffset);
10581            TRACE_AND_STEP();
10582            mul_byte(destval);
10583            break;
10584        case 5:
10585            DECODE_PRINTF("IMUL\tBYTE PTR ");
10586            destoffset = decode_rm01_address(rl);
10587            DECODE_PRINTF("\n");
10588            destval = fetch_data_byte(destoffset);
10589            TRACE_AND_STEP();
10590            imul_byte(destval);
10591            break;
10592        case 6:
10593            DECODE_PRINTF("DIV\tBYTE PTR ");
10594            destoffset = decode_rm01_address(rl);
10595            DECODE_PRINTF("\n");
10596            destval = fetch_data_byte(destoffset);
10597            TRACE_AND_STEP();
10598            div_byte(destval);
10599            break;
10600        case 7:
10601            DECODE_PRINTF("IDIV\tBYTE PTR ");
10602            destoffset = decode_rm01_address(rl);
10603            DECODE_PRINTF("\n");
10604            destval = fetch_data_byte(destoffset);
10605            TRACE_AND_STEP();
10606            idiv_byte(destval);
10607            break;
10608        }
10609        break;                  /* end mod==01 */
10610    case 2:                    /* mod=10 */
10611        switch (rh) {
10612        case 0:                /* test byte imm */
10613            DECODE_PRINTF("TEST\tBYTE PTR ");
10614            destoffset = decode_rm10_address(rl);
10615            DECODE_PRINTF(",");
10616            srcval = fetch_byte_imm();
10617            DECODE_PRINTF2("%02x\n", srcval);
10618            destval = fetch_data_byte(destoffset);
10619            TRACE_AND_STEP();
10620            test_byte(destval, srcval);
10621            break;
10622        case 1:
10623            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10624            HALT_SYS();
10625            break;
10626        case 2:
10627            DECODE_PRINTF("NOT\tBYTE PTR ");
10628            destoffset = decode_rm10_address(rl);
10629            DECODE_PRINTF("\n");
10630            destval = fetch_data_byte(destoffset);
10631            TRACE_AND_STEP();
10632            destval = not_byte(destval);
10633            store_data_byte(destoffset, destval);
10634            break;
10635        case 3:
10636            DECODE_PRINTF("NEG\tBYTE PTR ");
10637            destoffset = decode_rm10_address(rl);
10638            DECODE_PRINTF("\n");
10639            destval = fetch_data_byte(destoffset);
10640            TRACE_AND_STEP();
10641            destval = neg_byte(destval);
10642            store_data_byte(destoffset, destval);
10643            break;
10644        case 4:
10645            DECODE_PRINTF("MUL\tBYTE PTR ");
10646            destoffset = decode_rm10_address(rl);
10647            DECODE_PRINTF("\n");
10648            destval = fetch_data_byte(destoffset);
10649            TRACE_AND_STEP();
10650            mul_byte(destval);
10651            break;
10652        case 5:
10653            DECODE_PRINTF("IMUL\tBYTE PTR ");
10654            destoffset = decode_rm10_address(rl);
10655            DECODE_PRINTF("\n");
10656            destval = fetch_data_byte(destoffset);
10657            TRACE_AND_STEP();
10658            imul_byte(destval);
10659            break;
10660        case 6:
10661            DECODE_PRINTF("DIV\tBYTE PTR ");
10662            destoffset = decode_rm10_address(rl);
10663            DECODE_PRINTF("\n");
10664            destval = fetch_data_byte(destoffset);
10665            TRACE_AND_STEP();
10666            div_byte(destval);
10667            break;
10668        case 7:
10669            DECODE_PRINTF("IDIV\tBYTE PTR ");
10670            destoffset = decode_rm10_address(rl);
10671            DECODE_PRINTF("\n");
10672            destval = fetch_data_byte(destoffset);
10673            TRACE_AND_STEP();
10674            idiv_byte(destval);
10675            break;
10676        }
10677        break;                  /* end mod==10 */
10678    case 3:                    /* mod=11 */
10679        switch (rh) {
10680        case 0:                /* test byte imm */
10681            DECODE_PRINTF("TEST\t");
10682            destreg = DECODE_RM_BYTE_REGISTER(rl);
10683            DECODE_PRINTF(",");
10684            srcval = fetch_byte_imm();
10685            DECODE_PRINTF2("%02x\n", srcval);
10686            TRACE_AND_STEP();
10687            test_byte(*destreg, srcval);
10688            break;
10689        case 1:
10690            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10691            HALT_SYS();
10692            break;
10693        case 2:
10694            DECODE_PRINTF("NOT\t");
10695            destreg = DECODE_RM_BYTE_REGISTER(rl);
10696            DECODE_PRINTF("\n");
10697            TRACE_AND_STEP();
10698            *destreg = not_byte(*destreg);
10699            break;
10700        case 3:
10701            DECODE_PRINTF("NEG\t");
10702            destreg = DECODE_RM_BYTE_REGISTER(rl);
10703            DECODE_PRINTF("\n");
10704            TRACE_AND_STEP();
10705            *destreg = neg_byte(*destreg);
10706            break;
10707        case 4:
10708            DECODE_PRINTF("MUL\t");
10709            destreg = DECODE_RM_BYTE_REGISTER(rl);
10710            DECODE_PRINTF("\n");
10711            TRACE_AND_STEP();
10712            mul_byte(*destreg); /*!!!  */
10713            break;
10714        case 5:
10715            DECODE_PRINTF("IMUL\t");
10716            destreg = DECODE_RM_BYTE_REGISTER(rl);
10717            DECODE_PRINTF("\n");
10718            TRACE_AND_STEP();
10719            imul_byte(*destreg);
10720            break;
10721        case 6:
10722            DECODE_PRINTF("DIV\t");
10723            destreg = DECODE_RM_BYTE_REGISTER(rl);
10724            DECODE_PRINTF("\n");
10725            TRACE_AND_STEP();
10726            div_byte(*destreg);
10727            break;
10728        case 7:
10729            DECODE_PRINTF("IDIV\t");
10730            destreg = DECODE_RM_BYTE_REGISTER(rl);
10731            DECODE_PRINTF("\n");
10732            TRACE_AND_STEP();
10733            idiv_byte(*destreg);
10734            break;
10735        }
10736        break;                  /* end mod==11 */
10737    }
10738    DECODE_CLEAR_SEGOVR();
10739    END_OF_INSTR();
10740}
10741
10742/****************************************************************************
10743REMARKS:
10744Handles opcode 0xf7
10745****************************************************************************/
10746static void
10747x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10748{
10749    int mod, rl, rh;
10750    uint destoffset;
10751
10752    /* long, drawn out code follows.  Double switch for a total
10753       of 32 cases.  */
10754    START_OF_INSTR();
10755    FETCH_DECODE_MODRM(mod, rh, rl);
10756    switch (mod) {
10757    case 0:                    /* mod=00 */
10758        switch (rh) {
10759        case 0:                /* test word imm */
10760            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10761                u32 destval, srcval;
10762
10763                DECODE_PRINTF("TEST\tDWORD PTR ");
10764                destoffset = decode_rm00_address(rl);
10765                DECODE_PRINTF(",");
10766                srcval = fetch_long_imm();
10767                DECODE_PRINTF2("%x\n", srcval);
10768                destval = fetch_data_long(destoffset);
10769                TRACE_AND_STEP();
10770                test_long(destval, srcval);
10771            }
10772            else {
10773                u16 destval, srcval;
10774
10775                DECODE_PRINTF("TEST\tWORD PTR ");
10776                destoffset = decode_rm00_address(rl);
10777                DECODE_PRINTF(",");
10778                srcval = fetch_word_imm();
10779                DECODE_PRINTF2("%x\n", srcval);
10780                destval = fetch_data_word(destoffset);
10781                TRACE_AND_STEP();
10782                test_word(destval, srcval);
10783            }
10784            break;
10785        case 1:
10786            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10787            HALT_SYS();
10788            break;
10789        case 2:
10790            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10791                u32 destval;
10792
10793                DECODE_PRINTF("NOT\tDWORD PTR ");
10794                destoffset = decode_rm00_address(rl);
10795                DECODE_PRINTF("\n");
10796                destval = fetch_data_long(destoffset);
10797                TRACE_AND_STEP();
10798                destval = not_long(destval);
10799                store_data_long(destoffset, destval);
10800            }
10801            else {
10802                u16 destval;
10803
10804                DECODE_PRINTF("NOT\tWORD PTR ");
10805                destoffset = decode_rm00_address(rl);
10806                DECODE_PRINTF("\n");
10807                destval = fetch_data_word(destoffset);
10808                TRACE_AND_STEP();
10809                destval = not_word(destval);
10810                store_data_word(destoffset, destval);
10811            }
10812            break;
10813        case 3:
10814            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10815                u32 destval;
10816
10817                DECODE_PRINTF("NEG\tDWORD PTR ");
10818                destoffset = decode_rm00_address(rl);
10819                DECODE_PRINTF("\n");
10820                destval = fetch_data_long(destoffset);
10821                TRACE_AND_STEP();
10822                destval = neg_long(destval);
10823                store_data_long(destoffset, destval);
10824            }
10825            else {
10826                u16 destval;
10827
10828                DECODE_PRINTF("NEG\tWORD PTR ");
10829                destoffset = decode_rm00_address(rl);
10830                DECODE_PRINTF("\n");
10831                destval = fetch_data_word(destoffset);
10832                TRACE_AND_STEP();
10833                destval = neg_word(destval);
10834                store_data_word(destoffset, destval);
10835            }
10836            break;
10837        case 4:
10838            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10839                u32 destval;
10840
10841                DECODE_PRINTF("MUL\tDWORD PTR ");
10842                destoffset = decode_rm00_address(rl);
10843                DECODE_PRINTF("\n");
10844                destval = fetch_data_long(destoffset);
10845                TRACE_AND_STEP();
10846                mul_long(destval);
10847            }
10848            else {
10849                u16 destval;
10850
10851                DECODE_PRINTF("MUL\tWORD PTR ");
10852                destoffset = decode_rm00_address(rl);
10853                DECODE_PRINTF("\n");
10854                destval = fetch_data_word(destoffset);
10855                TRACE_AND_STEP();
10856                mul_word(destval);
10857            }
10858            break;
10859        case 5:
10860            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10861                u32 destval;
10862
10863                DECODE_PRINTF("IMUL\tDWORD PTR ");
10864                destoffset = decode_rm00_address(rl);
10865                DECODE_PRINTF("\n");
10866                destval = fetch_data_long(destoffset);
10867                TRACE_AND_STEP();
10868                imul_long(destval);
10869            }
10870            else {
10871                u16 destval;
10872
10873                DECODE_PRINTF("IMUL\tWORD PTR ");
10874                destoffset = decode_rm00_address(rl);
10875                DECODE_PRINTF("\n");
10876                destval = fetch_data_word(destoffset);
10877                TRACE_AND_STEP();
10878                imul_word(destval);
10879            }
10880            break;
10881        case 6:
10882            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10883                u32 destval;
10884
10885                DECODE_PRINTF("DIV\tDWORD PTR ");
10886                destoffset = decode_rm00_address(rl);
10887                DECODE_PRINTF("\n");
10888                destval = fetch_data_long(destoffset);
10889                TRACE_AND_STEP();
10890                div_long(destval);
10891            }
10892            else {
10893                u16 destval;
10894
10895                DECODE_PRINTF("DIV\tWORD PTR ");
10896                destoffset = decode_rm00_address(rl);
10897                DECODE_PRINTF("\n");
10898                destval = fetch_data_word(destoffset);
10899                TRACE_AND_STEP();
10900                div_word(destval);
10901            }
10902            break;
10903        case 7:
10904            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10905                u32 destval;
10906
10907                DECODE_PRINTF("IDIV\tDWORD PTR ");
10908                destoffset = decode_rm00_address(rl);
10909                DECODE_PRINTF("\n");
10910                destval = fetch_data_long(destoffset);
10911                TRACE_AND_STEP();
10912                idiv_long(destval);
10913            }
10914            else {
10915                u16 destval;
10916
10917                DECODE_PRINTF("IDIV\tWORD PTR ");
10918                destoffset = decode_rm00_address(rl);
10919                DECODE_PRINTF("\n");
10920                destval = fetch_data_word(destoffset);
10921                TRACE_AND_STEP();
10922                idiv_word(destval);
10923            }
10924            break;
10925        }
10926        break;                  /* end mod==00 */
10927    case 1:                    /* mod=01 */
10928        switch (rh) {
10929        case 0:                /* test word imm */
10930            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10931                u32 destval, srcval;
10932
10933                DECODE_PRINTF("TEST\tDWORD PTR ");
10934                destoffset = decode_rm01_address(rl);
10935                DECODE_PRINTF(",");
10936                srcval = fetch_long_imm();
10937                DECODE_PRINTF2("%x\n", srcval);
10938                destval = fetch_data_long(destoffset);
10939                TRACE_AND_STEP();
10940                test_long(destval, srcval);
10941            }
10942            else {
10943                u16 destval, srcval;
10944
10945                DECODE_PRINTF("TEST\tWORD PTR ");
10946                destoffset = decode_rm01_address(rl);
10947                DECODE_PRINTF(",");
10948                srcval = fetch_word_imm();
10949                DECODE_PRINTF2("%x\n", srcval);
10950                destval = fetch_data_word(destoffset);
10951                TRACE_AND_STEP();
10952                test_word(destval, srcval);
10953            }
10954            break;
10955        case 1:
10956            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10957            HALT_SYS();
10958            break;
10959        case 2:
10960            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10961                u32 destval;
10962
10963                DECODE_PRINTF("NOT\tDWORD PTR ");
10964                destoffset = decode_rm01_address(rl);
10965                DECODE_PRINTF("\n");
10966                destval = fetch_data_long(destoffset);
10967                TRACE_AND_STEP();
10968                destval = not_long(destval);
10969                store_data_long(destoffset, destval);
10970            }
10971            else {
10972                u16 destval;
10973
10974                DECODE_PRINTF("NOT\tWORD PTR ");
10975                destoffset = decode_rm01_address(rl);
10976                DECODE_PRINTF("\n");
10977                destval = fetch_data_word(destoffset);
10978                TRACE_AND_STEP();
10979                destval = not_word(destval);
10980                store_data_word(destoffset, destval);
10981            }
10982            break;
10983        case 3:
10984            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10985                u32 destval;
10986
10987                DECODE_PRINTF("NEG\tDWORD PTR ");
10988                destoffset = decode_rm01_address(rl);
10989                DECODE_PRINTF("\n");
10990                destval = fetch_data_long(destoffset);
10991                TRACE_AND_STEP();
10992                destval = neg_long(destval);
10993                store_data_long(destoffset, destval);
10994            }
10995            else {
10996                u16 destval;
10997
10998                DECODE_PRINTF("NEG\tWORD PTR ");
10999                destoffset = decode_rm01_address(rl);
11000                DECODE_PRINTF("\n");
11001                destval = fetch_data_word(destoffset);
11002                TRACE_AND_STEP();
11003                destval = neg_word(destval);
11004                store_data_word(destoffset, destval);
11005            }
11006            break;
11007        case 4:
11008            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11009                u32 destval;
11010
11011                DECODE_PRINTF("MUL\tDWORD PTR ");
11012                destoffset = decode_rm01_address(rl);
11013                DECODE_PRINTF("\n");
11014                destval = fetch_data_long(destoffset);
11015                TRACE_AND_STEP();
11016                mul_long(destval);
11017            }
11018            else {
11019                u16 destval;
11020
11021                DECODE_PRINTF("MUL\tWORD PTR ");
11022                destoffset = decode_rm01_address(rl);
11023                DECODE_PRINTF("\n");
11024                destval = fetch_data_word(destoffset);
11025                TRACE_AND_STEP();
11026                mul_word(destval);
11027            }
11028            break;
11029        case 5:
11030            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11031                u32 destval;
11032
11033                DECODE_PRINTF("IMUL\tDWORD PTR ");
11034                destoffset = decode_rm01_address(rl);
11035                DECODE_PRINTF("\n");
11036                destval = fetch_data_long(destoffset);
11037                TRACE_AND_STEP();
11038                imul_long(destval);
11039            }
11040            else {
11041                u16 destval;
11042
11043                DECODE_PRINTF("IMUL\tWORD PTR ");
11044                destoffset = decode_rm01_address(rl);
11045                DECODE_PRINTF("\n");
11046                destval = fetch_data_word(destoffset);
11047                TRACE_AND_STEP();
11048                imul_word(destval);
11049            }
11050            break;
11051        case 6:
11052            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11053                u32 destval;
11054
11055                DECODE_PRINTF("DIV\tDWORD PTR ");
11056                destoffset = decode_rm01_address(rl);
11057                DECODE_PRINTF("\n");
11058                destval = fetch_data_long(destoffset);
11059                TRACE_AND_STEP();
11060                div_long(destval);
11061            }
11062            else {
11063                u16 destval;
11064
11065                DECODE_PRINTF("DIV\tWORD PTR ");
11066                destoffset = decode_rm01_address(rl);
11067                DECODE_PRINTF("\n");
11068                destval = fetch_data_word(destoffset);
11069                TRACE_AND_STEP();
11070                div_word(destval);
11071            }
11072            break;
11073        case 7:
11074            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11075                u32 destval;
11076
11077                DECODE_PRINTF("IDIV\tDWORD PTR ");
11078                destoffset = decode_rm01_address(rl);
11079                DECODE_PRINTF("\n");
11080                destval = fetch_data_long(destoffset);
11081                TRACE_AND_STEP();
11082                idiv_long(destval);
11083            }
11084            else {
11085                u16 destval;
11086
11087                DECODE_PRINTF("IDIV\tWORD PTR ");
11088                destoffset = decode_rm01_address(rl);
11089                DECODE_PRINTF("\n");
11090                destval = fetch_data_word(destoffset);
11091                TRACE_AND_STEP();
11092                idiv_word(destval);
11093            }
11094            break;
11095        }
11096        break;                  /* end mod==01 */
11097    case 2:                    /* mod=10 */
11098        switch (rh) {
11099        case 0:                /* test word imm */
11100            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11101                u32 destval, srcval;
11102
11103                DECODE_PRINTF("TEST\tDWORD PTR ");
11104                destoffset = decode_rm10_address(rl);
11105                DECODE_PRINTF(",");
11106                srcval = fetch_long_imm();
11107                DECODE_PRINTF2("%x\n", srcval);
11108                destval = fetch_data_long(destoffset);
11109                TRACE_AND_STEP();
11110                test_long(destval, srcval);
11111            }
11112            else {
11113                u16 destval, srcval;
11114
11115                DECODE_PRINTF("TEST\tWORD PTR ");
11116                destoffset = decode_rm10_address(rl);
11117                DECODE_PRINTF(",");
11118                srcval = fetch_word_imm();
11119                DECODE_PRINTF2("%x\n", srcval);
11120                destval = fetch_data_word(destoffset);
11121                TRACE_AND_STEP();
11122                test_word(destval, srcval);
11123            }
11124            break;
11125        case 1:
11126            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11127            HALT_SYS();
11128            break;
11129        case 2:
11130            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11131                u32 destval;
11132
11133                DECODE_PRINTF("NOT\tDWORD PTR ");
11134                destoffset = decode_rm10_address(rl);
11135                DECODE_PRINTF("\n");
11136                destval = fetch_data_long(destoffset);
11137                TRACE_AND_STEP();
11138                destval = not_long(destval);
11139                store_data_long(destoffset, destval);
11140            }
11141            else {
11142                u16 destval;
11143
11144                DECODE_PRINTF("NOT\tWORD PTR ");
11145                destoffset = decode_rm10_address(rl);
11146                DECODE_PRINTF("\n");
11147                destval = fetch_data_word(destoffset);
11148                TRACE_AND_STEP();
11149                destval = not_word(destval);
11150                store_data_word(destoffset, destval);
11151            }
11152            break;
11153        case 3:
11154            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11155                u32 destval;
11156
11157                DECODE_PRINTF("NEG\tDWORD PTR ");
11158                destoffset = decode_rm10_address(rl);
11159                DECODE_PRINTF("\n");
11160                destval = fetch_data_long(destoffset);
11161                TRACE_AND_STEP();
11162                destval = neg_long(destval);
11163                store_data_long(destoffset, destval);
11164            }
11165            else {
11166                u16 destval;
11167
11168                DECODE_PRINTF("NEG\tWORD PTR ");
11169                destoffset = decode_rm10_address(rl);
11170                DECODE_PRINTF("\n");
11171                destval = fetch_data_word(destoffset);
11172                TRACE_AND_STEP();
11173                destval = neg_word(destval);
11174                store_data_word(destoffset, destval);
11175            }
11176            break;
11177        case 4:
11178            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11179                u32 destval;
11180
11181                DECODE_PRINTF("MUL\tDWORD PTR ");
11182                destoffset = decode_rm10_address(rl);
11183                DECODE_PRINTF("\n");
11184                destval = fetch_data_long(destoffset);
11185                TRACE_AND_STEP();
11186                mul_long(destval);
11187            }
11188            else {
11189                u16 destval;
11190
11191                DECODE_PRINTF("MUL\tWORD PTR ");
11192                destoffset = decode_rm10_address(rl);
11193                DECODE_PRINTF("\n");
11194                destval = fetch_data_word(destoffset);
11195                TRACE_AND_STEP();
11196                mul_word(destval);
11197            }
11198            break;
11199        case 5:
11200            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11201                u32 destval;
11202
11203                DECODE_PRINTF("IMUL\tDWORD PTR ");
11204                destoffset = decode_rm10_address(rl);
11205                DECODE_PRINTF("\n");
11206                destval = fetch_data_long(destoffset);
11207                TRACE_AND_STEP();
11208                imul_long(destval);
11209            }
11210            else {
11211                u16 destval;
11212
11213                DECODE_PRINTF("IMUL\tWORD PTR ");
11214                destoffset = decode_rm10_address(rl);
11215                DECODE_PRINTF("\n");
11216                destval = fetch_data_word(destoffset);
11217                TRACE_AND_STEP();
11218                imul_word(destval);
11219            }
11220            break;
11221        case 6:
11222            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11223                u32 destval;
11224
11225                DECODE_PRINTF("DIV\tDWORD PTR ");
11226                destoffset = decode_rm10_address(rl);
11227                DECODE_PRINTF("\n");
11228                destval = fetch_data_long(destoffset);
11229                TRACE_AND_STEP();
11230                div_long(destval);
11231            }
11232            else {
11233                u16 destval;
11234
11235                DECODE_PRINTF("DIV\tWORD PTR ");
11236                destoffset = decode_rm10_address(rl);
11237                DECODE_PRINTF("\n");
11238                destval = fetch_data_word(destoffset);
11239                TRACE_AND_STEP();
11240                div_word(destval);
11241            }
11242            break;
11243        case 7:
11244            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11245                u32 destval;
11246
11247                DECODE_PRINTF("IDIV\tDWORD PTR ");
11248                destoffset = decode_rm10_address(rl);
11249                DECODE_PRINTF("\n");
11250                destval = fetch_data_long(destoffset);
11251                TRACE_AND_STEP();
11252                idiv_long(destval);
11253            }
11254            else {
11255                u16 destval;
11256
11257                DECODE_PRINTF("IDIV\tWORD PTR ");
11258                destoffset = decode_rm10_address(rl);
11259                DECODE_PRINTF("\n");
11260                destval = fetch_data_word(destoffset);
11261                TRACE_AND_STEP();
11262                idiv_word(destval);
11263            }
11264            break;
11265        }
11266        break;                  /* end mod==10 */
11267    case 3:                    /* mod=11 */
11268        switch (rh) {
11269        case 0:                /* test word imm */
11270            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11271                u32 *destreg;
11272                u32 srcval;
11273
11274                DECODE_PRINTF("TEST\t");
11275                destreg = DECODE_RM_LONG_REGISTER(rl);
11276                DECODE_PRINTF(",");
11277                srcval = fetch_long_imm();
11278                DECODE_PRINTF2("%x\n", srcval);
11279                TRACE_AND_STEP();
11280                test_long(*destreg, srcval);
11281            }
11282            else {
11283                u16 *destreg;
11284                u16 srcval;
11285
11286                DECODE_PRINTF("TEST\t");
11287                destreg = DECODE_RM_WORD_REGISTER(rl);
11288                DECODE_PRINTF(",");
11289                srcval = fetch_word_imm();
11290                DECODE_PRINTF2("%x\n", srcval);
11291                TRACE_AND_STEP();
11292                test_word(*destreg, srcval);
11293            }
11294            break;
11295        case 1:
11296            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11297            HALT_SYS();
11298            break;
11299        case 2:
11300            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11301                u32 *destreg;
11302
11303                DECODE_PRINTF("NOT\t");
11304                destreg = DECODE_RM_LONG_REGISTER(rl);
11305                DECODE_PRINTF("\n");
11306                TRACE_AND_STEP();
11307                *destreg = not_long(*destreg);
11308            }
11309            else {
11310                u16 *destreg;
11311
11312                DECODE_PRINTF("NOT\t");
11313                destreg = DECODE_RM_WORD_REGISTER(rl);
11314                DECODE_PRINTF("\n");
11315                TRACE_AND_STEP();
11316                *destreg = not_word(*destreg);
11317            }
11318            break;
11319        case 3:
11320            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11321                u32 *destreg;
11322
11323                DECODE_PRINTF("NEG\t");
11324                destreg = DECODE_RM_LONG_REGISTER(rl);
11325                DECODE_PRINTF("\n");
11326                TRACE_AND_STEP();
11327                *destreg = neg_long(*destreg);
11328            }
11329            else {
11330                u16 *destreg;
11331
11332                DECODE_PRINTF("NEG\t");
11333                destreg = DECODE_RM_WORD_REGISTER(rl);
11334                DECODE_PRINTF("\n");
11335                TRACE_AND_STEP();
11336                *destreg = neg_word(*destreg);
11337            }
11338            break;
11339        case 4:
11340            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11341                u32 *destreg;
11342
11343                DECODE_PRINTF("MUL\t");
11344                destreg = DECODE_RM_LONG_REGISTER(rl);
11345                DECODE_PRINTF("\n");
11346                TRACE_AND_STEP();
11347                mul_long(*destreg);     /*!!!  */
11348            }
11349            else {
11350                u16 *destreg;
11351
11352                DECODE_PRINTF("MUL\t");
11353                destreg = DECODE_RM_WORD_REGISTER(rl);
11354                DECODE_PRINTF("\n");
11355                TRACE_AND_STEP();
11356                mul_word(*destreg);     /*!!!  */
11357            }
11358            break;
11359        case 5:
11360            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11361                u32 *destreg;
11362
11363                DECODE_PRINTF("IMUL\t");
11364                destreg = DECODE_RM_LONG_REGISTER(rl);
11365                DECODE_PRINTF("\n");
11366                TRACE_AND_STEP();
11367                imul_long(*destreg);
11368            }
11369            else {
11370                u16 *destreg;
11371
11372                DECODE_PRINTF("IMUL\t");
11373                destreg = DECODE_RM_WORD_REGISTER(rl);
11374                DECODE_PRINTF("\n");
11375                TRACE_AND_STEP();
11376                imul_word(*destreg);
11377            }
11378            break;
11379        case 6:
11380            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11381                u32 *destreg;
11382
11383                DECODE_PRINTF("DIV\t");
11384                destreg = DECODE_RM_LONG_REGISTER(rl);
11385                DECODE_PRINTF("\n");
11386                TRACE_AND_STEP();
11387                div_long(*destreg);
11388            }
11389            else {
11390                u16 *destreg;
11391
11392                DECODE_PRINTF("DIV\t");
11393                destreg = DECODE_RM_WORD_REGISTER(rl);
11394                DECODE_PRINTF("\n");
11395                TRACE_AND_STEP();
11396                div_word(*destreg);
11397            }
11398            break;
11399        case 7:
11400            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11401                u32 *destreg;
11402
11403                DECODE_PRINTF("IDIV\t");
11404                destreg = DECODE_RM_LONG_REGISTER(rl);
11405                DECODE_PRINTF("\n");
11406                TRACE_AND_STEP();
11407                idiv_long(*destreg);
11408            }
11409            else {
11410                u16 *destreg;
11411
11412                DECODE_PRINTF("IDIV\t");
11413                destreg = DECODE_RM_WORD_REGISTER(rl);
11414                DECODE_PRINTF("\n");
11415                TRACE_AND_STEP();
11416                idiv_word(*destreg);
11417            }
11418            break;
11419        }
11420        break;                  /* end mod==11 */
11421    }
11422    DECODE_CLEAR_SEGOVR();
11423    END_OF_INSTR();
11424}
11425
11426/****************************************************************************
11427REMARKS:
11428Handles opcode 0xf8
11429****************************************************************************/
11430static void
11431x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11432{
11433    /* clear the carry flag. */
11434    START_OF_INSTR();
11435    DECODE_PRINTF("CLC\n");
11436    TRACE_AND_STEP();
11437    CLEAR_FLAG(F_CF);
11438    DECODE_CLEAR_SEGOVR();
11439    END_OF_INSTR();
11440}
11441
11442/****************************************************************************
11443REMARKS:
11444Handles opcode 0xf9
11445****************************************************************************/
11446static void
11447x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11448{
11449    /* set the carry flag. */
11450    START_OF_INSTR();
11451    DECODE_PRINTF("STC\n");
11452    TRACE_AND_STEP();
11453    SET_FLAG(F_CF);
11454    DECODE_CLEAR_SEGOVR();
11455    END_OF_INSTR();
11456}
11457
11458/****************************************************************************
11459REMARKS:
11460Handles opcode 0xfa
11461****************************************************************************/
11462static void
11463x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11464{
11465    /* clear interrupts. */
11466    START_OF_INSTR();
11467    DECODE_PRINTF("CLI\n");
11468    TRACE_AND_STEP();
11469    CLEAR_FLAG(F_IF);
11470    DECODE_CLEAR_SEGOVR();
11471    END_OF_INSTR();
11472}
11473
11474/****************************************************************************
11475REMARKS:
11476Handles opcode 0xfb
11477****************************************************************************/
11478static void
11479x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11480{
11481    /* enable  interrupts. */
11482    START_OF_INSTR();
11483    DECODE_PRINTF("STI\n");
11484    TRACE_AND_STEP();
11485    SET_FLAG(F_IF);
11486    DECODE_CLEAR_SEGOVR();
11487    END_OF_INSTR();
11488}
11489
11490/****************************************************************************
11491REMARKS:
11492Handles opcode 0xfc
11493****************************************************************************/
11494static void
11495x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11496{
11497    /* clear interrupts. */
11498    START_OF_INSTR();
11499    DECODE_PRINTF("CLD\n");
11500    TRACE_AND_STEP();
11501    CLEAR_FLAG(F_DF);
11502    DECODE_CLEAR_SEGOVR();
11503    END_OF_INSTR();
11504}
11505
11506/****************************************************************************
11507REMARKS:
11508Handles opcode 0xfd
11509****************************************************************************/
11510static void
11511x86emuOp_std(u8 X86EMU_UNUSED(op1))
11512{
11513    /* clear interrupts. */
11514    START_OF_INSTR();
11515    DECODE_PRINTF("STD\n");
11516    TRACE_AND_STEP();
11517    SET_FLAG(F_DF);
11518    DECODE_CLEAR_SEGOVR();
11519    END_OF_INSTR();
11520}
11521
11522/****************************************************************************
11523REMARKS:
11524Handles opcode 0xfe
11525****************************************************************************/
11526static void
11527x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11528{
11529    int mod, rh, rl;
11530    u8 destval;
11531    uint destoffset;
11532    u8 *destreg;
11533
11534    /* Yet another special case instruction. */
11535    START_OF_INSTR();
11536    FETCH_DECODE_MODRM(mod, rh, rl);
11537#ifdef DEBUG
11538    if (DEBUG_DECODE()) {
11539        /* XXX DECODE_PRINTF may be changed to something more
11540           general, so that it is important to leave the strings
11541           in the same format, even though the result is that the
11542           above test is done twice. */
11543
11544        switch (rh) {
11545        case 0:
11546            DECODE_PRINTF("INC\t");
11547            break;
11548        case 1:
11549            DECODE_PRINTF("DEC\t");
11550            break;
11551        case 2:
11552        case 3:
11553        case 4:
11554        case 5:
11555        case 6:
11556        case 7:
11557            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11558            HALT_SYS();
11559            break;
11560        }
11561    }
11562#endif
11563    switch (mod) {
11564    case 0:
11565        DECODE_PRINTF("BYTE PTR ");
11566        destoffset = decode_rm00_address(rl);
11567        DECODE_PRINTF("\n");
11568        switch (rh) {
11569        case 0:                /* inc word ptr ... */
11570            destval = fetch_data_byte(destoffset);
11571            TRACE_AND_STEP();
11572            destval = inc_byte(destval);
11573            store_data_byte(destoffset, destval);
11574            break;
11575        case 1:                /* dec word ptr ... */
11576            destval = fetch_data_byte(destoffset);
11577            TRACE_AND_STEP();
11578            destval = dec_byte(destval);
11579            store_data_byte(destoffset, destval);
11580            break;
11581        }
11582        break;
11583    case 1:
11584        DECODE_PRINTF("BYTE PTR ");
11585        destoffset = decode_rm01_address(rl);
11586        DECODE_PRINTF("\n");
11587        switch (rh) {
11588        case 0:
11589            destval = fetch_data_byte(destoffset);
11590            TRACE_AND_STEP();
11591            destval = inc_byte(destval);
11592            store_data_byte(destoffset, destval);
11593            break;
11594        case 1:
11595            destval = fetch_data_byte(destoffset);
11596            TRACE_AND_STEP();
11597            destval = dec_byte(destval);
11598            store_data_byte(destoffset, destval);
11599            break;
11600        }
11601        break;
11602    case 2:
11603        DECODE_PRINTF("BYTE PTR ");
11604        destoffset = decode_rm10_address(rl);
11605        DECODE_PRINTF("\n");
11606        switch (rh) {
11607        case 0:
11608            destval = fetch_data_byte(destoffset);
11609            TRACE_AND_STEP();
11610            destval = inc_byte(destval);
11611            store_data_byte(destoffset, destval);
11612            break;
11613        case 1:
11614            destval = fetch_data_byte(destoffset);
11615            TRACE_AND_STEP();
11616            destval = dec_byte(destval);
11617            store_data_byte(destoffset, destval);
11618            break;
11619        }
11620        break;
11621    case 3:
11622        destreg = DECODE_RM_BYTE_REGISTER(rl);
11623        DECODE_PRINTF("\n");
11624        switch (rh) {
11625        case 0:
11626            TRACE_AND_STEP();
11627            *destreg = inc_byte(*destreg);
11628            break;
11629        case 1:
11630            TRACE_AND_STEP();
11631            *destreg = dec_byte(*destreg);
11632            break;
11633        }
11634        break;
11635    }
11636    DECODE_CLEAR_SEGOVR();
11637    END_OF_INSTR();
11638}
11639
11640/****************************************************************************
11641REMARKS:
11642Handles opcode 0xff
11643****************************************************************************/
11644static void
11645x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11646{
11647    int mod, rh, rl;
11648    uint destoffset = 0;
11649    u16 *destreg;
11650    u16 destval, destval2;
11651
11652    /* Yet another special case instruction. */
11653    START_OF_INSTR();
11654    FETCH_DECODE_MODRM(mod, rh, rl);
11655#ifdef DEBUG
11656    if (DEBUG_DECODE()) {
11657        /* XXX DECODE_PRINTF may be changed to something more
11658           general, so that it is important to leave the strings
11659           in the same format, even though the result is that the
11660           above test is done twice. */
11661
11662        switch (rh) {
11663        case 0:
11664            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11665                DECODE_PRINTF("INC\tDWORD PTR ");
11666            }
11667            else {
11668                DECODE_PRINTF("INC\tWORD PTR ");
11669            }
11670            break;
11671        case 1:
11672            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11673                DECODE_PRINTF("DEC\tDWORD PTR ");
11674            }
11675            else {
11676                DECODE_PRINTF("DEC\tWORD PTR ");
11677            }
11678            break;
11679        case 2:
11680            DECODE_PRINTF("CALL\t");
11681            break;
11682        case 3:
11683            DECODE_PRINTF("CALL\tFAR ");
11684            break;
11685        case 4:
11686            DECODE_PRINTF("JMP\t");
11687            break;
11688        case 5:
11689            DECODE_PRINTF("JMP\tFAR ");
11690            break;
11691        case 6:
11692            DECODE_PRINTF("PUSH\t");
11693            break;
11694        case 7:
11695            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11696            HALT_SYS();
11697            break;
11698        }
11699    }
11700#endif
11701    switch (mod) {
11702    case 0:
11703        destoffset = decode_rm00_address(rl);
11704        DECODE_PRINTF("\n");
11705        switch (rh) {
11706        case 0:                /* inc word ptr ... */
11707            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11708                u32 destval;
11709
11710                destval = fetch_data_long(destoffset);
11711                TRACE_AND_STEP();
11712                destval = inc_long(destval);
11713                store_data_long(destoffset, destval);
11714            }
11715            else {
11716                u16 destval;
11717
11718                destval = fetch_data_word(destoffset);
11719                TRACE_AND_STEP();
11720                destval = inc_word(destval);
11721                store_data_word(destoffset, destval);
11722            }
11723            break;
11724        case 1:                /* dec word ptr ... */
11725            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11726                u32 destval;
11727
11728                destval = fetch_data_long(destoffset);
11729                TRACE_AND_STEP();
11730                destval = dec_long(destval);
11731                store_data_long(destoffset, destval);
11732            }
11733            else {
11734                u16 destval;
11735
11736                destval = fetch_data_word(destoffset);
11737                TRACE_AND_STEP();
11738                destval = dec_word(destval);
11739                store_data_word(destoffset, destval);
11740            }
11741            break;
11742        case 2:                /* call word ptr ... */
11743            destval = fetch_data_word(destoffset);
11744            TRACE_AND_STEP();
11745            push_word(M.x86.R_IP);
11746            M.x86.R_IP = destval;
11747            break;
11748        case 3:                /* call far ptr ... */
11749            destval = fetch_data_word(destoffset);
11750            destval2 = fetch_data_word(destoffset + 2);
11751            TRACE_AND_STEP();
11752            push_word(M.x86.R_CS);
11753            M.x86.R_CS = destval2;
11754            push_word(M.x86.R_IP);
11755            M.x86.R_IP = destval;
11756            break;
11757        case 4:                /* jmp word ptr ... */
11758            destval = fetch_data_word(destoffset);
11759            TRACE_AND_STEP();
11760            M.x86.R_IP = destval;
11761            break;
11762        case 5:                /* jmp far ptr ... */
11763            destval = fetch_data_word(destoffset);
11764            destval2 = fetch_data_word(destoffset + 2);
11765            TRACE_AND_STEP();
11766            M.x86.R_IP = destval;
11767            M.x86.R_CS = destval2;
11768            break;
11769        case 6:                /*  push word ptr ... */
11770            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11771                u32 destval;
11772
11773                destval = fetch_data_long(destoffset);
11774                TRACE_AND_STEP();
11775                push_long(destval);
11776            }
11777            else {
11778                u16 destval;
11779
11780                destval = fetch_data_word(destoffset);
11781                TRACE_AND_STEP();
11782                push_word(destval);
11783            }
11784            break;
11785        }
11786        break;
11787    case 1:
11788        destoffset = decode_rm01_address(rl);
11789        DECODE_PRINTF("\n");
11790        switch (rh) {
11791        case 0:
11792            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11793                u32 destval;
11794
11795                destval = fetch_data_long(destoffset);
11796                TRACE_AND_STEP();
11797                destval = inc_long(destval);
11798                store_data_long(destoffset, destval);
11799            }
11800            else {
11801                u16 destval;
11802
11803                destval = fetch_data_word(destoffset);
11804                TRACE_AND_STEP();
11805                destval = inc_word(destval);
11806                store_data_word(destoffset, destval);
11807            }
11808            break;
11809        case 1:
11810            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11811                u32 destval;
11812
11813                destval = fetch_data_long(destoffset);
11814                TRACE_AND_STEP();
11815                destval = dec_long(destval);
11816                store_data_long(destoffset, destval);
11817            }
11818            else {
11819                u16 destval;
11820
11821                destval = fetch_data_word(destoffset);
11822                TRACE_AND_STEP();
11823                destval = dec_word(destval);
11824                store_data_word(destoffset, destval);
11825            }
11826            break;
11827        case 2:                /* call word ptr ... */
11828            destval = fetch_data_word(destoffset);
11829            TRACE_AND_STEP();
11830            push_word(M.x86.R_IP);
11831            M.x86.R_IP = destval;
11832            break;
11833        case 3:                /* call far ptr ... */
11834            destval = fetch_data_word(destoffset);
11835            destval2 = fetch_data_word(destoffset + 2);
11836            TRACE_AND_STEP();
11837            push_word(M.x86.R_CS);
11838            M.x86.R_CS = destval2;
11839            push_word(M.x86.R_IP);
11840            M.x86.R_IP = destval;
11841            break;
11842        case 4:                /* jmp word ptr ... */
11843            destval = fetch_data_word(destoffset);
11844            TRACE_AND_STEP();
11845            M.x86.R_IP = destval;
11846            break;
11847        case 5:                /* jmp far ptr ... */
11848            destval = fetch_data_word(destoffset);
11849            destval2 = fetch_data_word(destoffset + 2);
11850            TRACE_AND_STEP();
11851            M.x86.R_IP = destval;
11852            M.x86.R_CS = destval2;
11853            break;
11854        case 6:                /*  push word ptr ... */
11855            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11856                u32 destval;
11857
11858                destval = fetch_data_long(destoffset);
11859                TRACE_AND_STEP();
11860                push_long(destval);
11861            }
11862            else {
11863                u16 destval;
11864
11865                destval = fetch_data_word(destoffset);
11866                TRACE_AND_STEP();
11867                push_word(destval);
11868            }
11869            break;
11870        }
11871        break;
11872    case 2:
11873        destoffset = decode_rm10_address(rl);
11874        DECODE_PRINTF("\n");
11875        switch (rh) {
11876        case 0:
11877            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11878                u32 destval;
11879
11880                destval = fetch_data_long(destoffset);
11881                TRACE_AND_STEP();
11882                destval = inc_long(destval);
11883                store_data_long(destoffset, destval);
11884            }
11885            else {
11886                u16 destval;
11887
11888                destval = fetch_data_word(destoffset);
11889                TRACE_AND_STEP();
11890                destval = inc_word(destval);
11891                store_data_word(destoffset, destval);
11892            }
11893            break;
11894        case 1:
11895            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11896                u32 destval;
11897
11898                destval = fetch_data_long(destoffset);
11899                TRACE_AND_STEP();
11900                destval = dec_long(destval);
11901                store_data_long(destoffset, destval);
11902            }
11903            else {
11904                u16 destval;
11905
11906                destval = fetch_data_word(destoffset);
11907                TRACE_AND_STEP();
11908                destval = dec_word(destval);
11909                store_data_word(destoffset, destval);
11910            }
11911            break;
11912        case 2:                /* call word ptr ... */
11913            destval = fetch_data_word(destoffset);
11914            TRACE_AND_STEP();
11915            push_word(M.x86.R_IP);
11916            M.x86.R_IP = destval;
11917            break;
11918        case 3:                /* call far ptr ... */
11919            destval = fetch_data_word(destoffset);
11920            destval2 = fetch_data_word(destoffset + 2);
11921            TRACE_AND_STEP();
11922            push_word(M.x86.R_CS);
11923            M.x86.R_CS = destval2;
11924            push_word(M.x86.R_IP);
11925            M.x86.R_IP = destval;
11926            break;
11927        case 4:                /* jmp word ptr ... */
11928            destval = fetch_data_word(destoffset);
11929            TRACE_AND_STEP();
11930            M.x86.R_IP = destval;
11931            break;
11932        case 5:                /* jmp far ptr ... */
11933            destval = fetch_data_word(destoffset);
11934            destval2 = fetch_data_word(destoffset + 2);
11935            TRACE_AND_STEP();
11936            M.x86.R_IP = destval;
11937            M.x86.R_CS = destval2;
11938            break;
11939        case 6:                /*  push word ptr ... */
11940            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11941                u32 destval;
11942
11943                destval = fetch_data_long(destoffset);
11944                TRACE_AND_STEP();
11945                push_long(destval);
11946            }
11947            else {
11948                u16 destval;
11949
11950                destval = fetch_data_word(destoffset);
11951                TRACE_AND_STEP();
11952                push_word(destval);
11953            }
11954            break;
11955        }
11956        break;
11957    case 3:
11958        switch (rh) {
11959        case 0:
11960            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11961                u32 *destreg;
11962
11963                destreg = DECODE_RM_LONG_REGISTER(rl);
11964                DECODE_PRINTF("\n");
11965                TRACE_AND_STEP();
11966                *destreg = inc_long(*destreg);
11967            }
11968            else {
11969                u16 *destreg;
11970
11971                destreg = DECODE_RM_WORD_REGISTER(rl);
11972                DECODE_PRINTF("\n");
11973                TRACE_AND_STEP();
11974                *destreg = inc_word(*destreg);
11975            }
11976            break;
11977        case 1:
11978            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11979                u32 *destreg;
11980
11981                destreg = DECODE_RM_LONG_REGISTER(rl);
11982                DECODE_PRINTF("\n");
11983                TRACE_AND_STEP();
11984                *destreg = dec_long(*destreg);
11985            }
11986            else {
11987                u16 *destreg;
11988
11989                destreg = DECODE_RM_WORD_REGISTER(rl);
11990                DECODE_PRINTF("\n");
11991                TRACE_AND_STEP();
11992                *destreg = dec_word(*destreg);
11993            }
11994            break;
11995        case 2:                /* call word ptr ... */
11996            destreg = DECODE_RM_WORD_REGISTER(rl);
11997            DECODE_PRINTF("\n");
11998            TRACE_AND_STEP();
11999            push_word(M.x86.R_IP);
12000            M.x86.R_IP = *destreg;
12001            break;
12002        case 3:                /* jmp far ptr ... */
12003            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12004            TRACE_AND_STEP();
12005            HALT_SYS();
12006            break;
12007
12008        case 4:                /* jmp  ... */
12009            destreg = DECODE_RM_WORD_REGISTER(rl);
12010            DECODE_PRINTF("\n");
12011            TRACE_AND_STEP();
12012            M.x86.R_IP = (u16) (*destreg);
12013            break;
12014        case 5:                /* jmp far ptr ... */
12015            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12016            TRACE_AND_STEP();
12017            HALT_SYS();
12018            break;
12019        case 6:
12020            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12021                u32 *destreg;
12022
12023                destreg = DECODE_RM_LONG_REGISTER(rl);
12024                DECODE_PRINTF("\n");
12025                TRACE_AND_STEP();
12026                push_long(*destreg);
12027            }
12028            else {
12029                u16 *destreg;
12030
12031                destreg = DECODE_RM_WORD_REGISTER(rl);
12032                DECODE_PRINTF("\n");
12033                TRACE_AND_STEP();
12034                push_word(*destreg);
12035            }
12036            break;
12037        }
12038        break;
12039    }
12040    DECODE_CLEAR_SEGOVR();
12041    END_OF_INSTR();
12042}
12043
12044/***************************************************************************
12045 * Single byte operation code table:
12046 **************************************************************************/
12047void (*x86emu_optab[256]) (u8) = {
12048/*  0x00 */ x86emuOp_add_byte_RM_R,
12049/*  0x01 */ x86emuOp_add_word_RM_R,
12050/*  0x02 */ x86emuOp_add_byte_R_RM,
12051/*  0x03 */ x86emuOp_add_word_R_RM,
12052/*  0x04 */ x86emuOp_add_byte_AL_IMM,
12053/*  0x05 */ x86emuOp_add_word_AX_IMM,
12054/*  0x06 */ x86emuOp_push_ES,
12055/*  0x07 */ x86emuOp_pop_ES,
12056/*  0x08 */ x86emuOp_or_byte_RM_R,
12057/*  0x09 */ x86emuOp_or_word_RM_R,
12058/*  0x0a */ x86emuOp_or_byte_R_RM,
12059/*  0x0b */ x86emuOp_or_word_R_RM,
12060/*  0x0c */ x86emuOp_or_byte_AL_IMM,
12061/*  0x0d */ x86emuOp_or_word_AX_IMM,
12062/*  0x0e */ x86emuOp_push_CS,
12063/*  0x0f */ x86emuOp_two_byte,
12064/*  0x10 */ x86emuOp_adc_byte_RM_R,
12065/*  0x11 */ x86emuOp_adc_word_RM_R,
12066/*  0x12 */ x86emuOp_adc_byte_R_RM,
12067/*  0x13 */ x86emuOp_adc_word_R_RM,
12068/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
12069/*  0x15 */ x86emuOp_adc_word_AX_IMM,
12070/*  0x16 */ x86emuOp_push_SS,
12071/*  0x17 */ x86emuOp_pop_SS,
12072/*  0x18 */ x86emuOp_sbb_byte_RM_R,
12073/*  0x19 */ x86emuOp_sbb_word_RM_R,
12074/*  0x1a */ x86emuOp_sbb_byte_R_RM,
12075/*  0x1b */ x86emuOp_sbb_word_R_RM,
12076/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
12077/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
12078/*  0x1e */ x86emuOp_push_DS,
12079/*  0x1f */ x86emuOp_pop_DS,
12080/*  0x20 */ x86emuOp_and_byte_RM_R,
12081/*  0x21 */ x86emuOp_and_word_RM_R,
12082/*  0x22 */ x86emuOp_and_byte_R_RM,
12083/*  0x23 */ x86emuOp_and_word_R_RM,
12084/*  0x24 */ x86emuOp_and_byte_AL_IMM,
12085/*  0x25 */ x86emuOp_and_word_AX_IMM,
12086/*  0x26 */ x86emuOp_segovr_ES,
12087/*  0x27 */ x86emuOp_daa,
12088/*  0x28 */ x86emuOp_sub_byte_RM_R,
12089/*  0x29 */ x86emuOp_sub_word_RM_R,
12090/*  0x2a */ x86emuOp_sub_byte_R_RM,
12091/*  0x2b */ x86emuOp_sub_word_R_RM,
12092/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
12093/*  0x2d */ x86emuOp_sub_word_AX_IMM,
12094/*  0x2e */ x86emuOp_segovr_CS,
12095/*  0x2f */ x86emuOp_das,
12096/*  0x30 */ x86emuOp_xor_byte_RM_R,
12097/*  0x31 */ x86emuOp_xor_word_RM_R,
12098/*  0x32 */ x86emuOp_xor_byte_R_RM,
12099/*  0x33 */ x86emuOp_xor_word_R_RM,
12100/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
12101/*  0x35 */ x86emuOp_xor_word_AX_IMM,
12102/*  0x36 */ x86emuOp_segovr_SS,
12103/*  0x37 */ x86emuOp_aaa,
12104/*  0x38 */ x86emuOp_cmp_byte_RM_R,
12105/*  0x39 */ x86emuOp_cmp_word_RM_R,
12106/*  0x3a */ x86emuOp_cmp_byte_R_RM,
12107/*  0x3b */ x86emuOp_cmp_word_R_RM,
12108/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
12109/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
12110/*  0x3e */ x86emuOp_segovr_DS,
12111/*  0x3f */ x86emuOp_aas,
12112/*  0x40 */ x86emuOp_inc_AX,
12113/*  0x41 */ x86emuOp_inc_CX,
12114/*  0x42 */ x86emuOp_inc_DX,
12115/*  0x43 */ x86emuOp_inc_BX,
12116/*  0x44 */ x86emuOp_inc_SP,
12117/*  0x45 */ x86emuOp_inc_BP,
12118/*  0x46 */ x86emuOp_inc_SI,
12119/*  0x47 */ x86emuOp_inc_DI,
12120/*  0x48 */ x86emuOp_dec_AX,
12121/*  0x49 */ x86emuOp_dec_CX,
12122/*  0x4a */ x86emuOp_dec_DX,
12123/*  0x4b */ x86emuOp_dec_BX,
12124/*  0x4c */ x86emuOp_dec_SP,
12125/*  0x4d */ x86emuOp_dec_BP,
12126/*  0x4e */ x86emuOp_dec_SI,
12127/*  0x4f */ x86emuOp_dec_DI,
12128/*  0x50 */ x86emuOp_push_AX,
12129/*  0x51 */ x86emuOp_push_CX,
12130/*  0x52 */ x86emuOp_push_DX,
12131/*  0x53 */ x86emuOp_push_BX,
12132/*  0x54 */ x86emuOp_push_SP,
12133/*  0x55 */ x86emuOp_push_BP,
12134/*  0x56 */ x86emuOp_push_SI,
12135/*  0x57 */ x86emuOp_push_DI,
12136/*  0x58 */ x86emuOp_pop_AX,
12137/*  0x59 */ x86emuOp_pop_CX,
12138/*  0x5a */ x86emuOp_pop_DX,
12139/*  0x5b */ x86emuOp_pop_BX,
12140/*  0x5c */ x86emuOp_pop_SP,
12141/*  0x5d */ x86emuOp_pop_BP,
12142/*  0x5e */ x86emuOp_pop_SI,
12143/*  0x5f */ x86emuOp_pop_DI,
12144/*  0x60 */ x86emuOp_push_all,
12145/*  0x61 */ x86emuOp_pop_all,
12146                                                /*  0x62 */ x86emuOp_illegal_op,
12147                                                /* bound */
12148                                                /*  0x63 */ x86emuOp_illegal_op,
12149                                                /* arpl */
12150/*  0x64 */ x86emuOp_segovr_FS,
12151/*  0x65 */ x86emuOp_segovr_GS,
12152/*  0x66 */ x86emuOp_prefix_data,
12153/*  0x67 */ x86emuOp_prefix_addr,
12154/*  0x68 */ x86emuOp_push_word_IMM,
12155/*  0x69 */ x86emuOp_imul_word_IMM,
12156/*  0x6a */ x86emuOp_push_byte_IMM,
12157/*  0x6b */ x86emuOp_imul_byte_IMM,
12158/*  0x6c */ x86emuOp_ins_byte,
12159/*  0x6d */ x86emuOp_ins_word,
12160/*  0x6e */ x86emuOp_outs_byte,
12161/*  0x6f */ x86emuOp_outs_word,
12162/*  0x70 */ x86emuOp_jump_near_O,
12163/*  0x71 */ x86emuOp_jump_near_NO,
12164/*  0x72 */ x86emuOp_jump_near_B,
12165/*  0x73 */ x86emuOp_jump_near_NB,
12166/*  0x74 */ x86emuOp_jump_near_Z,
12167/*  0x75 */ x86emuOp_jump_near_NZ,
12168/*  0x76 */ x86emuOp_jump_near_BE,
12169/*  0x77 */ x86emuOp_jump_near_NBE,
12170/*  0x78 */ x86emuOp_jump_near_S,
12171/*  0x79 */ x86emuOp_jump_near_NS,
12172/*  0x7a */ x86emuOp_jump_near_P,
12173/*  0x7b */ x86emuOp_jump_near_NP,
12174/*  0x7c */ x86emuOp_jump_near_L,
12175/*  0x7d */ x86emuOp_jump_near_NL,
12176/*  0x7e */ x86emuOp_jump_near_LE,
12177/*  0x7f */ x86emuOp_jump_near_NLE,
12178/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
12179/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
12180/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
12181/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
12182/*  0x84 */ x86emuOp_test_byte_RM_R,
12183/*  0x85 */ x86emuOp_test_word_RM_R,
12184/*  0x86 */ x86emuOp_xchg_byte_RM_R,
12185/*  0x87 */ x86emuOp_xchg_word_RM_R,
12186/*  0x88 */ x86emuOp_mov_byte_RM_R,
12187/*  0x89 */ x86emuOp_mov_word_RM_R,
12188/*  0x8a */ x86emuOp_mov_byte_R_RM,
12189/*  0x8b */ x86emuOp_mov_word_R_RM,
12190/*  0x8c */ x86emuOp_mov_word_RM_SR,
12191/*  0x8d */ x86emuOp_lea_word_R_M,
12192/*  0x8e */ x86emuOp_mov_word_SR_RM,
12193/*  0x8f */ x86emuOp_pop_RM,
12194/*  0x90 */ x86emuOp_nop,
12195/*  0x91 */ x86emuOp_xchg_word_AX_CX,
12196/*  0x92 */ x86emuOp_xchg_word_AX_DX,
12197/*  0x93 */ x86emuOp_xchg_word_AX_BX,
12198/*  0x94 */ x86emuOp_xchg_word_AX_SP,
12199/*  0x95 */ x86emuOp_xchg_word_AX_BP,
12200/*  0x96 */ x86emuOp_xchg_word_AX_SI,
12201/*  0x97 */ x86emuOp_xchg_word_AX_DI,
12202/*  0x98 */ x86emuOp_cbw,
12203/*  0x99 */ x86emuOp_cwd,
12204/*  0x9a */ x86emuOp_call_far_IMM,
12205/*  0x9b */ x86emuOp_wait,
12206/*  0x9c */ x86emuOp_pushf_word,
12207/*  0x9d */ x86emuOp_popf_word,
12208/*  0x9e */ x86emuOp_sahf,
12209/*  0x9f */ x86emuOp_lahf,
12210/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
12211/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
12212/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
12213/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
12214/*  0xa4 */ x86emuOp_movs_byte,
12215/*  0xa5 */ x86emuOp_movs_word,
12216/*  0xa6 */ x86emuOp_cmps_byte,
12217/*  0xa7 */ x86emuOp_cmps_word,
12218/*  0xa8 */ x86emuOp_test_AL_IMM,
12219/*  0xa9 */ x86emuOp_test_AX_IMM,
12220/*  0xaa */ x86emuOp_stos_byte,
12221/*  0xab */ x86emuOp_stos_word,
12222/*  0xac */ x86emuOp_lods_byte,
12223/*  0xad */ x86emuOp_lods_word,
12224/*  0xac */ x86emuOp_scas_byte,
12225/*  0xad */ x86emuOp_scas_word,
12226/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
12227/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
12228/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
12229/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
12230/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
12231/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
12232/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
12233/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
12234/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
12235/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
12236/*  0xba */ x86emuOp_mov_word_DX_IMM,
12237/*  0xbb */ x86emuOp_mov_word_BX_IMM,
12238/*  0xbc */ x86emuOp_mov_word_SP_IMM,
12239/*  0xbd */ x86emuOp_mov_word_BP_IMM,
12240/*  0xbe */ x86emuOp_mov_word_SI_IMM,
12241/*  0xbf */ x86emuOp_mov_word_DI_IMM,
12242/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12243/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12244/*  0xc2 */ x86emuOp_ret_near_IMM,
12245/*  0xc3 */ x86emuOp_ret_near,
12246/*  0xc4 */ x86emuOp_les_R_IMM,
12247/*  0xc5 */ x86emuOp_lds_R_IMM,
12248/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
12249/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
12250/*  0xc8 */ x86emuOp_enter,
12251/*  0xc9 */ x86emuOp_leave,
12252/*  0xca */ x86emuOp_ret_far_IMM,
12253/*  0xcb */ x86emuOp_ret_far,
12254/*  0xcc */ x86emuOp_int3,
12255/*  0xcd */ x86emuOp_int_IMM,
12256/*  0xce */ x86emuOp_into,
12257/*  0xcf */ x86emuOp_iret,
12258/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
12259/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
12260/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12261/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
12262/*  0xd4 */ x86emuOp_aam,
12263/*  0xd5 */ x86emuOp_aad,
12264                                                /*  0xd6 */ x86emuOp_illegal_op,
12265                                                /* Undocumented SETALC instruction */
12266/*  0xd7 */ x86emuOp_xlat,
12267/*  0xd8 */ x86emuOp_esc_coprocess_d8,
12268/*  0xd9 */ x86emuOp_esc_coprocess_d9,
12269/*  0xda */ x86emuOp_esc_coprocess_da,
12270/*  0xdb */ x86emuOp_esc_coprocess_db,
12271/*  0xdc */ x86emuOp_esc_coprocess_dc,
12272/*  0xdd */ x86emuOp_esc_coprocess_dd,
12273/*  0xde */ x86emuOp_esc_coprocess_de,
12274/*  0xdf */ x86emuOp_esc_coprocess_df,
12275/*  0xe0 */ x86emuOp_loopne,
12276/*  0xe1 */ x86emuOp_loope,
12277/*  0xe2 */ x86emuOp_loop,
12278/*  0xe3 */ x86emuOp_jcxz,
12279/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
12280/*  0xe5 */ x86emuOp_in_word_AX_IMM,
12281/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
12282/*  0xe7 */ x86emuOp_out_word_IMM_AX,
12283/*  0xe8 */ x86emuOp_call_near_IMM,
12284/*  0xe9 */ x86emuOp_jump_near_IMM,
12285/*  0xea */ x86emuOp_jump_far_IMM,
12286/*  0xeb */ x86emuOp_jump_byte_IMM,
12287/*  0xec */ x86emuOp_in_byte_AL_DX,
12288/*  0xed */ x86emuOp_in_word_AX_DX,
12289/*  0xee */ x86emuOp_out_byte_DX_AL,
12290/*  0xef */ x86emuOp_out_word_DX_AX,
12291/*  0xf0 */ x86emuOp_lock,
12292/*  0xf1 */ x86emuOp_illegal_op,
12293/*  0xf2 */ x86emuOp_repne,
12294/*  0xf3 */ x86emuOp_repe,
12295/*  0xf4 */ x86emuOp_halt,
12296/*  0xf5 */ x86emuOp_cmc,
12297/*  0xf6 */ x86emuOp_opcF6_byte_RM,
12298/*  0xf7 */ x86emuOp_opcF7_word_RM,
12299/*  0xf8 */ x86emuOp_clc,
12300/*  0xf9 */ x86emuOp_stc,
12301/*  0xfa */ x86emuOp_cli,
12302/*  0xfb */ x86emuOp_sti,
12303/*  0xfc */ x86emuOp_cld,
12304/*  0xfd */ x86emuOp_std,
12305/*  0xfe */ x86emuOp_opcFE_byte_RM,
12306/*  0xff */ x86emuOp_opcFF_word_RM,
12307};
12308