1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
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.
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.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 processor instructions.
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].
42 * Each opcode proc has a comment preceeding it which gives it's table
43 * address. Several opcodes are missing (undefined) in the table.
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).
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.
71 ****************************************************************************/
73 /* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */
75 #include "x86emu/x86emui.h"
76 #include "x86emu/ops_protos.h"
77 #include "lib_printf.h"
79 /*----------------------------- Implementation ----------------------------*/
81 /****************************************************************************
83 op1 - Instruction op code
86 Handles illegal opcodes.
87 ****************************************************************************/
88 void x86emuOp_illegal_op(
92 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
94 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
95 M
.x86
.R_CS
, M
.x86
.R_IP
-1,op1
);
100 /****************************************************************************
103 ****************************************************************************/
104 void x86emuOp_add_byte_RM_R(u8
X86EMU_UNUSED(op1
))
108 u8
*destreg
, *srcreg
;
112 DECODE_PRINTF("ADD\t");
113 FETCH_DECODE_MODRM(mod
, rh
, rl
);
116 destoffset
= decode_rm00_address(rl
);
118 destval
= fetch_data_byte(destoffset
);
119 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
122 destval
= add_byte(destval
, *srcreg
);
123 store_data_byte(destoffset
, destval
);
126 destoffset
= decode_rm01_address(rl
);
128 destval
= fetch_data_byte(destoffset
);
129 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
132 destval
= add_byte(destval
, *srcreg
);
133 store_data_byte(destoffset
, destval
);
136 destoffset
= decode_rm10_address(rl
);
138 destval
= fetch_data_byte(destoffset
);
139 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
142 destval
= add_byte(destval
, *srcreg
);
143 store_data_byte(destoffset
, destval
);
145 case 3: /* register to register */
146 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
148 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
151 *destreg
= add_byte(*destreg
, *srcreg
);
154 DECODE_CLEAR_SEGOVR();
158 /****************************************************************************
161 ****************************************************************************/
162 void x86emuOp_add_word_RM_R(u8
X86EMU_UNUSED(op1
))
168 DECODE_PRINTF("ADD\t");
169 FETCH_DECODE_MODRM(mod
, rh
, rl
);
172 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
176 destoffset
= decode_rm00_address(rl
);
178 destval
= fetch_data_long(destoffset
);
179 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
182 destval
= add_long(destval
, *srcreg
);
183 store_data_long(destoffset
, destval
);
188 destoffset
= decode_rm00_address(rl
);
190 destval
= fetch_data_word(destoffset
);
191 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
194 destval
= add_word(destval
, *srcreg
);
195 store_data_word(destoffset
, destval
);
199 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
203 destoffset
= decode_rm01_address(rl
);
205 destval
= fetch_data_long(destoffset
);
206 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
209 destval
= add_long(destval
, *srcreg
);
210 store_data_long(destoffset
, destval
);
215 destoffset
= decode_rm01_address(rl
);
217 destval
= fetch_data_word(destoffset
);
218 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
221 destval
= add_word(destval
, *srcreg
);
222 store_data_word(destoffset
, destval
);
226 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
230 destoffset
= decode_rm10_address(rl
);
232 destval
= fetch_data_long(destoffset
);
233 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
236 destval
= add_long(destval
, *srcreg
);
237 store_data_long(destoffset
, destval
);
242 destoffset
= decode_rm10_address(rl
);
244 destval
= fetch_data_word(destoffset
);
245 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
248 destval
= add_word(destval
, *srcreg
);
249 store_data_word(destoffset
, destval
);
252 case 3: /* register to register */
253 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
254 u32
*destreg
,*srcreg
;
256 destreg
= DECODE_RM_LONG_REGISTER(rl
);
258 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
261 *destreg
= add_long(*destreg
, *srcreg
);
263 u16
*destreg
,*srcreg
;
265 destreg
= DECODE_RM_WORD_REGISTER(rl
);
267 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
270 *destreg
= add_word(*destreg
, *srcreg
);
274 DECODE_CLEAR_SEGOVR();
278 /****************************************************************************
281 ****************************************************************************/
282 void x86emuOp_add_byte_R_RM(u8
X86EMU_UNUSED(op1
))
285 u8
*destreg
, *srcreg
;
290 DECODE_PRINTF("ADD\t");
291 FETCH_DECODE_MODRM(mod
, rh
, rl
);
294 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
296 srcoffset
= decode_rm00_address(rl
);
297 srcval
= fetch_data_byte(srcoffset
);
300 *destreg
= add_byte(*destreg
, srcval
);
303 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
305 srcoffset
= decode_rm01_address(rl
);
306 srcval
= fetch_data_byte(srcoffset
);
309 *destreg
= add_byte(*destreg
, srcval
);
312 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
314 srcoffset
= decode_rm10_address(rl
);
315 srcval
= fetch_data_byte(srcoffset
);
318 *destreg
= add_byte(*destreg
, srcval
);
320 case 3: /* register to register */
321 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
323 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
326 *destreg
= add_byte(*destreg
, *srcreg
);
329 DECODE_CLEAR_SEGOVR();
333 /****************************************************************************
336 ****************************************************************************/
337 void x86emuOp_add_word_R_RM(u8
X86EMU_UNUSED(op1
))
343 DECODE_PRINTF("ADD\t");
344 FETCH_DECODE_MODRM(mod
, rh
, rl
);
347 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
351 destreg
= DECODE_RM_LONG_REGISTER(rh
);
353 srcoffset
= decode_rm00_address(rl
);
354 srcval
= fetch_data_long(srcoffset
);
357 *destreg
= add_long(*destreg
, srcval
);
362 destreg
= DECODE_RM_WORD_REGISTER(rh
);
364 srcoffset
= decode_rm00_address(rl
);
365 srcval
= fetch_data_word(srcoffset
);
368 *destreg
= add_word(*destreg
, srcval
);
372 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
376 destreg
= DECODE_RM_LONG_REGISTER(rh
);
378 srcoffset
= decode_rm01_address(rl
);
379 srcval
= fetch_data_long(srcoffset
);
382 *destreg
= add_long(*destreg
, srcval
);
387 destreg
= DECODE_RM_WORD_REGISTER(rh
);
389 srcoffset
= decode_rm01_address(rl
);
390 srcval
= fetch_data_word(srcoffset
);
393 *destreg
= add_word(*destreg
, srcval
);
397 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
401 destreg
= DECODE_RM_LONG_REGISTER(rh
);
403 srcoffset
= decode_rm10_address(rl
);
404 srcval
= fetch_data_long(srcoffset
);
407 *destreg
= add_long(*destreg
, srcval
);
412 destreg
= DECODE_RM_WORD_REGISTER(rh
);
414 srcoffset
= decode_rm10_address(rl
);
415 srcval
= fetch_data_word(srcoffset
);
418 *destreg
= add_word(*destreg
, srcval
);
421 case 3: /* register to register */
422 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
423 u32
*destreg
,*srcreg
;
425 destreg
= DECODE_RM_LONG_REGISTER(rh
);
427 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
430 *destreg
= add_long(*destreg
, *srcreg
);
432 u16
*destreg
,*srcreg
;
434 destreg
= DECODE_RM_WORD_REGISTER(rh
);
436 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
439 *destreg
= add_word(*destreg
, *srcreg
);
443 DECODE_CLEAR_SEGOVR();
447 /****************************************************************************
450 ****************************************************************************/
451 void x86emuOp_add_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
456 DECODE_PRINTF("ADD\tAL,");
457 srcval
= fetch_byte_imm();
458 DECODE_PRINTF2("%x\n", srcval
);
460 M
.x86
.R_AL
= add_byte(M
.x86
.R_AL
, srcval
);
461 DECODE_CLEAR_SEGOVR();
465 /****************************************************************************
468 ****************************************************************************/
469 void x86emuOp_add_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
474 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
475 DECODE_PRINTF("ADD\tEAX,");
476 srcval
= fetch_long_imm();
478 DECODE_PRINTF("ADD\tAX,");
479 srcval
= fetch_word_imm();
481 DECODE_PRINTF2("%x\n", srcval
);
483 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
484 M
.x86
.R_EAX
= add_long(M
.x86
.R_EAX
, srcval
);
486 M
.x86
.R_AX
= add_word(M
.x86
.R_AX
, (u16
)srcval
);
488 DECODE_CLEAR_SEGOVR();
492 /****************************************************************************
495 ****************************************************************************/
496 void x86emuOp_push_ES(u8
X86EMU_UNUSED(op1
))
499 DECODE_PRINTF("PUSH\tES\n");
501 push_word(M
.x86
.R_ES
);
502 DECODE_CLEAR_SEGOVR();
506 /****************************************************************************
509 ****************************************************************************/
510 void x86emuOp_pop_ES(u8
X86EMU_UNUSED(op1
))
513 DECODE_PRINTF("POP\tES\n");
515 M
.x86
.R_ES
= pop_word();
516 DECODE_CLEAR_SEGOVR();
520 /****************************************************************************
523 ****************************************************************************/
524 void x86emuOp_or_byte_RM_R(u8
X86EMU_UNUSED(op1
))
527 u8
*destreg
, *srcreg
;
532 DECODE_PRINTF("OR\t");
533 FETCH_DECODE_MODRM(mod
, rh
, rl
);
536 destoffset
= decode_rm00_address(rl
);
538 destval
= fetch_data_byte(destoffset
);
539 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
542 destval
= or_byte(destval
, *srcreg
);
543 store_data_byte(destoffset
, destval
);
546 destoffset
= decode_rm01_address(rl
);
548 destval
= fetch_data_byte(destoffset
);
549 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
552 destval
= or_byte(destval
, *srcreg
);
553 store_data_byte(destoffset
, destval
);
556 destoffset
= decode_rm10_address(rl
);
558 destval
= fetch_data_byte(destoffset
);
559 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
562 destval
= or_byte(destval
, *srcreg
);
563 store_data_byte(destoffset
, destval
);
565 case 3: /* register to register */
566 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
568 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
571 *destreg
= or_byte(*destreg
, *srcreg
);
574 DECODE_CLEAR_SEGOVR();
578 /****************************************************************************
581 ****************************************************************************/
582 void x86emuOp_or_word_RM_R(u8
X86EMU_UNUSED(op1
))
588 DECODE_PRINTF("OR\t");
589 FETCH_DECODE_MODRM(mod
, rh
, rl
);
592 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
596 destoffset
= decode_rm00_address(rl
);
598 destval
= fetch_data_long(destoffset
);
599 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
602 destval
= or_long(destval
, *srcreg
);
603 store_data_long(destoffset
, destval
);
608 destoffset
= decode_rm00_address(rl
);
610 destval
= fetch_data_word(destoffset
);
611 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
614 destval
= or_word(destval
, *srcreg
);
615 store_data_word(destoffset
, destval
);
619 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
623 destoffset
= decode_rm01_address(rl
);
625 destval
= fetch_data_long(destoffset
);
626 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
629 destval
= or_long(destval
, *srcreg
);
630 store_data_long(destoffset
, destval
);
635 destoffset
= decode_rm01_address(rl
);
637 destval
= fetch_data_word(destoffset
);
638 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
641 destval
= or_word(destval
, *srcreg
);
642 store_data_word(destoffset
, destval
);
646 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
650 destoffset
= decode_rm10_address(rl
);
652 destval
= fetch_data_long(destoffset
);
653 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
656 destval
= or_long(destval
, *srcreg
);
657 store_data_long(destoffset
, destval
);
662 destoffset
= decode_rm10_address(rl
);
664 destval
= fetch_data_word(destoffset
);
665 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
668 destval
= or_word(destval
, *srcreg
);
669 store_data_word(destoffset
, destval
);
672 case 3: /* register to register */
673 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
674 u32
*destreg
,*srcreg
;
676 destreg
= DECODE_RM_LONG_REGISTER(rl
);
678 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
681 *destreg
= or_long(*destreg
, *srcreg
);
683 u16
*destreg
,*srcreg
;
685 destreg
= DECODE_RM_WORD_REGISTER(rl
);
687 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
690 *destreg
= or_word(*destreg
, *srcreg
);
694 DECODE_CLEAR_SEGOVR();
698 /****************************************************************************
701 ****************************************************************************/
702 void x86emuOp_or_byte_R_RM(u8
X86EMU_UNUSED(op1
))
705 u8
*destreg
, *srcreg
;
710 DECODE_PRINTF("OR\t");
711 FETCH_DECODE_MODRM(mod
, rh
, rl
);
714 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
716 srcoffset
= decode_rm00_address(rl
);
717 srcval
= fetch_data_byte(srcoffset
);
720 *destreg
= or_byte(*destreg
, srcval
);
723 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
725 srcoffset
= decode_rm01_address(rl
);
726 srcval
= fetch_data_byte(srcoffset
);
729 *destreg
= or_byte(*destreg
, srcval
);
732 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
734 srcoffset
= decode_rm10_address(rl
);
735 srcval
= fetch_data_byte(srcoffset
);
738 *destreg
= or_byte(*destreg
, srcval
);
740 case 3: /* register to register */
741 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
743 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
746 *destreg
= or_byte(*destreg
, *srcreg
);
749 DECODE_CLEAR_SEGOVR();
753 /****************************************************************************
756 ****************************************************************************/
757 void x86emuOp_or_word_R_RM(u8
X86EMU_UNUSED(op1
))
763 DECODE_PRINTF("OR\t");
764 FETCH_DECODE_MODRM(mod
, rh
, rl
);
767 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
771 destreg
= DECODE_RM_LONG_REGISTER(rh
);
773 srcoffset
= decode_rm00_address(rl
);
774 srcval
= fetch_data_long(srcoffset
);
777 *destreg
= or_long(*destreg
, srcval
);
782 destreg
= DECODE_RM_WORD_REGISTER(rh
);
784 srcoffset
= decode_rm00_address(rl
);
785 srcval
= fetch_data_word(srcoffset
);
788 *destreg
= or_word(*destreg
, srcval
);
792 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
796 destreg
= DECODE_RM_LONG_REGISTER(rh
);
798 srcoffset
= decode_rm01_address(rl
);
799 srcval
= fetch_data_long(srcoffset
);
802 *destreg
= or_long(*destreg
, srcval
);
807 destreg
= DECODE_RM_WORD_REGISTER(rh
);
809 srcoffset
= decode_rm01_address(rl
);
810 srcval
= fetch_data_word(srcoffset
);
813 *destreg
= or_word(*destreg
, srcval
);
817 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
821 destreg
= DECODE_RM_LONG_REGISTER(rh
);
823 srcoffset
= decode_rm10_address(rl
);
824 srcval
= fetch_data_long(srcoffset
);
827 *destreg
= or_long(*destreg
, srcval
);
832 destreg
= DECODE_RM_WORD_REGISTER(rh
);
834 srcoffset
= decode_rm10_address(rl
);
835 srcval
= fetch_data_word(srcoffset
);
838 *destreg
= or_word(*destreg
, srcval
);
841 case 3: /* register to register */
842 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
843 u32
*destreg
,*srcreg
;
845 destreg
= DECODE_RM_LONG_REGISTER(rh
);
847 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
850 *destreg
= or_long(*destreg
, *srcreg
);
852 u16
*destreg
,*srcreg
;
854 destreg
= DECODE_RM_WORD_REGISTER(rh
);
856 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
859 *destreg
= or_word(*destreg
, *srcreg
);
863 DECODE_CLEAR_SEGOVR();
867 /****************************************************************************
870 ****************************************************************************/
871 void x86emuOp_or_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
876 DECODE_PRINTF("OR\tAL,");
877 srcval
= fetch_byte_imm();
878 DECODE_PRINTF2("%x\n", srcval
);
880 M
.x86
.R_AL
= or_byte(M
.x86
.R_AL
, srcval
);
881 DECODE_CLEAR_SEGOVR();
885 /****************************************************************************
888 ****************************************************************************/
889 void x86emuOp_or_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
894 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
895 DECODE_PRINTF("OR\tEAX,");
896 srcval
= fetch_long_imm();
898 DECODE_PRINTF("OR\tAX,");
899 srcval
= fetch_word_imm();
901 DECODE_PRINTF2("%x\n", srcval
);
903 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
904 M
.x86
.R_EAX
= or_long(M
.x86
.R_EAX
, srcval
);
906 M
.x86
.R_AX
= or_word(M
.x86
.R_AX
, (u16
)srcval
);
908 DECODE_CLEAR_SEGOVR();
912 /****************************************************************************
915 ****************************************************************************/
916 void x86emuOp_push_CS(u8
X86EMU_UNUSED(op1
))
919 DECODE_PRINTF("PUSH\tCS\n");
921 push_word(M
.x86
.R_CS
);
922 DECODE_CLEAR_SEGOVR();
926 /****************************************************************************
928 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
929 ****************************************************************************/
930 void x86emuOp_two_byte(u8
X86EMU_UNUSED(op1
))
932 u8 op2
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
933 INC_DECODED_INST_LEN(1);
934 (*x86emu_optab2
[op2
])(op2
);
937 /****************************************************************************
940 ****************************************************************************/
941 void x86emuOp_adc_byte_RM_R(u8
X86EMU_UNUSED(op1
))
944 u8
*destreg
, *srcreg
;
949 DECODE_PRINTF("ADC\t");
950 FETCH_DECODE_MODRM(mod
, rh
, rl
);
953 destoffset
= decode_rm00_address(rl
);
955 destval
= fetch_data_byte(destoffset
);
956 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
959 destval
= adc_byte(destval
, *srcreg
);
960 store_data_byte(destoffset
, destval
);
963 destoffset
= decode_rm01_address(rl
);
965 destval
= fetch_data_byte(destoffset
);
966 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
969 destval
= adc_byte(destval
, *srcreg
);
970 store_data_byte(destoffset
, destval
);
973 destoffset
= decode_rm10_address(rl
);
975 destval
= fetch_data_byte(destoffset
);
976 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
979 destval
= adc_byte(destval
, *srcreg
);
980 store_data_byte(destoffset
, destval
);
982 case 3: /* register to register */
983 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
985 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
988 *destreg
= adc_byte(*destreg
, *srcreg
);
991 DECODE_CLEAR_SEGOVR();
995 /****************************************************************************
998 ****************************************************************************/
999 void x86emuOp_adc_word_RM_R(u8
X86EMU_UNUSED(op1
))
1005 DECODE_PRINTF("ADC\t");
1006 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1009 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1013 destoffset
= decode_rm00_address(rl
);
1015 destval
= fetch_data_long(destoffset
);
1016 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1017 DECODE_PRINTF("\n");
1019 destval
= adc_long(destval
, *srcreg
);
1020 store_data_long(destoffset
, destval
);
1025 destoffset
= decode_rm00_address(rl
);
1027 destval
= fetch_data_word(destoffset
);
1028 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1029 DECODE_PRINTF("\n");
1031 destval
= adc_word(destval
, *srcreg
);
1032 store_data_word(destoffset
, destval
);
1036 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1040 destoffset
= decode_rm01_address(rl
);
1042 destval
= fetch_data_long(destoffset
);
1043 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1044 DECODE_PRINTF("\n");
1046 destval
= adc_long(destval
, *srcreg
);
1047 store_data_long(destoffset
, destval
);
1052 destoffset
= decode_rm01_address(rl
);
1054 destval
= fetch_data_word(destoffset
);
1055 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1056 DECODE_PRINTF("\n");
1058 destval
= adc_word(destval
, *srcreg
);
1059 store_data_word(destoffset
, destval
);
1063 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1067 destoffset
= decode_rm10_address(rl
);
1069 destval
= fetch_data_long(destoffset
);
1070 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1071 DECODE_PRINTF("\n");
1073 destval
= adc_long(destval
, *srcreg
);
1074 store_data_long(destoffset
, destval
);
1079 destoffset
= decode_rm10_address(rl
);
1081 destval
= fetch_data_word(destoffset
);
1082 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1083 DECODE_PRINTF("\n");
1085 destval
= adc_word(destval
, *srcreg
);
1086 store_data_word(destoffset
, destval
);
1089 case 3: /* register to register */
1090 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1091 u32
*destreg
,*srcreg
;
1093 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1095 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1096 DECODE_PRINTF("\n");
1098 *destreg
= adc_long(*destreg
, *srcreg
);
1100 u16
*destreg
,*srcreg
;
1102 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1104 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1105 DECODE_PRINTF("\n");
1107 *destreg
= adc_word(*destreg
, *srcreg
);
1111 DECODE_CLEAR_SEGOVR();
1115 /****************************************************************************
1118 ****************************************************************************/
1119 void x86emuOp_adc_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1122 u8
*destreg
, *srcreg
;
1127 DECODE_PRINTF("ADC\t");
1128 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1131 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1133 srcoffset
= decode_rm00_address(rl
);
1134 srcval
= fetch_data_byte(srcoffset
);
1135 DECODE_PRINTF("\n");
1137 *destreg
= adc_byte(*destreg
, srcval
);
1140 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1142 srcoffset
= decode_rm01_address(rl
);
1143 srcval
= fetch_data_byte(srcoffset
);
1144 DECODE_PRINTF("\n");
1146 *destreg
= adc_byte(*destreg
, srcval
);
1149 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1151 srcoffset
= decode_rm10_address(rl
);
1152 srcval
= fetch_data_byte(srcoffset
);
1153 DECODE_PRINTF("\n");
1155 *destreg
= adc_byte(*destreg
, srcval
);
1157 case 3: /* register to register */
1158 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1160 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1161 DECODE_PRINTF("\n");
1163 *destreg
= adc_byte(*destreg
, *srcreg
);
1166 DECODE_CLEAR_SEGOVR();
1170 /****************************************************************************
1173 ****************************************************************************/
1174 void x86emuOp_adc_word_R_RM(u8
X86EMU_UNUSED(op1
))
1180 DECODE_PRINTF("ADC\t");
1181 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1184 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1188 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1190 srcoffset
= decode_rm00_address(rl
);
1191 srcval
= fetch_data_long(srcoffset
);
1192 DECODE_PRINTF("\n");
1194 *destreg
= adc_long(*destreg
, srcval
);
1199 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1201 srcoffset
= decode_rm00_address(rl
);
1202 srcval
= fetch_data_word(srcoffset
);
1203 DECODE_PRINTF("\n");
1205 *destreg
= adc_word(*destreg
, srcval
);
1209 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1213 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1215 srcoffset
= decode_rm01_address(rl
);
1216 srcval
= fetch_data_long(srcoffset
);
1217 DECODE_PRINTF("\n");
1219 *destreg
= adc_long(*destreg
, srcval
);
1224 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1226 srcoffset
= decode_rm01_address(rl
);
1227 srcval
= fetch_data_word(srcoffset
);
1228 DECODE_PRINTF("\n");
1230 *destreg
= adc_word(*destreg
, srcval
);
1234 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1238 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1240 srcoffset
= decode_rm10_address(rl
);
1241 srcval
= fetch_data_long(srcoffset
);
1242 DECODE_PRINTF("\n");
1244 *destreg
= adc_long(*destreg
, srcval
);
1249 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1251 srcoffset
= decode_rm10_address(rl
);
1252 srcval
= fetch_data_word(srcoffset
);
1253 DECODE_PRINTF("\n");
1255 *destreg
= adc_word(*destreg
, srcval
);
1258 case 3: /* register to register */
1259 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1260 u32
*destreg
,*srcreg
;
1262 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1264 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1265 DECODE_PRINTF("\n");
1267 *destreg
= adc_long(*destreg
, *srcreg
);
1269 u16
*destreg
,*srcreg
;
1271 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1273 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1274 DECODE_PRINTF("\n");
1276 *destreg
= adc_word(*destreg
, *srcreg
);
1280 DECODE_CLEAR_SEGOVR();
1284 /****************************************************************************
1287 ****************************************************************************/
1288 void x86emuOp_adc_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
1293 DECODE_PRINTF("ADC\tAL,");
1294 srcval
= fetch_byte_imm();
1295 DECODE_PRINTF2("%x\n", srcval
);
1297 M
.x86
.R_AL
= adc_byte(M
.x86
.R_AL
, srcval
);
1298 DECODE_CLEAR_SEGOVR();
1302 /****************************************************************************
1305 ****************************************************************************/
1306 void x86emuOp_adc_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
1311 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1312 DECODE_PRINTF("ADC\tEAX,");
1313 srcval
= fetch_long_imm();
1315 DECODE_PRINTF("ADC\tAX,");
1316 srcval
= fetch_word_imm();
1318 DECODE_PRINTF2("%x\n", srcval
);
1320 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1321 M
.x86
.R_EAX
= adc_long(M
.x86
.R_EAX
, srcval
);
1323 M
.x86
.R_AX
= adc_word(M
.x86
.R_AX
, (u16
)srcval
);
1325 DECODE_CLEAR_SEGOVR();
1329 /****************************************************************************
1332 ****************************************************************************/
1333 void x86emuOp_push_SS(u8
X86EMU_UNUSED(op1
))
1336 DECODE_PRINTF("PUSH\tSS\n");
1338 push_word(M
.x86
.R_SS
);
1339 DECODE_CLEAR_SEGOVR();
1343 /****************************************************************************
1346 ****************************************************************************/
1347 void x86emuOp_pop_SS(u8
X86EMU_UNUSED(op1
))
1350 DECODE_PRINTF("POP\tSS\n");
1352 M
.x86
.R_SS
= pop_word();
1353 DECODE_CLEAR_SEGOVR();
1357 /****************************************************************************
1360 ****************************************************************************/
1361 void x86emuOp_sbb_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1364 u8
*destreg
, *srcreg
;
1369 DECODE_PRINTF("SBB\t");
1370 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1373 destoffset
= decode_rm00_address(rl
);
1375 destval
= fetch_data_byte(destoffset
);
1376 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1377 DECODE_PRINTF("\n");
1379 destval
= sbb_byte(destval
, *srcreg
);
1380 store_data_byte(destoffset
, destval
);
1383 destoffset
= decode_rm01_address(rl
);
1385 destval
= fetch_data_byte(destoffset
);
1386 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1387 DECODE_PRINTF("\n");
1389 destval
= sbb_byte(destval
, *srcreg
);
1390 store_data_byte(destoffset
, destval
);
1393 destoffset
= decode_rm10_address(rl
);
1395 destval
= fetch_data_byte(destoffset
);
1396 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1397 DECODE_PRINTF("\n");
1399 destval
= sbb_byte(destval
, *srcreg
);
1400 store_data_byte(destoffset
, destval
);
1402 case 3: /* register to register */
1403 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1405 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1406 DECODE_PRINTF("\n");
1408 *destreg
= sbb_byte(*destreg
, *srcreg
);
1411 DECODE_CLEAR_SEGOVR();
1415 /****************************************************************************
1418 ****************************************************************************/
1419 void x86emuOp_sbb_word_RM_R(u8
X86EMU_UNUSED(op1
))
1425 DECODE_PRINTF("SBB\t");
1426 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1429 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1433 destoffset
= decode_rm00_address(rl
);
1435 destval
= fetch_data_long(destoffset
);
1436 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1437 DECODE_PRINTF("\n");
1439 destval
= sbb_long(destval
, *srcreg
);
1440 store_data_long(destoffset
, destval
);
1445 destoffset
= decode_rm00_address(rl
);
1447 destval
= fetch_data_word(destoffset
);
1448 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1449 DECODE_PRINTF("\n");
1451 destval
= sbb_word(destval
, *srcreg
);
1452 store_data_word(destoffset
, destval
);
1456 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1460 destoffset
= decode_rm01_address(rl
);
1462 destval
= fetch_data_long(destoffset
);
1463 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1464 DECODE_PRINTF("\n");
1466 destval
= sbb_long(destval
, *srcreg
);
1467 store_data_long(destoffset
, destval
);
1472 destoffset
= decode_rm01_address(rl
);
1474 destval
= fetch_data_word(destoffset
);
1475 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1476 DECODE_PRINTF("\n");
1478 destval
= sbb_word(destval
, *srcreg
);
1479 store_data_word(destoffset
, destval
);
1483 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1487 destoffset
= decode_rm10_address(rl
);
1489 destval
= fetch_data_long(destoffset
);
1490 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1491 DECODE_PRINTF("\n");
1493 destval
= sbb_long(destval
, *srcreg
);
1494 store_data_long(destoffset
, destval
);
1499 destoffset
= decode_rm10_address(rl
);
1501 destval
= fetch_data_word(destoffset
);
1502 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1503 DECODE_PRINTF("\n");
1505 destval
= sbb_word(destval
, *srcreg
);
1506 store_data_word(destoffset
, destval
);
1509 case 3: /* register to register */
1510 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1511 u32
*destreg
,*srcreg
;
1513 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1515 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1516 DECODE_PRINTF("\n");
1518 *destreg
= sbb_long(*destreg
, *srcreg
);
1520 u16
*destreg
,*srcreg
;
1522 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1524 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1525 DECODE_PRINTF("\n");
1527 *destreg
= sbb_word(*destreg
, *srcreg
);
1531 DECODE_CLEAR_SEGOVR();
1535 /****************************************************************************
1538 ****************************************************************************/
1539 void x86emuOp_sbb_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1542 u8
*destreg
, *srcreg
;
1547 DECODE_PRINTF("SBB\t");
1548 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1551 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1553 srcoffset
= decode_rm00_address(rl
);
1554 srcval
= fetch_data_byte(srcoffset
);
1555 DECODE_PRINTF("\n");
1557 *destreg
= sbb_byte(*destreg
, srcval
);
1560 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1562 srcoffset
= decode_rm01_address(rl
);
1563 srcval
= fetch_data_byte(srcoffset
);
1564 DECODE_PRINTF("\n");
1566 *destreg
= sbb_byte(*destreg
, srcval
);
1569 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1571 srcoffset
= decode_rm10_address(rl
);
1572 srcval
= fetch_data_byte(srcoffset
);
1573 DECODE_PRINTF("\n");
1575 *destreg
= sbb_byte(*destreg
, srcval
);
1577 case 3: /* register to register */
1578 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1580 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1581 DECODE_PRINTF("\n");
1583 *destreg
= sbb_byte(*destreg
, *srcreg
);
1586 DECODE_CLEAR_SEGOVR();
1590 /****************************************************************************
1593 ****************************************************************************/
1594 void x86emuOp_sbb_word_R_RM(u8
X86EMU_UNUSED(op1
))
1600 DECODE_PRINTF("SBB\t");
1601 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1604 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1608 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1610 srcoffset
= decode_rm00_address(rl
);
1611 srcval
= fetch_data_long(srcoffset
);
1612 DECODE_PRINTF("\n");
1614 *destreg
= sbb_long(*destreg
, srcval
);
1619 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1621 srcoffset
= decode_rm00_address(rl
);
1622 srcval
= fetch_data_word(srcoffset
);
1623 DECODE_PRINTF("\n");
1625 *destreg
= sbb_word(*destreg
, srcval
);
1629 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1633 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1635 srcoffset
= decode_rm01_address(rl
);
1636 srcval
= fetch_data_long(srcoffset
);
1637 DECODE_PRINTF("\n");
1639 *destreg
= sbb_long(*destreg
, srcval
);
1644 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1646 srcoffset
= decode_rm01_address(rl
);
1647 srcval
= fetch_data_word(srcoffset
);
1648 DECODE_PRINTF("\n");
1650 *destreg
= sbb_word(*destreg
, srcval
);
1654 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1658 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1660 srcoffset
= decode_rm10_address(rl
);
1661 srcval
= fetch_data_long(srcoffset
);
1662 DECODE_PRINTF("\n");
1664 *destreg
= sbb_long(*destreg
, srcval
);
1669 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1671 srcoffset
= decode_rm10_address(rl
);
1672 srcval
= fetch_data_word(srcoffset
);
1673 DECODE_PRINTF("\n");
1675 *destreg
= sbb_word(*destreg
, srcval
);
1678 case 3: /* register to register */
1679 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1680 u32
*destreg
,*srcreg
;
1682 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1684 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1685 DECODE_PRINTF("\n");
1687 *destreg
= sbb_long(*destreg
, *srcreg
);
1689 u16
*destreg
,*srcreg
;
1691 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1693 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1694 DECODE_PRINTF("\n");
1696 *destreg
= sbb_word(*destreg
, *srcreg
);
1700 DECODE_CLEAR_SEGOVR();
1704 /****************************************************************************
1707 ****************************************************************************/
1708 void x86emuOp_sbb_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
1713 DECODE_PRINTF("SBB\tAL,");
1714 srcval
= fetch_byte_imm();
1715 DECODE_PRINTF2("%x\n", srcval
);
1717 M
.x86
.R_AL
= sbb_byte(M
.x86
.R_AL
, srcval
);
1718 DECODE_CLEAR_SEGOVR();
1722 /****************************************************************************
1725 ****************************************************************************/
1726 void x86emuOp_sbb_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
1731 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1732 DECODE_PRINTF("SBB\tEAX,");
1733 srcval
= fetch_long_imm();
1735 DECODE_PRINTF("SBB\tAX,");
1736 srcval
= fetch_word_imm();
1738 DECODE_PRINTF2("%x\n", srcval
);
1740 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1741 M
.x86
.R_EAX
= sbb_long(M
.x86
.R_EAX
, srcval
);
1743 M
.x86
.R_AX
= sbb_word(M
.x86
.R_AX
, (u16
)srcval
);
1745 DECODE_CLEAR_SEGOVR();
1749 /****************************************************************************
1752 ****************************************************************************/
1753 void x86emuOp_push_DS(u8
X86EMU_UNUSED(op1
))
1756 DECODE_PRINTF("PUSH\tDS\n");
1758 push_word(M
.x86
.R_DS
);
1759 DECODE_CLEAR_SEGOVR();
1763 /****************************************************************************
1766 ****************************************************************************/
1767 void x86emuOp_pop_DS(u8
X86EMU_UNUSED(op1
))
1770 DECODE_PRINTF("POP\tDS\n");
1772 M
.x86
.R_DS
= pop_word();
1773 DECODE_CLEAR_SEGOVR();
1777 /****************************************************************************
1780 ****************************************************************************/
1781 void x86emuOp_and_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1784 u8
*destreg
, *srcreg
;
1789 DECODE_PRINTF("AND\t");
1790 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1794 destoffset
= decode_rm00_address(rl
);
1796 destval
= fetch_data_byte(destoffset
);
1797 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1798 DECODE_PRINTF("\n");
1800 destval
= and_byte(destval
, *srcreg
);
1801 store_data_byte(destoffset
, destval
);
1805 destoffset
= decode_rm01_address(rl
);
1807 destval
= fetch_data_byte(destoffset
);
1808 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1809 DECODE_PRINTF("\n");
1811 destval
= and_byte(destval
, *srcreg
);
1812 store_data_byte(destoffset
, destval
);
1816 destoffset
= decode_rm10_address(rl
);
1818 destval
= fetch_data_byte(destoffset
);
1819 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1820 DECODE_PRINTF("\n");
1822 destval
= and_byte(destval
, *srcreg
);
1823 store_data_byte(destoffset
, destval
);
1826 case 3: /* register to register */
1827 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1829 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1830 DECODE_PRINTF("\n");
1832 *destreg
= and_byte(*destreg
, *srcreg
);
1835 DECODE_CLEAR_SEGOVR();
1839 /****************************************************************************
1842 ****************************************************************************/
1843 void x86emuOp_and_word_RM_R(u8
X86EMU_UNUSED(op1
))
1849 DECODE_PRINTF("AND\t");
1850 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1853 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1857 destoffset
= decode_rm00_address(rl
);
1859 destval
= fetch_data_long(destoffset
);
1860 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1861 DECODE_PRINTF("\n");
1863 destval
= and_long(destval
, *srcreg
);
1864 store_data_long(destoffset
, destval
);
1869 destoffset
= decode_rm00_address(rl
);
1871 destval
= fetch_data_word(destoffset
);
1872 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1873 DECODE_PRINTF("\n");
1875 destval
= and_word(destval
, *srcreg
);
1876 store_data_word(destoffset
, destval
);
1880 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1884 destoffset
= decode_rm01_address(rl
);
1886 destval
= fetch_data_long(destoffset
);
1887 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1888 DECODE_PRINTF("\n");
1890 destval
= and_long(destval
, *srcreg
);
1891 store_data_long(destoffset
, destval
);
1896 destoffset
= decode_rm01_address(rl
);
1898 destval
= fetch_data_word(destoffset
);
1899 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1900 DECODE_PRINTF("\n");
1902 destval
= and_word(destval
, *srcreg
);
1903 store_data_word(destoffset
, destval
);
1907 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1911 destoffset
= decode_rm10_address(rl
);
1913 destval
= fetch_data_long(destoffset
);
1914 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1915 DECODE_PRINTF("\n");
1917 destval
= and_long(destval
, *srcreg
);
1918 store_data_long(destoffset
, destval
);
1923 destoffset
= decode_rm10_address(rl
);
1925 destval
= fetch_data_word(destoffset
);
1926 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1927 DECODE_PRINTF("\n");
1929 destval
= and_word(destval
, *srcreg
);
1930 store_data_word(destoffset
, destval
);
1933 case 3: /* register to register */
1934 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1935 u32
*destreg
,*srcreg
;
1937 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1939 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1940 DECODE_PRINTF("\n");
1942 *destreg
= and_long(*destreg
, *srcreg
);
1944 u16
*destreg
,*srcreg
;
1946 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1948 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1949 DECODE_PRINTF("\n");
1951 *destreg
= and_word(*destreg
, *srcreg
);
1955 DECODE_CLEAR_SEGOVR();
1959 /****************************************************************************
1962 ****************************************************************************/
1963 void x86emuOp_and_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1966 u8
*destreg
, *srcreg
;
1971 DECODE_PRINTF("AND\t");
1972 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1975 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1977 srcoffset
= decode_rm00_address(rl
);
1978 srcval
= fetch_data_byte(srcoffset
);
1979 DECODE_PRINTF("\n");
1981 *destreg
= and_byte(*destreg
, srcval
);
1984 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1986 srcoffset
= decode_rm01_address(rl
);
1987 srcval
= fetch_data_byte(srcoffset
);
1988 DECODE_PRINTF("\n");
1990 *destreg
= and_byte(*destreg
, srcval
);
1993 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1995 srcoffset
= decode_rm10_address(rl
);
1996 srcval
= fetch_data_byte(srcoffset
);
1997 DECODE_PRINTF("\n");
1999 *destreg
= and_byte(*destreg
, srcval
);
2001 case 3: /* register to register */
2002 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2004 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2005 DECODE_PRINTF("\n");
2007 *destreg
= and_byte(*destreg
, *srcreg
);
2010 DECODE_CLEAR_SEGOVR();
2014 /****************************************************************************
2017 ****************************************************************************/
2018 void x86emuOp_and_word_R_RM(u8
X86EMU_UNUSED(op1
))
2024 DECODE_PRINTF("AND\t");
2025 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2028 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2032 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2034 srcoffset
= decode_rm00_address(rl
);
2035 srcval
= fetch_data_long(srcoffset
);
2036 DECODE_PRINTF("\n");
2038 *destreg
= and_long(*destreg
, srcval
);
2043 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2045 srcoffset
= decode_rm00_address(rl
);
2046 srcval
= fetch_data_word(srcoffset
);
2047 DECODE_PRINTF("\n");
2049 *destreg
= and_word(*destreg
, srcval
);
2053 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2057 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2059 srcoffset
= decode_rm01_address(rl
);
2060 srcval
= fetch_data_long(srcoffset
);
2061 DECODE_PRINTF("\n");
2063 *destreg
= and_long(*destreg
, srcval
);
2069 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2071 srcoffset
= decode_rm01_address(rl
);
2072 srcval
= fetch_data_word(srcoffset
);
2073 DECODE_PRINTF("\n");
2075 *destreg
= and_word(*destreg
, srcval
);
2079 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2083 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2085 srcoffset
= decode_rm10_address(rl
);
2086 srcval
= fetch_data_long(srcoffset
);
2087 DECODE_PRINTF("\n");
2089 *destreg
= and_long(*destreg
, srcval
);
2094 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2096 srcoffset
= decode_rm10_address(rl
);
2097 srcval
= fetch_data_word(srcoffset
);
2098 DECODE_PRINTF("\n");
2100 *destreg
= and_word(*destreg
, srcval
);
2103 case 3: /* register to register */
2104 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2105 u32
*destreg
,*srcreg
;
2107 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2109 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2110 DECODE_PRINTF("\n");
2112 *destreg
= and_long(*destreg
, *srcreg
);
2114 u16
*destreg
,*srcreg
;
2116 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2118 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2119 DECODE_PRINTF("\n");
2121 *destreg
= and_word(*destreg
, *srcreg
);
2125 DECODE_CLEAR_SEGOVR();
2129 /****************************************************************************
2132 ****************************************************************************/
2133 void x86emuOp_and_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2138 DECODE_PRINTF("AND\tAL,");
2139 srcval
= fetch_byte_imm();
2140 DECODE_PRINTF2("%x\n", srcval
);
2142 M
.x86
.R_AL
= and_byte(M
.x86
.R_AL
, srcval
);
2143 DECODE_CLEAR_SEGOVR();
2147 /****************************************************************************
2150 ****************************************************************************/
2151 void x86emuOp_and_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
2156 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2157 DECODE_PRINTF("AND\tEAX,");
2158 srcval
= fetch_long_imm();
2160 DECODE_PRINTF("AND\tAX,");
2161 srcval
= fetch_word_imm();
2163 DECODE_PRINTF2("%x\n", srcval
);
2165 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2166 M
.x86
.R_EAX
= and_long(M
.x86
.R_EAX
, srcval
);
2168 M
.x86
.R_AX
= and_word(M
.x86
.R_AX
, (u16
)srcval
);
2170 DECODE_CLEAR_SEGOVR();
2174 /****************************************************************************
2177 ****************************************************************************/
2178 void x86emuOp_segovr_ES(u8
X86EMU_UNUSED(op1
))
2181 DECODE_PRINTF("ES:\n");
2183 M
.x86
.mode
|= SYSMODE_SEGOVR_ES
;
2185 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2186 * opcode subroutines we do not want to do this.
2191 /****************************************************************************
2194 ****************************************************************************/
2195 void x86emuOp_daa(u8
X86EMU_UNUSED(op1
))
2198 DECODE_PRINTF("DAA\n");
2200 M
.x86
.R_AL
= daa_byte(M
.x86
.R_AL
);
2201 DECODE_CLEAR_SEGOVR();
2205 /****************************************************************************
2208 ****************************************************************************/
2209 void x86emuOp_sub_byte_RM_R(u8
X86EMU_UNUSED(op1
))
2212 u8
*destreg
, *srcreg
;
2217 DECODE_PRINTF("SUB\t");
2218 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2221 destoffset
= decode_rm00_address(rl
);
2223 destval
= fetch_data_byte(destoffset
);
2224 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2225 DECODE_PRINTF("\n");
2227 destval
= sub_byte(destval
, *srcreg
);
2228 store_data_byte(destoffset
, destval
);
2231 destoffset
= decode_rm01_address(rl
);
2233 destval
= fetch_data_byte(destoffset
);
2234 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2235 DECODE_PRINTF("\n");
2237 destval
= sub_byte(destval
, *srcreg
);
2238 store_data_byte(destoffset
, destval
);
2241 destoffset
= decode_rm10_address(rl
);
2243 destval
= fetch_data_byte(destoffset
);
2244 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2245 DECODE_PRINTF("\n");
2247 destval
= sub_byte(destval
, *srcreg
);
2248 store_data_byte(destoffset
, destval
);
2250 case 3: /* register to register */
2251 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
2253 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2254 DECODE_PRINTF("\n");
2256 *destreg
= sub_byte(*destreg
, *srcreg
);
2259 DECODE_CLEAR_SEGOVR();
2263 /****************************************************************************
2266 ****************************************************************************/
2267 void x86emuOp_sub_word_RM_R(u8
X86EMU_UNUSED(op1
))
2273 DECODE_PRINTF("SUB\t");
2274 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2277 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2281 destoffset
= decode_rm00_address(rl
);
2283 destval
= fetch_data_long(destoffset
);
2284 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2285 DECODE_PRINTF("\n");
2287 destval
= sub_long(destval
, *srcreg
);
2288 store_data_long(destoffset
, destval
);
2293 destoffset
= decode_rm00_address(rl
);
2295 destval
= fetch_data_word(destoffset
);
2296 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2297 DECODE_PRINTF("\n");
2299 destval
= sub_word(destval
, *srcreg
);
2300 store_data_word(destoffset
, destval
);
2304 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2308 destoffset
= decode_rm01_address(rl
);
2310 destval
= fetch_data_long(destoffset
);
2311 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2312 DECODE_PRINTF("\n");
2314 destval
= sub_long(destval
, *srcreg
);
2315 store_data_long(destoffset
, destval
);
2320 destoffset
= decode_rm01_address(rl
);
2322 destval
= fetch_data_word(destoffset
);
2323 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2324 DECODE_PRINTF("\n");
2326 destval
= sub_word(destval
, *srcreg
);
2327 store_data_word(destoffset
, destval
);
2331 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2335 destoffset
= decode_rm10_address(rl
);
2337 destval
= fetch_data_long(destoffset
);
2338 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2339 DECODE_PRINTF("\n");
2341 destval
= sub_long(destval
, *srcreg
);
2342 store_data_long(destoffset
, destval
);
2347 destoffset
= decode_rm10_address(rl
);
2349 destval
= fetch_data_word(destoffset
);
2350 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2351 DECODE_PRINTF("\n");
2353 destval
= sub_word(destval
, *srcreg
);
2354 store_data_word(destoffset
, destval
);
2357 case 3: /* register to register */
2358 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2359 u32
*destreg
,*srcreg
;
2361 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2363 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2364 DECODE_PRINTF("\n");
2366 *destreg
= sub_long(*destreg
, *srcreg
);
2368 u16
*destreg
,*srcreg
;
2370 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2372 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2373 DECODE_PRINTF("\n");
2375 *destreg
= sub_word(*destreg
, *srcreg
);
2379 DECODE_CLEAR_SEGOVR();
2383 /****************************************************************************
2386 ****************************************************************************/
2387 void x86emuOp_sub_byte_R_RM(u8
X86EMU_UNUSED(op1
))
2390 u8
*destreg
, *srcreg
;
2395 DECODE_PRINTF("SUB\t");
2396 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2399 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2401 srcoffset
= decode_rm00_address(rl
);
2402 srcval
= fetch_data_byte(srcoffset
);
2403 DECODE_PRINTF("\n");
2405 *destreg
= sub_byte(*destreg
, srcval
);
2408 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2410 srcoffset
= decode_rm01_address(rl
);
2411 srcval
= fetch_data_byte(srcoffset
);
2412 DECODE_PRINTF("\n");
2414 *destreg
= sub_byte(*destreg
, srcval
);
2417 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2419 srcoffset
= decode_rm10_address(rl
);
2420 srcval
= fetch_data_byte(srcoffset
);
2421 DECODE_PRINTF("\n");
2423 *destreg
= sub_byte(*destreg
, srcval
);
2425 case 3: /* register to register */
2426 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2428 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2429 DECODE_PRINTF("\n");
2431 *destreg
= sub_byte(*destreg
, *srcreg
);
2434 DECODE_CLEAR_SEGOVR();
2438 /****************************************************************************
2441 ****************************************************************************/
2442 void x86emuOp_sub_word_R_RM(u8
X86EMU_UNUSED(op1
))
2448 DECODE_PRINTF("SUB\t");
2449 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2452 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2456 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2458 srcoffset
= decode_rm00_address(rl
);
2459 srcval
= fetch_data_long(srcoffset
);
2460 DECODE_PRINTF("\n");
2462 *destreg
= sub_long(*destreg
, srcval
);
2467 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2469 srcoffset
= decode_rm00_address(rl
);
2470 srcval
= fetch_data_word(srcoffset
);
2471 DECODE_PRINTF("\n");
2473 *destreg
= sub_word(*destreg
, srcval
);
2477 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2481 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2483 srcoffset
= decode_rm01_address(rl
);
2484 srcval
= fetch_data_long(srcoffset
);
2485 DECODE_PRINTF("\n");
2487 *destreg
= sub_long(*destreg
, srcval
);
2492 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2494 srcoffset
= decode_rm01_address(rl
);
2495 srcval
= fetch_data_word(srcoffset
);
2496 DECODE_PRINTF("\n");
2498 *destreg
= sub_word(*destreg
, srcval
);
2502 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2506 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2508 srcoffset
= decode_rm10_address(rl
);
2509 srcval
= fetch_data_long(srcoffset
);
2510 DECODE_PRINTF("\n");
2512 *destreg
= sub_long(*destreg
, srcval
);
2517 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2519 srcoffset
= decode_rm10_address(rl
);
2520 srcval
= fetch_data_word(srcoffset
);
2521 DECODE_PRINTF("\n");
2523 *destreg
= sub_word(*destreg
, srcval
);
2526 case 3: /* register to register */
2527 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2528 u32
*destreg
,*srcreg
;
2530 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2532 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2533 DECODE_PRINTF("\n");
2535 *destreg
= sub_long(*destreg
, *srcreg
);
2537 u16
*destreg
,*srcreg
;
2539 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2541 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2542 DECODE_PRINTF("\n");
2544 *destreg
= sub_word(*destreg
, *srcreg
);
2548 DECODE_CLEAR_SEGOVR();
2552 /****************************************************************************
2555 ****************************************************************************/
2556 void x86emuOp_sub_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2561 DECODE_PRINTF("SUB\tAL,");
2562 srcval
= fetch_byte_imm();
2563 DECODE_PRINTF2("%x\n", srcval
);
2565 M
.x86
.R_AL
= sub_byte(M
.x86
.R_AL
, srcval
);
2566 DECODE_CLEAR_SEGOVR();
2570 /****************************************************************************
2573 ****************************************************************************/
2574 void x86emuOp_sub_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
2579 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2580 DECODE_PRINTF("SUB\tEAX,");
2581 srcval
= fetch_long_imm();
2583 DECODE_PRINTF("SUB\tAX,");
2584 srcval
= fetch_word_imm();
2586 DECODE_PRINTF2("%x\n", srcval
);
2588 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2589 M
.x86
.R_EAX
= sub_long(M
.x86
.R_EAX
, srcval
);
2591 M
.x86
.R_AX
= sub_word(M
.x86
.R_AX
, (u16
)srcval
);
2593 DECODE_CLEAR_SEGOVR();
2597 /****************************************************************************
2600 ****************************************************************************/
2601 void x86emuOp_segovr_CS(u8
X86EMU_UNUSED(op1
))
2604 DECODE_PRINTF("CS:\n");
2606 M
.x86
.mode
|= SYSMODE_SEGOVR_CS
;
2607 /* note no DECODE_CLEAR_SEGOVR here. */
2611 /****************************************************************************
2614 ****************************************************************************/
2615 void x86emuOp_das(u8
X86EMU_UNUSED(op1
))
2618 DECODE_PRINTF("DAS\n");
2620 M
.x86
.R_AL
= das_byte(M
.x86
.R_AL
);
2621 DECODE_CLEAR_SEGOVR();
2625 /****************************************************************************
2628 ****************************************************************************/
2629 void x86emuOp_xor_byte_RM_R(u8
X86EMU_UNUSED(op1
))
2632 u8
*destreg
, *srcreg
;
2637 DECODE_PRINTF("XOR\t");
2638 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2641 destoffset
= decode_rm00_address(rl
);
2643 destval
= fetch_data_byte(destoffset
);
2644 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2645 DECODE_PRINTF("\n");
2647 destval
= xor_byte(destval
, *srcreg
);
2648 store_data_byte(destoffset
, destval
);
2651 destoffset
= decode_rm01_address(rl
);
2653 destval
= fetch_data_byte(destoffset
);
2654 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2655 DECODE_PRINTF("\n");
2657 destval
= xor_byte(destval
, *srcreg
);
2658 store_data_byte(destoffset
, destval
);
2661 destoffset
= decode_rm10_address(rl
);
2663 destval
= fetch_data_byte(destoffset
);
2664 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2665 DECODE_PRINTF("\n");
2667 destval
= xor_byte(destval
, *srcreg
);
2668 store_data_byte(destoffset
, destval
);
2670 case 3: /* register to register */
2671 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
2673 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2674 DECODE_PRINTF("\n");
2676 *destreg
= xor_byte(*destreg
, *srcreg
);
2679 DECODE_CLEAR_SEGOVR();
2683 /****************************************************************************
2686 ****************************************************************************/
2687 void x86emuOp_xor_word_RM_R(u8
X86EMU_UNUSED(op1
))
2693 DECODE_PRINTF("XOR\t");
2694 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2697 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2701 destoffset
= decode_rm00_address(rl
);
2703 destval
= fetch_data_long(destoffset
);
2704 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2705 DECODE_PRINTF("\n");
2707 destval
= xor_long(destval
, *srcreg
);
2708 store_data_long(destoffset
, destval
);
2713 destoffset
= decode_rm00_address(rl
);
2715 destval
= fetch_data_word(destoffset
);
2716 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2717 DECODE_PRINTF("\n");
2719 destval
= xor_word(destval
, *srcreg
);
2720 store_data_word(destoffset
, destval
);
2724 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2728 destoffset
= decode_rm01_address(rl
);
2730 destval
= fetch_data_long(destoffset
);
2731 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2732 DECODE_PRINTF("\n");
2734 destval
= xor_long(destval
, *srcreg
);
2735 store_data_long(destoffset
, destval
);
2740 destoffset
= decode_rm01_address(rl
);
2742 destval
= fetch_data_word(destoffset
);
2743 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2744 DECODE_PRINTF("\n");
2746 destval
= xor_word(destval
, *srcreg
);
2747 store_data_word(destoffset
, destval
);
2751 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2755 destoffset
= decode_rm10_address(rl
);
2757 destval
= fetch_data_long(destoffset
);
2758 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2759 DECODE_PRINTF("\n");
2761 destval
= xor_long(destval
, *srcreg
);
2762 store_data_long(destoffset
, destval
);
2767 destoffset
= decode_rm10_address(rl
);
2769 destval
= fetch_data_word(destoffset
);
2770 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2771 DECODE_PRINTF("\n");
2773 destval
= xor_word(destval
, *srcreg
);
2774 store_data_word(destoffset
, destval
);
2777 case 3: /* register to register */
2778 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2779 u32
*destreg
,*srcreg
;
2781 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2783 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2784 DECODE_PRINTF("\n");
2786 *destreg
= xor_long(*destreg
, *srcreg
);
2788 u16
*destreg
,*srcreg
;
2790 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2792 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2793 DECODE_PRINTF("\n");
2795 *destreg
= xor_word(*destreg
, *srcreg
);
2799 DECODE_CLEAR_SEGOVR();
2803 /****************************************************************************
2806 ****************************************************************************/
2807 void x86emuOp_xor_byte_R_RM(u8
X86EMU_UNUSED(op1
))
2810 u8
*destreg
, *srcreg
;
2815 DECODE_PRINTF("XOR\t");
2816 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2819 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2821 srcoffset
= decode_rm00_address(rl
);
2822 srcval
= fetch_data_byte(srcoffset
);
2823 DECODE_PRINTF("\n");
2825 *destreg
= xor_byte(*destreg
, srcval
);
2828 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2830 srcoffset
= decode_rm01_address(rl
);
2831 srcval
= fetch_data_byte(srcoffset
);
2832 DECODE_PRINTF("\n");
2834 *destreg
= xor_byte(*destreg
, srcval
);
2837 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2839 srcoffset
= decode_rm10_address(rl
);
2840 srcval
= fetch_data_byte(srcoffset
);
2841 DECODE_PRINTF("\n");
2843 *destreg
= xor_byte(*destreg
, srcval
);
2845 case 3: /* register to register */
2846 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2848 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2849 DECODE_PRINTF("\n");
2851 *destreg
= xor_byte(*destreg
, *srcreg
);
2854 DECODE_CLEAR_SEGOVR();
2858 /****************************************************************************
2861 ****************************************************************************/
2862 void x86emuOp_xor_word_R_RM(u8
X86EMU_UNUSED(op1
))
2868 DECODE_PRINTF("XOR\t");
2869 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2872 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2876 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2878 srcoffset
= decode_rm00_address(rl
);
2879 srcval
= fetch_data_long(srcoffset
);
2880 DECODE_PRINTF("\n");
2882 *destreg
= xor_long(*destreg
, srcval
);
2887 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2889 srcoffset
= decode_rm00_address(rl
);
2890 srcval
= fetch_data_word(srcoffset
);
2891 DECODE_PRINTF("\n");
2893 *destreg
= xor_word(*destreg
, srcval
);
2897 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2901 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2903 srcoffset
= decode_rm01_address(rl
);
2904 srcval
= fetch_data_long(srcoffset
);
2905 DECODE_PRINTF("\n");
2907 *destreg
= xor_long(*destreg
, srcval
);
2912 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2914 srcoffset
= decode_rm01_address(rl
);
2915 srcval
= fetch_data_word(srcoffset
);
2916 DECODE_PRINTF("\n");
2918 *destreg
= xor_word(*destreg
, srcval
);
2922 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2926 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2928 srcoffset
= decode_rm10_address(rl
);
2929 srcval
= fetch_data_long(srcoffset
);
2930 DECODE_PRINTF("\n");
2932 *destreg
= xor_long(*destreg
, srcval
);
2937 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2939 srcoffset
= decode_rm10_address(rl
);
2940 srcval
= fetch_data_word(srcoffset
);
2941 DECODE_PRINTF("\n");
2943 *destreg
= xor_word(*destreg
, srcval
);
2946 case 3: /* register to register */
2947 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2948 u32
*destreg
,*srcreg
;
2950 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2952 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2953 DECODE_PRINTF("\n");
2955 *destreg
= xor_long(*destreg
, *srcreg
);
2957 u16
*destreg
,*srcreg
;
2959 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2961 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2962 DECODE_PRINTF("\n");
2964 *destreg
= xor_word(*destreg
, *srcreg
);
2968 DECODE_CLEAR_SEGOVR();
2972 /****************************************************************************
2975 ****************************************************************************/
2976 void x86emuOp_xor_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2981 DECODE_PRINTF("XOR\tAL,");
2982 srcval
= fetch_byte_imm();
2983 DECODE_PRINTF2("%x\n", srcval
);
2985 M
.x86
.R_AL
= xor_byte(M
.x86
.R_AL
, srcval
);
2986 DECODE_CLEAR_SEGOVR();
2990 /****************************************************************************
2993 ****************************************************************************/
2994 void x86emuOp_xor_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
2999 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3000 DECODE_PRINTF("XOR\tEAX,");
3001 srcval
= fetch_long_imm();
3003 DECODE_PRINTF("XOR\tAX,");
3004 srcval
= fetch_word_imm();
3006 DECODE_PRINTF2("%x\n", srcval
);
3008 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3009 M
.x86
.R_EAX
= xor_long(M
.x86
.R_EAX
, srcval
);
3011 M
.x86
.R_AX
= xor_word(M
.x86
.R_AX
, (u16
)srcval
);
3013 DECODE_CLEAR_SEGOVR();
3017 /****************************************************************************
3020 ****************************************************************************/
3021 void x86emuOp_segovr_SS(u8
X86EMU_UNUSED(op1
))
3024 DECODE_PRINTF("SS:\n");
3026 M
.x86
.mode
|= SYSMODE_SEGOVR_SS
;
3027 /* no DECODE_CLEAR_SEGOVR ! */
3031 /****************************************************************************
3034 ****************************************************************************/
3035 void x86emuOp_aaa(u8
X86EMU_UNUSED(op1
))
3038 DECODE_PRINTF("AAA\n");
3040 M
.x86
.R_AX
= aaa_word(M
.x86
.R_AX
);
3041 DECODE_CLEAR_SEGOVR();
3045 /****************************************************************************
3048 ****************************************************************************/
3049 void x86emuOp_cmp_byte_RM_R(u8
X86EMU_UNUSED(op1
))
3053 u8
*destreg
, *srcreg
;
3057 DECODE_PRINTF("CMP\t");
3058 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3061 destoffset
= decode_rm00_address(rl
);
3063 destval
= fetch_data_byte(destoffset
);
3064 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3065 DECODE_PRINTF("\n");
3067 cmp_byte(destval
, *srcreg
);
3070 destoffset
= decode_rm01_address(rl
);
3072 destval
= fetch_data_byte(destoffset
);
3073 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3074 DECODE_PRINTF("\n");
3076 cmp_byte(destval
, *srcreg
);
3079 destoffset
= decode_rm10_address(rl
);
3081 destval
= fetch_data_byte(destoffset
);
3082 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3083 DECODE_PRINTF("\n");
3085 cmp_byte(destval
, *srcreg
);
3087 case 3: /* register to register */
3088 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3090 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3091 DECODE_PRINTF("\n");
3093 cmp_byte(*destreg
, *srcreg
);
3096 DECODE_CLEAR_SEGOVR();
3100 /****************************************************************************
3103 ****************************************************************************/
3104 void x86emuOp_cmp_word_RM_R(u8
X86EMU_UNUSED(op1
))
3110 DECODE_PRINTF("CMP\t");
3111 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3114 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3118 destoffset
= decode_rm00_address(rl
);
3120 destval
= fetch_data_long(destoffset
);
3121 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3122 DECODE_PRINTF("\n");
3124 cmp_long(destval
, *srcreg
);
3129 destoffset
= decode_rm00_address(rl
);
3131 destval
= fetch_data_word(destoffset
);
3132 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3133 DECODE_PRINTF("\n");
3135 cmp_word(destval
, *srcreg
);
3139 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3143 destoffset
= decode_rm01_address(rl
);
3145 destval
= fetch_data_long(destoffset
);
3146 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3147 DECODE_PRINTF("\n");
3149 cmp_long(destval
, *srcreg
);
3154 destoffset
= decode_rm01_address(rl
);
3156 destval
= fetch_data_word(destoffset
);
3157 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3158 DECODE_PRINTF("\n");
3160 cmp_word(destval
, *srcreg
);
3164 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3168 destoffset
= decode_rm10_address(rl
);
3170 destval
= fetch_data_long(destoffset
);
3171 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3172 DECODE_PRINTF("\n");
3174 cmp_long(destval
, *srcreg
);
3179 destoffset
= decode_rm10_address(rl
);
3181 destval
= fetch_data_word(destoffset
);
3182 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3183 DECODE_PRINTF("\n");
3185 cmp_word(destval
, *srcreg
);
3188 case 3: /* register to register */
3189 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3190 u32
*destreg
,*srcreg
;
3192 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3194 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3195 DECODE_PRINTF("\n");
3197 cmp_long(*destreg
, *srcreg
);
3199 u16
*destreg
,*srcreg
;
3201 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3203 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3204 DECODE_PRINTF("\n");
3206 cmp_word(*destreg
, *srcreg
);
3210 DECODE_CLEAR_SEGOVR();
3214 /****************************************************************************
3217 ****************************************************************************/
3218 void x86emuOp_cmp_byte_R_RM(u8
X86EMU_UNUSED(op1
))
3221 u8
*destreg
, *srcreg
;
3226 DECODE_PRINTF("CMP\t");
3227 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3230 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3232 srcoffset
= decode_rm00_address(rl
);
3233 srcval
= fetch_data_byte(srcoffset
);
3234 DECODE_PRINTF("\n");
3236 cmp_byte(*destreg
, srcval
);
3239 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3241 srcoffset
= decode_rm01_address(rl
);
3242 srcval
= fetch_data_byte(srcoffset
);
3243 DECODE_PRINTF("\n");
3245 cmp_byte(*destreg
, srcval
);
3248 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3250 srcoffset
= decode_rm10_address(rl
);
3251 srcval
= fetch_data_byte(srcoffset
);
3252 DECODE_PRINTF("\n");
3254 cmp_byte(*destreg
, srcval
);
3256 case 3: /* register to register */
3257 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3259 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
3260 DECODE_PRINTF("\n");
3262 cmp_byte(*destreg
, *srcreg
);
3265 DECODE_CLEAR_SEGOVR();
3269 /****************************************************************************
3272 ****************************************************************************/
3273 void x86emuOp_cmp_word_R_RM(u8
X86EMU_UNUSED(op1
))
3279 DECODE_PRINTF("CMP\t");
3280 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3283 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3287 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3289 srcoffset
= decode_rm00_address(rl
);
3290 srcval
= fetch_data_long(srcoffset
);
3291 DECODE_PRINTF("\n");
3293 cmp_long(*destreg
, srcval
);
3298 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3300 srcoffset
= decode_rm00_address(rl
);
3301 srcval
= fetch_data_word(srcoffset
);
3302 DECODE_PRINTF("\n");
3304 cmp_word(*destreg
, srcval
);
3308 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3312 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3314 srcoffset
= decode_rm01_address(rl
);
3315 srcval
= fetch_data_long(srcoffset
);
3316 DECODE_PRINTF("\n");
3318 cmp_long(*destreg
, srcval
);
3323 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3325 srcoffset
= decode_rm01_address(rl
);
3326 srcval
= fetch_data_word(srcoffset
);
3327 DECODE_PRINTF("\n");
3329 cmp_word(*destreg
, srcval
);
3333 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3337 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3339 srcoffset
= decode_rm10_address(rl
);
3340 srcval
= fetch_data_long(srcoffset
);
3341 DECODE_PRINTF("\n");
3343 cmp_long(*destreg
, srcval
);
3348 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3350 srcoffset
= decode_rm10_address(rl
);
3351 srcval
= fetch_data_word(srcoffset
);
3352 DECODE_PRINTF("\n");
3354 cmp_word(*destreg
, srcval
);
3357 case 3: /* register to register */
3358 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3359 u32
*destreg
,*srcreg
;
3361 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3363 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
3364 DECODE_PRINTF("\n");
3366 cmp_long(*destreg
, *srcreg
);
3368 u16
*destreg
,*srcreg
;
3370 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3372 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
3373 DECODE_PRINTF("\n");
3375 cmp_word(*destreg
, *srcreg
);
3379 DECODE_CLEAR_SEGOVR();
3383 /****************************************************************************
3386 ****************************************************************************/
3387 void x86emuOp_cmp_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
3392 DECODE_PRINTF("CMP\tAL,");
3393 srcval
= fetch_byte_imm();
3394 DECODE_PRINTF2("%x\n", srcval
);
3396 cmp_byte(M
.x86
.R_AL
, srcval
);
3397 DECODE_CLEAR_SEGOVR();
3401 /****************************************************************************
3404 ****************************************************************************/
3405 void x86emuOp_cmp_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
3410 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3411 DECODE_PRINTF("CMP\tEAX,");
3412 srcval
= fetch_long_imm();
3414 DECODE_PRINTF("CMP\tAX,");
3415 srcval
= fetch_word_imm();
3417 DECODE_PRINTF2("%x\n", srcval
);
3419 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3420 cmp_long(M
.x86
.R_EAX
, srcval
);
3422 cmp_word(M
.x86
.R_AX
, (u16
)srcval
);
3424 DECODE_CLEAR_SEGOVR();
3428 /****************************************************************************
3431 ****************************************************************************/
3432 void x86emuOp_segovr_DS(u8
X86EMU_UNUSED(op1
))
3435 DECODE_PRINTF("DS:\n");
3437 M
.x86
.mode
|= SYSMODE_SEGOVR_DS
;
3438 /* NO DECODE_CLEAR_SEGOVR! */
3442 /****************************************************************************
3445 ****************************************************************************/
3446 void x86emuOp_aas(u8
X86EMU_UNUSED(op1
))
3449 DECODE_PRINTF("AAS\n");
3451 M
.x86
.R_AX
= aas_word(M
.x86
.R_AX
);
3452 DECODE_CLEAR_SEGOVR();
3456 /****************************************************************************
3459 ****************************************************************************/
3460 void x86emuOp_inc_AX(u8
X86EMU_UNUSED(op1
))
3463 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3464 DECODE_PRINTF("INC\tEAX\n");
3466 DECODE_PRINTF("INC\tAX\n");
3469 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3470 M
.x86
.R_EAX
= inc_long(M
.x86
.R_EAX
);
3472 M
.x86
.R_AX
= inc_word(M
.x86
.R_AX
);
3474 DECODE_CLEAR_SEGOVR();
3478 /****************************************************************************
3481 ****************************************************************************/
3482 void x86emuOp_inc_CX(u8
X86EMU_UNUSED(op1
))
3485 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3486 DECODE_PRINTF("INC\tECX\n");
3488 DECODE_PRINTF("INC\tCX\n");
3491 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3492 M
.x86
.R_ECX
= inc_long(M
.x86
.R_ECX
);
3494 M
.x86
.R_CX
= inc_word(M
.x86
.R_CX
);
3496 DECODE_CLEAR_SEGOVR();
3500 /****************************************************************************
3503 ****************************************************************************/
3504 void x86emuOp_inc_DX(u8
X86EMU_UNUSED(op1
))
3507 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3508 DECODE_PRINTF("INC\tEDX\n");
3510 DECODE_PRINTF("INC\tDX\n");
3513 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3514 M
.x86
.R_EDX
= inc_long(M
.x86
.R_EDX
);
3516 M
.x86
.R_DX
= inc_word(M
.x86
.R_DX
);
3518 DECODE_CLEAR_SEGOVR();
3522 /****************************************************************************
3525 ****************************************************************************/
3526 void x86emuOp_inc_BX(u8
X86EMU_UNUSED(op1
))
3529 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3530 DECODE_PRINTF("INC\tEBX\n");
3532 DECODE_PRINTF("INC\tBX\n");
3535 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3536 M
.x86
.R_EBX
= inc_long(M
.x86
.R_EBX
);
3538 M
.x86
.R_BX
= inc_word(M
.x86
.R_BX
);
3540 DECODE_CLEAR_SEGOVR();
3544 /****************************************************************************
3547 ****************************************************************************/
3548 void x86emuOp_inc_SP(u8
X86EMU_UNUSED(op1
))
3551 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3552 DECODE_PRINTF("INC\tESP\n");
3554 DECODE_PRINTF("INC\tSP\n");
3557 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3558 M
.x86
.R_ESP
= inc_long(M
.x86
.R_ESP
);
3560 M
.x86
.R_SP
= inc_word(M
.x86
.R_SP
);
3562 DECODE_CLEAR_SEGOVR();
3566 /****************************************************************************
3569 ****************************************************************************/
3570 void x86emuOp_inc_BP(u8
X86EMU_UNUSED(op1
))
3573 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3574 DECODE_PRINTF("INC\tEBP\n");
3576 DECODE_PRINTF("INC\tBP\n");
3579 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3580 M
.x86
.R_EBP
= inc_long(M
.x86
.R_EBP
);
3582 M
.x86
.R_BP
= inc_word(M
.x86
.R_BP
);
3584 DECODE_CLEAR_SEGOVR();
3588 /****************************************************************************
3591 ****************************************************************************/
3592 void x86emuOp_inc_SI(u8
X86EMU_UNUSED(op1
))
3595 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3596 DECODE_PRINTF("INC\tESI\n");
3598 DECODE_PRINTF("INC\tSI\n");
3601 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3602 M
.x86
.R_ESI
= inc_long(M
.x86
.R_ESI
);
3604 M
.x86
.R_SI
= inc_word(M
.x86
.R_SI
);
3606 DECODE_CLEAR_SEGOVR();
3610 /****************************************************************************
3613 ****************************************************************************/
3614 void x86emuOp_inc_DI(u8
X86EMU_UNUSED(op1
))
3617 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3618 DECODE_PRINTF("INC\tEDI\n");
3620 DECODE_PRINTF("INC\tDI\n");
3623 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3624 M
.x86
.R_EDI
= inc_long(M
.x86
.R_EDI
);
3626 M
.x86
.R_DI
= inc_word(M
.x86
.R_DI
);
3628 DECODE_CLEAR_SEGOVR();
3632 /****************************************************************************
3635 ****************************************************************************/
3636 void x86emuOp_dec_AX(u8
X86EMU_UNUSED(op1
))
3639 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3640 DECODE_PRINTF("DEC\tEAX\n");
3642 DECODE_PRINTF("DEC\tAX\n");
3645 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3646 M
.x86
.R_EAX
= dec_long(M
.x86
.R_EAX
);
3648 M
.x86
.R_AX
= dec_word(M
.x86
.R_AX
);
3650 DECODE_CLEAR_SEGOVR();
3654 /****************************************************************************
3657 ****************************************************************************/
3658 void x86emuOp_dec_CX(u8
X86EMU_UNUSED(op1
))
3661 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3662 DECODE_PRINTF("DEC\tECX\n");
3664 DECODE_PRINTF("DEC\tCX\n");
3667 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3668 M
.x86
.R_ECX
= dec_long(M
.x86
.R_ECX
);
3670 M
.x86
.R_CX
= dec_word(M
.x86
.R_CX
);
3672 DECODE_CLEAR_SEGOVR();
3676 /****************************************************************************
3679 ****************************************************************************/
3680 void x86emuOp_dec_DX(u8
X86EMU_UNUSED(op1
))
3683 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3684 DECODE_PRINTF("DEC\tEDX\n");
3686 DECODE_PRINTF("DEC\tDX\n");
3689 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3690 M
.x86
.R_EDX
= dec_long(M
.x86
.R_EDX
);
3692 M
.x86
.R_DX
= dec_word(M
.x86
.R_DX
);
3694 DECODE_CLEAR_SEGOVR();
3698 /****************************************************************************
3701 ****************************************************************************/
3702 void x86emuOp_dec_BX(u8
X86EMU_UNUSED(op1
))
3705 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3706 DECODE_PRINTF("DEC\tEBX\n");
3708 DECODE_PRINTF("DEC\tBX\n");
3711 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3712 M
.x86
.R_EBX
= dec_long(M
.x86
.R_EBX
);
3714 M
.x86
.R_BX
= dec_word(M
.x86
.R_BX
);
3716 DECODE_CLEAR_SEGOVR();
3720 /****************************************************************************
3723 ****************************************************************************/
3724 void x86emuOp_dec_SP(u8
X86EMU_UNUSED(op1
))
3727 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3728 DECODE_PRINTF("DEC\tESP\n");
3730 DECODE_PRINTF("DEC\tSP\n");
3733 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3734 M
.x86
.R_ESP
= dec_long(M
.x86
.R_ESP
);
3736 M
.x86
.R_SP
= dec_word(M
.x86
.R_SP
);
3738 DECODE_CLEAR_SEGOVR();
3742 /****************************************************************************
3745 ****************************************************************************/
3746 void x86emuOp_dec_BP(u8
X86EMU_UNUSED(op1
))
3749 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3750 DECODE_PRINTF("DEC\tEBP\n");
3752 DECODE_PRINTF("DEC\tBP\n");
3755 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3756 M
.x86
.R_EBP
= dec_long(M
.x86
.R_EBP
);
3758 M
.x86
.R_BP
= dec_word(M
.x86
.R_BP
);
3760 DECODE_CLEAR_SEGOVR();
3764 /****************************************************************************
3767 ****************************************************************************/
3768 void x86emuOp_dec_SI(u8
X86EMU_UNUSED(op1
))
3771 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3772 DECODE_PRINTF("DEC\tESI\n");
3774 DECODE_PRINTF("DEC\tSI\n");
3777 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3778 M
.x86
.R_ESI
= dec_long(M
.x86
.R_ESI
);
3780 M
.x86
.R_SI
= dec_word(M
.x86
.R_SI
);
3782 DECODE_CLEAR_SEGOVR();
3786 /****************************************************************************
3789 ****************************************************************************/
3790 void x86emuOp_dec_DI(u8
X86EMU_UNUSED(op1
))
3793 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3794 DECODE_PRINTF("DEC\tEDI\n");
3796 DECODE_PRINTF("DEC\tDI\n");
3799 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3800 M
.x86
.R_EDI
= dec_long(M
.x86
.R_EDI
);
3802 M
.x86
.R_DI
= dec_word(M
.x86
.R_DI
);
3804 DECODE_CLEAR_SEGOVR();
3808 /****************************************************************************
3811 ****************************************************************************/
3812 void x86emuOp_push_AX(u8
X86EMU_UNUSED(op1
))
3815 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3816 DECODE_PRINTF("PUSH\tEAX\n");
3818 DECODE_PRINTF("PUSH\tAX\n");
3821 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3822 push_long(M
.x86
.R_EAX
);
3824 push_word(M
.x86
.R_AX
);
3826 DECODE_CLEAR_SEGOVR();
3830 /****************************************************************************
3833 ****************************************************************************/
3834 void x86emuOp_push_CX(u8
X86EMU_UNUSED(op1
))
3837 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3838 DECODE_PRINTF("PUSH\tECX\n");
3840 DECODE_PRINTF("PUSH\tCX\n");
3843 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3844 push_long(M
.x86
.R_ECX
);
3846 push_word(M
.x86
.R_CX
);
3848 DECODE_CLEAR_SEGOVR();
3852 /****************************************************************************
3855 ****************************************************************************/
3856 void x86emuOp_push_DX(u8
X86EMU_UNUSED(op1
))
3859 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3860 DECODE_PRINTF("PUSH\tEDX\n");
3862 DECODE_PRINTF("PUSH\tDX\n");
3865 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3866 push_long(M
.x86
.R_EDX
);
3868 push_word(M
.x86
.R_DX
);
3870 DECODE_CLEAR_SEGOVR();
3874 /****************************************************************************
3877 ****************************************************************************/
3878 void x86emuOp_push_BX(u8
X86EMU_UNUSED(op1
))
3881 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3882 DECODE_PRINTF("PUSH\tEBX\n");
3884 DECODE_PRINTF("PUSH\tBX\n");
3887 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3888 push_long(M
.x86
.R_EBX
);
3890 push_word(M
.x86
.R_BX
);
3892 DECODE_CLEAR_SEGOVR();
3896 /****************************************************************************
3899 ****************************************************************************/
3900 void x86emuOp_push_SP(u8
X86EMU_UNUSED(op1
))
3903 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3904 DECODE_PRINTF("PUSH\tESP\n");
3906 DECODE_PRINTF("PUSH\tSP\n");
3909 /* Always push (E)SP, since we are emulating an i386 and above
3910 * processor. This is necessary as some BIOS'es use this to check
3911 * what type of processor is in the system.
3913 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3914 push_long(M
.x86
.R_ESP
);
3916 push_word((u16
)(M
.x86
.R_SP
));
3918 DECODE_CLEAR_SEGOVR();
3922 /****************************************************************************
3925 ****************************************************************************/
3926 void x86emuOp_push_BP(u8
X86EMU_UNUSED(op1
))
3929 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3930 DECODE_PRINTF("PUSH\tEBP\n");
3932 DECODE_PRINTF("PUSH\tBP\n");
3935 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3936 push_long(M
.x86
.R_EBP
);
3938 push_word(M
.x86
.R_BP
);
3940 DECODE_CLEAR_SEGOVR();
3944 /****************************************************************************
3947 ****************************************************************************/
3948 void x86emuOp_push_SI(u8
X86EMU_UNUSED(op1
))
3951 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3952 DECODE_PRINTF("PUSH\tESI\n");
3954 DECODE_PRINTF("PUSH\tSI\n");
3957 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3958 push_long(M
.x86
.R_ESI
);
3960 push_word(M
.x86
.R_SI
);
3962 DECODE_CLEAR_SEGOVR();
3966 /****************************************************************************
3969 ****************************************************************************/
3970 void x86emuOp_push_DI(u8
X86EMU_UNUSED(op1
))
3973 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3974 DECODE_PRINTF("PUSH\tEDI\n");
3976 DECODE_PRINTF("PUSH\tDI\n");
3979 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3980 push_long(M
.x86
.R_EDI
);
3982 push_word(M
.x86
.R_DI
);
3984 DECODE_CLEAR_SEGOVR();
3988 /****************************************************************************
3991 ****************************************************************************/
3992 void x86emuOp_pop_AX(u8
X86EMU_UNUSED(op1
))
3995 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3996 DECODE_PRINTF("POP\tEAX\n");
3998 DECODE_PRINTF("POP\tAX\n");
4001 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4002 M
.x86
.R_EAX
= pop_long();
4004 M
.x86
.R_AX
= pop_word();
4006 DECODE_CLEAR_SEGOVR();
4010 /****************************************************************************
4013 ****************************************************************************/
4014 void x86emuOp_pop_CX(u8
X86EMU_UNUSED(op1
))
4017 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4018 DECODE_PRINTF("POP\tECX\n");
4020 DECODE_PRINTF("POP\tCX\n");
4023 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4024 M
.x86
.R_ECX
= pop_long();
4026 M
.x86
.R_CX
= pop_word();
4028 DECODE_CLEAR_SEGOVR();
4032 /****************************************************************************
4035 ****************************************************************************/
4036 void x86emuOp_pop_DX(u8
X86EMU_UNUSED(op1
))
4039 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4040 DECODE_PRINTF("POP\tEDX\n");
4042 DECODE_PRINTF("POP\tDX\n");
4045 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4046 M
.x86
.R_EDX
= pop_long();
4048 M
.x86
.R_DX
= pop_word();
4050 DECODE_CLEAR_SEGOVR();
4054 /****************************************************************************
4057 ****************************************************************************/
4058 void x86emuOp_pop_BX(u8
X86EMU_UNUSED(op1
))
4061 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4062 DECODE_PRINTF("POP\tEBX\n");
4064 DECODE_PRINTF("POP\tBX\n");
4067 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4068 M
.x86
.R_EBX
= pop_long();
4070 M
.x86
.R_BX
= pop_word();
4072 DECODE_CLEAR_SEGOVR();
4076 /****************************************************************************
4079 ****************************************************************************/
4080 void x86emuOp_pop_SP(u8
X86EMU_UNUSED(op1
))
4083 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4084 DECODE_PRINTF("POP\tESP\n");
4086 DECODE_PRINTF("POP\tSP\n");
4089 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4090 M
.x86
.R_ESP
= pop_long();
4092 M
.x86
.R_SP
= pop_word();
4094 DECODE_CLEAR_SEGOVR();
4098 /****************************************************************************
4101 ****************************************************************************/
4102 void x86emuOp_pop_BP(u8
X86EMU_UNUSED(op1
))
4105 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4106 DECODE_PRINTF("POP\tEBP\n");
4108 DECODE_PRINTF("POP\tBP\n");
4111 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4112 M
.x86
.R_EBP
= pop_long();
4114 M
.x86
.R_BP
= pop_word();
4116 DECODE_CLEAR_SEGOVR();
4120 /****************************************************************************
4123 ****************************************************************************/
4124 void x86emuOp_pop_SI(u8
X86EMU_UNUSED(op1
))
4127 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4128 DECODE_PRINTF("POP\tESI\n");
4130 DECODE_PRINTF("POP\tSI\n");
4133 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4134 M
.x86
.R_ESI
= pop_long();
4136 M
.x86
.R_SI
= pop_word();
4138 DECODE_CLEAR_SEGOVR();
4142 /****************************************************************************
4145 ****************************************************************************/
4146 void x86emuOp_pop_DI(u8
X86EMU_UNUSED(op1
))
4149 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4150 DECODE_PRINTF("POP\tEDI\n");
4152 DECODE_PRINTF("POP\tDI\n");
4155 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4156 M
.x86
.R_EDI
= pop_long();
4158 M
.x86
.R_DI
= pop_word();
4160 DECODE_CLEAR_SEGOVR();
4164 /****************************************************************************
4167 ****************************************************************************/
4168 void x86emuOp_push_all(u8
X86EMU_UNUSED(op1
))
4171 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4172 DECODE_PRINTF("PUSHAD\n");
4174 DECODE_PRINTF("PUSHA\n");
4177 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4178 u32 old_sp
= M
.x86
.R_ESP
;
4180 push_long(M
.x86
.R_EAX
);
4181 push_long(M
.x86
.R_ECX
);
4182 push_long(M
.x86
.R_EDX
);
4183 push_long(M
.x86
.R_EBX
);
4185 push_long(M
.x86
.R_EBP
);
4186 push_long(M
.x86
.R_ESI
);
4187 push_long(M
.x86
.R_EDI
);
4189 u16 old_sp
= M
.x86
.R_SP
;
4191 push_word(M
.x86
.R_AX
);
4192 push_word(M
.x86
.R_CX
);
4193 push_word(M
.x86
.R_DX
);
4194 push_word(M
.x86
.R_BX
);
4196 push_word(M
.x86
.R_BP
);
4197 push_word(M
.x86
.R_SI
);
4198 push_word(M
.x86
.R_DI
);
4200 DECODE_CLEAR_SEGOVR();
4204 /****************************************************************************
4207 ****************************************************************************/
4208 void x86emuOp_pop_all(u8
X86EMU_UNUSED(op1
))
4211 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4212 DECODE_PRINTF("POPAD\n");
4214 DECODE_PRINTF("POPA\n");
4217 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4218 M
.x86
.R_EDI
= pop_long();
4219 M
.x86
.R_ESI
= pop_long();
4220 M
.x86
.R_EBP
= pop_long();
4221 M
.x86
.R_ESP
+= 4; /* skip ESP */
4222 M
.x86
.R_EBX
= pop_long();
4223 M
.x86
.R_EDX
= pop_long();
4224 M
.x86
.R_ECX
= pop_long();
4225 M
.x86
.R_EAX
= pop_long();
4227 M
.x86
.R_DI
= pop_word();
4228 M
.x86
.R_SI
= pop_word();
4229 M
.x86
.R_BP
= pop_word();
4230 M
.x86
.R_SP
+= 2; /* skip SP */
4231 M
.x86
.R_BX
= pop_word();
4232 M
.x86
.R_DX
= pop_word();
4233 M
.x86
.R_CX
= pop_word();
4234 M
.x86
.R_AX
= pop_word();
4236 DECODE_CLEAR_SEGOVR();
4240 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4241 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4243 /****************************************************************************
4246 ****************************************************************************/
4247 void x86emuOp_segovr_FS(u8
X86EMU_UNUSED(op1
))
4250 DECODE_PRINTF("FS:\n");
4252 M
.x86
.mode
|= SYSMODE_SEGOVR_FS
;
4254 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4255 * opcode subroutines we do not want to do this.
4260 /****************************************************************************
4263 ****************************************************************************/
4264 void x86emuOp_segovr_GS(u8
X86EMU_UNUSED(op1
))
4267 DECODE_PRINTF("GS:\n");
4269 M
.x86
.mode
|= SYSMODE_SEGOVR_GS
;
4271 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4272 * opcode subroutines we do not want to do this.
4277 /****************************************************************************
4279 Handles opcode 0x66 - prefix for 32-bit register
4280 ****************************************************************************/
4281 void x86emuOp_prefix_data(u8
X86EMU_UNUSED(op1
))
4284 DECODE_PRINTF("DATA:\n");
4286 M
.x86
.mode
|= SYSMODE_PREFIX_DATA
;
4287 /* note no DECODE_CLEAR_SEGOVR here. */
4291 /****************************************************************************
4293 Handles opcode 0x67 - prefix for 32-bit address
4294 ****************************************************************************/
4295 void x86emuOp_prefix_addr(u8
X86EMU_UNUSED(op1
))
4298 DECODE_PRINTF("ADDR:\n");
4300 M
.x86
.mode
|= SYSMODE_PREFIX_ADDR
;
4301 /* note no DECODE_CLEAR_SEGOVR here. */
4305 /****************************************************************************
4308 ****************************************************************************/
4309 void x86emuOp_push_word_IMM(u8
X86EMU_UNUSED(op1
))
4314 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4315 imm
= fetch_long_imm();
4317 imm
= fetch_word_imm();
4319 DECODE_PRINTF2("PUSH\t%x\n", imm
);
4321 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4324 push_word((u16
)imm
);
4326 DECODE_CLEAR_SEGOVR();
4330 /****************************************************************************
4333 ****************************************************************************/
4334 void x86emuOp_imul_word_IMM(u8
X86EMU_UNUSED(op1
))
4340 DECODE_PRINTF("IMUL\t");
4341 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4344 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4350 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4352 srcoffset
= decode_rm00_address(rl
);
4353 srcval
= fetch_data_long(srcoffset
);
4354 imm
= fetch_long_imm();
4355 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4357 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4365 *destreg
= (u32
)res_lo
;
4372 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4374 srcoffset
= decode_rm00_address(rl
);
4375 srcval
= fetch_data_word(srcoffset
);
4376 imm
= fetch_word_imm();
4377 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4379 res
= (s16
)srcval
* (s16
)imm
;
4387 *destreg
= (u16
)res
;
4391 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4397 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4399 srcoffset
= decode_rm01_address(rl
);
4400 srcval
= fetch_data_long(srcoffset
);
4401 imm
= fetch_long_imm();
4402 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4404 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4412 *destreg
= (u32
)res_lo
;
4419 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4421 srcoffset
= decode_rm01_address(rl
);
4422 srcval
= fetch_data_word(srcoffset
);
4423 imm
= fetch_word_imm();
4424 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4426 res
= (s16
)srcval
* (s16
)imm
;
4434 *destreg
= (u16
)res
;
4438 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4444 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4446 srcoffset
= decode_rm10_address(rl
);
4447 srcval
= fetch_data_long(srcoffset
);
4448 imm
= fetch_long_imm();
4449 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4451 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4459 *destreg
= (u32
)res_lo
;
4466 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4468 srcoffset
= decode_rm10_address(rl
);
4469 srcval
= fetch_data_word(srcoffset
);
4470 imm
= fetch_word_imm();
4471 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4473 res
= (s16
)srcval
* (s16
)imm
;
4481 *destreg
= (u16
)res
;
4484 case 3: /* register to register */
4485 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4486 u32
*destreg
,*srcreg
;
4490 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4492 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
4493 imm
= fetch_long_imm();
4494 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4496 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
4504 *destreg
= (u32
)res_lo
;
4506 u16
*destreg
,*srcreg
;
4510 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4512 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
4513 imm
= fetch_word_imm();
4514 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4515 res
= (s16
)*srcreg
* (s16
)imm
;
4523 *destreg
= (u16
)res
;
4527 DECODE_CLEAR_SEGOVR();
4531 /****************************************************************************
4534 ****************************************************************************/
4535 void x86emuOp_push_byte_IMM(u8
X86EMU_UNUSED(op1
))
4540 imm
= (s8
)fetch_byte_imm();
4541 DECODE_PRINTF2("PUSH\t%d\n", imm
);
4544 DECODE_CLEAR_SEGOVR();
4548 /****************************************************************************
4551 ****************************************************************************/
4552 void x86emuOp_imul_byte_IMM(u8
X86EMU_UNUSED(op1
))
4559 DECODE_PRINTF("IMUL\t");
4560 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4563 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4568 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4570 srcoffset
= decode_rm00_address(rl
);
4571 srcval
= fetch_data_long(srcoffset
);
4572 imm
= fetch_byte_imm();
4573 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4575 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4583 *destreg
= (u32
)res_lo
;
4589 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4591 srcoffset
= decode_rm00_address(rl
);
4592 srcval
= fetch_data_word(srcoffset
);
4593 imm
= fetch_byte_imm();
4594 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4596 res
= (s16
)srcval
* (s16
)imm
;
4604 *destreg
= (u16
)res
;
4608 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4613 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4615 srcoffset
= decode_rm01_address(rl
);
4616 srcval
= fetch_data_long(srcoffset
);
4617 imm
= fetch_byte_imm();
4618 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4620 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4628 *destreg
= (u32
)res_lo
;
4634 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4636 srcoffset
= decode_rm01_address(rl
);
4637 srcval
= fetch_data_word(srcoffset
);
4638 imm
= fetch_byte_imm();
4639 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4641 res
= (s16
)srcval
* (s16
)imm
;
4649 *destreg
= (u16
)res
;
4653 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4658 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4660 srcoffset
= decode_rm10_address(rl
);
4661 srcval
= fetch_data_long(srcoffset
);
4662 imm
= fetch_byte_imm();
4663 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4665 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4673 *destreg
= (u32
)res_lo
;
4679 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4681 srcoffset
= decode_rm10_address(rl
);
4682 srcval
= fetch_data_word(srcoffset
);
4683 imm
= fetch_byte_imm();
4684 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4686 res
= (s16
)srcval
* (s16
)imm
;
4694 *destreg
= (u16
)res
;
4697 case 3: /* register to register */
4698 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4699 u32
*destreg
,*srcreg
;
4702 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4704 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
4705 imm
= fetch_byte_imm();
4706 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4708 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
4716 *destreg
= (u32
)res_lo
;
4718 u16
*destreg
,*srcreg
;
4721 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4723 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
4724 imm
= fetch_byte_imm();
4725 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4726 res
= (s16
)*srcreg
* (s16
)imm
;
4734 *destreg
= (u16
)res
;
4738 DECODE_CLEAR_SEGOVR();
4742 /****************************************************************************
4745 ****************************************************************************/
4746 void x86emuOp_ins_byte(u8
X86EMU_UNUSED(op1
))
4749 DECODE_PRINTF("INSB\n");
4752 DECODE_CLEAR_SEGOVR();
4756 /****************************************************************************
4759 ****************************************************************************/
4760 void x86emuOp_ins_word(u8
X86EMU_UNUSED(op1
))
4763 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4764 DECODE_PRINTF("INSD\n");
4767 DECODE_PRINTF("INSW\n");
4771 DECODE_CLEAR_SEGOVR();
4775 /****************************************************************************
4778 ****************************************************************************/
4779 void x86emuOp_outs_byte(u8
X86EMU_UNUSED(op1
))
4782 DECODE_PRINTF("OUTSB\n");
4785 DECODE_CLEAR_SEGOVR();
4789 /****************************************************************************
4792 ****************************************************************************/
4793 void x86emuOp_outs_word(u8
X86EMU_UNUSED(op1
))
4796 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4797 DECODE_PRINTF("OUTSD\n");
4800 DECODE_PRINTF("OUTSW\n");
4804 DECODE_CLEAR_SEGOVR();
4808 /****************************************************************************
4811 ****************************************************************************/
4812 void x86emuOp_jump_near_O(u8
X86EMU_UNUSED(op1
))
4817 /* jump to byte offset if overflow flag is set */
4819 DECODE_PRINTF("JO\t");
4820 offset
= (s8
)fetch_byte_imm();
4821 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4822 DECODE_PRINTF2("%x\n", target
);
4824 if (ACCESS_FLAG(F_OF
))
4825 M
.x86
.R_IP
= target
;
4826 DECODE_CLEAR_SEGOVR();
4830 /****************************************************************************
4833 ****************************************************************************/
4834 void x86emuOp_jump_near_NO(u8
X86EMU_UNUSED(op1
))
4839 /* jump to byte offset if overflow is not set */
4841 DECODE_PRINTF("JNO\t");
4842 offset
= (s8
)fetch_byte_imm();
4843 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4844 DECODE_PRINTF2("%x\n", target
);
4846 if (!ACCESS_FLAG(F_OF
))
4847 M
.x86
.R_IP
= target
;
4848 DECODE_CLEAR_SEGOVR();
4852 /****************************************************************************
4855 ****************************************************************************/
4856 void x86emuOp_jump_near_B(u8
X86EMU_UNUSED(op1
))
4861 /* jump to byte offset if carry flag is set. */
4863 DECODE_PRINTF("JB\t");
4864 offset
= (s8
)fetch_byte_imm();
4865 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4866 DECODE_PRINTF2("%x\n", target
);
4868 if (ACCESS_FLAG(F_CF
))
4869 M
.x86
.R_IP
= target
;
4870 DECODE_CLEAR_SEGOVR();
4874 /****************************************************************************
4877 ****************************************************************************/
4878 void x86emuOp_jump_near_NB(u8
X86EMU_UNUSED(op1
))
4883 /* jump to byte offset if carry flag is clear. */
4885 DECODE_PRINTF("JNB\t");
4886 offset
= (s8
)fetch_byte_imm();
4887 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4888 DECODE_PRINTF2("%x\n", target
);
4890 if (!ACCESS_FLAG(F_CF
))
4891 M
.x86
.R_IP
= target
;
4892 DECODE_CLEAR_SEGOVR();
4896 /****************************************************************************
4899 ****************************************************************************/
4900 void x86emuOp_jump_near_Z(u8
X86EMU_UNUSED(op1
))
4905 /* jump to byte offset if zero flag is set. */
4907 DECODE_PRINTF("JZ\t");
4908 offset
= (s8
)fetch_byte_imm();
4909 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4910 DECODE_PRINTF2("%x\n", target
);
4912 if (ACCESS_FLAG(F_ZF
))
4913 M
.x86
.R_IP
= target
;
4914 DECODE_CLEAR_SEGOVR();
4918 /****************************************************************************
4921 ****************************************************************************/
4922 void x86emuOp_jump_near_NZ(u8
X86EMU_UNUSED(op1
))
4927 /* jump to byte offset if zero flag is clear. */
4929 DECODE_PRINTF("JNZ\t");
4930 offset
= (s8
)fetch_byte_imm();
4931 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4932 DECODE_PRINTF2("%x\n", target
);
4934 if (!ACCESS_FLAG(F_ZF
))
4935 M
.x86
.R_IP
= target
;
4936 DECODE_CLEAR_SEGOVR();
4940 /****************************************************************************
4943 ****************************************************************************/
4944 void x86emuOp_jump_near_BE(u8
X86EMU_UNUSED(op1
))
4949 /* jump to byte offset if carry flag is set or if the zero
4952 DECODE_PRINTF("JBE\t");
4953 offset
= (s8
)fetch_byte_imm();
4954 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4955 DECODE_PRINTF2("%x\n", target
);
4957 if (ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
))
4958 M
.x86
.R_IP
= target
;
4959 DECODE_CLEAR_SEGOVR();
4963 /****************************************************************************
4966 ****************************************************************************/
4967 void x86emuOp_jump_near_NBE(u8
X86EMU_UNUSED(op1
))
4972 /* jump to byte offset if carry flag is clear and if the zero
4975 DECODE_PRINTF("JNBE\t");
4976 offset
= (s8
)fetch_byte_imm();
4977 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4978 DECODE_PRINTF2("%x\n", target
);
4980 if (!(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
)))
4981 M
.x86
.R_IP
= target
;
4982 DECODE_CLEAR_SEGOVR();
4986 /****************************************************************************
4989 ****************************************************************************/
4990 void x86emuOp_jump_near_S(u8
X86EMU_UNUSED(op1
))
4995 /* jump to byte offset if sign flag is set */
4997 DECODE_PRINTF("JS\t");
4998 offset
= (s8
)fetch_byte_imm();
4999 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5000 DECODE_PRINTF2("%x\n", target
);
5002 if (ACCESS_FLAG(F_SF
))
5003 M
.x86
.R_IP
= target
;
5004 DECODE_CLEAR_SEGOVR();
5008 /****************************************************************************
5011 ****************************************************************************/
5012 void x86emuOp_jump_near_NS(u8
X86EMU_UNUSED(op1
))
5017 /* jump to byte offset if sign flag is clear */
5019 DECODE_PRINTF("JNS\t");
5020 offset
= (s8
)fetch_byte_imm();
5021 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5022 DECODE_PRINTF2("%x\n", target
);
5024 if (!ACCESS_FLAG(F_SF
))
5025 M
.x86
.R_IP
= target
;
5026 DECODE_CLEAR_SEGOVR();
5030 /****************************************************************************
5033 ****************************************************************************/
5034 void x86emuOp_jump_near_P(u8
X86EMU_UNUSED(op1
))
5039 /* jump to byte offset if parity flag is set (even parity) */
5041 DECODE_PRINTF("JP\t");
5042 offset
= (s8
)fetch_byte_imm();
5043 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5044 DECODE_PRINTF2("%x\n", target
);
5046 if (ACCESS_FLAG(F_PF
))
5047 M
.x86
.R_IP
= target
;
5048 DECODE_CLEAR_SEGOVR();
5052 /****************************************************************************
5055 ****************************************************************************/
5056 void x86emuOp_jump_near_NP(u8
X86EMU_UNUSED(op1
))
5061 /* jump to byte offset if parity flag is clear (odd parity) */
5063 DECODE_PRINTF("JNP\t");
5064 offset
= (s8
)fetch_byte_imm();
5065 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5066 DECODE_PRINTF2("%x\n", target
);
5068 if (!ACCESS_FLAG(F_PF
))
5069 M
.x86
.R_IP
= target
;
5070 DECODE_CLEAR_SEGOVR();
5074 /****************************************************************************
5077 ****************************************************************************/
5078 void x86emuOp_jump_near_L(u8
X86EMU_UNUSED(op1
))
5084 /* jump to byte offset if sign flag not equal to overflow flag. */
5086 DECODE_PRINTF("JL\t");
5087 offset
= (s8
)fetch_byte_imm();
5088 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5089 DECODE_PRINTF2("%x\n", target
);
5091 sf
= ACCESS_FLAG(F_SF
) != 0;
5092 of
= ACCESS_FLAG(F_OF
) != 0;
5094 M
.x86
.R_IP
= target
;
5095 DECODE_CLEAR_SEGOVR();
5099 /****************************************************************************
5102 ****************************************************************************/
5103 void x86emuOp_jump_near_NL(u8
X86EMU_UNUSED(op1
))
5109 /* jump to byte offset if sign flag not equal to overflow flag. */
5111 DECODE_PRINTF("JNL\t");
5112 offset
= (s8
)fetch_byte_imm();
5113 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5114 DECODE_PRINTF2("%x\n", target
);
5116 sf
= ACCESS_FLAG(F_SF
) != 0;
5117 of
= ACCESS_FLAG(F_OF
) != 0;
5118 /* note: inverse of above, but using == instead of xor. */
5120 M
.x86
.R_IP
= target
;
5121 DECODE_CLEAR_SEGOVR();
5125 /****************************************************************************
5128 ****************************************************************************/
5129 void x86emuOp_jump_near_LE(u8
X86EMU_UNUSED(op1
))
5135 /* jump to byte offset if sign flag not equal to overflow flag
5136 or the zero flag is set */
5138 DECODE_PRINTF("JLE\t");
5139 offset
= (s8
)fetch_byte_imm();
5140 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5141 DECODE_PRINTF2("%x\n", target
);
5143 sf
= ACCESS_FLAG(F_SF
) != 0;
5144 of
= ACCESS_FLAG(F_OF
) != 0;
5145 if ((sf
^ of
) || ACCESS_FLAG(F_ZF
))
5146 M
.x86
.R_IP
= target
;
5147 DECODE_CLEAR_SEGOVR();
5151 /****************************************************************************
5154 ****************************************************************************/
5155 void x86emuOp_jump_near_NLE(u8
X86EMU_UNUSED(op1
))
5161 /* jump to byte offset if sign flag equal to overflow flag.
5162 and the zero flag is clear */
5164 DECODE_PRINTF("JNLE\t");
5165 offset
= (s8
)fetch_byte_imm();
5166 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5167 DECODE_PRINTF2("%x\n", target
);
5169 sf
= ACCESS_FLAG(F_SF
) != 0;
5170 of
= ACCESS_FLAG(F_OF
) != 0;
5171 if ((sf
== of
) && !ACCESS_FLAG(F_ZF
))
5172 M
.x86
.R_IP
= target
;
5173 DECODE_CLEAR_SEGOVR();
5177 static u8 (*opc80_byte_operation
[])(u8 d
, u8 s
) =
5189 /****************************************************************************
5192 ****************************************************************************/
5193 void x86emuOp_opc80_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
5202 * Weirdo special case instruction format. Part of the opcode
5203 * held below in "RH". Doubly nested case would result, except
5204 * that the decoded instruction
5207 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5209 if (DEBUG_DECODE()) {
5213 DECODE_PRINTF("ADD\t");
5216 DECODE_PRINTF("OR\t");
5219 DECODE_PRINTF("ADC\t");
5222 DECODE_PRINTF("SBB\t");
5225 DECODE_PRINTF("AND\t");
5228 DECODE_PRINTF("SUB\t");
5231 DECODE_PRINTF("XOR\t");
5234 DECODE_PRINTF("CMP\t");
5239 /* know operation, decode the mod byte to find the addressing
5243 DECODE_PRINTF("BYTE PTR ");
5244 destoffset
= decode_rm00_address(rl
);
5246 destval
= fetch_data_byte(destoffset
);
5247 imm
= fetch_byte_imm();
5248 DECODE_PRINTF2("%x\n", imm
);
5250 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5252 store_data_byte(destoffset
, destval
);
5255 DECODE_PRINTF("BYTE PTR ");
5256 destoffset
= decode_rm01_address(rl
);
5258 destval
= fetch_data_byte(destoffset
);
5259 imm
= fetch_byte_imm();
5260 DECODE_PRINTF2("%x\n", imm
);
5262 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5264 store_data_byte(destoffset
, destval
);
5267 DECODE_PRINTF("BYTE PTR ");
5268 destoffset
= decode_rm10_address(rl
);
5270 destval
= fetch_data_byte(destoffset
);
5271 imm
= fetch_byte_imm();
5272 DECODE_PRINTF2("%x\n", imm
);
5274 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5276 store_data_byte(destoffset
, destval
);
5278 case 3: /* register to register */
5279 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5281 imm
= fetch_byte_imm();
5282 DECODE_PRINTF2("%x\n", imm
);
5284 destval
= (*opc80_byte_operation
[rh
]) (*destreg
, imm
);
5289 DECODE_CLEAR_SEGOVR();
5293 static u16 (*opc81_word_operation
[])(u16 d
, u16 s
) =
5305 static u32 (*opc81_long_operation
[])(u32 d
, u32 s
) =
5317 /****************************************************************************
5320 ****************************************************************************/
5321 void x86emuOp_opc81_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
5327 * Weirdo special case instruction format. Part of the opcode
5328 * held below in "RH". Doubly nested case would result, except
5329 * that the decoded instruction
5332 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5334 if (DEBUG_DECODE()) {
5338 DECODE_PRINTF("ADD\t");
5341 DECODE_PRINTF("OR\t");
5344 DECODE_PRINTF("ADC\t");
5347 DECODE_PRINTF("SBB\t");
5350 DECODE_PRINTF("AND\t");
5353 DECODE_PRINTF("SUB\t");
5356 DECODE_PRINTF("XOR\t");
5359 DECODE_PRINTF("CMP\t");
5365 * Know operation, decode the mod byte to find the addressing
5370 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5373 DECODE_PRINTF("DWORD PTR ");
5374 destoffset
= decode_rm00_address(rl
);
5376 destval
= fetch_data_long(destoffset
);
5377 imm
= fetch_long_imm();
5378 DECODE_PRINTF2("%x\n", imm
);
5380 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5382 store_data_long(destoffset
, destval
);
5386 DECODE_PRINTF("WORD PTR ");
5387 destoffset
= decode_rm00_address(rl
);
5389 destval
= fetch_data_word(destoffset
);
5390 imm
= fetch_word_imm();
5391 DECODE_PRINTF2("%x\n", imm
);
5393 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5395 store_data_word(destoffset
, destval
);
5399 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5402 DECODE_PRINTF("DWORD PTR ");
5403 destoffset
= decode_rm01_address(rl
);
5405 destval
= fetch_data_long(destoffset
);
5406 imm
= fetch_long_imm();
5407 DECODE_PRINTF2("%x\n", imm
);
5409 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5411 store_data_long(destoffset
, destval
);
5415 DECODE_PRINTF("WORD PTR ");
5416 destoffset
= decode_rm01_address(rl
);
5418 destval
= fetch_data_word(destoffset
);
5419 imm
= fetch_word_imm();
5420 DECODE_PRINTF2("%x\n", imm
);
5422 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5424 store_data_word(destoffset
, destval
);
5428 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5431 DECODE_PRINTF("DWORD PTR ");
5432 destoffset
= decode_rm10_address(rl
);
5434 destval
= fetch_data_long(destoffset
);
5435 imm
= fetch_long_imm();
5436 DECODE_PRINTF2("%x\n", imm
);
5438 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5440 store_data_long(destoffset
, destval
);
5444 DECODE_PRINTF("WORD PTR ");
5445 destoffset
= decode_rm10_address(rl
);
5447 destval
= fetch_data_word(destoffset
);
5448 imm
= fetch_word_imm();
5449 DECODE_PRINTF2("%x\n", imm
);
5451 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5453 store_data_word(destoffset
, destval
);
5456 case 3: /* register to register */
5457 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5461 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5463 imm
= fetch_long_imm();
5464 DECODE_PRINTF2("%x\n", imm
);
5466 destval
= (*opc81_long_operation
[rh
]) (*destreg
, imm
);
5473 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5475 imm
= fetch_word_imm();
5476 DECODE_PRINTF2("%x\n", imm
);
5478 destval
= (*opc81_word_operation
[rh
]) (*destreg
, imm
);
5484 DECODE_CLEAR_SEGOVR();
5488 static u8 (*opc82_byte_operation
[])(u8 s
, u8 d
) =
5491 or_byte
, /*01 *//*YYY UNUSED ???? */
5494 and_byte
, /*04 *//*YYY UNUSED ???? */
5496 xor_byte
, /*06 *//*YYY UNUSED ???? */
5500 /****************************************************************************
5503 ****************************************************************************/
5504 void x86emuOp_opc82_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
5513 * Weirdo special case instruction format. Part of the opcode
5514 * held below in "RH". Doubly nested case would result, except
5515 * that the decoded instruction Similar to opcode 81, except that
5516 * the immediate byte is sign extended to a word length.
5519 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5521 if (DEBUG_DECODE()) {
5524 DECODE_PRINTF("ADD\t");
5527 DECODE_PRINTF("OR\t");
5530 DECODE_PRINTF("ADC\t");
5533 DECODE_PRINTF("SBB\t");
5536 DECODE_PRINTF("AND\t");
5539 DECODE_PRINTF("SUB\t");
5542 DECODE_PRINTF("XOR\t");
5545 DECODE_PRINTF("CMP\t");
5550 /* know operation, decode the mod byte to find the addressing
5554 DECODE_PRINTF("BYTE PTR ");
5555 destoffset
= decode_rm00_address(rl
);
5556 destval
= fetch_data_byte(destoffset
);
5557 imm
= fetch_byte_imm();
5558 DECODE_PRINTF2(",%x\n", imm
);
5560 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5562 store_data_byte(destoffset
, destval
);
5565 DECODE_PRINTF("BYTE PTR ");
5566 destoffset
= decode_rm01_address(rl
);
5567 destval
= fetch_data_byte(destoffset
);
5568 imm
= fetch_byte_imm();
5569 DECODE_PRINTF2(",%x\n", imm
);
5571 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5573 store_data_byte(destoffset
, destval
);
5576 DECODE_PRINTF("BYTE PTR ");
5577 destoffset
= decode_rm10_address(rl
);
5578 destval
= fetch_data_byte(destoffset
);
5579 imm
= fetch_byte_imm();
5580 DECODE_PRINTF2(",%x\n", imm
);
5582 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5584 store_data_byte(destoffset
, destval
);
5586 case 3: /* register to register */
5587 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5588 imm
= fetch_byte_imm();
5589 DECODE_PRINTF2(",%x\n", imm
);
5591 destval
= (*opc82_byte_operation
[rh
]) (*destreg
, imm
);
5596 DECODE_CLEAR_SEGOVR();
5600 static u16 (*opc83_word_operation
[])(u16 s
, u16 d
) =
5603 or_word
, /*01 *//*YYY UNUSED ???? */
5606 and_word
, /*04 *//*YYY UNUSED ???? */
5608 xor_word
, /*06 *//*YYY UNUSED ???? */
5612 static u32 (*opc83_long_operation
[])(u32 s
, u32 d
) =
5615 or_long
, /*01 *//*YYY UNUSED ???? */
5618 and_long
, /*04 *//*YYY UNUSED ???? */
5620 xor_long
, /*06 *//*YYY UNUSED ???? */
5624 /****************************************************************************
5627 ****************************************************************************/
5628 void x86emuOp_opc83_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
5634 * Weirdo special case instruction format. Part of the opcode
5635 * held below in "RH". Doubly nested case would result, except
5636 * that the decoded instruction Similar to opcode 81, except that
5637 * the immediate byte is sign extended to a word length.
5640 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5642 if (DEBUG_DECODE()) {
5645 DECODE_PRINTF("ADD\t");
5648 DECODE_PRINTF("OR\t");
5651 DECODE_PRINTF("ADC\t");
5654 DECODE_PRINTF("SBB\t");
5657 DECODE_PRINTF("AND\t");
5660 DECODE_PRINTF("SUB\t");
5663 DECODE_PRINTF("XOR\t");
5666 DECODE_PRINTF("CMP\t");
5671 /* know operation, decode the mod byte to find the addressing
5675 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5678 DECODE_PRINTF("DWORD PTR ");
5679 destoffset
= decode_rm00_address(rl
);
5680 destval
= fetch_data_long(destoffset
);
5681 imm
= (s8
) fetch_byte_imm();
5682 DECODE_PRINTF2(",%x\n", imm
);
5684 destval
= (*opc83_long_operation
[rh
]) (destval
, imm
);
5686 store_data_long(destoffset
, destval
);
5690 DECODE_PRINTF("WORD PTR ");
5691 destoffset
= decode_rm00_address(rl
);
5692 destval
= fetch_data_word(destoffset
);
5693 imm
= (s8
) fetch_byte_imm();
5694 DECODE_PRINTF2(",%x\n", imm
);
5696 destval
= (*opc83_word_operation
[rh
]) (destval
, imm
);
5698 store_data_word(destoffset
, destval
);
5702 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5705 DECODE_PRINTF("DWORD PTR ");
5706 destoffset
= decode_rm01_address(rl
);
5707 destval
= fetch_data_long(destoffset
);
5708 imm
= (s8
) fetch_byte_imm();
5709 DECODE_PRINTF2(",%x\n", imm
);
5711 destval
= (*opc83_long_operation
[rh
]) (destval
, imm
);
5713 store_data_long(destoffset
, destval
);
5717 DECODE_PRINTF("WORD PTR ");
5718 destoffset
= decode_rm01_address(rl
);
5719 destval
= fetch_data_word(destoffset
);
5720 imm
= (s8
) fetch_byte_imm();
5721 DECODE_PRINTF2(",%x\n", imm
);
5723 destval
= (*opc83_word_operation
[rh
]) (destval
, imm
);
5725 store_data_word(destoffset
, destval
);
5729 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5732 DECODE_PRINTF("DWORD PTR ");
5733 destoffset
= decode_rm10_address(rl
);
5734 destval
= fetch_data_long(destoffset
);
5735 imm
= (s8
) fetch_byte_imm();
5736 DECODE_PRINTF2(",%x\n", imm
);
5738 destval
= (*opc83_long_operation
[rh
]) (destval
, imm
);
5740 store_data_long(destoffset
, destval
);
5744 DECODE_PRINTF("WORD PTR ");
5745 destoffset
= decode_rm10_address(rl
);
5746 destval
= fetch_data_word(destoffset
);
5747 imm
= (s8
) fetch_byte_imm();
5748 DECODE_PRINTF2(",%x\n", imm
);
5750 destval
= (*opc83_word_operation
[rh
]) (destval
, imm
);
5752 store_data_word(destoffset
, destval
);
5755 case 3: /* register to register */
5756 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5760 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5761 imm
= (s8
) fetch_byte_imm();
5762 DECODE_PRINTF2(",%x\n", imm
);
5764 destval
= (*opc83_long_operation
[rh
]) (*destreg
, imm
);
5771 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5772 imm
= (s8
) fetch_byte_imm();
5773 DECODE_PRINTF2(",%x\n", imm
);
5775 destval
= (*opc83_word_operation
[rh
]) (*destreg
, imm
);
5781 DECODE_CLEAR_SEGOVR();
5785 /****************************************************************************
5788 ****************************************************************************/
5789 void x86emuOp_test_byte_RM_R(u8
X86EMU_UNUSED(op1
))
5792 u8
*destreg
, *srcreg
;
5797 DECODE_PRINTF("TEST\t");
5798 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5801 destoffset
= decode_rm00_address(rl
);
5803 destval
= fetch_data_byte(destoffset
);
5804 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5805 DECODE_PRINTF("\n");
5807 test_byte(destval
, *srcreg
);
5810 destoffset
= decode_rm01_address(rl
);
5812 destval
= fetch_data_byte(destoffset
);
5813 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5814 DECODE_PRINTF("\n");
5816 test_byte(destval
, *srcreg
);
5819 destoffset
= decode_rm10_address(rl
);
5821 destval
= fetch_data_byte(destoffset
);
5822 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5823 DECODE_PRINTF("\n");
5825 test_byte(destval
, *srcreg
);
5827 case 3: /* register to register */
5828 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5830 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5831 DECODE_PRINTF("\n");
5833 test_byte(*destreg
, *srcreg
);
5836 DECODE_CLEAR_SEGOVR();
5840 /****************************************************************************
5843 ****************************************************************************/
5844 void x86emuOp_test_word_RM_R(u8
X86EMU_UNUSED(op1
))
5850 DECODE_PRINTF("TEST\t");
5851 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5854 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5858 destoffset
= decode_rm00_address(rl
);
5860 destval
= fetch_data_long(destoffset
);
5861 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5862 DECODE_PRINTF("\n");
5864 test_long(destval
, *srcreg
);
5869 destoffset
= decode_rm00_address(rl
);
5871 destval
= fetch_data_word(destoffset
);
5872 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5873 DECODE_PRINTF("\n");
5875 test_word(destval
, *srcreg
);
5879 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5883 destoffset
= decode_rm01_address(rl
);
5885 destval
= fetch_data_long(destoffset
);
5886 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5887 DECODE_PRINTF("\n");
5889 test_long(destval
, *srcreg
);
5894 destoffset
= decode_rm01_address(rl
);
5896 destval
= fetch_data_word(destoffset
);
5897 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5898 DECODE_PRINTF("\n");
5900 test_word(destval
, *srcreg
);
5904 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5908 destoffset
= decode_rm10_address(rl
);
5910 destval
= fetch_data_long(destoffset
);
5911 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5912 DECODE_PRINTF("\n");
5914 test_long(destval
, *srcreg
);
5919 destoffset
= decode_rm10_address(rl
);
5921 destval
= fetch_data_word(destoffset
);
5922 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5923 DECODE_PRINTF("\n");
5925 test_word(destval
, *srcreg
);
5928 case 3: /* register to register */
5929 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5930 u32
*destreg
,*srcreg
;
5932 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5934 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5935 DECODE_PRINTF("\n");
5937 test_long(*destreg
, *srcreg
);
5939 u16
*destreg
,*srcreg
;
5941 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5943 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5944 DECODE_PRINTF("\n");
5946 test_word(*destreg
, *srcreg
);
5950 DECODE_CLEAR_SEGOVR();
5954 /****************************************************************************
5957 ****************************************************************************/
5958 void x86emuOp_xchg_byte_RM_R(u8
X86EMU_UNUSED(op1
))
5961 u8
*destreg
, *srcreg
;
5967 DECODE_PRINTF("XCHG\t");
5968 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5971 destoffset
= decode_rm00_address(rl
);
5973 destval
= fetch_data_byte(destoffset
);
5974 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5975 DECODE_PRINTF("\n");
5980 store_data_byte(destoffset
, destval
);
5983 destoffset
= decode_rm01_address(rl
);
5985 destval
= fetch_data_byte(destoffset
);
5986 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5987 DECODE_PRINTF("\n");
5992 store_data_byte(destoffset
, destval
);
5995 destoffset
= decode_rm10_address(rl
);
5997 destval
= fetch_data_byte(destoffset
);
5998 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5999 DECODE_PRINTF("\n");
6004 store_data_byte(destoffset
, destval
);
6006 case 3: /* register to register */
6007 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
6009 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6010 DECODE_PRINTF("\n");
6017 DECODE_CLEAR_SEGOVR();
6021 /****************************************************************************
6024 ****************************************************************************/
6025 void x86emuOp_xchg_word_RM_R(u8
X86EMU_UNUSED(op1
))
6031 DECODE_PRINTF("XCHG\t");
6032 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6035 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6039 destoffset
= decode_rm00_address(rl
);
6041 destval
= fetch_data_long(destoffset
);
6042 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6043 DECODE_PRINTF("\n");
6048 store_data_long(destoffset
, destval
);
6053 destoffset
= decode_rm00_address(rl
);
6055 destval
= fetch_data_word(destoffset
);
6056 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6057 DECODE_PRINTF("\n");
6062 store_data_word(destoffset
, destval
);
6066 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6070 destoffset
= decode_rm01_address(rl
);
6072 destval
= fetch_data_long(destoffset
);
6073 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6074 DECODE_PRINTF("\n");
6079 store_data_long(destoffset
, destval
);
6084 destoffset
= decode_rm01_address(rl
);
6086 destval
= fetch_data_word(destoffset
);
6087 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6088 DECODE_PRINTF("\n");
6093 store_data_word(destoffset
, destval
);
6097 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6101 destoffset
= decode_rm10_address(rl
);
6103 destval
= fetch_data_long(destoffset
);
6104 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6105 DECODE_PRINTF("\n");
6110 store_data_long(destoffset
, destval
);
6115 destoffset
= decode_rm10_address(rl
);
6117 destval
= fetch_data_word(destoffset
);
6118 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6119 DECODE_PRINTF("\n");
6124 store_data_word(destoffset
, destval
);
6127 case 3: /* register to register */
6128 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6129 u32
*destreg
,*srcreg
;
6132 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6134 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6135 DECODE_PRINTF("\n");
6141 u16
*destreg
,*srcreg
;
6144 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6146 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6147 DECODE_PRINTF("\n");
6155 DECODE_CLEAR_SEGOVR();
6159 /****************************************************************************
6162 ****************************************************************************/
6163 void x86emuOp_mov_byte_RM_R(u8
X86EMU_UNUSED(op1
))
6166 u8
*destreg
, *srcreg
;
6170 DECODE_PRINTF("MOV\t");
6171 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6174 destoffset
= decode_rm00_address(rl
);
6176 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6177 DECODE_PRINTF("\n");
6179 store_data_byte(destoffset
, *srcreg
);
6182 destoffset
= decode_rm01_address(rl
);
6184 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6185 DECODE_PRINTF("\n");
6187 store_data_byte(destoffset
, *srcreg
);
6190 destoffset
= decode_rm10_address(rl
);
6192 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6193 DECODE_PRINTF("\n");
6195 store_data_byte(destoffset
, *srcreg
);
6197 case 3: /* register to register */
6198 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
6200 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6201 DECODE_PRINTF("\n");
6206 DECODE_CLEAR_SEGOVR();
6210 /****************************************************************************
6213 ****************************************************************************/
6214 void x86emuOp_mov_word_RM_R(u8
X86EMU_UNUSED(op1
))
6220 DECODE_PRINTF("MOV\t");
6221 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6224 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6227 destoffset
= decode_rm00_address(rl
);
6229 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6230 DECODE_PRINTF("\n");
6232 store_data_long(destoffset
, *srcreg
);
6236 destoffset
= decode_rm00_address(rl
);
6238 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6239 DECODE_PRINTF("\n");
6241 store_data_word(destoffset
, *srcreg
);
6245 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6248 destoffset
= decode_rm01_address(rl
);
6250 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6251 DECODE_PRINTF("\n");
6253 store_data_long(destoffset
, *srcreg
);
6257 destoffset
= decode_rm01_address(rl
);
6259 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6260 DECODE_PRINTF("\n");
6262 store_data_word(destoffset
, *srcreg
);
6266 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6269 destoffset
= decode_rm10_address(rl
);
6271 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6272 DECODE_PRINTF("\n");
6274 store_data_long(destoffset
, *srcreg
);
6278 destoffset
= decode_rm10_address(rl
);
6280 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6281 DECODE_PRINTF("\n");
6283 store_data_word(destoffset
, *srcreg
);
6286 case 3: /* register to register */
6287 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6288 u32
*destreg
,*srcreg
;
6290 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6292 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6293 DECODE_PRINTF("\n");
6297 u16
*destreg
,*srcreg
;
6299 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6301 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6302 DECODE_PRINTF("\n");
6308 DECODE_CLEAR_SEGOVR();
6312 /****************************************************************************
6315 ****************************************************************************/
6316 void x86emuOp_mov_byte_R_RM(u8
X86EMU_UNUSED(op1
))
6319 u8
*destreg
, *srcreg
;
6324 DECODE_PRINTF("MOV\t");
6325 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6328 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6330 srcoffset
= decode_rm00_address(rl
);
6331 srcval
= fetch_data_byte(srcoffset
);
6332 DECODE_PRINTF("\n");
6337 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6339 srcoffset
= decode_rm01_address(rl
);
6340 srcval
= fetch_data_byte(srcoffset
);
6341 DECODE_PRINTF("\n");
6346 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6348 srcoffset
= decode_rm10_address(rl
);
6349 srcval
= fetch_data_byte(srcoffset
);
6350 DECODE_PRINTF("\n");
6354 case 3: /* register to register */
6355 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6357 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
6358 DECODE_PRINTF("\n");
6363 DECODE_CLEAR_SEGOVR();
6367 /****************************************************************************
6370 ****************************************************************************/
6371 void x86emuOp_mov_word_R_RM(u8
X86EMU_UNUSED(op1
))
6377 DECODE_PRINTF("MOV\t");
6378 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6381 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6385 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6387 srcoffset
= decode_rm00_address(rl
);
6388 srcval
= fetch_data_long(srcoffset
);
6389 DECODE_PRINTF("\n");
6396 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6398 srcoffset
= decode_rm00_address(rl
);
6399 srcval
= fetch_data_word(srcoffset
);
6400 DECODE_PRINTF("\n");
6406 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6410 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6412 srcoffset
= decode_rm01_address(rl
);
6413 srcval
= fetch_data_long(srcoffset
);
6414 DECODE_PRINTF("\n");
6421 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6423 srcoffset
= decode_rm01_address(rl
);
6424 srcval
= fetch_data_word(srcoffset
);
6425 DECODE_PRINTF("\n");
6431 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6435 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6437 srcoffset
= decode_rm10_address(rl
);
6438 srcval
= fetch_data_long(srcoffset
);
6439 DECODE_PRINTF("\n");
6446 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6448 srcoffset
= decode_rm10_address(rl
);
6449 srcval
= fetch_data_word(srcoffset
);
6450 DECODE_PRINTF("\n");
6455 case 3: /* register to register */
6456 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6457 u32
*destreg
, *srcreg
;
6459 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6461 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
6462 DECODE_PRINTF("\n");
6466 u16
*destreg
, *srcreg
;
6468 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6470 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
6471 DECODE_PRINTF("\n");
6477 DECODE_CLEAR_SEGOVR();
6481 /****************************************************************************
6484 ****************************************************************************/
6485 void x86emuOp_mov_word_RM_SR(u8
X86EMU_UNUSED(op1
))
6488 u16
*destreg
, *srcreg
;
6493 DECODE_PRINTF("MOV\t");
6494 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6497 destoffset
= decode_rm00_address(rl
);
6499 srcreg
= decode_rm_seg_register(rh
);
6500 DECODE_PRINTF("\n");
6503 store_data_word(destoffset
, destval
);
6506 destoffset
= decode_rm01_address(rl
);
6508 srcreg
= decode_rm_seg_register(rh
);
6509 DECODE_PRINTF("\n");
6512 store_data_word(destoffset
, destval
);
6515 destoffset
= decode_rm10_address(rl
);
6517 srcreg
= decode_rm_seg_register(rh
);
6518 DECODE_PRINTF("\n");
6521 store_data_word(destoffset
, destval
);
6523 case 3: /* register to register */
6524 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6526 srcreg
= decode_rm_seg_register(rh
);
6527 DECODE_PRINTF("\n");
6532 DECODE_CLEAR_SEGOVR();
6536 /****************************************************************************
6539 ****************************************************************************/
6540 void x86emuOp_lea_word_R_M(u8
X86EMU_UNUSED(op1
))
6547 * TODO: Need to handle address size prefix!
6549 * lea eax,[eax+ebx*2] ??
6553 DECODE_PRINTF("LEA\t");
6554 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6557 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6559 destoffset
= decode_rm00_address(rl
);
6560 DECODE_PRINTF("\n");
6562 *srcreg
= (u16
)destoffset
;
6565 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6567 destoffset
= decode_rm01_address(rl
);
6568 DECODE_PRINTF("\n");
6570 *srcreg
= (u16
)destoffset
;
6573 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6575 destoffset
= decode_rm10_address(rl
);
6576 DECODE_PRINTF("\n");
6578 *srcreg
= (u16
)destoffset
;
6580 case 3: /* register to register */
6581 /* undefined. Do nothing. */
6584 DECODE_CLEAR_SEGOVR();
6588 /****************************************************************************
6591 ****************************************************************************/
6592 void x86emuOp_mov_word_SR_RM(u8
X86EMU_UNUSED(op1
))
6595 u16
*destreg
, *srcreg
;
6600 DECODE_PRINTF("MOV\t");
6601 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6604 destreg
= decode_rm_seg_register(rh
);
6606 srcoffset
= decode_rm00_address(rl
);
6607 srcval
= fetch_data_word(srcoffset
);
6608 DECODE_PRINTF("\n");
6613 destreg
= decode_rm_seg_register(rh
);
6615 srcoffset
= decode_rm01_address(rl
);
6616 srcval
= fetch_data_word(srcoffset
);
6617 DECODE_PRINTF("\n");
6622 destreg
= decode_rm_seg_register(rh
);
6624 srcoffset
= decode_rm10_address(rl
);
6625 srcval
= fetch_data_word(srcoffset
);
6626 DECODE_PRINTF("\n");
6630 case 3: /* register to register */
6631 destreg
= decode_rm_seg_register(rh
);
6633 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
6634 DECODE_PRINTF("\n");
6640 * Clean up, and reset all the R_xSP pointers to the correct
6641 * locations. This is about 3x too much overhead (doing all the
6642 * segreg ptrs when only one is needed, but this instruction
6643 * *cannot* be that common, and this isn't too much work anyway.
6645 DECODE_CLEAR_SEGOVR();
6649 /****************************************************************************
6652 ****************************************************************************/
6653 void x86emuOp_pop_RM(u8
X86EMU_UNUSED(op1
))
6659 DECODE_PRINTF("POP\t");
6660 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6662 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6667 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6670 destoffset
= decode_rm00_address(rl
);
6671 DECODE_PRINTF("\n");
6673 destval
= pop_long();
6674 store_data_long(destoffset
, destval
);
6678 destoffset
= decode_rm00_address(rl
);
6679 DECODE_PRINTF("\n");
6681 destval
= pop_word();
6682 store_data_word(destoffset
, destval
);
6686 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6689 destoffset
= decode_rm01_address(rl
);
6690 DECODE_PRINTF("\n");
6692 destval
= pop_long();
6693 store_data_long(destoffset
, destval
);
6697 destoffset
= decode_rm01_address(rl
);
6698 DECODE_PRINTF("\n");
6700 destval
= pop_word();
6701 store_data_word(destoffset
, destval
);
6705 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6708 destoffset
= decode_rm10_address(rl
);
6709 DECODE_PRINTF("\n");
6711 destval
= pop_long();
6712 store_data_long(destoffset
, destval
);
6716 destoffset
= decode_rm10_address(rl
);
6717 DECODE_PRINTF("\n");
6719 destval
= pop_word();
6720 store_data_word(destoffset
, destval
);
6723 case 3: /* register to register */
6724 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6727 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6728 DECODE_PRINTF("\n");
6730 *destreg
= pop_long();
6734 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6735 DECODE_PRINTF("\n");
6737 *destreg
= pop_word();
6741 DECODE_CLEAR_SEGOVR();
6745 /****************************************************************************
6748 ****************************************************************************/
6749 void x86emuOp_nop(u8
X86EMU_UNUSED(op1
))
6752 DECODE_PRINTF("NOP\n");
6754 DECODE_CLEAR_SEGOVR();
6758 /****************************************************************************
6761 ****************************************************************************/
6762 void x86emuOp_xchg_word_AX_CX(u8
X86EMU_UNUSED(op1
))
6767 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6768 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6770 DECODE_PRINTF("XCHG\tAX,CX\n");
6773 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6775 M
.x86
.R_EAX
= M
.x86
.R_ECX
;
6779 M
.x86
.R_AX
= M
.x86
.R_CX
;
6780 M
.x86
.R_CX
= (u16
)tmp
;
6782 DECODE_CLEAR_SEGOVR();
6786 /****************************************************************************
6789 ****************************************************************************/
6790 void x86emuOp_xchg_word_AX_DX(u8
X86EMU_UNUSED(op1
))
6795 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6796 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6798 DECODE_PRINTF("XCHG\tAX,DX\n");
6801 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6803 M
.x86
.R_EAX
= M
.x86
.R_EDX
;
6807 M
.x86
.R_AX
= M
.x86
.R_DX
;
6808 M
.x86
.R_DX
= (u16
)tmp
;
6810 DECODE_CLEAR_SEGOVR();
6814 /****************************************************************************
6817 ****************************************************************************/
6818 void x86emuOp_xchg_word_AX_BX(u8
X86EMU_UNUSED(op1
))
6823 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6824 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6826 DECODE_PRINTF("XCHG\tAX,BX\n");
6829 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6831 M
.x86
.R_EAX
= M
.x86
.R_EBX
;
6835 M
.x86
.R_AX
= M
.x86
.R_BX
;
6836 M
.x86
.R_BX
= (u16
)tmp
;
6838 DECODE_CLEAR_SEGOVR();
6842 /****************************************************************************
6845 ****************************************************************************/
6846 void x86emuOp_xchg_word_AX_SP(u8
X86EMU_UNUSED(op1
))
6851 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6852 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6854 DECODE_PRINTF("XCHG\tAX,SP\n");
6857 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6859 M
.x86
.R_EAX
= M
.x86
.R_ESP
;
6863 M
.x86
.R_AX
= M
.x86
.R_SP
;
6864 M
.x86
.R_SP
= (u16
)tmp
;
6866 DECODE_CLEAR_SEGOVR();
6870 /****************************************************************************
6873 ****************************************************************************/
6874 void x86emuOp_xchg_word_AX_BP(u8
X86EMU_UNUSED(op1
))
6879 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6880 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6882 DECODE_PRINTF("XCHG\tAX,BP\n");
6885 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6887 M
.x86
.R_EAX
= M
.x86
.R_EBP
;
6891 M
.x86
.R_AX
= M
.x86
.R_BP
;
6892 M
.x86
.R_BP
= (u16
)tmp
;
6894 DECODE_CLEAR_SEGOVR();
6898 /****************************************************************************
6901 ****************************************************************************/
6902 void x86emuOp_xchg_word_AX_SI(u8
X86EMU_UNUSED(op1
))
6907 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6908 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6910 DECODE_PRINTF("XCHG\tAX,SI\n");
6913 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6915 M
.x86
.R_EAX
= M
.x86
.R_ESI
;
6919 M
.x86
.R_AX
= M
.x86
.R_SI
;
6920 M
.x86
.R_SI
= (u16
)tmp
;
6922 DECODE_CLEAR_SEGOVR();
6926 /****************************************************************************
6929 ****************************************************************************/
6930 void x86emuOp_xchg_word_AX_DI(u8
X86EMU_UNUSED(op1
))
6935 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6936 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6938 DECODE_PRINTF("XCHG\tAX,DI\n");
6941 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6943 M
.x86
.R_EAX
= M
.x86
.R_EDI
;
6947 M
.x86
.R_AX
= M
.x86
.R_DI
;
6948 M
.x86
.R_DI
= (u16
)tmp
;
6950 DECODE_CLEAR_SEGOVR();
6954 /****************************************************************************
6957 ****************************************************************************/
6958 void x86emuOp_cbw(u8
X86EMU_UNUSED(op1
))
6961 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6962 DECODE_PRINTF("CWDE\n");
6964 DECODE_PRINTF("CBW\n");
6967 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6968 if (M
.x86
.R_AX
& 0x8000) {
6969 M
.x86
.R_EAX
|= 0xffff0000;
6971 M
.x86
.R_EAX
&= 0x0000ffff;
6974 if (M
.x86
.R_AL
& 0x80) {
6980 DECODE_CLEAR_SEGOVR();
6984 /****************************************************************************
6987 ****************************************************************************/
6988 void x86emuOp_cwd(u8
X86EMU_UNUSED(op1
))
6991 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6992 DECODE_PRINTF("CDQ\n");
6994 DECODE_PRINTF("CWD\n");
6996 DECODE_PRINTF("CWD\n");
6998 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6999 if (M
.x86
.R_EAX
& 0x80000000) {
7000 M
.x86
.R_EDX
= 0xffffffff;
7005 if (M
.x86
.R_AX
& 0x8000) {
7006 M
.x86
.R_DX
= 0xffff;
7011 DECODE_CLEAR_SEGOVR();
7015 /****************************************************************************
7018 ****************************************************************************/
7019 void x86emuOp_call_far_IMM(u8
X86EMU_UNUSED(op1
))
7024 DECODE_PRINTF("CALL\t");
7025 faroff
= fetch_word_imm();
7026 farseg
= fetch_word_imm();
7027 DECODE_PRINTF2("%04x:", farseg
);
7028 DECODE_PRINTF2("%04x\n", faroff
);
7029 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, farseg
, faroff
, "FAR ");
7032 push_word(M
.x86
.R_CS
);
7033 M
.x86
.R_CS
= farseg
;
7034 push_word(M
.x86
.R_IP
);
7035 M
.x86
.R_IP
= faroff
;
7036 DECODE_CLEAR_SEGOVR();
7040 /****************************************************************************
7043 ****************************************************************************/
7044 void x86emuOp_wait(u8
X86EMU_UNUSED(op1
))
7047 DECODE_PRINTF("WAIT");
7050 DECODE_CLEAR_SEGOVR();
7054 /****************************************************************************
7057 ****************************************************************************/
7058 void x86emuOp_pushf_word(u8
X86EMU_UNUSED(op1
))
7063 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7064 DECODE_PRINTF("PUSHFD\n");
7066 DECODE_PRINTF("PUSHF\n");
7070 /* clear out *all* bits not representing flags, and turn on real bits */
7071 flags
= (M
.x86
.R_EFLG
& F_MSK
) | F_ALWAYS_ON
;
7072 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7075 push_word((u16
)flags
);
7077 DECODE_CLEAR_SEGOVR();
7081 /****************************************************************************
7084 ****************************************************************************/
7085 void x86emuOp_popf_word(u8
X86EMU_UNUSED(op1
))
7088 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7089 DECODE_PRINTF("POPFD\n");
7091 DECODE_PRINTF("POPF\n");
7094 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7095 M
.x86
.R_EFLG
= pop_long();
7097 M
.x86
.R_FLG
= pop_word();
7099 DECODE_CLEAR_SEGOVR();
7103 /****************************************************************************
7106 ****************************************************************************/
7107 void x86emuOp_sahf(u8
X86EMU_UNUSED(op1
))
7110 DECODE_PRINTF("SAHF\n");
7112 /* clear the lower bits of the flag register */
7113 M
.x86
.R_FLG
&= 0xffffff00;
7114 /* or in the AH register into the flags register */
7115 M
.x86
.R_FLG
|= M
.x86
.R_AH
;
7116 DECODE_CLEAR_SEGOVR();
7120 /****************************************************************************
7123 ****************************************************************************/
7124 void x86emuOp_lahf(u8
X86EMU_UNUSED(op1
))
7127 DECODE_PRINTF("LAHF\n");
7129 M
.x86
.R_AH
= (u8
)(M
.x86
.R_FLG
& 0xff);
7130 /*undocumented TC++ behavior??? Nope. It's documented, but
7131 you have too look real hard to notice it. */
7133 DECODE_CLEAR_SEGOVR();
7137 /****************************************************************************
7140 ****************************************************************************/
7141 void x86emuOp_mov_AL_M_IMM(u8
X86EMU_UNUSED(op1
))
7146 DECODE_PRINTF("MOV\tAL,");
7147 offset
= fetch_word_imm();
7148 DECODE_PRINTF2("[%04x]\n", offset
);
7150 M
.x86
.R_AL
= fetch_data_byte(offset
);
7151 DECODE_CLEAR_SEGOVR();
7155 /****************************************************************************
7158 ****************************************************************************/
7159 void x86emuOp_mov_AX_M_IMM(u8
X86EMU_UNUSED(op1
))
7164 offset
= fetch_word_imm();
7165 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7166 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset
);
7168 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset
);
7171 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7172 M
.x86
.R_EAX
= fetch_data_long(offset
);
7174 M
.x86
.R_AX
= fetch_data_word(offset
);
7176 DECODE_CLEAR_SEGOVR();
7180 /****************************************************************************
7183 ****************************************************************************/
7184 void x86emuOp_mov_M_AL_IMM(u8
X86EMU_UNUSED(op1
))
7189 DECODE_PRINTF("MOV\t");
7190 offset
= fetch_word_imm();
7191 DECODE_PRINTF2("[%04x],AL\n", offset
);
7193 store_data_byte(offset
, M
.x86
.R_AL
);
7194 DECODE_CLEAR_SEGOVR();
7198 /****************************************************************************
7201 ****************************************************************************/
7202 void x86emuOp_mov_M_AX_IMM(u8
X86EMU_UNUSED(op1
))
7207 offset
= fetch_word_imm();
7208 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7209 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset
);
7211 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset
);
7214 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7215 store_data_long(offset
, M
.x86
.R_EAX
);
7217 store_data_word(offset
, M
.x86
.R_AX
);
7219 DECODE_CLEAR_SEGOVR();
7223 /****************************************************************************
7226 ****************************************************************************/
7227 void x86emuOp_movs_byte(u8
X86EMU_UNUSED(op1
))
7234 DECODE_PRINTF("MOVS\tBYTE\n");
7235 if (ACCESS_FLAG(F_DF
)) /* down */
7241 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7242 /* dont care whether REPE or REPNE */
7243 /* move them until CX is ZERO. */
7246 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7249 val
= fetch_data_byte(M
.x86
.R_SI
);
7250 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
7254 DECODE_CLEAR_SEGOVR();
7258 /****************************************************************************
7261 ****************************************************************************/
7262 void x86emuOp_movs_word(u8
X86EMU_UNUSED(op1
))
7269 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7270 DECODE_PRINTF("MOVS\tDWORD\n");
7271 if (ACCESS_FLAG(F_DF
)) /* down */
7276 DECODE_PRINTF("MOVS\tWORD\n");
7277 if (ACCESS_FLAG(F_DF
)) /* down */
7284 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7285 /* dont care whether REPE or REPNE */
7286 /* move them until CX is ZERO. */
7289 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7292 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7293 val
= fetch_data_long(M
.x86
.R_SI
);
7294 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
7296 val
= fetch_data_word(M
.x86
.R_SI
);
7297 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, (u16
)val
);
7302 DECODE_CLEAR_SEGOVR();
7306 /****************************************************************************
7309 ****************************************************************************/
7310 void x86emuOp_cmps_byte(u8
X86EMU_UNUSED(op1
))
7316 DECODE_PRINTF("CMPS\tBYTE\n");
7318 if (ACCESS_FLAG(F_DF
)) /* down */
7323 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7325 /* move them until CX is ZERO. */
7326 while (M
.x86
.R_CX
!= 0) {
7327 val1
= fetch_data_byte(M
.x86
.R_SI
);
7328 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7329 cmp_byte(val1
, val2
);
7333 if (ACCESS_FLAG(F_ZF
) == 0)
7336 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7337 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7339 /* move them until CX is ZERO. */
7340 while (M
.x86
.R_CX
!= 0) {
7341 val1
= fetch_data_byte(M
.x86
.R_SI
);
7342 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7343 cmp_byte(val1
, val2
);
7347 if (ACCESS_FLAG(F_ZF
))
7348 break; /* zero flag set means equal */
7350 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7352 val1
= fetch_data_byte(M
.x86
.R_SI
);
7353 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7354 cmp_byte(val1
, val2
);
7358 DECODE_CLEAR_SEGOVR();
7362 /****************************************************************************
7365 ****************************************************************************/
7366 void x86emuOp_cmps_word(u8
X86EMU_UNUSED(op1
))
7372 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7373 DECODE_PRINTF("CMPS\tDWORD\n");
7374 if (ACCESS_FLAG(F_DF
)) /* down */
7379 DECODE_PRINTF("CMPS\tWORD\n");
7380 if (ACCESS_FLAG(F_DF
)) /* down */
7386 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7388 /* move them until CX is ZERO. */
7389 while (M
.x86
.R_CX
!= 0) {
7390 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7391 val1
= fetch_data_long(M
.x86
.R_SI
);
7392 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7393 cmp_long(val1
, val2
);
7395 val1
= fetch_data_word(M
.x86
.R_SI
);
7396 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7397 cmp_word((u16
)val1
, (u16
)val2
);
7402 if (ACCESS_FLAG(F_ZF
) == 0)
7405 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7406 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7408 /* move them until CX is ZERO. */
7409 while (M
.x86
.R_CX
!= 0) {
7410 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7411 val1
= fetch_data_long(M
.x86
.R_SI
);
7412 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7413 cmp_long(val1
, val2
);
7415 val1
= fetch_data_word(M
.x86
.R_SI
);
7416 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7417 cmp_word((u16
)val1
, (u16
)val2
);
7422 if (ACCESS_FLAG(F_ZF
))
7423 break; /* zero flag set means equal */
7425 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7427 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7428 val1
= fetch_data_long(M
.x86
.R_SI
);
7429 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7430 cmp_long(val1
, val2
);
7432 val1
= fetch_data_word(M
.x86
.R_SI
);
7433 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7434 cmp_word((u16
)val1
, (u16
)val2
);
7439 DECODE_CLEAR_SEGOVR();
7443 /****************************************************************************
7446 ****************************************************************************/
7447 void x86emuOp_test_AL_IMM(u8
X86EMU_UNUSED(op1
))
7452 DECODE_PRINTF("TEST\tAL,");
7453 imm
= fetch_byte_imm();
7454 DECODE_PRINTF2("%04x\n", imm
);
7456 test_byte(M
.x86
.R_AL
, (u8
)imm
);
7457 DECODE_CLEAR_SEGOVR();
7461 /****************************************************************************
7464 ****************************************************************************/
7465 void x86emuOp_test_AX_IMM(u8
X86EMU_UNUSED(op1
))
7470 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7471 DECODE_PRINTF("TEST\tEAX,");
7472 srcval
= fetch_long_imm();
7474 DECODE_PRINTF("TEST\tAX,");
7475 srcval
= fetch_word_imm();
7477 DECODE_PRINTF2("%x\n", srcval
);
7479 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7480 test_long(M
.x86
.R_EAX
, srcval
);
7482 test_word(M
.x86
.R_AX
, (u16
)srcval
);
7484 DECODE_CLEAR_SEGOVR();
7488 /****************************************************************************
7491 ****************************************************************************/
7492 void x86emuOp_stos_byte(u8
X86EMU_UNUSED(op1
))
7497 DECODE_PRINTF("STOS\tBYTE\n");
7498 if (ACCESS_FLAG(F_DF
)) /* down */
7503 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7504 /* dont care whether REPE or REPNE */
7505 /* move them until CX is ZERO. */
7506 while (M
.x86
.R_CX
!= 0) {
7507 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
7511 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7513 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
7516 DECODE_CLEAR_SEGOVR();
7520 /****************************************************************************
7523 ****************************************************************************/
7524 void x86emuOp_stos_word(u8
X86EMU_UNUSED(op1
))
7530 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7531 DECODE_PRINTF("STOS\tDWORD\n");
7532 if (ACCESS_FLAG(F_DF
)) /* down */
7537 DECODE_PRINTF("STOS\tWORD\n");
7538 if (ACCESS_FLAG(F_DF
)) /* down */
7545 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7546 /* dont care whether REPE or REPNE */
7547 /* move them until CX is ZERO. */
7550 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7553 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7554 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_EAX
);
7556 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AX
);
7560 DECODE_CLEAR_SEGOVR();
7564 /****************************************************************************
7567 ****************************************************************************/
7568 void x86emuOp_lods_byte(u8
X86EMU_UNUSED(op1
))
7573 DECODE_PRINTF("LODS\tBYTE\n");
7575 if (ACCESS_FLAG(F_DF
)) /* down */
7579 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7580 /* dont care whether REPE or REPNE */
7581 /* move them until CX is ZERO. */
7582 while (M
.x86
.R_CX
!= 0) {
7583 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
7587 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7589 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
7592 DECODE_CLEAR_SEGOVR();
7596 /****************************************************************************
7599 ****************************************************************************/
7600 void x86emuOp_lods_word(u8
X86EMU_UNUSED(op1
))
7606 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7607 DECODE_PRINTF("LODS\tDWORD\n");
7608 if (ACCESS_FLAG(F_DF
)) /* down */
7613 DECODE_PRINTF("LODS\tWORD\n");
7614 if (ACCESS_FLAG(F_DF
)) /* down */
7621 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7622 /* dont care whether REPE or REPNE */
7623 /* move them until CX is ZERO. */
7626 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7629 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7630 M
.x86
.R_EAX
= fetch_data_long(M
.x86
.R_SI
);
7632 M
.x86
.R_AX
= fetch_data_word(M
.x86
.R_SI
);
7636 DECODE_CLEAR_SEGOVR();
7640 /****************************************************************************
7643 ****************************************************************************/
7644 void x86emuOp_scas_byte(u8
X86EMU_UNUSED(op1
))
7650 DECODE_PRINTF("SCAS\tBYTE\n");
7652 if (ACCESS_FLAG(F_DF
)) /* down */
7656 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7658 /* move them until CX is ZERO. */
7659 while (M
.x86
.R_CX
!= 0) {
7660 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7661 cmp_byte(M
.x86
.R_AL
, val2
);
7664 if (ACCESS_FLAG(F_ZF
) == 0)
7667 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7668 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7670 /* move them until CX is ZERO. */
7671 while (M
.x86
.R_CX
!= 0) {
7672 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7673 cmp_byte(M
.x86
.R_AL
, val2
);
7676 if (ACCESS_FLAG(F_ZF
))
7677 break; /* zero flag set means equal */
7679 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7681 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7682 cmp_byte(M
.x86
.R_AL
, val2
);
7685 DECODE_CLEAR_SEGOVR();
7689 /****************************************************************************
7692 ****************************************************************************/
7693 void x86emuOp_scas_word(u8
X86EMU_UNUSED(op1
))
7699 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7700 DECODE_PRINTF("SCAS\tDWORD\n");
7701 if (ACCESS_FLAG(F_DF
)) /* down */
7706 DECODE_PRINTF("SCAS\tWORD\n");
7707 if (ACCESS_FLAG(F_DF
)) /* down */
7713 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7715 /* move them until CX is ZERO. */
7716 while (M
.x86
.R_CX
!= 0) {
7717 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7718 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7719 cmp_long(M
.x86
.R_EAX
, val
);
7721 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7722 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7726 if (ACCESS_FLAG(F_ZF
) == 0)
7729 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7730 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7732 /* move them until CX is ZERO. */
7733 while (M
.x86
.R_CX
!= 0) {
7734 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7735 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7736 cmp_long(M
.x86
.R_EAX
, val
);
7738 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7739 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7743 if (ACCESS_FLAG(F_ZF
))
7744 break; /* zero flag set means equal */
7746 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7748 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7749 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7750 cmp_long(M
.x86
.R_EAX
, val
);
7752 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7753 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7757 DECODE_CLEAR_SEGOVR();
7761 /****************************************************************************
7764 ****************************************************************************/
7765 void x86emuOp_mov_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
7770 DECODE_PRINTF("MOV\tAL,");
7771 imm
= fetch_byte_imm();
7772 DECODE_PRINTF2("%x\n", imm
);
7775 DECODE_CLEAR_SEGOVR();
7779 /****************************************************************************
7782 ****************************************************************************/
7783 void x86emuOp_mov_byte_CL_IMM(u8
X86EMU_UNUSED(op1
))
7788 DECODE_PRINTF("MOV\tCL,");
7789 imm
= fetch_byte_imm();
7790 DECODE_PRINTF2("%x\n", imm
);
7793 DECODE_CLEAR_SEGOVR();
7797 /****************************************************************************
7800 ****************************************************************************/
7801 void x86emuOp_mov_byte_DL_IMM(u8
X86EMU_UNUSED(op1
))
7806 DECODE_PRINTF("MOV\tDL,");
7807 imm
= fetch_byte_imm();
7808 DECODE_PRINTF2("%x\n", imm
);
7811 DECODE_CLEAR_SEGOVR();
7815 /****************************************************************************
7818 ****************************************************************************/
7819 void x86emuOp_mov_byte_BL_IMM(u8
X86EMU_UNUSED(op1
))
7824 DECODE_PRINTF("MOV\tBL,");
7825 imm
= fetch_byte_imm();
7826 DECODE_PRINTF2("%x\n", imm
);
7829 DECODE_CLEAR_SEGOVR();
7833 /****************************************************************************
7836 ****************************************************************************/
7837 void x86emuOp_mov_byte_AH_IMM(u8
X86EMU_UNUSED(op1
))
7842 DECODE_PRINTF("MOV\tAH,");
7843 imm
= fetch_byte_imm();
7844 DECODE_PRINTF2("%x\n", imm
);
7847 DECODE_CLEAR_SEGOVR();
7851 /****************************************************************************
7854 ****************************************************************************/
7855 void x86emuOp_mov_byte_CH_IMM(u8
X86EMU_UNUSED(op1
))
7860 DECODE_PRINTF("MOV\tCH,");
7861 imm
= fetch_byte_imm();
7862 DECODE_PRINTF2("%x\n", imm
);
7865 DECODE_CLEAR_SEGOVR();
7869 /****************************************************************************
7872 ****************************************************************************/
7873 void x86emuOp_mov_byte_DH_IMM(u8
X86EMU_UNUSED(op1
))
7878 DECODE_PRINTF("MOV\tDH,");
7879 imm
= fetch_byte_imm();
7880 DECODE_PRINTF2("%x\n", imm
);
7883 DECODE_CLEAR_SEGOVR();
7887 /****************************************************************************
7890 ****************************************************************************/
7891 void x86emuOp_mov_byte_BH_IMM(u8
X86EMU_UNUSED(op1
))
7896 DECODE_PRINTF("MOV\tBH,");
7897 imm
= fetch_byte_imm();
7898 DECODE_PRINTF2("%x\n", imm
);
7901 DECODE_CLEAR_SEGOVR();
7905 /****************************************************************************
7908 ****************************************************************************/
7909 void x86emuOp_mov_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
7914 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7915 DECODE_PRINTF("MOV\tEAX,");
7916 srcval
= fetch_long_imm();
7918 DECODE_PRINTF("MOV\tAX,");
7919 srcval
= fetch_word_imm();
7921 DECODE_PRINTF2("%x\n", srcval
);
7923 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7924 M
.x86
.R_EAX
= srcval
;
7926 M
.x86
.R_AX
= (u16
)srcval
;
7928 DECODE_CLEAR_SEGOVR();
7932 /****************************************************************************
7935 ****************************************************************************/
7936 void x86emuOp_mov_word_CX_IMM(u8
X86EMU_UNUSED(op1
))
7941 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7942 DECODE_PRINTF("MOV\tECX,");
7943 srcval
= fetch_long_imm();
7945 DECODE_PRINTF("MOV\tCX,");
7946 srcval
= fetch_word_imm();
7948 DECODE_PRINTF2("%x\n", srcval
);
7950 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7951 M
.x86
.R_ECX
= srcval
;
7953 M
.x86
.R_CX
= (u16
)srcval
;
7955 DECODE_CLEAR_SEGOVR();
7959 /****************************************************************************
7962 ****************************************************************************/
7963 void x86emuOp_mov_word_DX_IMM(u8
X86EMU_UNUSED(op1
))
7968 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7969 DECODE_PRINTF("MOV\tEDX,");
7970 srcval
= fetch_long_imm();
7972 DECODE_PRINTF("MOV\tDX,");
7973 srcval
= fetch_word_imm();
7975 DECODE_PRINTF2("%x\n", srcval
);
7977 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7978 M
.x86
.R_EDX
= srcval
;
7980 M
.x86
.R_DX
= (u16
)srcval
;
7982 DECODE_CLEAR_SEGOVR();
7986 /****************************************************************************
7989 ****************************************************************************/
7990 void x86emuOp_mov_word_BX_IMM(u8
X86EMU_UNUSED(op1
))
7995 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7996 DECODE_PRINTF("MOV\tEBX,");
7997 srcval
= fetch_long_imm();
7999 DECODE_PRINTF("MOV\tBX,");
8000 srcval
= fetch_word_imm();
8002 DECODE_PRINTF2("%x\n", srcval
);
8004 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8005 M
.x86
.R_EBX
= srcval
;
8007 M
.x86
.R_BX
= (u16
)srcval
;
8009 DECODE_CLEAR_SEGOVR();
8013 /****************************************************************************
8016 ****************************************************************************/
8017 void x86emuOp_mov_word_SP_IMM(u8
X86EMU_UNUSED(op1
))
8022 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8023 DECODE_PRINTF("MOV\tESP,");
8024 srcval
= fetch_long_imm();
8026 DECODE_PRINTF("MOV\tSP,");
8027 srcval
= fetch_word_imm();
8029 DECODE_PRINTF2("%x\n", srcval
);
8031 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8032 M
.x86
.R_ESP
= srcval
;
8034 M
.x86
.R_SP
= (u16
)srcval
;
8036 DECODE_CLEAR_SEGOVR();
8040 /****************************************************************************
8043 ****************************************************************************/
8044 void x86emuOp_mov_word_BP_IMM(u8
X86EMU_UNUSED(op1
))
8049 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8050 DECODE_PRINTF("MOV\tEBP,");
8051 srcval
= fetch_long_imm();
8053 DECODE_PRINTF("MOV\tBP,");
8054 srcval
= fetch_word_imm();
8056 DECODE_PRINTF2("%x\n", srcval
);
8058 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8059 M
.x86
.R_EBP
= srcval
;
8061 M
.x86
.R_BP
= (u16
)srcval
;
8063 DECODE_CLEAR_SEGOVR();
8067 /****************************************************************************
8070 ****************************************************************************/
8071 void x86emuOp_mov_word_SI_IMM(u8
X86EMU_UNUSED(op1
))
8076 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8077 DECODE_PRINTF("MOV\tESI,");
8078 srcval
= fetch_long_imm();
8080 DECODE_PRINTF("MOV\tSI,");
8081 srcval
= fetch_word_imm();
8083 DECODE_PRINTF2("%x\n", srcval
);
8085 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8086 M
.x86
.R_ESI
= srcval
;
8088 M
.x86
.R_SI
= (u16
)srcval
;
8090 DECODE_CLEAR_SEGOVR();
8094 /****************************************************************************
8097 ****************************************************************************/
8098 void x86emuOp_mov_word_DI_IMM(u8
X86EMU_UNUSED(op1
))
8103 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8104 DECODE_PRINTF("MOV\tEDI,");
8105 srcval
= fetch_long_imm();
8107 DECODE_PRINTF("MOV\tDI,");
8108 srcval
= fetch_word_imm();
8110 DECODE_PRINTF2("%x\n", srcval
);
8112 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8113 M
.x86
.R_EDI
= srcval
;
8115 M
.x86
.R_DI
= (u16
)srcval
;
8117 DECODE_CLEAR_SEGOVR();
8121 /* used by opcodes c0, d0, and d2. */
8122 static u8(*opcD0_byte_operation
[])(u8 d
, u8 s
) =
8130 shl_byte
, /* sal_byte === shl_byte by definition */
8134 /****************************************************************************
8137 ****************************************************************************/
8138 void x86emuOp_opcC0_byte_RM_MEM(u8
X86EMU_UNUSED(op1
))
8147 * Yet another weirdo special case instruction format. Part of
8148 * the opcode held below in "RH". Doubly nested case would
8149 * result, except that the decoded instruction
8152 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8154 if (DEBUG_DECODE()) {
8158 DECODE_PRINTF("ROL\t");
8161 DECODE_PRINTF("ROR\t");
8164 DECODE_PRINTF("RCL\t");
8167 DECODE_PRINTF("RCR\t");
8170 DECODE_PRINTF("SHL\t");
8173 DECODE_PRINTF("SHR\t");
8176 DECODE_PRINTF("SAL\t");
8179 DECODE_PRINTF("SAR\t");
8184 /* know operation, decode the mod byte to find the addressing
8188 DECODE_PRINTF("BYTE PTR ");
8189 destoffset
= decode_rm00_address(rl
);
8190 amt
= fetch_byte_imm();
8191 DECODE_PRINTF2(",%x\n", amt
);
8192 destval
= fetch_data_byte(destoffset
);
8194 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8195 store_data_byte(destoffset
, destval
);
8198 DECODE_PRINTF("BYTE PTR ");
8199 destoffset
= decode_rm01_address(rl
);
8200 amt
= fetch_byte_imm();
8201 DECODE_PRINTF2(",%x\n", amt
);
8202 destval
= fetch_data_byte(destoffset
);
8204 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8205 store_data_byte(destoffset
, destval
);
8208 DECODE_PRINTF("BYTE PTR ");
8209 destoffset
= decode_rm10_address(rl
);
8210 amt
= fetch_byte_imm();
8211 DECODE_PRINTF2(",%x\n", amt
);
8212 destval
= fetch_data_byte(destoffset
);
8214 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8215 store_data_byte(destoffset
, destval
);
8217 case 3: /* register to register */
8218 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
8219 amt
= fetch_byte_imm();
8220 DECODE_PRINTF2(",%x\n", amt
);
8222 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
8226 DECODE_CLEAR_SEGOVR();
8230 /* used by opcodes c1, d1, and d3. */
8231 static u16(*opcD1_word_operation
[])(u16 s
, u8 d
) =
8239 shl_word
, /* sal_byte === shl_byte by definition */
8243 /* used by opcodes c1, d1, and d3. */
8244 static u32 (*opcD1_long_operation
[])(u32 s
, u8 d
) =
8252 shl_long
, /* sal_byte === shl_byte by definition */
8256 /****************************************************************************
8259 ****************************************************************************/
8260 void x86emuOp_opcC1_word_RM_MEM(u8
X86EMU_UNUSED(op1
))
8267 * Yet another weirdo special case instruction format. Part of
8268 * the opcode held below in "RH". Doubly nested case would
8269 * result, except that the decoded instruction
8272 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8274 if (DEBUG_DECODE()) {
8278 DECODE_PRINTF("ROL\t");
8281 DECODE_PRINTF("ROR\t");
8284 DECODE_PRINTF("RCL\t");
8287 DECODE_PRINTF("RCR\t");
8290 DECODE_PRINTF("SHL\t");
8293 DECODE_PRINTF("SHR\t");
8296 DECODE_PRINTF("SAL\t");
8299 DECODE_PRINTF("SAR\t");
8304 /* know operation, decode the mod byte to find the addressing
8308 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8311 DECODE_PRINTF("DWORD PTR ");
8312 destoffset
= decode_rm00_address(rl
);
8313 amt
= fetch_byte_imm();
8314 DECODE_PRINTF2(",%x\n", amt
);
8315 destval
= fetch_data_long(destoffset
);
8317 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8318 store_data_long(destoffset
, destval
);
8322 DECODE_PRINTF("WORD PTR ");
8323 destoffset
= decode_rm00_address(rl
);
8324 amt
= fetch_byte_imm();
8325 DECODE_PRINTF2(",%x\n", amt
);
8326 destval
= fetch_data_word(destoffset
);
8328 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8329 store_data_word(destoffset
, destval
);
8333 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8336 DECODE_PRINTF("DWORD PTR ");
8337 destoffset
= decode_rm01_address(rl
);
8338 amt
= fetch_byte_imm();
8339 DECODE_PRINTF2(",%x\n", amt
);
8340 destval
= fetch_data_long(destoffset
);
8342 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8343 store_data_long(destoffset
, destval
);
8347 DECODE_PRINTF("WORD PTR ");
8348 destoffset
= decode_rm01_address(rl
);
8349 amt
= fetch_byte_imm();
8350 DECODE_PRINTF2(",%x\n", amt
);
8351 destval
= fetch_data_word(destoffset
);
8353 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8354 store_data_word(destoffset
, destval
);
8358 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8361 DECODE_PRINTF("DWORD PTR ");
8362 destoffset
= decode_rm10_address(rl
);
8363 amt
= fetch_byte_imm();
8364 DECODE_PRINTF2(",%x\n", amt
);
8365 destval
= fetch_data_long(destoffset
);
8367 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8368 store_data_long(destoffset
, destval
);
8372 DECODE_PRINTF("WORD PTR ");
8373 destoffset
= decode_rm10_address(rl
);
8374 amt
= fetch_byte_imm();
8375 DECODE_PRINTF2(",%x\n", amt
);
8376 destval
= fetch_data_word(destoffset
);
8378 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8379 store_data_word(destoffset
, destval
);
8382 case 3: /* register to register */
8383 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8386 destreg
= DECODE_RM_LONG_REGISTER(rl
);
8387 amt
= fetch_byte_imm();
8388 DECODE_PRINTF2(",%x\n", amt
);
8390 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
8394 destreg
= DECODE_RM_WORD_REGISTER(rl
);
8395 amt
= fetch_byte_imm();
8396 DECODE_PRINTF2(",%x\n", amt
);
8398 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
8402 DECODE_CLEAR_SEGOVR();
8406 /****************************************************************************
8409 ****************************************************************************/
8410 void x86emuOp_ret_near_IMM(u8
X86EMU_UNUSED(op1
))
8415 DECODE_PRINTF("RET\t");
8416 imm
= fetch_word_imm();
8417 DECODE_PRINTF2("%x\n", imm
);
8418 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8420 M
.x86
.R_IP
= pop_word();
8422 DECODE_CLEAR_SEGOVR();
8426 /****************************************************************************
8429 ****************************************************************************/
8430 void x86emuOp_ret_near(u8
X86EMU_UNUSED(op1
))
8433 DECODE_PRINTF("RET\n");
8434 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8436 M
.x86
.R_IP
= pop_word();
8437 DECODE_CLEAR_SEGOVR();
8441 /****************************************************************************
8444 ****************************************************************************/
8445 void x86emuOp_les_R_IMM(u8
X86EMU_UNUSED(op1
))
8452 DECODE_PRINTF("LES\t");
8453 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8456 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8458 srcoffset
= decode_rm00_address(rl
);
8459 DECODE_PRINTF("\n");
8461 *dstreg
= fetch_data_word(srcoffset
);
8462 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8465 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8467 srcoffset
= decode_rm01_address(rl
);
8468 DECODE_PRINTF("\n");
8470 *dstreg
= fetch_data_word(srcoffset
);
8471 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8474 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8476 srcoffset
= decode_rm10_address(rl
);
8477 DECODE_PRINTF("\n");
8479 *dstreg
= fetch_data_word(srcoffset
);
8480 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8482 case 3: /* register to register */
8486 DECODE_CLEAR_SEGOVR();
8490 /****************************************************************************
8493 ****************************************************************************/
8494 void x86emuOp_lds_R_IMM(u8
X86EMU_UNUSED(op1
))
8501 DECODE_PRINTF("LDS\t");
8502 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8505 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8507 srcoffset
= decode_rm00_address(rl
);
8508 DECODE_PRINTF("\n");
8510 *dstreg
= fetch_data_word(srcoffset
);
8511 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8514 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8516 srcoffset
= decode_rm01_address(rl
);
8517 DECODE_PRINTF("\n");
8519 *dstreg
= fetch_data_word(srcoffset
);
8520 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8523 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8525 srcoffset
= decode_rm10_address(rl
);
8526 DECODE_PRINTF("\n");
8528 *dstreg
= fetch_data_word(srcoffset
);
8529 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8531 case 3: /* register to register */
8535 DECODE_CLEAR_SEGOVR();
8539 /****************************************************************************
8542 ****************************************************************************/
8543 void x86emuOp_mov_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
8551 DECODE_PRINTF("MOV\t");
8552 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8554 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8559 DECODE_PRINTF("BYTE PTR ");
8560 destoffset
= decode_rm00_address(rl
);
8561 imm
= fetch_byte_imm();
8562 DECODE_PRINTF2(",%2x\n", imm
);
8564 store_data_byte(destoffset
, imm
);
8567 DECODE_PRINTF("BYTE PTR ");
8568 destoffset
= decode_rm01_address(rl
);
8569 imm
= fetch_byte_imm();
8570 DECODE_PRINTF2(",%2x\n", imm
);
8572 store_data_byte(destoffset
, imm
);
8575 DECODE_PRINTF("BYTE PTR ");
8576 destoffset
= decode_rm10_address(rl
);
8577 imm
= fetch_byte_imm();
8578 DECODE_PRINTF2(",%2x\n", imm
);
8580 store_data_byte(destoffset
, imm
);
8582 case 3: /* register to register */
8583 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
8584 imm
= fetch_byte_imm();
8585 DECODE_PRINTF2(",%2x\n", imm
);
8590 DECODE_CLEAR_SEGOVR();
8594 /****************************************************************************
8597 ****************************************************************************/
8598 void x86emuOp_mov_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
8604 DECODE_PRINTF("MOV\t");
8605 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8607 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8612 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8615 DECODE_PRINTF("DWORD PTR ");
8616 destoffset
= decode_rm00_address(rl
);
8617 imm
= fetch_long_imm();
8618 DECODE_PRINTF2(",%x\n", imm
);
8620 store_data_long(destoffset
, imm
);
8624 DECODE_PRINTF("WORD PTR ");
8625 destoffset
= decode_rm00_address(rl
);
8626 imm
= fetch_word_imm();
8627 DECODE_PRINTF2(",%x\n", imm
);
8629 store_data_word(destoffset
, imm
);
8633 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8636 DECODE_PRINTF("DWORD PTR ");
8637 destoffset
= decode_rm01_address(rl
);
8638 imm
= fetch_long_imm();
8639 DECODE_PRINTF2(",%x\n", imm
);
8641 store_data_long(destoffset
, imm
);
8645 DECODE_PRINTF("WORD PTR ");
8646 destoffset
= decode_rm01_address(rl
);
8647 imm
= fetch_word_imm();
8648 DECODE_PRINTF2(",%x\n", imm
);
8650 store_data_word(destoffset
, imm
);
8654 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8657 DECODE_PRINTF("DWORD PTR ");
8658 destoffset
= decode_rm10_address(rl
);
8659 imm
= fetch_long_imm();
8660 DECODE_PRINTF2(",%x\n", imm
);
8662 store_data_long(destoffset
, imm
);
8666 DECODE_PRINTF("WORD PTR ");
8667 destoffset
= decode_rm10_address(rl
);
8668 imm
= fetch_word_imm();
8669 DECODE_PRINTF2(",%x\n", imm
);
8671 store_data_word(destoffset
, imm
);
8674 case 3: /* register to register */
8675 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8679 destreg
= DECODE_RM_LONG_REGISTER(rl
);
8680 imm
= fetch_long_imm();
8681 DECODE_PRINTF2(",%x\n", imm
);
8688 destreg
= DECODE_RM_WORD_REGISTER(rl
);
8689 imm
= fetch_word_imm();
8690 DECODE_PRINTF2(",%x\n", imm
);
8696 DECODE_CLEAR_SEGOVR();
8700 /****************************************************************************
8703 ****************************************************************************/
8704 void x86emuOp_enter(u8
X86EMU_UNUSED(op1
))
8706 u16 local
,frame_pointer
;
8711 local
= fetch_word_imm();
8712 nesting
= fetch_byte_imm();
8713 DECODE_PRINTF2("ENTER %x\n", local
);
8714 DECODE_PRINTF2(",%x\n", nesting
);
8716 push_word(M
.x86
.R_BP
);
8717 frame_pointer
= M
.x86
.R_SP
;
8719 for (i
= 1; i
< nesting
; i
++) {
8721 push_word(fetch_data_word_abs(M
.x86
.R_SS
, M
.x86
.R_BP
));
8723 push_word(frame_pointer
);
8725 M
.x86
.R_BP
= frame_pointer
;
8726 M
.x86
.R_SP
= (u16
)(M
.x86
.R_SP
- local
);
8727 DECODE_CLEAR_SEGOVR();
8731 /****************************************************************************
8734 ****************************************************************************/
8735 void x86emuOp_leave(u8
X86EMU_UNUSED(op1
))
8738 DECODE_PRINTF("LEAVE\n");
8740 M
.x86
.R_SP
= M
.x86
.R_BP
;
8741 M
.x86
.R_BP
= pop_word();
8742 DECODE_CLEAR_SEGOVR();
8746 /****************************************************************************
8749 ****************************************************************************/
8750 void x86emuOp_ret_far_IMM(u8
X86EMU_UNUSED(op1
))
8755 DECODE_PRINTF("RETF\t");
8756 imm
= fetch_word_imm();
8757 DECODE_PRINTF2("%x\n", imm
);
8758 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8760 M
.x86
.R_IP
= pop_word();
8761 M
.x86
.R_CS
= pop_word();
8763 DECODE_CLEAR_SEGOVR();
8767 /****************************************************************************
8770 ****************************************************************************/
8771 void x86emuOp_ret_far(u8
X86EMU_UNUSED(op1
))
8774 DECODE_PRINTF("RETF\n");
8775 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8777 M
.x86
.R_IP
= pop_word();
8778 M
.x86
.R_CS
= pop_word();
8779 DECODE_CLEAR_SEGOVR();
8783 /****************************************************************************
8786 ****************************************************************************/
8787 void x86emuOp_int3(u8
X86EMU_UNUSED(op1
))
8792 DECODE_PRINTF("INT 3\n");
8793 tmp
= (u16
) mem_access_word(3 * 4 + 2);
8794 /* access the segment register */
8796 if (_X86EMU_intrTab
[3]) {
8797 (*_X86EMU_intrTab
[3])(3);
8799 push_word((u16
)M
.x86
.R_FLG
);
8802 push_word(M
.x86
.R_CS
);
8803 M
.x86
.R_CS
= mem_access_word(3 * 4 + 2);
8804 push_word(M
.x86
.R_IP
);
8805 M
.x86
.R_IP
= mem_access_word(3 * 4);
8807 DECODE_CLEAR_SEGOVR();
8811 /****************************************************************************
8814 ****************************************************************************/
8815 void x86emuOp_int_IMM(u8
X86EMU_UNUSED(op1
))
8821 DECODE_PRINTF("INT\t");
8822 intnum
= fetch_byte_imm();
8823 DECODE_PRINTF2("%x\n", intnum
);
8824 tmp
= mem_access_word(intnum
* 4 + 2);
8826 if (_X86EMU_intrTab
[intnum
]) {
8827 (*_X86EMU_intrTab
[intnum
])(intnum
);
8829 push_word((u16
)M
.x86
.R_FLG
);
8832 push_word(M
.x86
.R_CS
);
8833 M
.x86
.R_CS
= mem_access_word(intnum
* 4 + 2);
8834 push_word(M
.x86
.R_IP
);
8835 M
.x86
.R_IP
= mem_access_word(intnum
* 4);
8837 DECODE_CLEAR_SEGOVR();
8841 /****************************************************************************
8844 ****************************************************************************/
8845 void x86emuOp_into(u8
X86EMU_UNUSED(op1
))
8850 DECODE_PRINTF("INTO\n");
8852 if (ACCESS_FLAG(F_OF
)) {
8853 tmp
= mem_access_word(4 * 4 + 2);
8854 if (_X86EMU_intrTab
[4]) {
8855 (*_X86EMU_intrTab
[4])(4);
8857 push_word((u16
)M
.x86
.R_FLG
);
8860 push_word(M
.x86
.R_CS
);
8861 M
.x86
.R_CS
= mem_access_word(4 * 4 + 2);
8862 push_word(M
.x86
.R_IP
);
8863 M
.x86
.R_IP
= mem_access_word(4 * 4);
8866 DECODE_CLEAR_SEGOVR();
8870 /****************************************************************************
8873 ****************************************************************************/
8874 void x86emuOp_iret(u8
X86EMU_UNUSED(op1
))
8877 DECODE_PRINTF("IRET\n");
8881 M
.x86
.R_IP
= pop_word();
8882 M
.x86
.R_CS
= pop_word();
8883 M
.x86
.R_FLG
= pop_word();
8884 DECODE_CLEAR_SEGOVR();
8888 /****************************************************************************
8891 ****************************************************************************/
8892 void x86emuOp_opcD0_byte_RM_1(u8
X86EMU_UNUSED(op1
))
8900 * Yet another weirdo special case instruction format. Part of
8901 * the opcode held below in "RH". Doubly nested case would
8902 * result, except that the decoded instruction
8905 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8907 if (DEBUG_DECODE()) {
8910 DECODE_PRINTF("ROL\t");
8913 DECODE_PRINTF("ROR\t");
8916 DECODE_PRINTF("RCL\t");
8919 DECODE_PRINTF("RCR\t");
8922 DECODE_PRINTF("SHL\t");
8925 DECODE_PRINTF("SHR\t");
8928 DECODE_PRINTF("SAL\t");
8931 DECODE_PRINTF("SAR\t");
8936 /* know operation, decode the mod byte to find the addressing
8940 DECODE_PRINTF("BYTE PTR ");
8941 destoffset
= decode_rm00_address(rl
);
8942 DECODE_PRINTF(",1\n");
8943 destval
= fetch_data_byte(destoffset
);
8945 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
8946 store_data_byte(destoffset
, destval
);
8949 DECODE_PRINTF("BYTE PTR ");
8950 destoffset
= decode_rm01_address(rl
);
8951 DECODE_PRINTF(",1\n");
8952 destval
= fetch_data_byte(destoffset
);
8954 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
8955 store_data_byte(destoffset
, destval
);
8958 DECODE_PRINTF("BYTE PTR ");
8959 destoffset
= decode_rm10_address(rl
);
8960 DECODE_PRINTF(",1\n");
8961 destval
= fetch_data_byte(destoffset
);
8963 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
8964 store_data_byte(destoffset
, destval
);
8966 case 3: /* register to register */
8967 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
8968 DECODE_PRINTF(",1\n");
8970 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, 1);
8974 DECODE_CLEAR_SEGOVR();
8978 /****************************************************************************
8981 ****************************************************************************/
8982 void x86emuOp_opcD1_word_RM_1(u8
X86EMU_UNUSED(op1
))
8988 * Yet another weirdo special case instruction format. Part of
8989 * the opcode held below in "RH". Doubly nested case would
8990 * result, except that the decoded instruction
8993 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8995 if (DEBUG_DECODE()) {
8998 DECODE_PRINTF("ROL\t");
9001 DECODE_PRINTF("ROR\t");
9004 DECODE_PRINTF("RCL\t");
9007 DECODE_PRINTF("RCR\t");
9010 DECODE_PRINTF("SHL\t");
9013 DECODE_PRINTF("SHR\t");
9016 DECODE_PRINTF("SAL\t");
9019 DECODE_PRINTF("SAR\t");
9024 /* know operation, decode the mod byte to find the addressing
9028 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9031 DECODE_PRINTF("DWORD PTR ");
9032 destoffset
= decode_rm00_address(rl
);
9033 DECODE_PRINTF(",1\n");
9034 destval
= fetch_data_long(destoffset
);
9036 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9037 store_data_long(destoffset
, destval
);
9041 DECODE_PRINTF("WORD PTR ");
9042 destoffset
= decode_rm00_address(rl
);
9043 DECODE_PRINTF(",1\n");
9044 destval
= fetch_data_word(destoffset
);
9046 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9047 store_data_word(destoffset
, destval
);
9051 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9054 DECODE_PRINTF("DWORD PTR ");
9055 destoffset
= decode_rm01_address(rl
);
9056 DECODE_PRINTF(",1\n");
9057 destval
= fetch_data_long(destoffset
);
9059 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9060 store_data_long(destoffset
, destval
);
9064 DECODE_PRINTF("WORD PTR ");
9065 destoffset
= decode_rm01_address(rl
);
9066 DECODE_PRINTF(",1\n");
9067 destval
= fetch_data_word(destoffset
);
9069 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9070 store_data_word(destoffset
, destval
);
9074 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9077 DECODE_PRINTF("DWORD PTR ");
9078 destoffset
= decode_rm10_address(rl
);
9079 DECODE_PRINTF(",1\n");
9080 destval
= fetch_data_long(destoffset
);
9082 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9083 store_data_long(destoffset
, destval
);
9087 DECODE_PRINTF("BYTE PTR ");
9088 destoffset
= decode_rm10_address(rl
);
9089 DECODE_PRINTF(",1\n");
9090 destval
= fetch_data_word(destoffset
);
9092 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9093 store_data_word(destoffset
, destval
);
9096 case 3: /* register to register */
9097 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9101 destreg
= DECODE_RM_LONG_REGISTER(rl
);
9102 DECODE_PRINTF(",1\n");
9104 destval
= (*opcD1_long_operation
[rh
]) (*destreg
, 1);
9110 destreg
= DECODE_RM_WORD_REGISTER(rl
);
9111 DECODE_PRINTF(",1\n");
9113 destval
= (*opcD1_word_operation
[rh
]) (*destreg
, 1);
9118 DECODE_CLEAR_SEGOVR();
9122 /****************************************************************************
9125 ****************************************************************************/
9126 void x86emuOp_opcD2_byte_RM_CL(u8
X86EMU_UNUSED(op1
))
9135 * Yet another weirdo special case instruction format. Part of
9136 * the opcode held below in "RH". Doubly nested case would
9137 * result, except that the decoded instruction
9140 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9142 if (DEBUG_DECODE()) {
9145 DECODE_PRINTF("ROL\t");
9148 DECODE_PRINTF("ROR\t");
9151 DECODE_PRINTF("RCL\t");
9154 DECODE_PRINTF("RCR\t");
9157 DECODE_PRINTF("SHL\t");
9160 DECODE_PRINTF("SHR\t");
9163 DECODE_PRINTF("SAL\t");
9166 DECODE_PRINTF("SAR\t");
9171 /* know operation, decode the mod byte to find the addressing
9176 DECODE_PRINTF("BYTE PTR ");
9177 destoffset
= decode_rm00_address(rl
);
9178 DECODE_PRINTF(",CL\n");
9179 destval
= fetch_data_byte(destoffset
);
9181 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9182 store_data_byte(destoffset
, destval
);
9185 DECODE_PRINTF("BYTE PTR ");
9186 destoffset
= decode_rm01_address(rl
);
9187 DECODE_PRINTF(",CL\n");
9188 destval
= fetch_data_byte(destoffset
);
9190 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9191 store_data_byte(destoffset
, destval
);
9194 DECODE_PRINTF("BYTE PTR ");
9195 destoffset
= decode_rm10_address(rl
);
9196 DECODE_PRINTF(",CL\n");
9197 destval
= fetch_data_byte(destoffset
);
9199 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9200 store_data_byte(destoffset
, destval
);
9202 case 3: /* register to register */
9203 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
9204 DECODE_PRINTF(",CL\n");
9206 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
9210 DECODE_CLEAR_SEGOVR();
9214 /****************************************************************************
9217 ****************************************************************************/
9218 void x86emuOp_opcD3_word_RM_CL(u8
X86EMU_UNUSED(op1
))
9225 * Yet another weirdo special case instruction format. Part of
9226 * the opcode held below in "RH". Doubly nested case would
9227 * result, except that the decoded instruction
9230 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9232 if (DEBUG_DECODE()) {
9235 DECODE_PRINTF("ROL\t");
9238 DECODE_PRINTF("ROR\t");
9241 DECODE_PRINTF("RCL\t");
9244 DECODE_PRINTF("RCR\t");
9247 DECODE_PRINTF("SHL\t");
9250 DECODE_PRINTF("SHR\t");
9253 DECODE_PRINTF("SAL\t");
9256 DECODE_PRINTF("SAR\t");
9261 /* know operation, decode the mod byte to find the addressing
9266 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9269 DECODE_PRINTF("DWORD PTR ");
9270 destoffset
= decode_rm00_address(rl
);
9271 DECODE_PRINTF(",CL\n");
9272 destval
= fetch_data_long(destoffset
);
9274 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9275 store_data_long(destoffset
, destval
);
9279 DECODE_PRINTF("WORD PTR ");
9280 destoffset
= decode_rm00_address(rl
);
9281 DECODE_PRINTF(",CL\n");
9282 destval
= fetch_data_word(destoffset
);
9284 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9285 store_data_word(destoffset
, destval
);
9289 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9292 DECODE_PRINTF("DWORD PTR ");
9293 destoffset
= decode_rm01_address(rl
);
9294 DECODE_PRINTF(",CL\n");
9295 destval
= fetch_data_long(destoffset
);
9297 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9298 store_data_long(destoffset
, destval
);
9302 DECODE_PRINTF("WORD PTR ");
9303 destoffset
= decode_rm01_address(rl
);
9304 DECODE_PRINTF(",CL\n");
9305 destval
= fetch_data_word(destoffset
);
9307 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9308 store_data_word(destoffset
, destval
);
9312 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9315 DECODE_PRINTF("DWORD PTR ");
9316 destoffset
= decode_rm10_address(rl
);
9317 DECODE_PRINTF(",CL\n");
9318 destval
= fetch_data_long(destoffset
);
9320 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9321 store_data_long(destoffset
, destval
);
9325 DECODE_PRINTF("WORD PTR ");
9326 destoffset
= decode_rm10_address(rl
);
9327 DECODE_PRINTF(",CL\n");
9328 destval
= fetch_data_word(destoffset
);
9330 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9331 store_data_word(destoffset
, destval
);
9334 case 3: /* register to register */
9335 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9338 destreg
= DECODE_RM_LONG_REGISTER(rl
);
9339 DECODE_PRINTF(",CL\n");
9341 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
9345 destreg
= DECODE_RM_WORD_REGISTER(rl
);
9346 DECODE_PRINTF(",CL\n");
9348 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
9352 DECODE_CLEAR_SEGOVR();
9356 /****************************************************************************
9359 ****************************************************************************/
9360 void x86emuOp_aam(u8
X86EMU_UNUSED(op1
))
9365 DECODE_PRINTF("AAM\n");
9366 a
= fetch_byte_imm(); /* this is a stupid encoding. */
9368 DECODE_PRINTF("ERROR DECODING AAM\n");
9373 /* note the type change here --- returning AL and AH in AX. */
9374 M
.x86
.R_AX
= aam_word(M
.x86
.R_AL
);
9375 DECODE_CLEAR_SEGOVR();
9379 /****************************************************************************
9382 ****************************************************************************/
9383 void x86emuOp_aad(u8
X86EMU_UNUSED(op1
))
9388 DECODE_PRINTF("AAD\n");
9389 a
= fetch_byte_imm();
9391 M
.x86
.R_AX
= aad_word(M
.x86
.R_AX
);
9392 DECODE_CLEAR_SEGOVR();
9396 /* opcode 0xd6 ILLEGAL OPCODE */
9398 /****************************************************************************
9401 ****************************************************************************/
9402 void x86emuOp_xlat(u8
X86EMU_UNUSED(op1
))
9407 DECODE_PRINTF("XLAT\n");
9409 addr
= (u16
)(M
.x86
.R_BX
+ (u8
)M
.x86
.R_AL
);
9410 M
.x86
.R_AL
= fetch_data_byte(addr
);
9411 DECODE_CLEAR_SEGOVR();
9415 /* instuctions D8 .. DF are in i87_ops.c */
9417 /****************************************************************************
9420 ****************************************************************************/
9421 void x86emuOp_loopne(u8
X86EMU_UNUSED(op1
))
9426 DECODE_PRINTF("LOOPNE\t");
9427 ip
= (s8
) fetch_byte_imm();
9428 ip
+= (s16
) M
.x86
.R_IP
;
9429 DECODE_PRINTF2("%04x\n", ip
);
9432 if (M
.x86
.R_CX
!= 0 && !ACCESS_FLAG(F_ZF
)) /* CX != 0 and !ZF */
9434 DECODE_CLEAR_SEGOVR();
9438 /****************************************************************************
9441 ****************************************************************************/
9442 void x86emuOp_loope(u8
X86EMU_UNUSED(op1
))
9447 DECODE_PRINTF("LOOPE\t");
9448 ip
= (s8
) fetch_byte_imm();
9449 ip
+= (s16
) M
.x86
.R_IP
;
9450 DECODE_PRINTF2("%04x\n", ip
);
9453 if (M
.x86
.R_CX
!= 0 && ACCESS_FLAG(F_ZF
)) /* CX != 0 and ZF */
9455 DECODE_CLEAR_SEGOVR();
9459 /****************************************************************************
9462 ****************************************************************************/
9463 void x86emuOp_loop(u8
X86EMU_UNUSED(op1
))
9468 DECODE_PRINTF("LOOP\t");
9469 ip
= (s8
) fetch_byte_imm();
9470 ip
+= (s16
) M
.x86
.R_IP
;
9471 DECODE_PRINTF2("%04x\n", ip
);
9474 if (M
.x86
.R_CX
!= 0)
9476 DECODE_CLEAR_SEGOVR();
9480 /****************************************************************************
9483 ****************************************************************************/
9484 void x86emuOp_jcxz(u8
X86EMU_UNUSED(op1
))
9489 /* jump to byte offset if overflow flag is set */
9491 DECODE_PRINTF("JCXZ\t");
9492 offset
= (s8
)fetch_byte_imm();
9493 target
= (u16
)(M
.x86
.R_IP
+ offset
);
9494 DECODE_PRINTF2("%x\n", target
);
9496 if (M
.x86
.R_CX
== 0)
9497 M
.x86
.R_IP
= target
;
9498 DECODE_CLEAR_SEGOVR();
9502 /****************************************************************************
9505 ****************************************************************************/
9506 void x86emuOp_in_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
9511 DECODE_PRINTF("IN\t");
9512 port
= (u8
) fetch_byte_imm();
9513 DECODE_PRINTF2("%x,AL\n", port
);
9515 M
.x86
.R_AL
= (*sys_inb
)(port
);
9516 DECODE_CLEAR_SEGOVR();
9520 /****************************************************************************
9523 ****************************************************************************/
9524 void x86emuOp_in_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
9529 DECODE_PRINTF("IN\t");
9530 port
= (u8
) fetch_byte_imm();
9531 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9532 DECODE_PRINTF2("EAX,%x\n", port
);
9534 DECODE_PRINTF2("AX,%x\n", port
);
9537 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9538 M
.x86
.R_EAX
= (*sys_inl
)(port
);
9540 M
.x86
.R_AX
= (*sys_inw
)(port
);
9542 DECODE_CLEAR_SEGOVR();
9546 /****************************************************************************
9549 ****************************************************************************/
9550 void x86emuOp_out_byte_IMM_AL(u8
X86EMU_UNUSED(op1
))
9555 DECODE_PRINTF("OUT\t");
9556 port
= (u8
) fetch_byte_imm();
9557 DECODE_PRINTF2("%x,AL\n", port
);
9559 (*sys_outb
)(port
, M
.x86
.R_AL
);
9560 DECODE_CLEAR_SEGOVR();
9564 /****************************************************************************
9567 ****************************************************************************/
9568 void x86emuOp_out_word_IMM_AX(u8
X86EMU_UNUSED(op1
))
9573 DECODE_PRINTF("OUT\t");
9574 port
= (u8
) fetch_byte_imm();
9575 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9576 DECODE_PRINTF2("%x,EAX\n", port
);
9578 DECODE_PRINTF2("%x,AX\n", port
);
9581 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9582 (*sys_outl
)(port
, M
.x86
.R_EAX
);
9584 (*sys_outw
)(port
, M
.x86
.R_AX
);
9586 DECODE_CLEAR_SEGOVR();
9590 /****************************************************************************
9593 ****************************************************************************/
9594 void x86emuOp_call_near_IMM(u8
X86EMU_UNUSED(op1
))
9599 DECODE_PRINTF("CALL\t");
9600 ip
= (s16
) fetch_word_imm();
9601 ip
+= (s16
) M
.x86
.R_IP
; /* CHECK SIGN */
9602 DECODE_PRINTF2("%04x\n", ip
);
9603 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip
, "");
9605 push_word(M
.x86
.R_IP
);
9607 DECODE_CLEAR_SEGOVR();
9611 /****************************************************************************
9614 ****************************************************************************/
9615 void x86emuOp_jump_near_IMM(u8
X86EMU_UNUSED(op1
))
9620 DECODE_PRINTF("JMP\t");
9621 ip
= (s16
)fetch_word_imm();
9622 ip
+= (s16
)M
.x86
.R_IP
;
9623 DECODE_PRINTF2("%04x\n", ip
);
9625 M
.x86
.R_IP
= (u16
)ip
;
9626 DECODE_CLEAR_SEGOVR();
9630 /****************************************************************************
9633 ****************************************************************************/
9634 void x86emuOp_jump_far_IMM(u8
X86EMU_UNUSED(op1
))
9639 DECODE_PRINTF("JMP\tFAR ");
9640 ip
= fetch_word_imm();
9641 cs
= fetch_word_imm();
9642 DECODE_PRINTF2("%04x:", cs
);
9643 DECODE_PRINTF2("%04x\n", ip
);
9647 DECODE_CLEAR_SEGOVR();
9651 /****************************************************************************
9654 ****************************************************************************/
9655 void x86emuOp_jump_byte_IMM(u8
X86EMU_UNUSED(op1
))
9661 DECODE_PRINTF("JMP\t");
9662 offset
= (s8
)fetch_byte_imm();
9663 target
= (u16
)(M
.x86
.R_IP
+ offset
);
9664 DECODE_PRINTF2("%x\n", target
);
9666 M
.x86
.R_IP
= target
;
9667 DECODE_CLEAR_SEGOVR();
9671 /****************************************************************************
9674 ****************************************************************************/
9675 void x86emuOp_in_byte_AL_DX(u8
X86EMU_UNUSED(op1
))
9678 DECODE_PRINTF("IN\tAL,DX\n");
9680 M
.x86
.R_AL
= (*sys_inb
)(M
.x86
.R_DX
);
9681 DECODE_CLEAR_SEGOVR();
9685 /****************************************************************************
9688 ****************************************************************************/
9689 void x86emuOp_in_word_AX_DX(u8
X86EMU_UNUSED(op1
))
9692 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9693 DECODE_PRINTF("IN\tEAX,DX\n");
9695 DECODE_PRINTF("IN\tAX,DX\n");
9698 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9699 M
.x86
.R_EAX
= (*sys_inl
)(M
.x86
.R_DX
);
9701 M
.x86
.R_AX
= (*sys_inw
)(M
.x86
.R_DX
);
9703 DECODE_CLEAR_SEGOVR();
9707 /****************************************************************************
9710 ****************************************************************************/
9711 void x86emuOp_out_byte_DX_AL(u8
X86EMU_UNUSED(op1
))
9714 DECODE_PRINTF("OUT\tDX,AL\n");
9716 (*sys_outb
)(M
.x86
.R_DX
, M
.x86
.R_AL
);
9717 DECODE_CLEAR_SEGOVR();
9721 /****************************************************************************
9724 ****************************************************************************/
9725 void x86emuOp_out_word_DX_AX(u8
X86EMU_UNUSED(op1
))
9728 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9729 DECODE_PRINTF("OUT\tDX,EAX\n");
9731 DECODE_PRINTF("OUT\tDX,AX\n");
9734 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9735 (*sys_outl
)(M
.x86
.R_DX
, M
.x86
.R_EAX
);
9737 (*sys_outw
)(M
.x86
.R_DX
, M
.x86
.R_AX
);
9739 DECODE_CLEAR_SEGOVR();
9743 /****************************************************************************
9746 ****************************************************************************/
9747 void x86emuOp_lock(u8
X86EMU_UNUSED(op1
))
9750 DECODE_PRINTF("LOCK:\n");
9752 DECODE_CLEAR_SEGOVR();
9756 /*opcode 0xf1 ILLEGAL OPERATION */
9758 /****************************************************************************
9761 ****************************************************************************/
9762 void x86emuOp_repne(u8
X86EMU_UNUSED(op1
))
9765 DECODE_PRINTF("REPNE\n");
9767 M
.x86
.mode
|= SYSMODE_PREFIX_REPNE
;
9768 DECODE_CLEAR_SEGOVR();
9772 /****************************************************************************
9775 ****************************************************************************/
9776 void x86emuOp_repe(u8
X86EMU_UNUSED(op1
))
9779 DECODE_PRINTF("REPE\n");
9781 M
.x86
.mode
|= SYSMODE_PREFIX_REPE
;
9782 DECODE_CLEAR_SEGOVR();
9786 /****************************************************************************
9789 ****************************************************************************/
9790 void x86emuOp_halt(u8
X86EMU_UNUSED(op1
))
9793 DECODE_PRINTF("HALT\n");
9796 DECODE_CLEAR_SEGOVR();
9800 /****************************************************************************
9803 ****************************************************************************/
9804 void x86emuOp_cmc(u8
X86EMU_UNUSED(op1
))
9806 /* complement the carry flag. */
9808 DECODE_PRINTF("CMC\n");
9811 DECODE_CLEAR_SEGOVR();
9815 /****************************************************************************
9818 ****************************************************************************/
9819 void x86emuOp_opcF6_byte_RM(u8
X86EMU_UNUSED(op1
))
9826 /* long, drawn out code follows. Double switch for a total
9829 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9831 case 0: /* mod=00 */
9833 case 0: /* test byte imm */
9834 DECODE_PRINTF("TEST\tBYTE PTR ");
9835 destoffset
= decode_rm00_address(rl
);
9837 srcval
= fetch_byte_imm();
9838 DECODE_PRINTF2("%02x\n", srcval
);
9839 destval
= fetch_data_byte(destoffset
);
9841 test_byte(destval
, srcval
);
9844 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9848 DECODE_PRINTF("NOT\tBYTE PTR ");
9849 destoffset
= decode_rm00_address(rl
);
9850 DECODE_PRINTF("\n");
9851 destval
= fetch_data_byte(destoffset
);
9853 destval
= not_byte(destval
);
9854 store_data_byte(destoffset
, destval
);
9857 DECODE_PRINTF("NEG\tBYTE PTR ");
9858 destoffset
= decode_rm00_address(rl
);
9859 DECODE_PRINTF("\n");
9860 destval
= fetch_data_byte(destoffset
);
9862 destval
= neg_byte(destval
);
9863 store_data_byte(destoffset
, destval
);
9866 DECODE_PRINTF("MUL\tBYTE PTR ");
9867 destoffset
= decode_rm00_address(rl
);
9868 DECODE_PRINTF("\n");
9869 destval
= fetch_data_byte(destoffset
);
9874 DECODE_PRINTF("IMUL\tBYTE PTR ");
9875 destoffset
= decode_rm00_address(rl
);
9876 DECODE_PRINTF("\n");
9877 destval
= fetch_data_byte(destoffset
);
9882 DECODE_PRINTF("DIV\tBYTE PTR ");
9883 destoffset
= decode_rm00_address(rl
);
9884 DECODE_PRINTF("\n");
9885 destval
= fetch_data_byte(destoffset
);
9890 DECODE_PRINTF("IDIV\tBYTE PTR ");
9891 destoffset
= decode_rm00_address(rl
);
9892 DECODE_PRINTF("\n");
9893 destval
= fetch_data_byte(destoffset
);
9898 break; /* end mod==00 */
9899 case 1: /* mod=01 */
9901 case 0: /* test byte imm */
9902 DECODE_PRINTF("TEST\tBYTE PTR ");
9903 destoffset
= decode_rm01_address(rl
);
9905 srcval
= fetch_byte_imm();
9906 DECODE_PRINTF2("%02x\n", srcval
);
9907 destval
= fetch_data_byte(destoffset
);
9909 test_byte(destval
, srcval
);
9912 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9916 DECODE_PRINTF("NOT\tBYTE PTR ");
9917 destoffset
= decode_rm01_address(rl
);
9918 DECODE_PRINTF("\n");
9919 destval
= fetch_data_byte(destoffset
);
9921 destval
= not_byte(destval
);
9922 store_data_byte(destoffset
, destval
);
9925 DECODE_PRINTF("NEG\tBYTE PTR ");
9926 destoffset
= decode_rm01_address(rl
);
9927 DECODE_PRINTF("\n");
9928 destval
= fetch_data_byte(destoffset
);
9930 destval
= neg_byte(destval
);
9931 store_data_byte(destoffset
, destval
);
9934 DECODE_PRINTF("MUL\tBYTE PTR ");
9935 destoffset
= decode_rm01_address(rl
);
9936 DECODE_PRINTF("\n");
9937 destval
= fetch_data_byte(destoffset
);
9942 DECODE_PRINTF("IMUL\tBYTE PTR ");
9943 destoffset
= decode_rm01_address(rl
);
9944 DECODE_PRINTF("\n");
9945 destval
= fetch_data_byte(destoffset
);
9950 DECODE_PRINTF("DIV\tBYTE PTR ");
9951 destoffset
= decode_rm01_address(rl
);
9952 DECODE_PRINTF("\n");
9953 destval
= fetch_data_byte(destoffset
);
9958 DECODE_PRINTF("IDIV\tBYTE PTR ");
9959 destoffset
= decode_rm01_address(rl
);
9960 DECODE_PRINTF("\n");
9961 destval
= fetch_data_byte(destoffset
);
9966 break; /* end mod==01 */
9967 case 2: /* mod=10 */
9969 case 0: /* test byte imm */
9970 DECODE_PRINTF("TEST\tBYTE PTR ");
9971 destoffset
= decode_rm10_address(rl
);
9973 srcval
= fetch_byte_imm();
9974 DECODE_PRINTF2("%02x\n", srcval
);
9975 destval
= fetch_data_byte(destoffset
);
9977 test_byte(destval
, srcval
);
9980 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
9984 DECODE_PRINTF("NOT\tBYTE PTR ");
9985 destoffset
= decode_rm10_address(rl
);
9986 DECODE_PRINTF("\n");
9987 destval
= fetch_data_byte(destoffset
);
9989 destval
= not_byte(destval
);
9990 store_data_byte(destoffset
, destval
);
9993 DECODE_PRINTF("NEG\tBYTE PTR ");
9994 destoffset
= decode_rm10_address(rl
);
9995 DECODE_PRINTF("\n");
9996 destval
= fetch_data_byte(destoffset
);
9998 destval
= neg_byte(destval
);
9999 store_data_byte(destoffset
, destval
);
10002 DECODE_PRINTF("MUL\tBYTE PTR ");
10003 destoffset
= decode_rm10_address(rl
);
10004 DECODE_PRINTF("\n");
10005 destval
= fetch_data_byte(destoffset
);
10010 DECODE_PRINTF("IMUL\tBYTE PTR ");
10011 destoffset
= decode_rm10_address(rl
);
10012 DECODE_PRINTF("\n");
10013 destval
= fetch_data_byte(destoffset
);
10015 imul_byte(destval
);
10018 DECODE_PRINTF("DIV\tBYTE PTR ");
10019 destoffset
= decode_rm10_address(rl
);
10020 DECODE_PRINTF("\n");
10021 destval
= fetch_data_byte(destoffset
);
10026 DECODE_PRINTF("IDIV\tBYTE PTR ");
10027 destoffset
= decode_rm10_address(rl
);
10028 DECODE_PRINTF("\n");
10029 destval
= fetch_data_byte(destoffset
);
10031 idiv_byte(destval
);
10034 break; /* end mod==10 */
10035 case 3: /* mod=11 */
10037 case 0: /* test byte imm */
10038 DECODE_PRINTF("TEST\t");
10039 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10040 DECODE_PRINTF(",");
10041 srcval
= fetch_byte_imm();
10042 DECODE_PRINTF2("%02x\n", srcval
);
10044 test_byte(*destreg
, srcval
);
10047 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10051 DECODE_PRINTF("NOT\t");
10052 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10053 DECODE_PRINTF("\n");
10055 *destreg
= not_byte(*destreg
);
10058 DECODE_PRINTF("NEG\t");
10059 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10060 DECODE_PRINTF("\n");
10062 *destreg
= neg_byte(*destreg
);
10065 DECODE_PRINTF("MUL\t");
10066 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10067 DECODE_PRINTF("\n");
10069 mul_byte(*destreg
); /*!!! */
10072 DECODE_PRINTF("IMUL\t");
10073 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10074 DECODE_PRINTF("\n");
10076 imul_byte(*destreg
);
10079 DECODE_PRINTF("DIV\t");
10080 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10081 DECODE_PRINTF("\n");
10083 div_byte(*destreg
);
10086 DECODE_PRINTF("IDIV\t");
10087 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10088 DECODE_PRINTF("\n");
10090 idiv_byte(*destreg
);
10093 break; /* end mod==11 */
10095 DECODE_CLEAR_SEGOVR();
10099 /****************************************************************************
10101 Handles opcode 0xf7
10102 ****************************************************************************/
10103 void x86emuOp_opcF7_word_RM(u8
X86EMU_UNUSED(op1
))
10108 /* long, drawn out code follows. Double switch for a total
10111 FETCH_DECODE_MODRM(mod
, rh
, rl
);
10113 case 0: /* mod=00 */
10115 case 0: /* test word imm */
10116 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10117 u32 destval
,srcval
;
10119 DECODE_PRINTF("TEST\tDWORD PTR ");
10120 destoffset
= decode_rm00_address(rl
);
10121 DECODE_PRINTF(",");
10122 srcval
= fetch_long_imm();
10123 DECODE_PRINTF2("%x\n", srcval
);
10124 destval
= fetch_data_long(destoffset
);
10126 test_long(destval
, srcval
);
10128 u16 destval
,srcval
;
10130 DECODE_PRINTF("TEST\tWORD PTR ");
10131 destoffset
= decode_rm00_address(rl
);
10132 DECODE_PRINTF(",");
10133 srcval
= fetch_word_imm();
10134 DECODE_PRINTF2("%x\n", srcval
);
10135 destval
= fetch_data_word(destoffset
);
10137 test_word(destval
, srcval
);
10141 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10145 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10148 DECODE_PRINTF("NOT\tDWORD PTR ");
10149 destoffset
= decode_rm00_address(rl
);
10150 DECODE_PRINTF("\n");
10151 destval
= fetch_data_long(destoffset
);
10153 destval
= not_long(destval
);
10154 store_data_long(destoffset
, destval
);
10158 DECODE_PRINTF("NOT\tWORD PTR ");
10159 destoffset
= decode_rm00_address(rl
);
10160 DECODE_PRINTF("\n");
10161 destval
= fetch_data_word(destoffset
);
10163 destval
= not_word(destval
);
10164 store_data_word(destoffset
, destval
);
10168 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10171 DECODE_PRINTF("NEG\tDWORD PTR ");
10172 destoffset
= decode_rm00_address(rl
);
10173 DECODE_PRINTF("\n");
10174 destval
= fetch_data_long(destoffset
);
10176 destval
= neg_long(destval
);
10177 store_data_long(destoffset
, destval
);
10181 DECODE_PRINTF("NEG\tWORD PTR ");
10182 destoffset
= decode_rm00_address(rl
);
10183 DECODE_PRINTF("\n");
10184 destval
= fetch_data_word(destoffset
);
10186 destval
= neg_word(destval
);
10187 store_data_word(destoffset
, destval
);
10191 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10194 DECODE_PRINTF("MUL\tDWORD PTR ");
10195 destoffset
= decode_rm00_address(rl
);
10196 DECODE_PRINTF("\n");
10197 destval
= fetch_data_long(destoffset
);
10203 DECODE_PRINTF("MUL\tWORD PTR ");
10204 destoffset
= decode_rm00_address(rl
);
10205 DECODE_PRINTF("\n");
10206 destval
= fetch_data_word(destoffset
);
10212 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10215 DECODE_PRINTF("IMUL\tDWORD PTR ");
10216 destoffset
= decode_rm00_address(rl
);
10217 DECODE_PRINTF("\n");
10218 destval
= fetch_data_long(destoffset
);
10220 imul_long(destval
);
10224 DECODE_PRINTF("IMUL\tWORD PTR ");
10225 destoffset
= decode_rm00_address(rl
);
10226 DECODE_PRINTF("\n");
10227 destval
= fetch_data_word(destoffset
);
10229 imul_word(destval
);
10233 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10236 DECODE_PRINTF("DIV\tDWORD PTR ");
10237 destoffset
= decode_rm00_address(rl
);
10238 DECODE_PRINTF("\n");
10239 destval
= fetch_data_long(destoffset
);
10245 DECODE_PRINTF("DIV\tWORD PTR ");
10246 destoffset
= decode_rm00_address(rl
);
10247 DECODE_PRINTF("\n");
10248 destval
= fetch_data_word(destoffset
);
10254 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10257 DECODE_PRINTF("IDIV\tDWORD PTR ");
10258 destoffset
= decode_rm00_address(rl
);
10259 DECODE_PRINTF("\n");
10260 destval
= fetch_data_long(destoffset
);
10262 idiv_long(destval
);
10266 DECODE_PRINTF("IDIV\tWORD PTR ");
10267 destoffset
= decode_rm00_address(rl
);
10268 DECODE_PRINTF("\n");
10269 destval
= fetch_data_word(destoffset
);
10271 idiv_word(destval
);
10275 break; /* end mod==00 */
10276 case 1: /* mod=01 */
10278 case 0: /* test word imm */
10279 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10280 u32 destval
,srcval
;
10282 DECODE_PRINTF("TEST\tDWORD PTR ");
10283 destoffset
= decode_rm01_address(rl
);
10284 DECODE_PRINTF(",");
10285 srcval
= fetch_long_imm();
10286 DECODE_PRINTF2("%x\n", srcval
);
10287 destval
= fetch_data_long(destoffset
);
10289 test_long(destval
, srcval
);
10291 u16 destval
,srcval
;
10293 DECODE_PRINTF("TEST\tWORD PTR ");
10294 destoffset
= decode_rm01_address(rl
);
10295 DECODE_PRINTF(",");
10296 srcval
= fetch_word_imm();
10297 DECODE_PRINTF2("%x\n", srcval
);
10298 destval
= fetch_data_word(destoffset
);
10300 test_word(destval
, srcval
);
10304 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10308 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10311 DECODE_PRINTF("NOT\tDWORD PTR ");
10312 destoffset
= decode_rm01_address(rl
);
10313 DECODE_PRINTF("\n");
10314 destval
= fetch_data_long(destoffset
);
10316 destval
= not_long(destval
);
10317 store_data_long(destoffset
, destval
);
10321 DECODE_PRINTF("NOT\tWORD PTR ");
10322 destoffset
= decode_rm01_address(rl
);
10323 DECODE_PRINTF("\n");
10324 destval
= fetch_data_word(destoffset
);
10326 destval
= not_word(destval
);
10327 store_data_word(destoffset
, destval
);
10331 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10334 DECODE_PRINTF("NEG\tDWORD PTR ");
10335 destoffset
= decode_rm01_address(rl
);
10336 DECODE_PRINTF("\n");
10337 destval
= fetch_data_long(destoffset
);
10339 destval
= neg_long(destval
);
10340 store_data_long(destoffset
, destval
);
10344 DECODE_PRINTF("NEG\tWORD PTR ");
10345 destoffset
= decode_rm01_address(rl
);
10346 DECODE_PRINTF("\n");
10347 destval
= fetch_data_word(destoffset
);
10349 destval
= neg_word(destval
);
10350 store_data_word(destoffset
, destval
);
10354 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10357 DECODE_PRINTF("MUL\tDWORD PTR ");
10358 destoffset
= decode_rm01_address(rl
);
10359 DECODE_PRINTF("\n");
10360 destval
= fetch_data_long(destoffset
);
10366 DECODE_PRINTF("MUL\tWORD PTR ");
10367 destoffset
= decode_rm01_address(rl
);
10368 DECODE_PRINTF("\n");
10369 destval
= fetch_data_word(destoffset
);
10375 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10378 DECODE_PRINTF("IMUL\tDWORD PTR ");
10379 destoffset
= decode_rm01_address(rl
);
10380 DECODE_PRINTF("\n");
10381 destval
= fetch_data_long(destoffset
);
10383 imul_long(destval
);
10387 DECODE_PRINTF("IMUL\tWORD PTR ");
10388 destoffset
= decode_rm01_address(rl
);
10389 DECODE_PRINTF("\n");
10390 destval
= fetch_data_word(destoffset
);
10392 imul_word(destval
);
10396 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10399 DECODE_PRINTF("DIV\tDWORD PTR ");
10400 destoffset
= decode_rm01_address(rl
);
10401 DECODE_PRINTF("\n");
10402 destval
= fetch_data_long(destoffset
);
10408 DECODE_PRINTF("DIV\tWORD PTR ");
10409 destoffset
= decode_rm01_address(rl
);
10410 DECODE_PRINTF("\n");
10411 destval
= fetch_data_word(destoffset
);
10417 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10420 DECODE_PRINTF("IDIV\tDWORD PTR ");
10421 destoffset
= decode_rm01_address(rl
);
10422 DECODE_PRINTF("\n");
10423 destval
= fetch_data_long(destoffset
);
10425 idiv_long(destval
);
10429 DECODE_PRINTF("IDIV\tWORD PTR ");
10430 destoffset
= decode_rm01_address(rl
);
10431 DECODE_PRINTF("\n");
10432 destval
= fetch_data_word(destoffset
);
10434 idiv_word(destval
);
10438 break; /* end mod==01 */
10439 case 2: /* mod=10 */
10441 case 0: /* test word imm */
10442 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10443 u32 destval
,srcval
;
10445 DECODE_PRINTF("TEST\tDWORD PTR ");
10446 destoffset
= decode_rm10_address(rl
);
10447 DECODE_PRINTF(",");
10448 srcval
= fetch_long_imm();
10449 DECODE_PRINTF2("%x\n", srcval
);
10450 destval
= fetch_data_long(destoffset
);
10452 test_long(destval
, srcval
);
10454 u16 destval
,srcval
;
10456 DECODE_PRINTF("TEST\tWORD PTR ");
10457 destoffset
= decode_rm10_address(rl
);
10458 DECODE_PRINTF(",");
10459 srcval
= fetch_word_imm();
10460 DECODE_PRINTF2("%x\n", srcval
);
10461 destval
= fetch_data_word(destoffset
);
10463 test_word(destval
, srcval
);
10467 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10471 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10474 DECODE_PRINTF("NOT\tDWORD PTR ");
10475 destoffset
= decode_rm10_address(rl
);
10476 DECODE_PRINTF("\n");
10477 destval
= fetch_data_long(destoffset
);
10479 destval
= not_long(destval
);
10480 store_data_long(destoffset
, destval
);
10484 DECODE_PRINTF("NOT\tWORD PTR ");
10485 destoffset
= decode_rm10_address(rl
);
10486 DECODE_PRINTF("\n");
10487 destval
= fetch_data_word(destoffset
);
10489 destval
= not_word(destval
);
10490 store_data_word(destoffset
, destval
);
10494 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10497 DECODE_PRINTF("NEG\tDWORD PTR ");
10498 destoffset
= decode_rm10_address(rl
);
10499 DECODE_PRINTF("\n");
10500 destval
= fetch_data_long(destoffset
);
10502 destval
= neg_long(destval
);
10503 store_data_long(destoffset
, destval
);
10507 DECODE_PRINTF("NEG\tWORD PTR ");
10508 destoffset
= decode_rm10_address(rl
);
10509 DECODE_PRINTF("\n");
10510 destval
= fetch_data_word(destoffset
);
10512 destval
= neg_word(destval
);
10513 store_data_word(destoffset
, destval
);
10517 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10520 DECODE_PRINTF("MUL\tDWORD PTR ");
10521 destoffset
= decode_rm10_address(rl
);
10522 DECODE_PRINTF("\n");
10523 destval
= fetch_data_long(destoffset
);
10529 DECODE_PRINTF("MUL\tWORD PTR ");
10530 destoffset
= decode_rm10_address(rl
);
10531 DECODE_PRINTF("\n");
10532 destval
= fetch_data_word(destoffset
);
10538 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10541 DECODE_PRINTF("IMUL\tDWORD PTR ");
10542 destoffset
= decode_rm10_address(rl
);
10543 DECODE_PRINTF("\n");
10544 destval
= fetch_data_long(destoffset
);
10546 imul_long(destval
);
10550 DECODE_PRINTF("IMUL\tWORD PTR ");
10551 destoffset
= decode_rm10_address(rl
);
10552 DECODE_PRINTF("\n");
10553 destval
= fetch_data_word(destoffset
);
10555 imul_word(destval
);
10559 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10562 DECODE_PRINTF("DIV\tDWORD PTR ");
10563 destoffset
= decode_rm10_address(rl
);
10564 DECODE_PRINTF("\n");
10565 destval
= fetch_data_long(destoffset
);
10571 DECODE_PRINTF("DIV\tWORD PTR ");
10572 destoffset
= decode_rm10_address(rl
);
10573 DECODE_PRINTF("\n");
10574 destval
= fetch_data_word(destoffset
);
10580 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10583 DECODE_PRINTF("IDIV\tDWORD PTR ");
10584 destoffset
= decode_rm10_address(rl
);
10585 DECODE_PRINTF("\n");
10586 destval
= fetch_data_long(destoffset
);
10588 idiv_long(destval
);
10592 DECODE_PRINTF("IDIV\tWORD PTR ");
10593 destoffset
= decode_rm10_address(rl
);
10594 DECODE_PRINTF("\n");
10595 destval
= fetch_data_word(destoffset
);
10597 idiv_word(destval
);
10601 break; /* end mod==10 */
10602 case 3: /* mod=11 */
10604 case 0: /* test word imm */
10605 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10609 DECODE_PRINTF("TEST\t");
10610 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10611 DECODE_PRINTF(",");
10612 srcval
= fetch_long_imm();
10613 DECODE_PRINTF2("%x\n", srcval
);
10615 test_long(*destreg
, srcval
);
10620 DECODE_PRINTF("TEST\t");
10621 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10622 DECODE_PRINTF(",");
10623 srcval
= fetch_word_imm();
10624 DECODE_PRINTF2("%x\n", srcval
);
10626 test_word(*destreg
, srcval
);
10630 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10634 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10637 DECODE_PRINTF("NOT\t");
10638 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10639 DECODE_PRINTF("\n");
10641 *destreg
= not_long(*destreg
);
10645 DECODE_PRINTF("NOT\t");
10646 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10647 DECODE_PRINTF("\n");
10649 *destreg
= not_word(*destreg
);
10653 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10656 DECODE_PRINTF("NEG\t");
10657 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10658 DECODE_PRINTF("\n");
10660 *destreg
= neg_long(*destreg
);
10664 DECODE_PRINTF("NEG\t");
10665 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10666 DECODE_PRINTF("\n");
10668 *destreg
= neg_word(*destreg
);
10672 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10675 DECODE_PRINTF("MUL\t");
10676 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10677 DECODE_PRINTF("\n");
10679 mul_long(*destreg
); /*!!! */
10683 DECODE_PRINTF("MUL\t");
10684 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10685 DECODE_PRINTF("\n");
10687 mul_word(*destreg
); /*!!! */
10691 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10694 DECODE_PRINTF("IMUL\t");
10695 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10696 DECODE_PRINTF("\n");
10698 imul_long(*destreg
);
10702 DECODE_PRINTF("IMUL\t");
10703 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10704 DECODE_PRINTF("\n");
10706 imul_word(*destreg
);
10710 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10713 DECODE_PRINTF("DIV\t");
10714 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10715 DECODE_PRINTF("\n");
10717 div_long(*destreg
);
10721 DECODE_PRINTF("DIV\t");
10722 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10723 DECODE_PRINTF("\n");
10725 div_word(*destreg
);
10729 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10732 DECODE_PRINTF("IDIV\t");
10733 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10734 DECODE_PRINTF("\n");
10736 idiv_long(*destreg
);
10740 DECODE_PRINTF("IDIV\t");
10741 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10742 DECODE_PRINTF("\n");
10744 idiv_word(*destreg
);
10748 break; /* end mod==11 */
10750 DECODE_CLEAR_SEGOVR();
10754 /****************************************************************************
10756 Handles opcode 0xf8
10757 ****************************************************************************/
10758 void x86emuOp_clc(u8
X86EMU_UNUSED(op1
))
10760 /* clear the carry flag. */
10762 DECODE_PRINTF("CLC\n");
10765 DECODE_CLEAR_SEGOVR();
10769 /****************************************************************************
10771 Handles opcode 0xf9
10772 ****************************************************************************/
10773 void x86emuOp_stc(u8
X86EMU_UNUSED(op1
))
10775 /* set the carry flag. */
10777 DECODE_PRINTF("STC\n");
10780 DECODE_CLEAR_SEGOVR();
10784 /****************************************************************************
10786 Handles opcode 0xfa
10787 ****************************************************************************/
10788 void x86emuOp_cli(u8
X86EMU_UNUSED(op1
))
10790 /* clear interrupts. */
10792 DECODE_PRINTF("CLI\n");
10795 DECODE_CLEAR_SEGOVR();
10799 /****************************************************************************
10801 Handles opcode 0xfb
10802 ****************************************************************************/
10803 void x86emuOp_sti(u8
X86EMU_UNUSED(op1
))
10805 /* enable interrupts. */
10807 DECODE_PRINTF("STI\n");
10810 DECODE_CLEAR_SEGOVR();
10814 /****************************************************************************
10816 Handles opcode 0xfc
10817 ****************************************************************************/
10818 void x86emuOp_cld(u8
X86EMU_UNUSED(op1
))
10820 /* clear interrupts. */
10822 DECODE_PRINTF("CLD\n");
10825 DECODE_CLEAR_SEGOVR();
10829 /****************************************************************************
10831 Handles opcode 0xfd
10832 ****************************************************************************/
10833 void x86emuOp_std(u8
X86EMU_UNUSED(op1
))
10835 /* clear interrupts. */
10837 DECODE_PRINTF("STD\n");
10840 DECODE_CLEAR_SEGOVR();
10844 /****************************************************************************
10846 Handles opcode 0xfe
10847 ****************************************************************************/
10848 void x86emuOp_opcFE_byte_RM(u8
X86EMU_UNUSED(op1
))
10855 /* Yet another special case instruction. */
10857 FETCH_DECODE_MODRM(mod
, rh
, rl
);
10859 if (DEBUG_DECODE()) {
10863 DECODE_PRINTF("INC\t");
10866 DECODE_PRINTF("DEC\t");
10874 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod
);
10882 DECODE_PRINTF("BYTE PTR ");
10883 destoffset
= decode_rm00_address(rl
);
10884 DECODE_PRINTF("\n");
10886 case 0: /* inc word ptr ... */
10887 destval
= fetch_data_byte(destoffset
);
10889 destval
= inc_byte(destval
);
10890 store_data_byte(destoffset
, destval
);
10892 case 1: /* dec word ptr ... */
10893 destval
= fetch_data_byte(destoffset
);
10895 destval
= dec_byte(destval
);
10896 store_data_byte(destoffset
, destval
);
10901 DECODE_PRINTF("BYTE PTR ");
10902 destoffset
= decode_rm01_address(rl
);
10903 DECODE_PRINTF("\n");
10906 destval
= fetch_data_byte(destoffset
);
10908 destval
= inc_byte(destval
);
10909 store_data_byte(destoffset
, destval
);
10912 destval
= fetch_data_byte(destoffset
);
10914 destval
= dec_byte(destval
);
10915 store_data_byte(destoffset
, destval
);
10920 DECODE_PRINTF("BYTE PTR ");
10921 destoffset
= decode_rm10_address(rl
);
10922 DECODE_PRINTF("\n");
10925 destval
= fetch_data_byte(destoffset
);
10927 destval
= inc_byte(destval
);
10928 store_data_byte(destoffset
, destval
);
10931 destval
= fetch_data_byte(destoffset
);
10933 destval
= dec_byte(destval
);
10934 store_data_byte(destoffset
, destval
);
10939 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10940 DECODE_PRINTF("\n");
10944 *destreg
= inc_byte(*destreg
);
10948 *destreg
= dec_byte(*destreg
);
10953 DECODE_CLEAR_SEGOVR();
10957 /****************************************************************************
10959 Handles opcode 0xff
10960 ****************************************************************************/
10961 void x86emuOp_opcFF_word_RM(u8
X86EMU_UNUSED(op1
))
10964 uint destoffset
= 0;
10966 u16 destval
,destval2
;
10968 /* Yet another special case instruction. */
10970 FETCH_DECODE_MODRM(mod
, rh
, rl
);
10972 if (DEBUG_DECODE()) {
10976 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10977 DECODE_PRINTF("INC\tDWORD PTR ");
10979 DECODE_PRINTF("INC\tWORD PTR ");
10983 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10984 DECODE_PRINTF("DEC\tDWORD PTR ");
10986 DECODE_PRINTF("DEC\tWORD PTR ");
10990 DECODE_PRINTF("CALL\t ");
10993 DECODE_PRINTF("CALL\tFAR ");
10996 DECODE_PRINTF("JMP\t");
10999 DECODE_PRINTF("JMP\tFAR ");
11002 DECODE_PRINTF("PUSH\t");
11005 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11013 destoffset
= decode_rm00_address(rl
);
11014 DECODE_PRINTF("\n");
11016 case 0: /* inc word ptr ... */
11017 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11020 destval
= fetch_data_long(destoffset
);
11022 destval
= inc_long(destval
);
11023 store_data_long(destoffset
, destval
);
11027 destval
= fetch_data_word(destoffset
);
11029 destval
= inc_word(destval
);
11030 store_data_word(destoffset
, destval
);
11033 case 1: /* dec word ptr ... */
11034 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11037 destval
= fetch_data_long(destoffset
);
11039 destval
= dec_long(destval
);
11040 store_data_long(destoffset
, destval
);
11044 destval
= fetch_data_word(destoffset
);
11046 destval
= dec_word(destval
);
11047 store_data_word(destoffset
, destval
);
11050 case 2: /* call word ptr ... */
11051 destval
= fetch_data_word(destoffset
);
11053 push_word(M
.x86
.R_IP
);
11054 M
.x86
.R_IP
= destval
;
11056 case 3: /* call far ptr ... */
11057 destval
= fetch_data_word(destoffset
);
11058 destval2
= fetch_data_word(destoffset
+ 2);
11060 push_word(M
.x86
.R_CS
);
11061 M
.x86
.R_CS
= destval2
;
11062 push_word(M
.x86
.R_IP
);
11063 M
.x86
.R_IP
= destval
;
11065 case 4: /* jmp word ptr ... */
11066 destval
= fetch_data_word(destoffset
);
11068 M
.x86
.R_IP
= destval
;
11070 case 5: /* jmp far ptr ... */
11071 destval
= fetch_data_word(destoffset
);
11072 destval2
= fetch_data_word(destoffset
+ 2);
11074 M
.x86
.R_IP
= destval
;
11075 M
.x86
.R_CS
= destval2
;
11077 case 6: /* push word ptr ... */
11078 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11081 destval
= fetch_data_long(destoffset
);
11083 push_long(destval
);
11087 destval
= fetch_data_word(destoffset
);
11089 push_word(destval
);
11095 destoffset
= decode_rm01_address(rl
);
11096 DECODE_PRINTF("\n");
11099 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11102 destval
= fetch_data_long(destoffset
);
11104 destval
= inc_long(destval
);
11105 store_data_long(destoffset
, destval
);
11109 destval
= fetch_data_word(destoffset
);
11111 destval
= inc_word(destval
);
11112 store_data_word(destoffset
, destval
);
11116 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11119 destval
= fetch_data_long(destoffset
);
11121 destval
= dec_long(destval
);
11122 store_data_long(destoffset
, destval
);
11126 destval
= fetch_data_word(destoffset
);
11128 destval
= dec_word(destval
);
11129 store_data_word(destoffset
, destval
);
11132 case 2: /* call word ptr ... */
11133 destval
= fetch_data_word(destoffset
);
11135 push_word(M
.x86
.R_IP
);
11136 M
.x86
.R_IP
= destval
;
11138 case 3: /* call far ptr ... */
11139 destval
= fetch_data_word(destoffset
);
11140 destval2
= fetch_data_word(destoffset
+ 2);
11142 push_word(M
.x86
.R_CS
);
11143 M
.x86
.R_CS
= destval2
;
11144 push_word(M
.x86
.R_IP
);
11145 M
.x86
.R_IP
= destval
;
11147 case 4: /* jmp word ptr ... */
11148 destval
= fetch_data_word(destoffset
);
11150 M
.x86
.R_IP
= destval
;
11152 case 5: /* jmp far ptr ... */
11153 destval
= fetch_data_word(destoffset
);
11154 destval2
= fetch_data_word(destoffset
+ 2);
11156 M
.x86
.R_IP
= destval
;
11157 M
.x86
.R_CS
= destval2
;
11159 case 6: /* push word ptr ... */
11160 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11163 destval
= fetch_data_long(destoffset
);
11165 push_long(destval
);
11169 destval
= fetch_data_word(destoffset
);
11171 push_word(destval
);
11177 destoffset
= decode_rm10_address(rl
);
11178 DECODE_PRINTF("\n");
11181 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11184 destval
= fetch_data_long(destoffset
);
11186 destval
= inc_long(destval
);
11187 store_data_long(destoffset
, destval
);
11191 destval
= fetch_data_word(destoffset
);
11193 destval
= inc_word(destval
);
11194 store_data_word(destoffset
, destval
);
11198 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11201 destval
= fetch_data_long(destoffset
);
11203 destval
= dec_long(destval
);
11204 store_data_long(destoffset
, destval
);
11208 destval
= fetch_data_word(destoffset
);
11210 destval
= dec_word(destval
);
11211 store_data_word(destoffset
, destval
);
11214 case 2: /* call word ptr ... */
11215 destval
= fetch_data_word(destoffset
);
11217 push_word(M
.x86
.R_IP
);
11218 M
.x86
.R_IP
= destval
;
11220 case 3: /* call far ptr ... */
11221 destval
= fetch_data_word(destoffset
);
11222 destval2
= fetch_data_word(destoffset
+ 2);
11224 push_word(M
.x86
.R_CS
);
11225 M
.x86
.R_CS
= destval2
;
11226 push_word(M
.x86
.R_IP
);
11227 M
.x86
.R_IP
= destval
;
11229 case 4: /* jmp word ptr ... */
11230 destval
= fetch_data_word(destoffset
);
11232 M
.x86
.R_IP
= destval
;
11234 case 5: /* jmp far ptr ... */
11235 destval
= fetch_data_word(destoffset
);
11236 destval2
= fetch_data_word(destoffset
+ 2);
11238 M
.x86
.R_IP
= destval
;
11239 M
.x86
.R_CS
= destval2
;
11241 case 6: /* push word ptr ... */
11242 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11245 destval
= fetch_data_long(destoffset
);
11247 push_long(destval
);
11251 destval
= fetch_data_word(destoffset
);
11253 push_word(destval
);
11261 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11264 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11265 DECODE_PRINTF("\n");
11267 *destreg
= inc_long(*destreg
);
11271 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11272 DECODE_PRINTF("\n");
11274 *destreg
= inc_word(*destreg
);
11278 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11281 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11282 DECODE_PRINTF("\n");
11284 *destreg
= dec_long(*destreg
);
11288 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11289 DECODE_PRINTF("\n");
11291 *destreg
= dec_word(*destreg
);
11294 case 2: /* call word ptr ... */
11295 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11296 DECODE_PRINTF("\n");
11298 push_word(M
.x86
.R_IP
);
11299 M
.x86
.R_IP
= *destreg
;
11301 case 3: /* jmp far ptr ... */
11302 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11307 case 4: /* jmp ... */
11308 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11309 DECODE_PRINTF("\n");
11311 M
.x86
.R_IP
= (u16
) (*destreg
);
11313 case 5: /* jmp far ptr ... */
11314 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11319 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11322 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11323 DECODE_PRINTF("\n");
11325 push_long(*destreg
);
11329 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11330 DECODE_PRINTF("\n");
11332 push_word(*destreg
);
11338 DECODE_CLEAR_SEGOVR();
11342 /***************************************************************************
11343 * Single byte operation code table:
11344 **************************************************************************/
11345 void (*x86emu_optab
[256])(u8
) =
11347 /* 0x00 */ x86emuOp_add_byte_RM_R
,
11348 /* 0x01 */ x86emuOp_add_word_RM_R
,
11349 /* 0x02 */ x86emuOp_add_byte_R_RM
,
11350 /* 0x03 */ x86emuOp_add_word_R_RM
,
11351 /* 0x04 */ x86emuOp_add_byte_AL_IMM
,
11352 /* 0x05 */ x86emuOp_add_word_AX_IMM
,
11353 /* 0x06 */ x86emuOp_push_ES
,
11354 /* 0x07 */ x86emuOp_pop_ES
,
11356 /* 0x08 */ x86emuOp_or_byte_RM_R
,
11357 /* 0x09 */ x86emuOp_or_word_RM_R
,
11358 /* 0x0a */ x86emuOp_or_byte_R_RM
,
11359 /* 0x0b */ x86emuOp_or_word_R_RM
,
11360 /* 0x0c */ x86emuOp_or_byte_AL_IMM
,
11361 /* 0x0d */ x86emuOp_or_word_AX_IMM
,
11362 /* 0x0e */ x86emuOp_push_CS
,
11363 /* 0x0f */ x86emuOp_two_byte
,
11365 /* 0x10 */ x86emuOp_adc_byte_RM_R
,
11366 /* 0x11 */ x86emuOp_adc_word_RM_R
,
11367 /* 0x12 */ x86emuOp_adc_byte_R_RM
,
11368 /* 0x13 */ x86emuOp_adc_word_R_RM
,
11369 /* 0x14 */ x86emuOp_adc_byte_AL_IMM
,
11370 /* 0x15 */ x86emuOp_adc_word_AX_IMM
,
11371 /* 0x16 */ x86emuOp_push_SS
,
11372 /* 0x17 */ x86emuOp_pop_SS
,
11374 /* 0x18 */ x86emuOp_sbb_byte_RM_R
,
11375 /* 0x19 */ x86emuOp_sbb_word_RM_R
,
11376 /* 0x1a */ x86emuOp_sbb_byte_R_RM
,
11377 /* 0x1b */ x86emuOp_sbb_word_R_RM
,
11378 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM
,
11379 /* 0x1d */ x86emuOp_sbb_word_AX_IMM
,
11380 /* 0x1e */ x86emuOp_push_DS
,
11381 /* 0x1f */ x86emuOp_pop_DS
,
11383 /* 0x20 */ x86emuOp_and_byte_RM_R
,
11384 /* 0x21 */ x86emuOp_and_word_RM_R
,
11385 /* 0x22 */ x86emuOp_and_byte_R_RM
,
11386 /* 0x23 */ x86emuOp_and_word_R_RM
,
11387 /* 0x24 */ x86emuOp_and_byte_AL_IMM
,
11388 /* 0x25 */ x86emuOp_and_word_AX_IMM
,
11389 /* 0x26 */ x86emuOp_segovr_ES
,
11390 /* 0x27 */ x86emuOp_daa
,
11392 /* 0x28 */ x86emuOp_sub_byte_RM_R
,
11393 /* 0x29 */ x86emuOp_sub_word_RM_R
,
11394 /* 0x2a */ x86emuOp_sub_byte_R_RM
,
11395 /* 0x2b */ x86emuOp_sub_word_R_RM
,
11396 /* 0x2c */ x86emuOp_sub_byte_AL_IMM
,
11397 /* 0x2d */ x86emuOp_sub_word_AX_IMM
,
11398 /* 0x2e */ x86emuOp_segovr_CS
,
11399 /* 0x2f */ x86emuOp_das
,
11401 /* 0x30 */ x86emuOp_xor_byte_RM_R
,
11402 /* 0x31 */ x86emuOp_xor_word_RM_R
,
11403 /* 0x32 */ x86emuOp_xor_byte_R_RM
,
11404 /* 0x33 */ x86emuOp_xor_word_R_RM
,
11405 /* 0x34 */ x86emuOp_xor_byte_AL_IMM
,
11406 /* 0x35 */ x86emuOp_xor_word_AX_IMM
,
11407 /* 0x36 */ x86emuOp_segovr_SS
,
11408 /* 0x37 */ x86emuOp_aaa
,
11410 /* 0x38 */ x86emuOp_cmp_byte_RM_R
,
11411 /* 0x39 */ x86emuOp_cmp_word_RM_R
,
11412 /* 0x3a */ x86emuOp_cmp_byte_R_RM
,
11413 /* 0x3b */ x86emuOp_cmp_word_R_RM
,
11414 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM
,
11415 /* 0x3d */ x86emuOp_cmp_word_AX_IMM
,
11416 /* 0x3e */ x86emuOp_segovr_DS
,
11417 /* 0x3f */ x86emuOp_aas
,
11419 /* 0x40 */ x86emuOp_inc_AX
,
11420 /* 0x41 */ x86emuOp_inc_CX
,
11421 /* 0x42 */ x86emuOp_inc_DX
,
11422 /* 0x43 */ x86emuOp_inc_BX
,
11423 /* 0x44 */ x86emuOp_inc_SP
,
11424 /* 0x45 */ x86emuOp_inc_BP
,
11425 /* 0x46 */ x86emuOp_inc_SI
,
11426 /* 0x47 */ x86emuOp_inc_DI
,
11428 /* 0x48 */ x86emuOp_dec_AX
,
11429 /* 0x49 */ x86emuOp_dec_CX
,
11430 /* 0x4a */ x86emuOp_dec_DX
,
11431 /* 0x4b */ x86emuOp_dec_BX
,
11432 /* 0x4c */ x86emuOp_dec_SP
,
11433 /* 0x4d */ x86emuOp_dec_BP
,
11434 /* 0x4e */ x86emuOp_dec_SI
,
11435 /* 0x4f */ x86emuOp_dec_DI
,
11437 /* 0x50 */ x86emuOp_push_AX
,
11438 /* 0x51 */ x86emuOp_push_CX
,
11439 /* 0x52 */ x86emuOp_push_DX
,
11440 /* 0x53 */ x86emuOp_push_BX
,
11441 /* 0x54 */ x86emuOp_push_SP
,
11442 /* 0x55 */ x86emuOp_push_BP
,
11443 /* 0x56 */ x86emuOp_push_SI
,
11444 /* 0x57 */ x86emuOp_push_DI
,
11446 /* 0x58 */ x86emuOp_pop_AX
,
11447 /* 0x59 */ x86emuOp_pop_CX
,
11448 /* 0x5a */ x86emuOp_pop_DX
,
11449 /* 0x5b */ x86emuOp_pop_BX
,
11450 /* 0x5c */ x86emuOp_pop_SP
,
11451 /* 0x5d */ x86emuOp_pop_BP
,
11452 /* 0x5e */ x86emuOp_pop_SI
,
11453 /* 0x5f */ x86emuOp_pop_DI
,
11455 /* 0x60 */ x86emuOp_push_all
,
11456 /* 0x61 */ x86emuOp_pop_all
,
11457 /* 0x62 */ x86emuOp_illegal_op
, /* bound */
11458 /* 0x63 */ x86emuOp_illegal_op
, /* arpl */
11459 /* 0x64 */ x86emuOp_segovr_FS
,
11460 /* 0x65 */ x86emuOp_segovr_GS
,
11461 /* 0x66 */ x86emuOp_prefix_data
,
11462 /* 0x67 */ x86emuOp_prefix_addr
,
11464 /* 0x68 */ x86emuOp_push_word_IMM
,
11465 /* 0x69 */ x86emuOp_imul_word_IMM
,
11466 /* 0x6a */ x86emuOp_push_byte_IMM
,
11467 /* 0x6b */ x86emuOp_imul_byte_IMM
,
11468 /* 0x6c */ x86emuOp_ins_byte
,
11469 /* 0x6d */ x86emuOp_ins_word
,
11470 /* 0x6e */ x86emuOp_outs_byte
,
11471 /* 0x6f */ x86emuOp_outs_word
,
11473 /* 0x70 */ x86emuOp_jump_near_O
,
11474 /* 0x71 */ x86emuOp_jump_near_NO
,
11475 /* 0x72 */ x86emuOp_jump_near_B
,
11476 /* 0x73 */ x86emuOp_jump_near_NB
,
11477 /* 0x74 */ x86emuOp_jump_near_Z
,
11478 /* 0x75 */ x86emuOp_jump_near_NZ
,
11479 /* 0x76 */ x86emuOp_jump_near_BE
,
11480 /* 0x77 */ x86emuOp_jump_near_NBE
,
11482 /* 0x78 */ x86emuOp_jump_near_S
,
11483 /* 0x79 */ x86emuOp_jump_near_NS
,
11484 /* 0x7a */ x86emuOp_jump_near_P
,
11485 /* 0x7b */ x86emuOp_jump_near_NP
,
11486 /* 0x7c */ x86emuOp_jump_near_L
,
11487 /* 0x7d */ x86emuOp_jump_near_NL
,
11488 /* 0x7e */ x86emuOp_jump_near_LE
,
11489 /* 0x7f */ x86emuOp_jump_near_NLE
,
11491 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM
,
11492 /* 0x81 */ x86emuOp_opc81_word_RM_IMM
,
11493 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM
,
11494 /* 0x83 */ x86emuOp_opc83_word_RM_IMM
,
11495 /* 0x84 */ x86emuOp_test_byte_RM_R
,
11496 /* 0x85 */ x86emuOp_test_word_RM_R
,
11497 /* 0x86 */ x86emuOp_xchg_byte_RM_R
,
11498 /* 0x87 */ x86emuOp_xchg_word_RM_R
,
11500 /* 0x88 */ x86emuOp_mov_byte_RM_R
,
11501 /* 0x89 */ x86emuOp_mov_word_RM_R
,
11502 /* 0x8a */ x86emuOp_mov_byte_R_RM
,
11503 /* 0x8b */ x86emuOp_mov_word_R_RM
,
11504 /* 0x8c */ x86emuOp_mov_word_RM_SR
,
11505 /* 0x8d */ x86emuOp_lea_word_R_M
,
11506 /* 0x8e */ x86emuOp_mov_word_SR_RM
,
11507 /* 0x8f */ x86emuOp_pop_RM
,
11509 /* 0x90 */ x86emuOp_nop
,
11510 /* 0x91 */ x86emuOp_xchg_word_AX_CX
,
11511 /* 0x92 */ x86emuOp_xchg_word_AX_DX
,
11512 /* 0x93 */ x86emuOp_xchg_word_AX_BX
,
11513 /* 0x94 */ x86emuOp_xchg_word_AX_SP
,
11514 /* 0x95 */ x86emuOp_xchg_word_AX_BP
,
11515 /* 0x96 */ x86emuOp_xchg_word_AX_SI
,
11516 /* 0x97 */ x86emuOp_xchg_word_AX_DI
,
11518 /* 0x98 */ x86emuOp_cbw
,
11519 /* 0x99 */ x86emuOp_cwd
,
11520 /* 0x9a */ x86emuOp_call_far_IMM
,
11521 /* 0x9b */ x86emuOp_wait
,
11522 /* 0x9c */ x86emuOp_pushf_word
,
11523 /* 0x9d */ x86emuOp_popf_word
,
11524 /* 0x9e */ x86emuOp_sahf
,
11525 /* 0x9f */ x86emuOp_lahf
,
11527 /* 0xa0 */ x86emuOp_mov_AL_M_IMM
,
11528 /* 0xa1 */ x86emuOp_mov_AX_M_IMM
,
11529 /* 0xa2 */ x86emuOp_mov_M_AL_IMM
,
11530 /* 0xa3 */ x86emuOp_mov_M_AX_IMM
,
11531 /* 0xa4 */ x86emuOp_movs_byte
,
11532 /* 0xa5 */ x86emuOp_movs_word
,
11533 /* 0xa6 */ x86emuOp_cmps_byte
,
11534 /* 0xa7 */ x86emuOp_cmps_word
,
11535 /* 0xa8 */ x86emuOp_test_AL_IMM
,
11536 /* 0xa9 */ x86emuOp_test_AX_IMM
,
11537 /* 0xaa */ x86emuOp_stos_byte
,
11538 /* 0xab */ x86emuOp_stos_word
,
11539 /* 0xac */ x86emuOp_lods_byte
,
11540 /* 0xad */ x86emuOp_lods_word
,
11541 /* 0xac */ x86emuOp_scas_byte
,
11542 /* 0xad */ x86emuOp_scas_word
,
11545 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM
,
11546 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM
,
11547 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM
,
11548 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM
,
11549 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM
,
11550 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM
,
11551 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM
,
11552 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM
,
11554 /* 0xb8 */ x86emuOp_mov_word_AX_IMM
,
11555 /* 0xb9 */ x86emuOp_mov_word_CX_IMM
,
11556 /* 0xba */ x86emuOp_mov_word_DX_IMM
,
11557 /* 0xbb */ x86emuOp_mov_word_BX_IMM
,
11558 /* 0xbc */ x86emuOp_mov_word_SP_IMM
,
11559 /* 0xbd */ x86emuOp_mov_word_BP_IMM
,
11560 /* 0xbe */ x86emuOp_mov_word_SI_IMM
,
11561 /* 0xbf */ x86emuOp_mov_word_DI_IMM
,
11563 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM
,
11564 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM
,
11565 /* 0xc2 */ x86emuOp_ret_near_IMM
,
11566 /* 0xc3 */ x86emuOp_ret_near
,
11567 /* 0xc4 */ x86emuOp_les_R_IMM
,
11568 /* 0xc5 */ x86emuOp_lds_R_IMM
,
11569 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM
,
11570 /* 0xc7 */ x86emuOp_mov_word_RM_IMM
,
11571 /* 0xc8 */ x86emuOp_enter
,
11572 /* 0xc9 */ x86emuOp_leave
,
11573 /* 0xca */ x86emuOp_ret_far_IMM
,
11574 /* 0xcb */ x86emuOp_ret_far
,
11575 /* 0xcc */ x86emuOp_int3
,
11576 /* 0xcd */ x86emuOp_int_IMM
,
11577 /* 0xce */ x86emuOp_into
,
11578 /* 0xcf */ x86emuOp_iret
,
11580 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1
,
11581 /* 0xd1 */ x86emuOp_opcD1_word_RM_1
,
11582 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL
,
11583 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL
,
11584 /* 0xd4 */ x86emuOp_aam
,
11585 /* 0xd5 */ x86emuOp_aad
,
11586 /* 0xd6 */ x86emuOp_illegal_op
, /* Undocumented SETALC instruction */
11587 /* 0xd7 */ x86emuOp_xlat
,
11588 /* 0xd8 */ x86emuOp_esc_coprocess_d8
,
11589 /* 0xd9 */ x86emuOp_esc_coprocess_d9
,
11590 /* 0xda */ x86emuOp_esc_coprocess_da
,
11591 /* 0xdb */ x86emuOp_esc_coprocess_db
,
11592 /* 0xdc */ x86emuOp_esc_coprocess_dc
,
11593 /* 0xdd */ x86emuOp_esc_coprocess_dd
,
11594 /* 0xde */ x86emuOp_esc_coprocess_de
,
11595 /* 0xdf */ x86emuOp_esc_coprocess_df
,
11597 /* 0xe0 */ x86emuOp_loopne
,
11598 /* 0xe1 */ x86emuOp_loope
,
11599 /* 0xe2 */ x86emuOp_loop
,
11600 /* 0xe3 */ x86emuOp_jcxz
,
11601 /* 0xe4 */ x86emuOp_in_byte_AL_IMM
,
11602 /* 0xe5 */ x86emuOp_in_word_AX_IMM
,
11603 /* 0xe6 */ x86emuOp_out_byte_IMM_AL
,
11604 /* 0xe7 */ x86emuOp_out_word_IMM_AX
,
11606 /* 0xe8 */ x86emuOp_call_near_IMM
,
11607 /* 0xe9 */ x86emuOp_jump_near_IMM
,
11608 /* 0xea */ x86emuOp_jump_far_IMM
,
11609 /* 0xeb */ x86emuOp_jump_byte_IMM
,
11610 /* 0xec */ x86emuOp_in_byte_AL_DX
,
11611 /* 0xed */ x86emuOp_in_word_AX_DX
,
11612 /* 0xee */ x86emuOp_out_byte_DX_AL
,
11613 /* 0xef */ x86emuOp_out_word_DX_AX
,
11615 /* 0xf0 */ x86emuOp_lock
,
11616 /* 0xf1 */ x86emuOp_illegal_op
,
11617 /* 0xf2 */ x86emuOp_repne
,
11618 /* 0xf3 */ x86emuOp_repe
,
11619 /* 0xf4 */ x86emuOp_halt
,
11620 /* 0xf5 */ x86emuOp_cmc
,
11621 /* 0xf6 */ x86emuOp_opcF6_byte_RM
,
11622 /* 0xf7 */ x86emuOp_opcF7_word_RM
,
11624 /* 0xf8 */ x86emuOp_clc
,
11625 /* 0xf9 */ x86emuOp_stc
,
11626 /* 0xfa */ x86emuOp_cli
,
11627 /* 0xfb */ x86emuOp_sti
,
11628 /* 0xfc */ x86emuOp_cld
,
11629 /* 0xfd */ x86emuOp_std
,
11630 /* 0xfe */ x86emuOp_opcFE_byte_RM
,
11631 /* 0xff */ x86emuOp_opcFF_word_RM
,