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 #include "x86emu/x86emui.h"
75 /*----------------------------- Implementation ----------------------------*/
77 /****************************************************************************
79 op1 - Instruction op code
82 Handles illegal opcodes.
83 ****************************************************************************/
84 static void x86emuOp_illegal_op(
88 if (M
.x86
.R_SP
!= 0) {
89 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
91 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92 M
.x86
.R_CS
, M
.x86
.R_IP
-1,op1
);
96 /* If we get here, it means the stack pointer is back to zero
97 * so we are just returning from an emulator service call
98 * so therte is no need to display an error message. We trap
99 * the emulator with an 0xF1 opcode to finish the service
107 /****************************************************************************
110 ****************************************************************************/
111 static void x86emuOp_add_byte_RM_R(u8
X86EMU_UNUSED(op1
))
115 u8
*destreg
, *srcreg
;
119 DECODE_PRINTF("ADD\t");
120 FETCH_DECODE_MODRM(mod
, rh
, rl
);
123 destoffset
= decode_rm00_address(rl
);
125 destval
= fetch_data_byte(destoffset
);
126 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
129 destval
= add_byte(destval
, *srcreg
);
130 store_data_byte(destoffset
, destval
);
133 destoffset
= decode_rm01_address(rl
);
135 destval
= fetch_data_byte(destoffset
);
136 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
139 destval
= add_byte(destval
, *srcreg
);
140 store_data_byte(destoffset
, destval
);
143 destoffset
= decode_rm10_address(rl
);
145 destval
= fetch_data_byte(destoffset
);
146 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
149 destval
= add_byte(destval
, *srcreg
);
150 store_data_byte(destoffset
, destval
);
152 case 3: /* register to register */
153 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
155 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
158 *destreg
= add_byte(*destreg
, *srcreg
);
161 DECODE_CLEAR_SEGOVR();
165 /****************************************************************************
168 ****************************************************************************/
169 static void x86emuOp_add_word_RM_R(u8
X86EMU_UNUSED(op1
))
175 DECODE_PRINTF("ADD\t");
176 FETCH_DECODE_MODRM(mod
, rh
, rl
);
179 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
183 destoffset
= decode_rm00_address(rl
);
185 destval
= fetch_data_long(destoffset
);
186 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
189 destval
= add_long(destval
, *srcreg
);
190 store_data_long(destoffset
, destval
);
195 destoffset
= decode_rm00_address(rl
);
197 destval
= fetch_data_word(destoffset
);
198 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
201 destval
= add_word(destval
, *srcreg
);
202 store_data_word(destoffset
, destval
);
206 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
210 destoffset
= decode_rm01_address(rl
);
212 destval
= fetch_data_long(destoffset
);
213 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
216 destval
= add_long(destval
, *srcreg
);
217 store_data_long(destoffset
, destval
);
222 destoffset
= decode_rm01_address(rl
);
224 destval
= fetch_data_word(destoffset
);
225 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
228 destval
= add_word(destval
, *srcreg
);
229 store_data_word(destoffset
, destval
);
233 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
237 destoffset
= decode_rm10_address(rl
);
239 destval
= fetch_data_long(destoffset
);
240 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
243 destval
= add_long(destval
, *srcreg
);
244 store_data_long(destoffset
, destval
);
249 destoffset
= decode_rm10_address(rl
);
251 destval
= fetch_data_word(destoffset
);
252 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
255 destval
= add_word(destval
, *srcreg
);
256 store_data_word(destoffset
, destval
);
259 case 3: /* register to register */
260 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
261 u32
*destreg
,*srcreg
;
263 destreg
= DECODE_RM_LONG_REGISTER(rl
);
265 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
268 *destreg
= add_long(*destreg
, *srcreg
);
270 u16
*destreg
,*srcreg
;
272 destreg
= DECODE_RM_WORD_REGISTER(rl
);
274 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
277 *destreg
= add_word(*destreg
, *srcreg
);
281 DECODE_CLEAR_SEGOVR();
285 /****************************************************************************
288 ****************************************************************************/
289 static void x86emuOp_add_byte_R_RM(u8
X86EMU_UNUSED(op1
))
292 u8
*destreg
, *srcreg
;
297 DECODE_PRINTF("ADD\t");
298 FETCH_DECODE_MODRM(mod
, rh
, rl
);
301 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
303 srcoffset
= decode_rm00_address(rl
);
304 srcval
= fetch_data_byte(srcoffset
);
307 *destreg
= add_byte(*destreg
, srcval
);
310 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
312 srcoffset
= decode_rm01_address(rl
);
313 srcval
= fetch_data_byte(srcoffset
);
316 *destreg
= add_byte(*destreg
, srcval
);
319 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
321 srcoffset
= decode_rm10_address(rl
);
322 srcval
= fetch_data_byte(srcoffset
);
325 *destreg
= add_byte(*destreg
, srcval
);
327 case 3: /* register to register */
328 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
330 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
333 *destreg
= add_byte(*destreg
, *srcreg
);
336 DECODE_CLEAR_SEGOVR();
340 /****************************************************************************
343 ****************************************************************************/
344 static void x86emuOp_add_word_R_RM(u8
X86EMU_UNUSED(op1
))
350 DECODE_PRINTF("ADD\t");
351 FETCH_DECODE_MODRM(mod
, rh
, rl
);
354 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
358 destreg
= DECODE_RM_LONG_REGISTER(rh
);
360 srcoffset
= decode_rm00_address(rl
);
361 srcval
= fetch_data_long(srcoffset
);
364 *destreg
= add_long(*destreg
, srcval
);
369 destreg
= DECODE_RM_WORD_REGISTER(rh
);
371 srcoffset
= decode_rm00_address(rl
);
372 srcval
= fetch_data_word(srcoffset
);
375 *destreg
= add_word(*destreg
, srcval
);
379 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
383 destreg
= DECODE_RM_LONG_REGISTER(rh
);
385 srcoffset
= decode_rm01_address(rl
);
386 srcval
= fetch_data_long(srcoffset
);
389 *destreg
= add_long(*destreg
, srcval
);
394 destreg
= DECODE_RM_WORD_REGISTER(rh
);
396 srcoffset
= decode_rm01_address(rl
);
397 srcval
= fetch_data_word(srcoffset
);
400 *destreg
= add_word(*destreg
, srcval
);
404 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
408 destreg
= DECODE_RM_LONG_REGISTER(rh
);
410 srcoffset
= decode_rm10_address(rl
);
411 srcval
= fetch_data_long(srcoffset
);
414 *destreg
= add_long(*destreg
, srcval
);
419 destreg
= DECODE_RM_WORD_REGISTER(rh
);
421 srcoffset
= decode_rm10_address(rl
);
422 srcval
= fetch_data_word(srcoffset
);
425 *destreg
= add_word(*destreg
, srcval
);
428 case 3: /* register to register */
429 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
430 u32
*destreg
,*srcreg
;
432 destreg
= DECODE_RM_LONG_REGISTER(rh
);
434 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
437 *destreg
= add_long(*destreg
, *srcreg
);
439 u16
*destreg
,*srcreg
;
441 destreg
= DECODE_RM_WORD_REGISTER(rh
);
443 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
446 *destreg
= add_word(*destreg
, *srcreg
);
450 DECODE_CLEAR_SEGOVR();
454 /****************************************************************************
457 ****************************************************************************/
458 static void x86emuOp_add_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
463 DECODE_PRINTF("ADD\tAL,");
464 srcval
= fetch_byte_imm();
465 DECODE_PRINTF2("%x\n", srcval
);
467 M
.x86
.R_AL
= add_byte(M
.x86
.R_AL
, srcval
);
468 DECODE_CLEAR_SEGOVR();
472 /****************************************************************************
475 ****************************************************************************/
476 static void x86emuOp_add_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
481 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
482 DECODE_PRINTF("ADD\tEAX,");
483 srcval
= fetch_long_imm();
485 DECODE_PRINTF("ADD\tAX,");
486 srcval
= fetch_word_imm();
488 DECODE_PRINTF2("%x\n", srcval
);
490 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
491 M
.x86
.R_EAX
= add_long(M
.x86
.R_EAX
, srcval
);
493 M
.x86
.R_AX
= add_word(M
.x86
.R_AX
, (u16
)srcval
);
495 DECODE_CLEAR_SEGOVR();
499 /****************************************************************************
502 ****************************************************************************/
503 static void x86emuOp_push_ES(u8
X86EMU_UNUSED(op1
))
506 DECODE_PRINTF("PUSH\tES\n");
508 push_word(M
.x86
.R_ES
);
509 DECODE_CLEAR_SEGOVR();
513 /****************************************************************************
516 ****************************************************************************/
517 static void x86emuOp_pop_ES(u8
X86EMU_UNUSED(op1
))
520 DECODE_PRINTF("POP\tES\n");
522 M
.x86
.R_ES
= pop_word();
523 DECODE_CLEAR_SEGOVR();
527 /****************************************************************************
530 ****************************************************************************/
531 static void x86emuOp_or_byte_RM_R(u8
X86EMU_UNUSED(op1
))
534 u8
*destreg
, *srcreg
;
539 DECODE_PRINTF("OR\t");
540 FETCH_DECODE_MODRM(mod
, rh
, rl
);
543 destoffset
= decode_rm00_address(rl
);
545 destval
= fetch_data_byte(destoffset
);
546 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
549 destval
= or_byte(destval
, *srcreg
);
550 store_data_byte(destoffset
, destval
);
553 destoffset
= decode_rm01_address(rl
);
555 destval
= fetch_data_byte(destoffset
);
556 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
559 destval
= or_byte(destval
, *srcreg
);
560 store_data_byte(destoffset
, destval
);
563 destoffset
= decode_rm10_address(rl
);
565 destval
= fetch_data_byte(destoffset
);
566 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
569 destval
= or_byte(destval
, *srcreg
);
570 store_data_byte(destoffset
, destval
);
572 case 3: /* register to register */
573 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
575 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
578 *destreg
= or_byte(*destreg
, *srcreg
);
581 DECODE_CLEAR_SEGOVR();
585 /****************************************************************************
588 ****************************************************************************/
589 static void x86emuOp_or_word_RM_R(u8
X86EMU_UNUSED(op1
))
595 DECODE_PRINTF("OR\t");
596 FETCH_DECODE_MODRM(mod
, rh
, rl
);
599 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
603 destoffset
= decode_rm00_address(rl
);
605 destval
= fetch_data_long(destoffset
);
606 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
609 destval
= or_long(destval
, *srcreg
);
610 store_data_long(destoffset
, destval
);
615 destoffset
= decode_rm00_address(rl
);
617 destval
= fetch_data_word(destoffset
);
618 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
621 destval
= or_word(destval
, *srcreg
);
622 store_data_word(destoffset
, destval
);
626 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
630 destoffset
= decode_rm01_address(rl
);
632 destval
= fetch_data_long(destoffset
);
633 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
636 destval
= or_long(destval
, *srcreg
);
637 store_data_long(destoffset
, destval
);
642 destoffset
= decode_rm01_address(rl
);
644 destval
= fetch_data_word(destoffset
);
645 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
648 destval
= or_word(destval
, *srcreg
);
649 store_data_word(destoffset
, destval
);
653 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
657 destoffset
= decode_rm10_address(rl
);
659 destval
= fetch_data_long(destoffset
);
660 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
663 destval
= or_long(destval
, *srcreg
);
664 store_data_long(destoffset
, destval
);
669 destoffset
= decode_rm10_address(rl
);
671 destval
= fetch_data_word(destoffset
);
672 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
675 destval
= or_word(destval
, *srcreg
);
676 store_data_word(destoffset
, destval
);
679 case 3: /* register to register */
680 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
681 u32
*destreg
,*srcreg
;
683 destreg
= DECODE_RM_LONG_REGISTER(rl
);
685 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
688 *destreg
= or_long(*destreg
, *srcreg
);
690 u16
*destreg
,*srcreg
;
692 destreg
= DECODE_RM_WORD_REGISTER(rl
);
694 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
697 *destreg
= or_word(*destreg
, *srcreg
);
701 DECODE_CLEAR_SEGOVR();
705 /****************************************************************************
708 ****************************************************************************/
709 static void x86emuOp_or_byte_R_RM(u8
X86EMU_UNUSED(op1
))
712 u8
*destreg
, *srcreg
;
717 DECODE_PRINTF("OR\t");
718 FETCH_DECODE_MODRM(mod
, rh
, rl
);
721 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
723 srcoffset
= decode_rm00_address(rl
);
724 srcval
= fetch_data_byte(srcoffset
);
727 *destreg
= or_byte(*destreg
, srcval
);
730 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
732 srcoffset
= decode_rm01_address(rl
);
733 srcval
= fetch_data_byte(srcoffset
);
736 *destreg
= or_byte(*destreg
, srcval
);
739 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
741 srcoffset
= decode_rm10_address(rl
);
742 srcval
= fetch_data_byte(srcoffset
);
745 *destreg
= or_byte(*destreg
, srcval
);
747 case 3: /* register to register */
748 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
750 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
753 *destreg
= or_byte(*destreg
, *srcreg
);
756 DECODE_CLEAR_SEGOVR();
760 /****************************************************************************
763 ****************************************************************************/
764 static void x86emuOp_or_word_R_RM(u8
X86EMU_UNUSED(op1
))
770 DECODE_PRINTF("OR\t");
771 FETCH_DECODE_MODRM(mod
, rh
, rl
);
774 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
778 destreg
= DECODE_RM_LONG_REGISTER(rh
);
780 srcoffset
= decode_rm00_address(rl
);
781 srcval
= fetch_data_long(srcoffset
);
784 *destreg
= or_long(*destreg
, srcval
);
789 destreg
= DECODE_RM_WORD_REGISTER(rh
);
791 srcoffset
= decode_rm00_address(rl
);
792 srcval
= fetch_data_word(srcoffset
);
795 *destreg
= or_word(*destreg
, srcval
);
799 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
803 destreg
= DECODE_RM_LONG_REGISTER(rh
);
805 srcoffset
= decode_rm01_address(rl
);
806 srcval
= fetch_data_long(srcoffset
);
809 *destreg
= or_long(*destreg
, srcval
);
814 destreg
= DECODE_RM_WORD_REGISTER(rh
);
816 srcoffset
= decode_rm01_address(rl
);
817 srcval
= fetch_data_word(srcoffset
);
820 *destreg
= or_word(*destreg
, srcval
);
824 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
828 destreg
= DECODE_RM_LONG_REGISTER(rh
);
830 srcoffset
= decode_rm10_address(rl
);
831 srcval
= fetch_data_long(srcoffset
);
834 *destreg
= or_long(*destreg
, srcval
);
839 destreg
= DECODE_RM_WORD_REGISTER(rh
);
841 srcoffset
= decode_rm10_address(rl
);
842 srcval
= fetch_data_word(srcoffset
);
845 *destreg
= or_word(*destreg
, srcval
);
848 case 3: /* register to register */
849 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
850 u32
*destreg
,*srcreg
;
852 destreg
= DECODE_RM_LONG_REGISTER(rh
);
854 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
857 *destreg
= or_long(*destreg
, *srcreg
);
859 u16
*destreg
,*srcreg
;
861 destreg
= DECODE_RM_WORD_REGISTER(rh
);
863 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
866 *destreg
= or_word(*destreg
, *srcreg
);
870 DECODE_CLEAR_SEGOVR();
874 /****************************************************************************
877 ****************************************************************************/
878 static void x86emuOp_or_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
883 DECODE_PRINTF("OR\tAL,");
884 srcval
= fetch_byte_imm();
885 DECODE_PRINTF2("%x\n", srcval
);
887 M
.x86
.R_AL
= or_byte(M
.x86
.R_AL
, srcval
);
888 DECODE_CLEAR_SEGOVR();
892 /****************************************************************************
895 ****************************************************************************/
896 static void x86emuOp_or_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
901 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
902 DECODE_PRINTF("OR\tEAX,");
903 srcval
= fetch_long_imm();
905 DECODE_PRINTF("OR\tAX,");
906 srcval
= fetch_word_imm();
908 DECODE_PRINTF2("%x\n", srcval
);
910 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
911 M
.x86
.R_EAX
= or_long(M
.x86
.R_EAX
, srcval
);
913 M
.x86
.R_AX
= or_word(M
.x86
.R_AX
, (u16
)srcval
);
915 DECODE_CLEAR_SEGOVR();
919 /****************************************************************************
922 ****************************************************************************/
923 static void x86emuOp_push_CS(u8
X86EMU_UNUSED(op1
))
926 DECODE_PRINTF("PUSH\tCS\n");
928 push_word(M
.x86
.R_CS
);
929 DECODE_CLEAR_SEGOVR();
933 /****************************************************************************
935 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
936 ****************************************************************************/
937 static void x86emuOp_two_byte(u8
X86EMU_UNUSED(op1
))
939 u8 op2
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
940 INC_DECODED_INST_LEN(1);
941 (*x86emu_optab2
[op2
])(op2
);
944 /****************************************************************************
947 ****************************************************************************/
948 static void x86emuOp_adc_byte_RM_R(u8
X86EMU_UNUSED(op1
))
951 u8
*destreg
, *srcreg
;
956 DECODE_PRINTF("ADC\t");
957 FETCH_DECODE_MODRM(mod
, rh
, rl
);
960 destoffset
= decode_rm00_address(rl
);
962 destval
= fetch_data_byte(destoffset
);
963 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
966 destval
= adc_byte(destval
, *srcreg
);
967 store_data_byte(destoffset
, destval
);
970 destoffset
= decode_rm01_address(rl
);
972 destval
= fetch_data_byte(destoffset
);
973 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
976 destval
= adc_byte(destval
, *srcreg
);
977 store_data_byte(destoffset
, destval
);
980 destoffset
= decode_rm10_address(rl
);
982 destval
= fetch_data_byte(destoffset
);
983 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
986 destval
= adc_byte(destval
, *srcreg
);
987 store_data_byte(destoffset
, destval
);
989 case 3: /* register to register */
990 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
992 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
995 *destreg
= adc_byte(*destreg
, *srcreg
);
998 DECODE_CLEAR_SEGOVR();
1002 /****************************************************************************
1005 ****************************************************************************/
1006 static void x86emuOp_adc_word_RM_R(u8
X86EMU_UNUSED(op1
))
1012 DECODE_PRINTF("ADC\t");
1013 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1016 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1020 destoffset
= decode_rm00_address(rl
);
1022 destval
= fetch_data_long(destoffset
);
1023 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1024 DECODE_PRINTF("\n");
1026 destval
= adc_long(destval
, *srcreg
);
1027 store_data_long(destoffset
, destval
);
1032 destoffset
= decode_rm00_address(rl
);
1034 destval
= fetch_data_word(destoffset
);
1035 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1036 DECODE_PRINTF("\n");
1038 destval
= adc_word(destval
, *srcreg
);
1039 store_data_word(destoffset
, destval
);
1043 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1047 destoffset
= decode_rm01_address(rl
);
1049 destval
= fetch_data_long(destoffset
);
1050 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1051 DECODE_PRINTF("\n");
1053 destval
= adc_long(destval
, *srcreg
);
1054 store_data_long(destoffset
, destval
);
1059 destoffset
= decode_rm01_address(rl
);
1061 destval
= fetch_data_word(destoffset
);
1062 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1063 DECODE_PRINTF("\n");
1065 destval
= adc_word(destval
, *srcreg
);
1066 store_data_word(destoffset
, destval
);
1070 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1074 destoffset
= decode_rm10_address(rl
);
1076 destval
= fetch_data_long(destoffset
);
1077 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1078 DECODE_PRINTF("\n");
1080 destval
= adc_long(destval
, *srcreg
);
1081 store_data_long(destoffset
, destval
);
1086 destoffset
= decode_rm10_address(rl
);
1088 destval
= fetch_data_word(destoffset
);
1089 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1090 DECODE_PRINTF("\n");
1092 destval
= adc_word(destval
, *srcreg
);
1093 store_data_word(destoffset
, destval
);
1096 case 3: /* register to register */
1097 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1098 u32
*destreg
,*srcreg
;
1100 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1102 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1103 DECODE_PRINTF("\n");
1105 *destreg
= adc_long(*destreg
, *srcreg
);
1107 u16
*destreg
,*srcreg
;
1109 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1111 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1112 DECODE_PRINTF("\n");
1114 *destreg
= adc_word(*destreg
, *srcreg
);
1118 DECODE_CLEAR_SEGOVR();
1122 /****************************************************************************
1125 ****************************************************************************/
1126 static void x86emuOp_adc_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1129 u8
*destreg
, *srcreg
;
1134 DECODE_PRINTF("ADC\t");
1135 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1138 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1140 srcoffset
= decode_rm00_address(rl
);
1141 srcval
= fetch_data_byte(srcoffset
);
1142 DECODE_PRINTF("\n");
1144 *destreg
= adc_byte(*destreg
, srcval
);
1147 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1149 srcoffset
= decode_rm01_address(rl
);
1150 srcval
= fetch_data_byte(srcoffset
);
1151 DECODE_PRINTF("\n");
1153 *destreg
= adc_byte(*destreg
, srcval
);
1156 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1158 srcoffset
= decode_rm10_address(rl
);
1159 srcval
= fetch_data_byte(srcoffset
);
1160 DECODE_PRINTF("\n");
1162 *destreg
= adc_byte(*destreg
, srcval
);
1164 case 3: /* register to register */
1165 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1167 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1168 DECODE_PRINTF("\n");
1170 *destreg
= adc_byte(*destreg
, *srcreg
);
1173 DECODE_CLEAR_SEGOVR();
1177 /****************************************************************************
1180 ****************************************************************************/
1181 static void x86emuOp_adc_word_R_RM(u8
X86EMU_UNUSED(op1
))
1187 DECODE_PRINTF("ADC\t");
1188 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1191 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1195 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1197 srcoffset
= decode_rm00_address(rl
);
1198 srcval
= fetch_data_long(srcoffset
);
1199 DECODE_PRINTF("\n");
1201 *destreg
= adc_long(*destreg
, srcval
);
1206 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1208 srcoffset
= decode_rm00_address(rl
);
1209 srcval
= fetch_data_word(srcoffset
);
1210 DECODE_PRINTF("\n");
1212 *destreg
= adc_word(*destreg
, srcval
);
1216 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1220 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1222 srcoffset
= decode_rm01_address(rl
);
1223 srcval
= fetch_data_long(srcoffset
);
1224 DECODE_PRINTF("\n");
1226 *destreg
= adc_long(*destreg
, srcval
);
1231 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1233 srcoffset
= decode_rm01_address(rl
);
1234 srcval
= fetch_data_word(srcoffset
);
1235 DECODE_PRINTF("\n");
1237 *destreg
= adc_word(*destreg
, srcval
);
1241 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1245 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1247 srcoffset
= decode_rm10_address(rl
);
1248 srcval
= fetch_data_long(srcoffset
);
1249 DECODE_PRINTF("\n");
1251 *destreg
= adc_long(*destreg
, srcval
);
1256 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1258 srcoffset
= decode_rm10_address(rl
);
1259 srcval
= fetch_data_word(srcoffset
);
1260 DECODE_PRINTF("\n");
1262 *destreg
= adc_word(*destreg
, srcval
);
1265 case 3: /* register to register */
1266 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1267 u32
*destreg
,*srcreg
;
1269 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1271 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1272 DECODE_PRINTF("\n");
1274 *destreg
= adc_long(*destreg
, *srcreg
);
1276 u16
*destreg
,*srcreg
;
1278 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1280 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1281 DECODE_PRINTF("\n");
1283 *destreg
= adc_word(*destreg
, *srcreg
);
1287 DECODE_CLEAR_SEGOVR();
1291 /****************************************************************************
1294 ****************************************************************************/
1295 static void x86emuOp_adc_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
1300 DECODE_PRINTF("ADC\tAL,");
1301 srcval
= fetch_byte_imm();
1302 DECODE_PRINTF2("%x\n", srcval
);
1304 M
.x86
.R_AL
= adc_byte(M
.x86
.R_AL
, srcval
);
1305 DECODE_CLEAR_SEGOVR();
1309 /****************************************************************************
1312 ****************************************************************************/
1313 static void x86emuOp_adc_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
1318 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1319 DECODE_PRINTF("ADC\tEAX,");
1320 srcval
= fetch_long_imm();
1322 DECODE_PRINTF("ADC\tAX,");
1323 srcval
= fetch_word_imm();
1325 DECODE_PRINTF2("%x\n", srcval
);
1327 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1328 M
.x86
.R_EAX
= adc_long(M
.x86
.R_EAX
, srcval
);
1330 M
.x86
.R_AX
= adc_word(M
.x86
.R_AX
, (u16
)srcval
);
1332 DECODE_CLEAR_SEGOVR();
1336 /****************************************************************************
1339 ****************************************************************************/
1340 static void x86emuOp_push_SS(u8
X86EMU_UNUSED(op1
))
1343 DECODE_PRINTF("PUSH\tSS\n");
1345 push_word(M
.x86
.R_SS
);
1346 DECODE_CLEAR_SEGOVR();
1350 /****************************************************************************
1353 ****************************************************************************/
1354 static void x86emuOp_pop_SS(u8
X86EMU_UNUSED(op1
))
1357 DECODE_PRINTF("POP\tSS\n");
1359 M
.x86
.R_SS
= pop_word();
1360 DECODE_CLEAR_SEGOVR();
1364 /****************************************************************************
1367 ****************************************************************************/
1368 static void x86emuOp_sbb_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1371 u8
*destreg
, *srcreg
;
1376 DECODE_PRINTF("SBB\t");
1377 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1380 destoffset
= decode_rm00_address(rl
);
1382 destval
= fetch_data_byte(destoffset
);
1383 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1384 DECODE_PRINTF("\n");
1386 destval
= sbb_byte(destval
, *srcreg
);
1387 store_data_byte(destoffset
, destval
);
1390 destoffset
= decode_rm01_address(rl
);
1392 destval
= fetch_data_byte(destoffset
);
1393 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1394 DECODE_PRINTF("\n");
1396 destval
= sbb_byte(destval
, *srcreg
);
1397 store_data_byte(destoffset
, destval
);
1400 destoffset
= decode_rm10_address(rl
);
1402 destval
= fetch_data_byte(destoffset
);
1403 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1404 DECODE_PRINTF("\n");
1406 destval
= sbb_byte(destval
, *srcreg
);
1407 store_data_byte(destoffset
, destval
);
1409 case 3: /* register to register */
1410 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1412 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1413 DECODE_PRINTF("\n");
1415 *destreg
= sbb_byte(*destreg
, *srcreg
);
1418 DECODE_CLEAR_SEGOVR();
1422 /****************************************************************************
1425 ****************************************************************************/
1426 static void x86emuOp_sbb_word_RM_R(u8
X86EMU_UNUSED(op1
))
1432 DECODE_PRINTF("SBB\t");
1433 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1436 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1440 destoffset
= decode_rm00_address(rl
);
1442 destval
= fetch_data_long(destoffset
);
1443 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1444 DECODE_PRINTF("\n");
1446 destval
= sbb_long(destval
, *srcreg
);
1447 store_data_long(destoffset
, destval
);
1452 destoffset
= decode_rm00_address(rl
);
1454 destval
= fetch_data_word(destoffset
);
1455 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1456 DECODE_PRINTF("\n");
1458 destval
= sbb_word(destval
, *srcreg
);
1459 store_data_word(destoffset
, destval
);
1463 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1467 destoffset
= decode_rm01_address(rl
);
1469 destval
= fetch_data_long(destoffset
);
1470 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1471 DECODE_PRINTF("\n");
1473 destval
= sbb_long(destval
, *srcreg
);
1474 store_data_long(destoffset
, destval
);
1479 destoffset
= decode_rm01_address(rl
);
1481 destval
= fetch_data_word(destoffset
);
1482 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1483 DECODE_PRINTF("\n");
1485 destval
= sbb_word(destval
, *srcreg
);
1486 store_data_word(destoffset
, destval
);
1490 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1494 destoffset
= decode_rm10_address(rl
);
1496 destval
= fetch_data_long(destoffset
);
1497 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1498 DECODE_PRINTF("\n");
1500 destval
= sbb_long(destval
, *srcreg
);
1501 store_data_long(destoffset
, destval
);
1506 destoffset
= decode_rm10_address(rl
);
1508 destval
= fetch_data_word(destoffset
);
1509 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1510 DECODE_PRINTF("\n");
1512 destval
= sbb_word(destval
, *srcreg
);
1513 store_data_word(destoffset
, destval
);
1516 case 3: /* register to register */
1517 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1518 u32
*destreg
,*srcreg
;
1520 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1522 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1523 DECODE_PRINTF("\n");
1525 *destreg
= sbb_long(*destreg
, *srcreg
);
1527 u16
*destreg
,*srcreg
;
1529 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1531 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1532 DECODE_PRINTF("\n");
1534 *destreg
= sbb_word(*destreg
, *srcreg
);
1538 DECODE_CLEAR_SEGOVR();
1542 /****************************************************************************
1545 ****************************************************************************/
1546 static void x86emuOp_sbb_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1549 u8
*destreg
, *srcreg
;
1554 DECODE_PRINTF("SBB\t");
1555 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1558 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1560 srcoffset
= decode_rm00_address(rl
);
1561 srcval
= fetch_data_byte(srcoffset
);
1562 DECODE_PRINTF("\n");
1564 *destreg
= sbb_byte(*destreg
, srcval
);
1567 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1569 srcoffset
= decode_rm01_address(rl
);
1570 srcval
= fetch_data_byte(srcoffset
);
1571 DECODE_PRINTF("\n");
1573 *destreg
= sbb_byte(*destreg
, srcval
);
1576 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1578 srcoffset
= decode_rm10_address(rl
);
1579 srcval
= fetch_data_byte(srcoffset
);
1580 DECODE_PRINTF("\n");
1582 *destreg
= sbb_byte(*destreg
, srcval
);
1584 case 3: /* register to register */
1585 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1587 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1588 DECODE_PRINTF("\n");
1590 *destreg
= sbb_byte(*destreg
, *srcreg
);
1593 DECODE_CLEAR_SEGOVR();
1597 /****************************************************************************
1600 ****************************************************************************/
1601 static void x86emuOp_sbb_word_R_RM(u8
X86EMU_UNUSED(op1
))
1607 DECODE_PRINTF("SBB\t");
1608 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1611 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1615 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1617 srcoffset
= decode_rm00_address(rl
);
1618 srcval
= fetch_data_long(srcoffset
);
1619 DECODE_PRINTF("\n");
1621 *destreg
= sbb_long(*destreg
, srcval
);
1626 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1628 srcoffset
= decode_rm00_address(rl
);
1629 srcval
= fetch_data_word(srcoffset
);
1630 DECODE_PRINTF("\n");
1632 *destreg
= sbb_word(*destreg
, srcval
);
1636 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1640 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1642 srcoffset
= decode_rm01_address(rl
);
1643 srcval
= fetch_data_long(srcoffset
);
1644 DECODE_PRINTF("\n");
1646 *destreg
= sbb_long(*destreg
, srcval
);
1651 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1653 srcoffset
= decode_rm01_address(rl
);
1654 srcval
= fetch_data_word(srcoffset
);
1655 DECODE_PRINTF("\n");
1657 *destreg
= sbb_word(*destreg
, srcval
);
1661 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1665 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1667 srcoffset
= decode_rm10_address(rl
);
1668 srcval
= fetch_data_long(srcoffset
);
1669 DECODE_PRINTF("\n");
1671 *destreg
= sbb_long(*destreg
, srcval
);
1676 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1678 srcoffset
= decode_rm10_address(rl
);
1679 srcval
= fetch_data_word(srcoffset
);
1680 DECODE_PRINTF("\n");
1682 *destreg
= sbb_word(*destreg
, srcval
);
1685 case 3: /* register to register */
1686 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1687 u32
*destreg
,*srcreg
;
1689 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1691 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1692 DECODE_PRINTF("\n");
1694 *destreg
= sbb_long(*destreg
, *srcreg
);
1696 u16
*destreg
,*srcreg
;
1698 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1700 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1701 DECODE_PRINTF("\n");
1703 *destreg
= sbb_word(*destreg
, *srcreg
);
1707 DECODE_CLEAR_SEGOVR();
1711 /****************************************************************************
1714 ****************************************************************************/
1715 static void x86emuOp_sbb_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
1720 DECODE_PRINTF("SBB\tAL,");
1721 srcval
= fetch_byte_imm();
1722 DECODE_PRINTF2("%x\n", srcval
);
1724 M
.x86
.R_AL
= sbb_byte(M
.x86
.R_AL
, srcval
);
1725 DECODE_CLEAR_SEGOVR();
1729 /****************************************************************************
1732 ****************************************************************************/
1733 static void x86emuOp_sbb_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
1738 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1739 DECODE_PRINTF("SBB\tEAX,");
1740 srcval
= fetch_long_imm();
1742 DECODE_PRINTF("SBB\tAX,");
1743 srcval
= fetch_word_imm();
1745 DECODE_PRINTF2("%x\n", srcval
);
1747 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1748 M
.x86
.R_EAX
= sbb_long(M
.x86
.R_EAX
, srcval
);
1750 M
.x86
.R_AX
= sbb_word(M
.x86
.R_AX
, (u16
)srcval
);
1752 DECODE_CLEAR_SEGOVR();
1756 /****************************************************************************
1759 ****************************************************************************/
1760 static void x86emuOp_push_DS(u8
X86EMU_UNUSED(op1
))
1763 DECODE_PRINTF("PUSH\tDS\n");
1765 push_word(M
.x86
.R_DS
);
1766 DECODE_CLEAR_SEGOVR();
1770 /****************************************************************************
1773 ****************************************************************************/
1774 static void x86emuOp_pop_DS(u8
X86EMU_UNUSED(op1
))
1777 DECODE_PRINTF("POP\tDS\n");
1779 M
.x86
.R_DS
= pop_word();
1780 DECODE_CLEAR_SEGOVR();
1784 /****************************************************************************
1787 ****************************************************************************/
1788 static void x86emuOp_and_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1791 u8
*destreg
, *srcreg
;
1796 DECODE_PRINTF("AND\t");
1797 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1801 destoffset
= decode_rm00_address(rl
);
1803 destval
= fetch_data_byte(destoffset
);
1804 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1805 DECODE_PRINTF("\n");
1807 destval
= and_byte(destval
, *srcreg
);
1808 store_data_byte(destoffset
, destval
);
1812 destoffset
= decode_rm01_address(rl
);
1814 destval
= fetch_data_byte(destoffset
);
1815 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1816 DECODE_PRINTF("\n");
1818 destval
= and_byte(destval
, *srcreg
);
1819 store_data_byte(destoffset
, destval
);
1823 destoffset
= decode_rm10_address(rl
);
1825 destval
= fetch_data_byte(destoffset
);
1826 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1827 DECODE_PRINTF("\n");
1829 destval
= and_byte(destval
, *srcreg
);
1830 store_data_byte(destoffset
, destval
);
1833 case 3: /* register to register */
1834 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1836 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1837 DECODE_PRINTF("\n");
1839 *destreg
= and_byte(*destreg
, *srcreg
);
1842 DECODE_CLEAR_SEGOVR();
1846 /****************************************************************************
1849 ****************************************************************************/
1850 static void x86emuOp_and_word_RM_R(u8
X86EMU_UNUSED(op1
))
1856 DECODE_PRINTF("AND\t");
1857 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1860 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1864 destoffset
= decode_rm00_address(rl
);
1866 destval
= fetch_data_long(destoffset
);
1867 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1868 DECODE_PRINTF("\n");
1870 destval
= and_long(destval
, *srcreg
);
1871 store_data_long(destoffset
, destval
);
1876 destoffset
= decode_rm00_address(rl
);
1878 destval
= fetch_data_word(destoffset
);
1879 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1880 DECODE_PRINTF("\n");
1882 destval
= and_word(destval
, *srcreg
);
1883 store_data_word(destoffset
, destval
);
1887 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1891 destoffset
= decode_rm01_address(rl
);
1893 destval
= fetch_data_long(destoffset
);
1894 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1895 DECODE_PRINTF("\n");
1897 destval
= and_long(destval
, *srcreg
);
1898 store_data_long(destoffset
, destval
);
1903 destoffset
= decode_rm01_address(rl
);
1905 destval
= fetch_data_word(destoffset
);
1906 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1907 DECODE_PRINTF("\n");
1909 destval
= and_word(destval
, *srcreg
);
1910 store_data_word(destoffset
, destval
);
1914 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1918 destoffset
= decode_rm10_address(rl
);
1920 destval
= fetch_data_long(destoffset
);
1921 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1922 DECODE_PRINTF("\n");
1924 destval
= and_long(destval
, *srcreg
);
1925 store_data_long(destoffset
, destval
);
1930 destoffset
= decode_rm10_address(rl
);
1932 destval
= fetch_data_word(destoffset
);
1933 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1934 DECODE_PRINTF("\n");
1936 destval
= and_word(destval
, *srcreg
);
1937 store_data_word(destoffset
, destval
);
1940 case 3: /* register to register */
1941 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1942 u32
*destreg
,*srcreg
;
1944 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1946 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1947 DECODE_PRINTF("\n");
1949 *destreg
= and_long(*destreg
, *srcreg
);
1951 u16
*destreg
,*srcreg
;
1953 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1955 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1956 DECODE_PRINTF("\n");
1958 *destreg
= and_word(*destreg
, *srcreg
);
1962 DECODE_CLEAR_SEGOVR();
1966 /****************************************************************************
1969 ****************************************************************************/
1970 static void x86emuOp_and_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1973 u8
*destreg
, *srcreg
;
1978 DECODE_PRINTF("AND\t");
1979 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1982 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1984 srcoffset
= decode_rm00_address(rl
);
1985 srcval
= fetch_data_byte(srcoffset
);
1986 DECODE_PRINTF("\n");
1988 *destreg
= and_byte(*destreg
, srcval
);
1991 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1993 srcoffset
= decode_rm01_address(rl
);
1994 srcval
= fetch_data_byte(srcoffset
);
1995 DECODE_PRINTF("\n");
1997 *destreg
= and_byte(*destreg
, srcval
);
2000 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2002 srcoffset
= decode_rm10_address(rl
);
2003 srcval
= fetch_data_byte(srcoffset
);
2004 DECODE_PRINTF("\n");
2006 *destreg
= and_byte(*destreg
, srcval
);
2008 case 3: /* register to register */
2009 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2011 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2012 DECODE_PRINTF("\n");
2014 *destreg
= and_byte(*destreg
, *srcreg
);
2017 DECODE_CLEAR_SEGOVR();
2021 /****************************************************************************
2024 ****************************************************************************/
2025 static void x86emuOp_and_word_R_RM(u8
X86EMU_UNUSED(op1
))
2031 DECODE_PRINTF("AND\t");
2032 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2035 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2039 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2041 srcoffset
= decode_rm00_address(rl
);
2042 srcval
= fetch_data_long(srcoffset
);
2043 DECODE_PRINTF("\n");
2045 *destreg
= and_long(*destreg
, srcval
);
2050 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2052 srcoffset
= decode_rm00_address(rl
);
2053 srcval
= fetch_data_word(srcoffset
);
2054 DECODE_PRINTF("\n");
2056 *destreg
= and_word(*destreg
, srcval
);
2060 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2064 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2066 srcoffset
= decode_rm01_address(rl
);
2067 srcval
= fetch_data_long(srcoffset
);
2068 DECODE_PRINTF("\n");
2070 *destreg
= and_long(*destreg
, srcval
);
2076 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2078 srcoffset
= decode_rm01_address(rl
);
2079 srcval
= fetch_data_word(srcoffset
);
2080 DECODE_PRINTF("\n");
2082 *destreg
= and_word(*destreg
, srcval
);
2086 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2090 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2092 srcoffset
= decode_rm10_address(rl
);
2093 srcval
= fetch_data_long(srcoffset
);
2094 DECODE_PRINTF("\n");
2096 *destreg
= and_long(*destreg
, srcval
);
2101 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2103 srcoffset
= decode_rm10_address(rl
);
2104 srcval
= fetch_data_word(srcoffset
);
2105 DECODE_PRINTF("\n");
2107 *destreg
= and_word(*destreg
, srcval
);
2110 case 3: /* register to register */
2111 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2112 u32
*destreg
,*srcreg
;
2114 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2116 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2117 DECODE_PRINTF("\n");
2119 *destreg
= and_long(*destreg
, *srcreg
);
2121 u16
*destreg
,*srcreg
;
2123 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2125 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2126 DECODE_PRINTF("\n");
2128 *destreg
= and_word(*destreg
, *srcreg
);
2132 DECODE_CLEAR_SEGOVR();
2136 /****************************************************************************
2139 ****************************************************************************/
2140 static void x86emuOp_and_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2145 DECODE_PRINTF("AND\tAL,");
2146 srcval
= fetch_byte_imm();
2147 DECODE_PRINTF2("%x\n", srcval
);
2149 M
.x86
.R_AL
= and_byte(M
.x86
.R_AL
, srcval
);
2150 DECODE_CLEAR_SEGOVR();
2154 /****************************************************************************
2157 ****************************************************************************/
2158 static void x86emuOp_and_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
2163 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2164 DECODE_PRINTF("AND\tEAX,");
2165 srcval
= fetch_long_imm();
2167 DECODE_PRINTF("AND\tAX,");
2168 srcval
= fetch_word_imm();
2170 DECODE_PRINTF2("%x\n", srcval
);
2172 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2173 M
.x86
.R_EAX
= and_long(M
.x86
.R_EAX
, srcval
);
2175 M
.x86
.R_AX
= and_word(M
.x86
.R_AX
, (u16
)srcval
);
2177 DECODE_CLEAR_SEGOVR();
2181 /****************************************************************************
2184 ****************************************************************************/
2185 static void x86emuOp_segovr_ES(u8
X86EMU_UNUSED(op1
))
2188 DECODE_PRINTF("ES:\n");
2190 M
.x86
.mode
|= SYSMODE_SEGOVR_ES
;
2192 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2193 * opcode subroutines we do not want to do this.
2198 /****************************************************************************
2201 ****************************************************************************/
2202 static void x86emuOp_daa(u8
X86EMU_UNUSED(op1
))
2205 DECODE_PRINTF("DAA\n");
2207 M
.x86
.R_AL
= daa_byte(M
.x86
.R_AL
);
2208 DECODE_CLEAR_SEGOVR();
2212 /****************************************************************************
2215 ****************************************************************************/
2216 static void x86emuOp_sub_byte_RM_R(u8
X86EMU_UNUSED(op1
))
2219 u8
*destreg
, *srcreg
;
2224 DECODE_PRINTF("SUB\t");
2225 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2228 destoffset
= decode_rm00_address(rl
);
2230 destval
= fetch_data_byte(destoffset
);
2231 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2232 DECODE_PRINTF("\n");
2234 destval
= sub_byte(destval
, *srcreg
);
2235 store_data_byte(destoffset
, destval
);
2238 destoffset
= decode_rm01_address(rl
);
2240 destval
= fetch_data_byte(destoffset
);
2241 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2242 DECODE_PRINTF("\n");
2244 destval
= sub_byte(destval
, *srcreg
);
2245 store_data_byte(destoffset
, destval
);
2248 destoffset
= decode_rm10_address(rl
);
2250 destval
= fetch_data_byte(destoffset
);
2251 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2252 DECODE_PRINTF("\n");
2254 destval
= sub_byte(destval
, *srcreg
);
2255 store_data_byte(destoffset
, destval
);
2257 case 3: /* register to register */
2258 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
2260 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2261 DECODE_PRINTF("\n");
2263 *destreg
= sub_byte(*destreg
, *srcreg
);
2266 DECODE_CLEAR_SEGOVR();
2270 /****************************************************************************
2273 ****************************************************************************/
2274 static void x86emuOp_sub_word_RM_R(u8
X86EMU_UNUSED(op1
))
2280 DECODE_PRINTF("SUB\t");
2281 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2284 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2288 destoffset
= decode_rm00_address(rl
);
2290 destval
= fetch_data_long(destoffset
);
2291 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2292 DECODE_PRINTF("\n");
2294 destval
= sub_long(destval
, *srcreg
);
2295 store_data_long(destoffset
, destval
);
2300 destoffset
= decode_rm00_address(rl
);
2302 destval
= fetch_data_word(destoffset
);
2303 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2304 DECODE_PRINTF("\n");
2306 destval
= sub_word(destval
, *srcreg
);
2307 store_data_word(destoffset
, destval
);
2311 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2315 destoffset
= decode_rm01_address(rl
);
2317 destval
= fetch_data_long(destoffset
);
2318 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2319 DECODE_PRINTF("\n");
2321 destval
= sub_long(destval
, *srcreg
);
2322 store_data_long(destoffset
, destval
);
2327 destoffset
= decode_rm01_address(rl
);
2329 destval
= fetch_data_word(destoffset
);
2330 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2331 DECODE_PRINTF("\n");
2333 destval
= sub_word(destval
, *srcreg
);
2334 store_data_word(destoffset
, destval
);
2338 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2342 destoffset
= decode_rm10_address(rl
);
2344 destval
= fetch_data_long(destoffset
);
2345 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2346 DECODE_PRINTF("\n");
2348 destval
= sub_long(destval
, *srcreg
);
2349 store_data_long(destoffset
, destval
);
2354 destoffset
= decode_rm10_address(rl
);
2356 destval
= fetch_data_word(destoffset
);
2357 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2358 DECODE_PRINTF("\n");
2360 destval
= sub_word(destval
, *srcreg
);
2361 store_data_word(destoffset
, destval
);
2364 case 3: /* register to register */
2365 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2366 u32
*destreg
,*srcreg
;
2368 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2370 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2371 DECODE_PRINTF("\n");
2373 *destreg
= sub_long(*destreg
, *srcreg
);
2375 u16
*destreg
,*srcreg
;
2377 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2379 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2380 DECODE_PRINTF("\n");
2382 *destreg
= sub_word(*destreg
, *srcreg
);
2386 DECODE_CLEAR_SEGOVR();
2390 /****************************************************************************
2393 ****************************************************************************/
2394 static void x86emuOp_sub_byte_R_RM(u8
X86EMU_UNUSED(op1
))
2397 u8
*destreg
, *srcreg
;
2402 DECODE_PRINTF("SUB\t");
2403 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2406 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2408 srcoffset
= decode_rm00_address(rl
);
2409 srcval
= fetch_data_byte(srcoffset
);
2410 DECODE_PRINTF("\n");
2412 *destreg
= sub_byte(*destreg
, srcval
);
2415 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2417 srcoffset
= decode_rm01_address(rl
);
2418 srcval
= fetch_data_byte(srcoffset
);
2419 DECODE_PRINTF("\n");
2421 *destreg
= sub_byte(*destreg
, srcval
);
2424 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2426 srcoffset
= decode_rm10_address(rl
);
2427 srcval
= fetch_data_byte(srcoffset
);
2428 DECODE_PRINTF("\n");
2430 *destreg
= sub_byte(*destreg
, srcval
);
2432 case 3: /* register to register */
2433 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2435 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2436 DECODE_PRINTF("\n");
2438 *destreg
= sub_byte(*destreg
, *srcreg
);
2441 DECODE_CLEAR_SEGOVR();
2445 /****************************************************************************
2448 ****************************************************************************/
2449 static void x86emuOp_sub_word_R_RM(u8
X86EMU_UNUSED(op1
))
2455 DECODE_PRINTF("SUB\t");
2456 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2459 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2463 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2465 srcoffset
= decode_rm00_address(rl
);
2466 srcval
= fetch_data_long(srcoffset
);
2467 DECODE_PRINTF("\n");
2469 *destreg
= sub_long(*destreg
, srcval
);
2474 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2476 srcoffset
= decode_rm00_address(rl
);
2477 srcval
= fetch_data_word(srcoffset
);
2478 DECODE_PRINTF("\n");
2480 *destreg
= sub_word(*destreg
, srcval
);
2484 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2488 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2490 srcoffset
= decode_rm01_address(rl
);
2491 srcval
= fetch_data_long(srcoffset
);
2492 DECODE_PRINTF("\n");
2494 *destreg
= sub_long(*destreg
, srcval
);
2499 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2501 srcoffset
= decode_rm01_address(rl
);
2502 srcval
= fetch_data_word(srcoffset
);
2503 DECODE_PRINTF("\n");
2505 *destreg
= sub_word(*destreg
, srcval
);
2509 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2513 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2515 srcoffset
= decode_rm10_address(rl
);
2516 srcval
= fetch_data_long(srcoffset
);
2517 DECODE_PRINTF("\n");
2519 *destreg
= sub_long(*destreg
, srcval
);
2524 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2526 srcoffset
= decode_rm10_address(rl
);
2527 srcval
= fetch_data_word(srcoffset
);
2528 DECODE_PRINTF("\n");
2530 *destreg
= sub_word(*destreg
, srcval
);
2533 case 3: /* register to register */
2534 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2535 u32
*destreg
,*srcreg
;
2537 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2539 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2540 DECODE_PRINTF("\n");
2542 *destreg
= sub_long(*destreg
, *srcreg
);
2544 u16
*destreg
,*srcreg
;
2546 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2548 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2549 DECODE_PRINTF("\n");
2551 *destreg
= sub_word(*destreg
, *srcreg
);
2555 DECODE_CLEAR_SEGOVR();
2559 /****************************************************************************
2562 ****************************************************************************/
2563 static void x86emuOp_sub_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2568 DECODE_PRINTF("SUB\tAL,");
2569 srcval
= fetch_byte_imm();
2570 DECODE_PRINTF2("%x\n", srcval
);
2572 M
.x86
.R_AL
= sub_byte(M
.x86
.R_AL
, srcval
);
2573 DECODE_CLEAR_SEGOVR();
2577 /****************************************************************************
2580 ****************************************************************************/
2581 static void x86emuOp_sub_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
2586 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2587 DECODE_PRINTF("SUB\tEAX,");
2588 srcval
= fetch_long_imm();
2590 DECODE_PRINTF("SUB\tAX,");
2591 srcval
= fetch_word_imm();
2593 DECODE_PRINTF2("%x\n", srcval
);
2595 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2596 M
.x86
.R_EAX
= sub_long(M
.x86
.R_EAX
, srcval
);
2598 M
.x86
.R_AX
= sub_word(M
.x86
.R_AX
, (u16
)srcval
);
2600 DECODE_CLEAR_SEGOVR();
2604 /****************************************************************************
2607 ****************************************************************************/
2608 static void x86emuOp_segovr_CS(u8
X86EMU_UNUSED(op1
))
2611 DECODE_PRINTF("CS:\n");
2613 M
.x86
.mode
|= SYSMODE_SEGOVR_CS
;
2614 /* note no DECODE_CLEAR_SEGOVR here. */
2618 /****************************************************************************
2621 ****************************************************************************/
2622 static void x86emuOp_das(u8
X86EMU_UNUSED(op1
))
2625 DECODE_PRINTF("DAS\n");
2627 M
.x86
.R_AL
= das_byte(M
.x86
.R_AL
);
2628 DECODE_CLEAR_SEGOVR();
2632 /****************************************************************************
2635 ****************************************************************************/
2636 static void x86emuOp_xor_byte_RM_R(u8
X86EMU_UNUSED(op1
))
2639 u8
*destreg
, *srcreg
;
2644 DECODE_PRINTF("XOR\t");
2645 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2648 destoffset
= decode_rm00_address(rl
);
2650 destval
= fetch_data_byte(destoffset
);
2651 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2652 DECODE_PRINTF("\n");
2654 destval
= xor_byte(destval
, *srcreg
);
2655 store_data_byte(destoffset
, destval
);
2658 destoffset
= decode_rm01_address(rl
);
2660 destval
= fetch_data_byte(destoffset
);
2661 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2662 DECODE_PRINTF("\n");
2664 destval
= xor_byte(destval
, *srcreg
);
2665 store_data_byte(destoffset
, destval
);
2668 destoffset
= decode_rm10_address(rl
);
2670 destval
= fetch_data_byte(destoffset
);
2671 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2672 DECODE_PRINTF("\n");
2674 destval
= xor_byte(destval
, *srcreg
);
2675 store_data_byte(destoffset
, destval
);
2677 case 3: /* register to register */
2678 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
2680 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
2681 DECODE_PRINTF("\n");
2683 *destreg
= xor_byte(*destreg
, *srcreg
);
2686 DECODE_CLEAR_SEGOVR();
2690 /****************************************************************************
2693 ****************************************************************************/
2694 static void x86emuOp_xor_word_RM_R(u8
X86EMU_UNUSED(op1
))
2700 DECODE_PRINTF("XOR\t");
2701 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2704 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2708 destoffset
= decode_rm00_address(rl
);
2710 destval
= fetch_data_long(destoffset
);
2711 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2712 DECODE_PRINTF("\n");
2714 destval
= xor_long(destval
, *srcreg
);
2715 store_data_long(destoffset
, destval
);
2720 destoffset
= decode_rm00_address(rl
);
2722 destval
= fetch_data_word(destoffset
);
2723 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2724 DECODE_PRINTF("\n");
2726 destval
= xor_word(destval
, *srcreg
);
2727 store_data_word(destoffset
, destval
);
2731 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2735 destoffset
= decode_rm01_address(rl
);
2737 destval
= fetch_data_long(destoffset
);
2738 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2739 DECODE_PRINTF("\n");
2741 destval
= xor_long(destval
, *srcreg
);
2742 store_data_long(destoffset
, destval
);
2747 destoffset
= decode_rm01_address(rl
);
2749 destval
= fetch_data_word(destoffset
);
2750 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2751 DECODE_PRINTF("\n");
2753 destval
= xor_word(destval
, *srcreg
);
2754 store_data_word(destoffset
, destval
);
2758 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2762 destoffset
= decode_rm10_address(rl
);
2764 destval
= fetch_data_long(destoffset
);
2765 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2766 DECODE_PRINTF("\n");
2768 destval
= xor_long(destval
, *srcreg
);
2769 store_data_long(destoffset
, destval
);
2774 destoffset
= decode_rm10_address(rl
);
2776 destval
= fetch_data_word(destoffset
);
2777 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2778 DECODE_PRINTF("\n");
2780 destval
= xor_word(destval
, *srcreg
);
2781 store_data_word(destoffset
, destval
);
2784 case 3: /* register to register */
2785 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2786 u32
*destreg
,*srcreg
;
2788 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2790 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2791 DECODE_PRINTF("\n");
2793 *destreg
= xor_long(*destreg
, *srcreg
);
2795 u16
*destreg
,*srcreg
;
2797 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2799 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2800 DECODE_PRINTF("\n");
2802 *destreg
= xor_word(*destreg
, *srcreg
);
2806 DECODE_CLEAR_SEGOVR();
2810 /****************************************************************************
2813 ****************************************************************************/
2814 static void x86emuOp_xor_byte_R_RM(u8
X86EMU_UNUSED(op1
))
2817 u8
*destreg
, *srcreg
;
2822 DECODE_PRINTF("XOR\t");
2823 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2826 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2828 srcoffset
= decode_rm00_address(rl
);
2829 srcval
= fetch_data_byte(srcoffset
);
2830 DECODE_PRINTF("\n");
2832 *destreg
= xor_byte(*destreg
, srcval
);
2835 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2837 srcoffset
= decode_rm01_address(rl
);
2838 srcval
= fetch_data_byte(srcoffset
);
2839 DECODE_PRINTF("\n");
2841 *destreg
= xor_byte(*destreg
, srcval
);
2844 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2846 srcoffset
= decode_rm10_address(rl
);
2847 srcval
= fetch_data_byte(srcoffset
);
2848 DECODE_PRINTF("\n");
2850 *destreg
= xor_byte(*destreg
, srcval
);
2852 case 3: /* register to register */
2853 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
2855 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2856 DECODE_PRINTF("\n");
2858 *destreg
= xor_byte(*destreg
, *srcreg
);
2861 DECODE_CLEAR_SEGOVR();
2865 /****************************************************************************
2868 ****************************************************************************/
2869 static void x86emuOp_xor_word_R_RM(u8
X86EMU_UNUSED(op1
))
2875 DECODE_PRINTF("XOR\t");
2876 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2879 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2883 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2885 srcoffset
= decode_rm00_address(rl
);
2886 srcval
= fetch_data_long(srcoffset
);
2887 DECODE_PRINTF("\n");
2889 *destreg
= xor_long(*destreg
, srcval
);
2894 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2896 srcoffset
= decode_rm00_address(rl
);
2897 srcval
= fetch_data_word(srcoffset
);
2898 DECODE_PRINTF("\n");
2900 *destreg
= xor_word(*destreg
, srcval
);
2904 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2908 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2910 srcoffset
= decode_rm01_address(rl
);
2911 srcval
= fetch_data_long(srcoffset
);
2912 DECODE_PRINTF("\n");
2914 *destreg
= xor_long(*destreg
, srcval
);
2919 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2921 srcoffset
= decode_rm01_address(rl
);
2922 srcval
= fetch_data_word(srcoffset
);
2923 DECODE_PRINTF("\n");
2925 *destreg
= xor_word(*destreg
, srcval
);
2929 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2933 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2935 srcoffset
= decode_rm10_address(rl
);
2936 srcval
= fetch_data_long(srcoffset
);
2937 DECODE_PRINTF("\n");
2939 *destreg
= xor_long(*destreg
, srcval
);
2944 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2946 srcoffset
= decode_rm10_address(rl
);
2947 srcval
= fetch_data_word(srcoffset
);
2948 DECODE_PRINTF("\n");
2950 *destreg
= xor_word(*destreg
, srcval
);
2953 case 3: /* register to register */
2954 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2955 u32
*destreg
,*srcreg
;
2957 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2959 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2960 DECODE_PRINTF("\n");
2962 *destreg
= xor_long(*destreg
, *srcreg
);
2964 u16
*destreg
,*srcreg
;
2966 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2968 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2969 DECODE_PRINTF("\n");
2971 *destreg
= xor_word(*destreg
, *srcreg
);
2975 DECODE_CLEAR_SEGOVR();
2979 /****************************************************************************
2982 ****************************************************************************/
2983 static void x86emuOp_xor_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
2988 DECODE_PRINTF("XOR\tAL,");
2989 srcval
= fetch_byte_imm();
2990 DECODE_PRINTF2("%x\n", srcval
);
2992 M
.x86
.R_AL
= xor_byte(M
.x86
.R_AL
, srcval
);
2993 DECODE_CLEAR_SEGOVR();
2997 /****************************************************************************
3000 ****************************************************************************/
3001 static void x86emuOp_xor_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
3006 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3007 DECODE_PRINTF("XOR\tEAX,");
3008 srcval
= fetch_long_imm();
3010 DECODE_PRINTF("XOR\tAX,");
3011 srcval
= fetch_word_imm();
3013 DECODE_PRINTF2("%x\n", srcval
);
3015 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3016 M
.x86
.R_EAX
= xor_long(M
.x86
.R_EAX
, srcval
);
3018 M
.x86
.R_AX
= xor_word(M
.x86
.R_AX
, (u16
)srcval
);
3020 DECODE_CLEAR_SEGOVR();
3024 /****************************************************************************
3027 ****************************************************************************/
3028 static void x86emuOp_segovr_SS(u8
X86EMU_UNUSED(op1
))
3031 DECODE_PRINTF("SS:\n");
3033 M
.x86
.mode
|= SYSMODE_SEGOVR_SS
;
3034 /* no DECODE_CLEAR_SEGOVR ! */
3038 /****************************************************************************
3041 ****************************************************************************/
3042 static void x86emuOp_aaa(u8
X86EMU_UNUSED(op1
))
3045 DECODE_PRINTF("AAA\n");
3047 M
.x86
.R_AX
= aaa_word(M
.x86
.R_AX
);
3048 DECODE_CLEAR_SEGOVR();
3052 /****************************************************************************
3055 ****************************************************************************/
3056 static void x86emuOp_cmp_byte_RM_R(u8
X86EMU_UNUSED(op1
))
3060 u8
*destreg
, *srcreg
;
3064 DECODE_PRINTF("CMP\t");
3065 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3068 destoffset
= decode_rm00_address(rl
);
3070 destval
= fetch_data_byte(destoffset
);
3071 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3072 DECODE_PRINTF("\n");
3074 cmp_byte(destval
, *srcreg
);
3077 destoffset
= decode_rm01_address(rl
);
3079 destval
= fetch_data_byte(destoffset
);
3080 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3081 DECODE_PRINTF("\n");
3083 cmp_byte(destval
, *srcreg
);
3086 destoffset
= decode_rm10_address(rl
);
3088 destval
= fetch_data_byte(destoffset
);
3089 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3090 DECODE_PRINTF("\n");
3092 cmp_byte(destval
, *srcreg
);
3094 case 3: /* register to register */
3095 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3097 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
3098 DECODE_PRINTF("\n");
3100 cmp_byte(*destreg
, *srcreg
);
3103 DECODE_CLEAR_SEGOVR();
3107 /****************************************************************************
3110 ****************************************************************************/
3111 static void x86emuOp_cmp_word_RM_R(u8
X86EMU_UNUSED(op1
))
3117 DECODE_PRINTF("CMP\t");
3118 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3121 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3125 destoffset
= decode_rm00_address(rl
);
3127 destval
= fetch_data_long(destoffset
);
3128 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3129 DECODE_PRINTF("\n");
3131 cmp_long(destval
, *srcreg
);
3136 destoffset
= decode_rm00_address(rl
);
3138 destval
= fetch_data_word(destoffset
);
3139 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3140 DECODE_PRINTF("\n");
3142 cmp_word(destval
, *srcreg
);
3146 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3150 destoffset
= decode_rm01_address(rl
);
3152 destval
= fetch_data_long(destoffset
);
3153 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3154 DECODE_PRINTF("\n");
3156 cmp_long(destval
, *srcreg
);
3161 destoffset
= decode_rm01_address(rl
);
3163 destval
= fetch_data_word(destoffset
);
3164 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3165 DECODE_PRINTF("\n");
3167 cmp_word(destval
, *srcreg
);
3171 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3175 destoffset
= decode_rm10_address(rl
);
3177 destval
= fetch_data_long(destoffset
);
3178 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3179 DECODE_PRINTF("\n");
3181 cmp_long(destval
, *srcreg
);
3186 destoffset
= decode_rm10_address(rl
);
3188 destval
= fetch_data_word(destoffset
);
3189 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3190 DECODE_PRINTF("\n");
3192 cmp_word(destval
, *srcreg
);
3195 case 3: /* register to register */
3196 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3197 u32
*destreg
,*srcreg
;
3199 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3201 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
3202 DECODE_PRINTF("\n");
3204 cmp_long(*destreg
, *srcreg
);
3206 u16
*destreg
,*srcreg
;
3208 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3210 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
3211 DECODE_PRINTF("\n");
3213 cmp_word(*destreg
, *srcreg
);
3217 DECODE_CLEAR_SEGOVR();
3221 /****************************************************************************
3224 ****************************************************************************/
3225 static void x86emuOp_cmp_byte_R_RM(u8
X86EMU_UNUSED(op1
))
3228 u8
*destreg
, *srcreg
;
3233 DECODE_PRINTF("CMP\t");
3234 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3237 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3239 srcoffset
= decode_rm00_address(rl
);
3240 srcval
= fetch_data_byte(srcoffset
);
3241 DECODE_PRINTF("\n");
3243 cmp_byte(*destreg
, srcval
);
3246 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3248 srcoffset
= decode_rm01_address(rl
);
3249 srcval
= fetch_data_byte(srcoffset
);
3250 DECODE_PRINTF("\n");
3252 cmp_byte(*destreg
, srcval
);
3255 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3257 srcoffset
= decode_rm10_address(rl
);
3258 srcval
= fetch_data_byte(srcoffset
);
3259 DECODE_PRINTF("\n");
3261 cmp_byte(*destreg
, srcval
);
3263 case 3: /* register to register */
3264 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
3266 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
3267 DECODE_PRINTF("\n");
3269 cmp_byte(*destreg
, *srcreg
);
3272 DECODE_CLEAR_SEGOVR();
3276 /****************************************************************************
3279 ****************************************************************************/
3280 static void x86emuOp_cmp_word_R_RM(u8
X86EMU_UNUSED(op1
))
3286 DECODE_PRINTF("CMP\t");
3287 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3290 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3294 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3296 srcoffset
= decode_rm00_address(rl
);
3297 srcval
= fetch_data_long(srcoffset
);
3298 DECODE_PRINTF("\n");
3300 cmp_long(*destreg
, srcval
);
3305 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3307 srcoffset
= decode_rm00_address(rl
);
3308 srcval
= fetch_data_word(srcoffset
);
3309 DECODE_PRINTF("\n");
3311 cmp_word(*destreg
, srcval
);
3315 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3319 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3321 srcoffset
= decode_rm01_address(rl
);
3322 srcval
= fetch_data_long(srcoffset
);
3323 DECODE_PRINTF("\n");
3325 cmp_long(*destreg
, srcval
);
3330 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3332 srcoffset
= decode_rm01_address(rl
);
3333 srcval
= fetch_data_word(srcoffset
);
3334 DECODE_PRINTF("\n");
3336 cmp_word(*destreg
, srcval
);
3340 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3344 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3346 srcoffset
= decode_rm10_address(rl
);
3347 srcval
= fetch_data_long(srcoffset
);
3348 DECODE_PRINTF("\n");
3350 cmp_long(*destreg
, srcval
);
3355 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3357 srcoffset
= decode_rm10_address(rl
);
3358 srcval
= fetch_data_word(srcoffset
);
3359 DECODE_PRINTF("\n");
3361 cmp_word(*destreg
, srcval
);
3364 case 3: /* register to register */
3365 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3366 u32
*destreg
,*srcreg
;
3368 destreg
= DECODE_RM_LONG_REGISTER(rh
);
3370 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
3371 DECODE_PRINTF("\n");
3373 cmp_long(*destreg
, *srcreg
);
3375 u16
*destreg
,*srcreg
;
3377 destreg
= DECODE_RM_WORD_REGISTER(rh
);
3379 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
3380 DECODE_PRINTF("\n");
3382 cmp_word(*destreg
, *srcreg
);
3386 DECODE_CLEAR_SEGOVR();
3390 /****************************************************************************
3393 ****************************************************************************/
3394 static void x86emuOp_cmp_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
3399 DECODE_PRINTF("CMP\tAL,");
3400 srcval
= fetch_byte_imm();
3401 DECODE_PRINTF2("%x\n", srcval
);
3403 cmp_byte(M
.x86
.R_AL
, srcval
);
3404 DECODE_CLEAR_SEGOVR();
3408 /****************************************************************************
3411 ****************************************************************************/
3412 static void x86emuOp_cmp_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
3417 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3418 DECODE_PRINTF("CMP\tEAX,");
3419 srcval
= fetch_long_imm();
3421 DECODE_PRINTF("CMP\tAX,");
3422 srcval
= fetch_word_imm();
3424 DECODE_PRINTF2("%x\n", srcval
);
3426 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3427 cmp_long(M
.x86
.R_EAX
, srcval
);
3429 cmp_word(M
.x86
.R_AX
, (u16
)srcval
);
3431 DECODE_CLEAR_SEGOVR();
3435 /****************************************************************************
3438 ****************************************************************************/
3439 static void x86emuOp_segovr_DS(u8
X86EMU_UNUSED(op1
))
3442 DECODE_PRINTF("DS:\n");
3444 M
.x86
.mode
|= SYSMODE_SEGOVR_DS
;
3445 /* NO DECODE_CLEAR_SEGOVR! */
3449 /****************************************************************************
3452 ****************************************************************************/
3453 static void x86emuOp_aas(u8
X86EMU_UNUSED(op1
))
3456 DECODE_PRINTF("AAS\n");
3458 M
.x86
.R_AX
= aas_word(M
.x86
.R_AX
);
3459 DECODE_CLEAR_SEGOVR();
3463 /****************************************************************************
3466 ****************************************************************************/
3467 static void x86emuOp_inc_AX(u8
X86EMU_UNUSED(op1
))
3470 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3471 DECODE_PRINTF("INC\tEAX\n");
3473 DECODE_PRINTF("INC\tAX\n");
3476 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3477 M
.x86
.R_EAX
= inc_long(M
.x86
.R_EAX
);
3479 M
.x86
.R_AX
= inc_word(M
.x86
.R_AX
);
3481 DECODE_CLEAR_SEGOVR();
3485 /****************************************************************************
3488 ****************************************************************************/
3489 static void x86emuOp_inc_CX(u8
X86EMU_UNUSED(op1
))
3492 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3493 DECODE_PRINTF("INC\tECX\n");
3495 DECODE_PRINTF("INC\tCX\n");
3498 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3499 M
.x86
.R_ECX
= inc_long(M
.x86
.R_ECX
);
3501 M
.x86
.R_CX
= inc_word(M
.x86
.R_CX
);
3503 DECODE_CLEAR_SEGOVR();
3507 /****************************************************************************
3510 ****************************************************************************/
3511 static void x86emuOp_inc_DX(u8
X86EMU_UNUSED(op1
))
3514 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3515 DECODE_PRINTF("INC\tEDX\n");
3517 DECODE_PRINTF("INC\tDX\n");
3520 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3521 M
.x86
.R_EDX
= inc_long(M
.x86
.R_EDX
);
3523 M
.x86
.R_DX
= inc_word(M
.x86
.R_DX
);
3525 DECODE_CLEAR_SEGOVR();
3529 /****************************************************************************
3532 ****************************************************************************/
3533 static void x86emuOp_inc_BX(u8
X86EMU_UNUSED(op1
))
3536 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3537 DECODE_PRINTF("INC\tEBX\n");
3539 DECODE_PRINTF("INC\tBX\n");
3542 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3543 M
.x86
.R_EBX
= inc_long(M
.x86
.R_EBX
);
3545 M
.x86
.R_BX
= inc_word(M
.x86
.R_BX
);
3547 DECODE_CLEAR_SEGOVR();
3551 /****************************************************************************
3554 ****************************************************************************/
3555 static void x86emuOp_inc_SP(u8
X86EMU_UNUSED(op1
))
3558 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3559 DECODE_PRINTF("INC\tESP\n");
3561 DECODE_PRINTF("INC\tSP\n");
3564 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3565 M
.x86
.R_ESP
= inc_long(M
.x86
.R_ESP
);
3567 M
.x86
.R_SP
= inc_word(M
.x86
.R_SP
);
3569 DECODE_CLEAR_SEGOVR();
3573 /****************************************************************************
3576 ****************************************************************************/
3577 static void x86emuOp_inc_BP(u8
X86EMU_UNUSED(op1
))
3580 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3581 DECODE_PRINTF("INC\tEBP\n");
3583 DECODE_PRINTF("INC\tBP\n");
3586 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3587 M
.x86
.R_EBP
= inc_long(M
.x86
.R_EBP
);
3589 M
.x86
.R_BP
= inc_word(M
.x86
.R_BP
);
3591 DECODE_CLEAR_SEGOVR();
3595 /****************************************************************************
3598 ****************************************************************************/
3599 static void x86emuOp_inc_SI(u8
X86EMU_UNUSED(op1
))
3602 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3603 DECODE_PRINTF("INC\tESI\n");
3605 DECODE_PRINTF("INC\tSI\n");
3608 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3609 M
.x86
.R_ESI
= inc_long(M
.x86
.R_ESI
);
3611 M
.x86
.R_SI
= inc_word(M
.x86
.R_SI
);
3613 DECODE_CLEAR_SEGOVR();
3617 /****************************************************************************
3620 ****************************************************************************/
3621 static void x86emuOp_inc_DI(u8
X86EMU_UNUSED(op1
))
3624 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3625 DECODE_PRINTF("INC\tEDI\n");
3627 DECODE_PRINTF("INC\tDI\n");
3630 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3631 M
.x86
.R_EDI
= inc_long(M
.x86
.R_EDI
);
3633 M
.x86
.R_DI
= inc_word(M
.x86
.R_DI
);
3635 DECODE_CLEAR_SEGOVR();
3639 /****************************************************************************
3642 ****************************************************************************/
3643 static void x86emuOp_dec_AX(u8
X86EMU_UNUSED(op1
))
3646 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3647 DECODE_PRINTF("DEC\tEAX\n");
3649 DECODE_PRINTF("DEC\tAX\n");
3652 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3653 M
.x86
.R_EAX
= dec_long(M
.x86
.R_EAX
);
3655 M
.x86
.R_AX
= dec_word(M
.x86
.R_AX
);
3657 DECODE_CLEAR_SEGOVR();
3661 /****************************************************************************
3664 ****************************************************************************/
3665 static void x86emuOp_dec_CX(u8
X86EMU_UNUSED(op1
))
3668 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3669 DECODE_PRINTF("DEC\tECX\n");
3671 DECODE_PRINTF("DEC\tCX\n");
3674 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3675 M
.x86
.R_ECX
= dec_long(M
.x86
.R_ECX
);
3677 M
.x86
.R_CX
= dec_word(M
.x86
.R_CX
);
3679 DECODE_CLEAR_SEGOVR();
3683 /****************************************************************************
3686 ****************************************************************************/
3687 static void x86emuOp_dec_DX(u8
X86EMU_UNUSED(op1
))
3690 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3691 DECODE_PRINTF("DEC\tEDX\n");
3693 DECODE_PRINTF("DEC\tDX\n");
3696 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3697 M
.x86
.R_EDX
= dec_long(M
.x86
.R_EDX
);
3699 M
.x86
.R_DX
= dec_word(M
.x86
.R_DX
);
3701 DECODE_CLEAR_SEGOVR();
3705 /****************************************************************************
3708 ****************************************************************************/
3709 static void x86emuOp_dec_BX(u8
X86EMU_UNUSED(op1
))
3712 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3713 DECODE_PRINTF("DEC\tEBX\n");
3715 DECODE_PRINTF("DEC\tBX\n");
3718 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3719 M
.x86
.R_EBX
= dec_long(M
.x86
.R_EBX
);
3721 M
.x86
.R_BX
= dec_word(M
.x86
.R_BX
);
3723 DECODE_CLEAR_SEGOVR();
3727 /****************************************************************************
3730 ****************************************************************************/
3731 static void x86emuOp_dec_SP(u8
X86EMU_UNUSED(op1
))
3734 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3735 DECODE_PRINTF("DEC\tESP\n");
3737 DECODE_PRINTF("DEC\tSP\n");
3740 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3741 M
.x86
.R_ESP
= dec_long(M
.x86
.R_ESP
);
3743 M
.x86
.R_SP
= dec_word(M
.x86
.R_SP
);
3745 DECODE_CLEAR_SEGOVR();
3749 /****************************************************************************
3752 ****************************************************************************/
3753 static void x86emuOp_dec_BP(u8
X86EMU_UNUSED(op1
))
3756 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3757 DECODE_PRINTF("DEC\tEBP\n");
3759 DECODE_PRINTF("DEC\tBP\n");
3762 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3763 M
.x86
.R_EBP
= dec_long(M
.x86
.R_EBP
);
3765 M
.x86
.R_BP
= dec_word(M
.x86
.R_BP
);
3767 DECODE_CLEAR_SEGOVR();
3771 /****************************************************************************
3774 ****************************************************************************/
3775 static void x86emuOp_dec_SI(u8
X86EMU_UNUSED(op1
))
3778 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3779 DECODE_PRINTF("DEC\tESI\n");
3781 DECODE_PRINTF("DEC\tSI\n");
3784 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3785 M
.x86
.R_ESI
= dec_long(M
.x86
.R_ESI
);
3787 M
.x86
.R_SI
= dec_word(M
.x86
.R_SI
);
3789 DECODE_CLEAR_SEGOVR();
3793 /****************************************************************************
3796 ****************************************************************************/
3797 static void x86emuOp_dec_DI(u8
X86EMU_UNUSED(op1
))
3800 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3801 DECODE_PRINTF("DEC\tEDI\n");
3803 DECODE_PRINTF("DEC\tDI\n");
3806 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3807 M
.x86
.R_EDI
= dec_long(M
.x86
.R_EDI
);
3809 M
.x86
.R_DI
= dec_word(M
.x86
.R_DI
);
3811 DECODE_CLEAR_SEGOVR();
3815 /****************************************************************************
3818 ****************************************************************************/
3819 static void x86emuOp_push_AX(u8
X86EMU_UNUSED(op1
))
3822 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3823 DECODE_PRINTF("PUSH\tEAX\n");
3825 DECODE_PRINTF("PUSH\tAX\n");
3828 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3829 push_long(M
.x86
.R_EAX
);
3831 push_word(M
.x86
.R_AX
);
3833 DECODE_CLEAR_SEGOVR();
3837 /****************************************************************************
3840 ****************************************************************************/
3841 static void x86emuOp_push_CX(u8
X86EMU_UNUSED(op1
))
3844 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3845 DECODE_PRINTF("PUSH\tECX\n");
3847 DECODE_PRINTF("PUSH\tCX\n");
3850 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3851 push_long(M
.x86
.R_ECX
);
3853 push_word(M
.x86
.R_CX
);
3855 DECODE_CLEAR_SEGOVR();
3859 /****************************************************************************
3862 ****************************************************************************/
3863 static void x86emuOp_push_DX(u8
X86EMU_UNUSED(op1
))
3866 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3867 DECODE_PRINTF("PUSH\tEDX\n");
3869 DECODE_PRINTF("PUSH\tDX\n");
3872 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3873 push_long(M
.x86
.R_EDX
);
3875 push_word(M
.x86
.R_DX
);
3877 DECODE_CLEAR_SEGOVR();
3881 /****************************************************************************
3884 ****************************************************************************/
3885 static void x86emuOp_push_BX(u8
X86EMU_UNUSED(op1
))
3888 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3889 DECODE_PRINTF("PUSH\tEBX\n");
3891 DECODE_PRINTF("PUSH\tBX\n");
3894 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3895 push_long(M
.x86
.R_EBX
);
3897 push_word(M
.x86
.R_BX
);
3899 DECODE_CLEAR_SEGOVR();
3903 /****************************************************************************
3906 ****************************************************************************/
3907 static void x86emuOp_push_SP(u8
X86EMU_UNUSED(op1
))
3910 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3911 DECODE_PRINTF("PUSH\tESP\n");
3913 DECODE_PRINTF("PUSH\tSP\n");
3916 /* Always push (E)SP, since we are emulating an i386 and above
3917 * processor. This is necessary as some BIOS'es use this to check
3918 * what type of processor is in the system.
3920 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3921 push_long(M
.x86
.R_ESP
);
3923 push_word((u16
)(M
.x86
.R_SP
));
3925 DECODE_CLEAR_SEGOVR();
3929 /****************************************************************************
3932 ****************************************************************************/
3933 static void x86emuOp_push_BP(u8
X86EMU_UNUSED(op1
))
3936 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3937 DECODE_PRINTF("PUSH\tEBP\n");
3939 DECODE_PRINTF("PUSH\tBP\n");
3942 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3943 push_long(M
.x86
.R_EBP
);
3945 push_word(M
.x86
.R_BP
);
3947 DECODE_CLEAR_SEGOVR();
3951 /****************************************************************************
3954 ****************************************************************************/
3955 static void x86emuOp_push_SI(u8
X86EMU_UNUSED(op1
))
3958 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3959 DECODE_PRINTF("PUSH\tESI\n");
3961 DECODE_PRINTF("PUSH\tSI\n");
3964 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3965 push_long(M
.x86
.R_ESI
);
3967 push_word(M
.x86
.R_SI
);
3969 DECODE_CLEAR_SEGOVR();
3973 /****************************************************************************
3976 ****************************************************************************/
3977 static void x86emuOp_push_DI(u8
X86EMU_UNUSED(op1
))
3980 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3981 DECODE_PRINTF("PUSH\tEDI\n");
3983 DECODE_PRINTF("PUSH\tDI\n");
3986 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3987 push_long(M
.x86
.R_EDI
);
3989 push_word(M
.x86
.R_DI
);
3991 DECODE_CLEAR_SEGOVR();
3995 /****************************************************************************
3998 ****************************************************************************/
3999 static void x86emuOp_pop_AX(u8
X86EMU_UNUSED(op1
))
4002 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4003 DECODE_PRINTF("POP\tEAX\n");
4005 DECODE_PRINTF("POP\tAX\n");
4008 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4009 M
.x86
.R_EAX
= pop_long();
4011 M
.x86
.R_AX
= pop_word();
4013 DECODE_CLEAR_SEGOVR();
4017 /****************************************************************************
4020 ****************************************************************************/
4021 static void x86emuOp_pop_CX(u8
X86EMU_UNUSED(op1
))
4024 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4025 DECODE_PRINTF("POP\tECX\n");
4027 DECODE_PRINTF("POP\tCX\n");
4030 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4031 M
.x86
.R_ECX
= pop_long();
4033 M
.x86
.R_CX
= pop_word();
4035 DECODE_CLEAR_SEGOVR();
4039 /****************************************************************************
4042 ****************************************************************************/
4043 static void x86emuOp_pop_DX(u8
X86EMU_UNUSED(op1
))
4046 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4047 DECODE_PRINTF("POP\tEDX\n");
4049 DECODE_PRINTF("POP\tDX\n");
4052 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4053 M
.x86
.R_EDX
= pop_long();
4055 M
.x86
.R_DX
= pop_word();
4057 DECODE_CLEAR_SEGOVR();
4061 /****************************************************************************
4064 ****************************************************************************/
4065 static void x86emuOp_pop_BX(u8
X86EMU_UNUSED(op1
))
4068 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4069 DECODE_PRINTF("POP\tEBX\n");
4071 DECODE_PRINTF("POP\tBX\n");
4074 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4075 M
.x86
.R_EBX
= pop_long();
4077 M
.x86
.R_BX
= pop_word();
4079 DECODE_CLEAR_SEGOVR();
4083 /****************************************************************************
4086 ****************************************************************************/
4087 static void x86emuOp_pop_SP(u8
X86EMU_UNUSED(op1
))
4090 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4091 DECODE_PRINTF("POP\tESP\n");
4093 DECODE_PRINTF("POP\tSP\n");
4096 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4097 M
.x86
.R_ESP
= pop_long();
4099 M
.x86
.R_SP
= pop_word();
4101 DECODE_CLEAR_SEGOVR();
4105 /****************************************************************************
4108 ****************************************************************************/
4109 static void x86emuOp_pop_BP(u8
X86EMU_UNUSED(op1
))
4112 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4113 DECODE_PRINTF("POP\tEBP\n");
4115 DECODE_PRINTF("POP\tBP\n");
4118 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4119 M
.x86
.R_EBP
= pop_long();
4121 M
.x86
.R_BP
= pop_word();
4123 DECODE_CLEAR_SEGOVR();
4127 /****************************************************************************
4130 ****************************************************************************/
4131 static void x86emuOp_pop_SI(u8
X86EMU_UNUSED(op1
))
4134 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4135 DECODE_PRINTF("POP\tESI\n");
4137 DECODE_PRINTF("POP\tSI\n");
4140 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4141 M
.x86
.R_ESI
= pop_long();
4143 M
.x86
.R_SI
= pop_word();
4145 DECODE_CLEAR_SEGOVR();
4149 /****************************************************************************
4152 ****************************************************************************/
4153 static void x86emuOp_pop_DI(u8
X86EMU_UNUSED(op1
))
4156 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4157 DECODE_PRINTF("POP\tEDI\n");
4159 DECODE_PRINTF("POP\tDI\n");
4162 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4163 M
.x86
.R_EDI
= pop_long();
4165 M
.x86
.R_DI
= pop_word();
4167 DECODE_CLEAR_SEGOVR();
4171 /****************************************************************************
4174 ****************************************************************************/
4175 static void x86emuOp_push_all(u8
X86EMU_UNUSED(op1
))
4178 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4179 DECODE_PRINTF("PUSHAD\n");
4181 DECODE_PRINTF("PUSHA\n");
4184 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4185 u32 old_sp
= M
.x86
.R_ESP
;
4187 push_long(M
.x86
.R_EAX
);
4188 push_long(M
.x86
.R_ECX
);
4189 push_long(M
.x86
.R_EDX
);
4190 push_long(M
.x86
.R_EBX
);
4192 push_long(M
.x86
.R_EBP
);
4193 push_long(M
.x86
.R_ESI
);
4194 push_long(M
.x86
.R_EDI
);
4196 u16 old_sp
= M
.x86
.R_SP
;
4198 push_word(M
.x86
.R_AX
);
4199 push_word(M
.x86
.R_CX
);
4200 push_word(M
.x86
.R_DX
);
4201 push_word(M
.x86
.R_BX
);
4203 push_word(M
.x86
.R_BP
);
4204 push_word(M
.x86
.R_SI
);
4205 push_word(M
.x86
.R_DI
);
4207 DECODE_CLEAR_SEGOVR();
4211 /****************************************************************************
4214 ****************************************************************************/
4215 static void x86emuOp_pop_all(u8
X86EMU_UNUSED(op1
))
4218 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4219 DECODE_PRINTF("POPAD\n");
4221 DECODE_PRINTF("POPA\n");
4224 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4225 M
.x86
.R_EDI
= pop_long();
4226 M
.x86
.R_ESI
= pop_long();
4227 M
.x86
.R_EBP
= pop_long();
4228 M
.x86
.R_ESP
+= 4; /* skip ESP */
4229 M
.x86
.R_EBX
= pop_long();
4230 M
.x86
.R_EDX
= pop_long();
4231 M
.x86
.R_ECX
= pop_long();
4232 M
.x86
.R_EAX
= pop_long();
4234 M
.x86
.R_DI
= pop_word();
4235 M
.x86
.R_SI
= pop_word();
4236 M
.x86
.R_BP
= pop_word();
4237 M
.x86
.R_SP
+= 2; /* skip SP */
4238 M
.x86
.R_BX
= pop_word();
4239 M
.x86
.R_DX
= pop_word();
4240 M
.x86
.R_CX
= pop_word();
4241 M
.x86
.R_AX
= pop_word();
4243 DECODE_CLEAR_SEGOVR();
4247 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4248 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4250 /****************************************************************************
4253 ****************************************************************************/
4254 static void x86emuOp_segovr_FS(u8
X86EMU_UNUSED(op1
))
4257 DECODE_PRINTF("FS:\n");
4259 M
.x86
.mode
|= SYSMODE_SEGOVR_FS
;
4261 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4262 * opcode subroutines we do not want to do this.
4267 /****************************************************************************
4270 ****************************************************************************/
4271 static void x86emuOp_segovr_GS(u8
X86EMU_UNUSED(op1
))
4274 DECODE_PRINTF("GS:\n");
4276 M
.x86
.mode
|= SYSMODE_SEGOVR_GS
;
4278 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4279 * opcode subroutines we do not want to do this.
4284 /****************************************************************************
4286 Handles opcode 0x66 - prefix for 32-bit register
4287 ****************************************************************************/
4288 static void x86emuOp_prefix_data(u8
X86EMU_UNUSED(op1
))
4291 DECODE_PRINTF("DATA:\n");
4293 M
.x86
.mode
|= SYSMODE_PREFIX_DATA
;
4294 /* note no DECODE_CLEAR_SEGOVR here. */
4298 /****************************************************************************
4300 Handles opcode 0x67 - prefix for 32-bit address
4301 ****************************************************************************/
4302 static void x86emuOp_prefix_addr(u8
X86EMU_UNUSED(op1
))
4305 DECODE_PRINTF("ADDR:\n");
4307 M
.x86
.mode
|= SYSMODE_PREFIX_ADDR
;
4308 /* note no DECODE_CLEAR_SEGOVR here. */
4312 /****************************************************************************
4315 ****************************************************************************/
4316 static void x86emuOp_push_word_IMM(u8
X86EMU_UNUSED(op1
))
4321 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4322 imm
= fetch_long_imm();
4324 imm
= fetch_word_imm();
4326 DECODE_PRINTF2("PUSH\t%x\n", imm
);
4328 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4331 push_word((u16
)imm
);
4333 DECODE_CLEAR_SEGOVR();
4337 /****************************************************************************
4340 ****************************************************************************/
4341 static void x86emuOp_imul_word_IMM(u8
X86EMU_UNUSED(op1
))
4347 DECODE_PRINTF("IMUL\t");
4348 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4351 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4357 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4359 srcoffset
= decode_rm00_address(rl
);
4360 srcval
= fetch_data_long(srcoffset
);
4361 imm
= fetch_long_imm();
4362 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4364 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4372 *destreg
= (u32
)res_lo
;
4379 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4381 srcoffset
= decode_rm00_address(rl
);
4382 srcval
= fetch_data_word(srcoffset
);
4383 imm
= fetch_word_imm();
4384 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4386 res
= (s16
)srcval
* (s16
)imm
;
4394 *destreg
= (u16
)res
;
4398 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4404 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4406 srcoffset
= decode_rm01_address(rl
);
4407 srcval
= fetch_data_long(srcoffset
);
4408 imm
= fetch_long_imm();
4409 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4411 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4419 *destreg
= (u32
)res_lo
;
4426 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4428 srcoffset
= decode_rm01_address(rl
);
4429 srcval
= fetch_data_word(srcoffset
);
4430 imm
= fetch_word_imm();
4431 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4433 res
= (s16
)srcval
* (s16
)imm
;
4441 *destreg
= (u16
)res
;
4445 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4451 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4453 srcoffset
= decode_rm10_address(rl
);
4454 srcval
= fetch_data_long(srcoffset
);
4455 imm
= fetch_long_imm();
4456 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4458 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4466 *destreg
= (u32
)res_lo
;
4473 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4475 srcoffset
= decode_rm10_address(rl
);
4476 srcval
= fetch_data_word(srcoffset
);
4477 imm
= fetch_word_imm();
4478 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4480 res
= (s16
)srcval
* (s16
)imm
;
4488 *destreg
= (u16
)res
;
4491 case 3: /* register to register */
4492 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4493 u32
*destreg
,*srcreg
;
4497 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4499 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
4500 imm
= fetch_long_imm();
4501 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4503 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
4511 *destreg
= (u32
)res_lo
;
4513 u16
*destreg
,*srcreg
;
4517 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4519 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
4520 imm
= fetch_word_imm();
4521 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4522 res
= (s16
)*srcreg
* (s16
)imm
;
4530 *destreg
= (u16
)res
;
4534 DECODE_CLEAR_SEGOVR();
4538 /****************************************************************************
4541 ****************************************************************************/
4542 static void x86emuOp_push_byte_IMM(u8
X86EMU_UNUSED(op1
))
4547 imm
= (s8
)fetch_byte_imm();
4548 DECODE_PRINTF2("PUSH\t%d\n", imm
);
4550 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4551 push_long((s32
)imm
);
4555 DECODE_CLEAR_SEGOVR();
4559 /****************************************************************************
4562 ****************************************************************************/
4563 static void x86emuOp_imul_byte_IMM(u8
X86EMU_UNUSED(op1
))
4570 DECODE_PRINTF("IMUL\t");
4571 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4574 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4579 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4581 srcoffset
= decode_rm00_address(rl
);
4582 srcval
= fetch_data_long(srcoffset
);
4583 imm
= fetch_byte_imm();
4584 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4586 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4594 *destreg
= (u32
)res_lo
;
4600 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4602 srcoffset
= decode_rm00_address(rl
);
4603 srcval
= fetch_data_word(srcoffset
);
4604 imm
= fetch_byte_imm();
4605 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4607 res
= (s16
)srcval
* (s16
)imm
;
4615 *destreg
= (u16
)res
;
4619 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4624 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4626 srcoffset
= decode_rm01_address(rl
);
4627 srcval
= fetch_data_long(srcoffset
);
4628 imm
= fetch_byte_imm();
4629 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4631 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4639 *destreg
= (u32
)res_lo
;
4645 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4647 srcoffset
= decode_rm01_address(rl
);
4648 srcval
= fetch_data_word(srcoffset
);
4649 imm
= fetch_byte_imm();
4650 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4652 res
= (s16
)srcval
* (s16
)imm
;
4660 *destreg
= (u16
)res
;
4664 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4669 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4671 srcoffset
= decode_rm10_address(rl
);
4672 srcval
= fetch_data_long(srcoffset
);
4673 imm
= fetch_byte_imm();
4674 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4676 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
4684 *destreg
= (u32
)res_lo
;
4690 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4692 srcoffset
= decode_rm10_address(rl
);
4693 srcval
= fetch_data_word(srcoffset
);
4694 imm
= fetch_byte_imm();
4695 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4697 res
= (s16
)srcval
* (s16
)imm
;
4705 *destreg
= (u16
)res
;
4708 case 3: /* register to register */
4709 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4710 u32
*destreg
,*srcreg
;
4713 destreg
= DECODE_RM_LONG_REGISTER(rh
);
4715 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
4716 imm
= fetch_byte_imm();
4717 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4719 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
4727 *destreg
= (u32
)res_lo
;
4729 u16
*destreg
,*srcreg
;
4732 destreg
= DECODE_RM_WORD_REGISTER(rh
);
4734 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
4735 imm
= fetch_byte_imm();
4736 DECODE_PRINTF2(",%d\n", (s32
)imm
);
4737 res
= (s16
)*srcreg
* (s16
)imm
;
4745 *destreg
= (u16
)res
;
4749 DECODE_CLEAR_SEGOVR();
4753 /****************************************************************************
4756 ****************************************************************************/
4757 static void x86emuOp_ins_byte(u8
X86EMU_UNUSED(op1
))
4760 DECODE_PRINTF("INSB\n");
4763 DECODE_CLEAR_SEGOVR();
4767 /****************************************************************************
4770 ****************************************************************************/
4771 static void x86emuOp_ins_word(u8
X86EMU_UNUSED(op1
))
4774 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4775 DECODE_PRINTF("INSD\n");
4778 DECODE_PRINTF("INSW\n");
4782 DECODE_CLEAR_SEGOVR();
4786 /****************************************************************************
4789 ****************************************************************************/
4790 static void x86emuOp_outs_byte(u8
X86EMU_UNUSED(op1
))
4793 DECODE_PRINTF("OUTSB\n");
4796 DECODE_CLEAR_SEGOVR();
4800 /****************************************************************************
4803 ****************************************************************************/
4804 static void x86emuOp_outs_word(u8
X86EMU_UNUSED(op1
))
4807 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4808 DECODE_PRINTF("OUTSD\n");
4811 DECODE_PRINTF("OUTSW\n");
4815 DECODE_CLEAR_SEGOVR();
4819 /****************************************************************************
4822 ****************************************************************************/
4823 static void x86emuOp_jump_near_O(u8
X86EMU_UNUSED(op1
))
4828 /* jump to byte offset if overflow flag is set */
4830 DECODE_PRINTF("JO\t");
4831 offset
= (s8
)fetch_byte_imm();
4832 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4833 DECODE_PRINTF2("%x\n", target
);
4835 if (ACCESS_FLAG(F_OF
))
4836 M
.x86
.R_IP
= target
;
4837 DECODE_CLEAR_SEGOVR();
4841 /****************************************************************************
4844 ****************************************************************************/
4845 static void x86emuOp_jump_near_NO(u8
X86EMU_UNUSED(op1
))
4850 /* jump to byte offset if overflow is not set */
4852 DECODE_PRINTF("JNO\t");
4853 offset
= (s8
)fetch_byte_imm();
4854 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4855 DECODE_PRINTF2("%x\n", target
);
4857 if (!ACCESS_FLAG(F_OF
))
4858 M
.x86
.R_IP
= target
;
4859 DECODE_CLEAR_SEGOVR();
4863 /****************************************************************************
4866 ****************************************************************************/
4867 static void x86emuOp_jump_near_B(u8
X86EMU_UNUSED(op1
))
4872 /* jump to byte offset if carry flag is set. */
4874 DECODE_PRINTF("JB\t");
4875 offset
= (s8
)fetch_byte_imm();
4876 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4877 DECODE_PRINTF2("%x\n", target
);
4879 if (ACCESS_FLAG(F_CF
))
4880 M
.x86
.R_IP
= target
;
4881 DECODE_CLEAR_SEGOVR();
4885 /****************************************************************************
4888 ****************************************************************************/
4889 static void x86emuOp_jump_near_NB(u8
X86EMU_UNUSED(op1
))
4894 /* jump to byte offset if carry flag is clear. */
4896 DECODE_PRINTF("JNB\t");
4897 offset
= (s8
)fetch_byte_imm();
4898 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4899 DECODE_PRINTF2("%x\n", target
);
4901 if (!ACCESS_FLAG(F_CF
))
4902 M
.x86
.R_IP
= target
;
4903 DECODE_CLEAR_SEGOVR();
4907 /****************************************************************************
4910 ****************************************************************************/
4911 static void x86emuOp_jump_near_Z(u8
X86EMU_UNUSED(op1
))
4916 /* jump to byte offset if zero flag is set. */
4918 DECODE_PRINTF("JZ\t");
4919 offset
= (s8
)fetch_byte_imm();
4920 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4921 DECODE_PRINTF2("%x\n", target
);
4923 if (ACCESS_FLAG(F_ZF
))
4924 M
.x86
.R_IP
= target
;
4925 DECODE_CLEAR_SEGOVR();
4929 /****************************************************************************
4932 ****************************************************************************/
4933 static void x86emuOp_jump_near_NZ(u8
X86EMU_UNUSED(op1
))
4938 /* jump to byte offset if zero flag is clear. */
4940 DECODE_PRINTF("JNZ\t");
4941 offset
= (s8
)fetch_byte_imm();
4942 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4943 DECODE_PRINTF2("%x\n", target
);
4945 if (!ACCESS_FLAG(F_ZF
))
4946 M
.x86
.R_IP
= target
;
4947 DECODE_CLEAR_SEGOVR();
4951 /****************************************************************************
4954 ****************************************************************************/
4955 static void x86emuOp_jump_near_BE(u8
X86EMU_UNUSED(op1
))
4960 /* jump to byte offset if carry flag is set or if the zero
4963 DECODE_PRINTF("JBE\t");
4964 offset
= (s8
)fetch_byte_imm();
4965 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4966 DECODE_PRINTF2("%x\n", target
);
4968 if (ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
))
4969 M
.x86
.R_IP
= target
;
4970 DECODE_CLEAR_SEGOVR();
4974 /****************************************************************************
4977 ****************************************************************************/
4978 static void x86emuOp_jump_near_NBE(u8
X86EMU_UNUSED(op1
))
4983 /* jump to byte offset if carry flag is clear and if the zero
4986 DECODE_PRINTF("JNBE\t");
4987 offset
= (s8
)fetch_byte_imm();
4988 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
4989 DECODE_PRINTF2("%x\n", target
);
4991 if (!(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
)))
4992 M
.x86
.R_IP
= target
;
4993 DECODE_CLEAR_SEGOVR();
4997 /****************************************************************************
5000 ****************************************************************************/
5001 static void x86emuOp_jump_near_S(u8
X86EMU_UNUSED(op1
))
5006 /* jump to byte offset if sign flag is set */
5008 DECODE_PRINTF("JS\t");
5009 offset
= (s8
)fetch_byte_imm();
5010 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5011 DECODE_PRINTF2("%x\n", target
);
5013 if (ACCESS_FLAG(F_SF
))
5014 M
.x86
.R_IP
= target
;
5015 DECODE_CLEAR_SEGOVR();
5019 /****************************************************************************
5022 ****************************************************************************/
5023 static void x86emuOp_jump_near_NS(u8
X86EMU_UNUSED(op1
))
5028 /* jump to byte offset if sign flag is clear */
5030 DECODE_PRINTF("JNS\t");
5031 offset
= (s8
)fetch_byte_imm();
5032 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5033 DECODE_PRINTF2("%x\n", target
);
5035 if (!ACCESS_FLAG(F_SF
))
5036 M
.x86
.R_IP
= target
;
5037 DECODE_CLEAR_SEGOVR();
5041 /****************************************************************************
5044 ****************************************************************************/
5045 static void x86emuOp_jump_near_P(u8
X86EMU_UNUSED(op1
))
5050 /* jump to byte offset if parity flag is set (even parity) */
5052 DECODE_PRINTF("JP\t");
5053 offset
= (s8
)fetch_byte_imm();
5054 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5055 DECODE_PRINTF2("%x\n", target
);
5057 if (ACCESS_FLAG(F_PF
))
5058 M
.x86
.R_IP
= target
;
5059 DECODE_CLEAR_SEGOVR();
5063 /****************************************************************************
5066 ****************************************************************************/
5067 static void x86emuOp_jump_near_NP(u8
X86EMU_UNUSED(op1
))
5072 /* jump to byte offset if parity flag is clear (odd parity) */
5074 DECODE_PRINTF("JNP\t");
5075 offset
= (s8
)fetch_byte_imm();
5076 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5077 DECODE_PRINTF2("%x\n", target
);
5079 if (!ACCESS_FLAG(F_PF
))
5080 M
.x86
.R_IP
= target
;
5081 DECODE_CLEAR_SEGOVR();
5085 /****************************************************************************
5088 ****************************************************************************/
5089 static void x86emuOp_jump_near_L(u8
X86EMU_UNUSED(op1
))
5095 /* jump to byte offset if sign flag not equal to overflow flag. */
5097 DECODE_PRINTF("JL\t");
5098 offset
= (s8
)fetch_byte_imm();
5099 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5100 DECODE_PRINTF2("%x\n", target
);
5102 sf
= ACCESS_FLAG(F_SF
) != 0;
5103 of
= ACCESS_FLAG(F_OF
) != 0;
5105 M
.x86
.R_IP
= target
;
5106 DECODE_CLEAR_SEGOVR();
5110 /****************************************************************************
5113 ****************************************************************************/
5114 static void x86emuOp_jump_near_NL(u8
X86EMU_UNUSED(op1
))
5120 /* jump to byte offset if sign flag not equal to overflow flag. */
5122 DECODE_PRINTF("JNL\t");
5123 offset
= (s8
)fetch_byte_imm();
5124 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5125 DECODE_PRINTF2("%x\n", target
);
5127 sf
= ACCESS_FLAG(F_SF
) != 0;
5128 of
= ACCESS_FLAG(F_OF
) != 0;
5129 /* note: inverse of above, but using == instead of xor. */
5131 M
.x86
.R_IP
= target
;
5132 DECODE_CLEAR_SEGOVR();
5136 /****************************************************************************
5139 ****************************************************************************/
5140 static void x86emuOp_jump_near_LE(u8
X86EMU_UNUSED(op1
))
5146 /* jump to byte offset if sign flag not equal to overflow flag
5147 or the zero flag is set */
5149 DECODE_PRINTF("JLE\t");
5150 offset
= (s8
)fetch_byte_imm();
5151 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5152 DECODE_PRINTF2("%x\n", target
);
5154 sf
= ACCESS_FLAG(F_SF
) != 0;
5155 of
= ACCESS_FLAG(F_OF
) != 0;
5156 if ((sf
^ of
) || ACCESS_FLAG(F_ZF
))
5157 M
.x86
.R_IP
= target
;
5158 DECODE_CLEAR_SEGOVR();
5162 /****************************************************************************
5165 ****************************************************************************/
5166 static void x86emuOp_jump_near_NLE(u8
X86EMU_UNUSED(op1
))
5172 /* jump to byte offset if sign flag equal to overflow flag.
5173 and the zero flag is clear */
5175 DECODE_PRINTF("JNLE\t");
5176 offset
= (s8
)fetch_byte_imm();
5177 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
5178 DECODE_PRINTF2("%x\n", target
);
5180 sf
= ACCESS_FLAG(F_SF
) != 0;
5181 of
= ACCESS_FLAG(F_OF
) != 0;
5182 if ((sf
== of
) && !ACCESS_FLAG(F_ZF
))
5183 M
.x86
.R_IP
= target
;
5184 DECODE_CLEAR_SEGOVR();
5188 static u8 (*opc80_byte_operation
[])(u8 d
, u8 s
) =
5200 /****************************************************************************
5203 ****************************************************************************/
5204 static void x86emuOp_opc80_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
5213 * Weirdo special case instruction format. Part of the opcode
5214 * held below in "RH". Doubly nested case would result, except
5215 * that the decoded instruction
5218 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5220 if (DEBUG_DECODE()) {
5221 /* XXX DECODE_PRINTF may be changed to something more
5222 general, so that it is important to leave the strings
5223 in the same format, even though the result is that the
5224 above test is done twice. */
5228 DECODE_PRINTF("ADD\t");
5231 DECODE_PRINTF("OR\t");
5234 DECODE_PRINTF("ADC\t");
5237 DECODE_PRINTF("SBB\t");
5240 DECODE_PRINTF("AND\t");
5243 DECODE_PRINTF("SUB\t");
5246 DECODE_PRINTF("XOR\t");
5249 DECODE_PRINTF("CMP\t");
5254 /* know operation, decode the mod byte to find the addressing
5258 DECODE_PRINTF("BYTE PTR ");
5259 destoffset
= decode_rm00_address(rl
);
5261 destval
= fetch_data_byte(destoffset
);
5262 imm
= fetch_byte_imm();
5263 DECODE_PRINTF2("%x\n", imm
);
5265 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5267 store_data_byte(destoffset
, destval
);
5270 DECODE_PRINTF("BYTE PTR ");
5271 destoffset
= decode_rm01_address(rl
);
5273 destval
= fetch_data_byte(destoffset
);
5274 imm
= fetch_byte_imm();
5275 DECODE_PRINTF2("%x\n", imm
);
5277 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5279 store_data_byte(destoffset
, destval
);
5282 DECODE_PRINTF("BYTE PTR ");
5283 destoffset
= decode_rm10_address(rl
);
5285 destval
= fetch_data_byte(destoffset
);
5286 imm
= fetch_byte_imm();
5287 DECODE_PRINTF2("%x\n", imm
);
5289 destval
= (*opc80_byte_operation
[rh
]) (destval
, imm
);
5291 store_data_byte(destoffset
, destval
);
5293 case 3: /* register to register */
5294 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5296 imm
= fetch_byte_imm();
5297 DECODE_PRINTF2("%x\n", imm
);
5299 destval
= (*opc80_byte_operation
[rh
]) (*destreg
, imm
);
5304 DECODE_CLEAR_SEGOVR();
5308 static u16 (*opc81_word_operation
[])(u16 d
, u16 s
) =
5320 static u32 (*opc81_long_operation
[])(u32 d
, u32 s
) =
5332 /****************************************************************************
5335 ****************************************************************************/
5336 static void x86emuOp_opc81_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
5342 * Weirdo special case instruction format. Part of the opcode
5343 * held below in "RH". Doubly nested case would result, except
5344 * that the decoded instruction
5347 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5349 if (DEBUG_DECODE()) {
5350 /* XXX DECODE_PRINTF may be changed to something more
5351 general, so that it is important to leave the strings
5352 in the same format, even though the result is that the
5353 above test is done twice. */
5357 DECODE_PRINTF("ADD\t");
5360 DECODE_PRINTF("OR\t");
5363 DECODE_PRINTF("ADC\t");
5366 DECODE_PRINTF("SBB\t");
5369 DECODE_PRINTF("AND\t");
5372 DECODE_PRINTF("SUB\t");
5375 DECODE_PRINTF("XOR\t");
5378 DECODE_PRINTF("CMP\t");
5384 * Know operation, decode the mod byte to find the addressing
5389 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5392 DECODE_PRINTF("DWORD PTR ");
5393 destoffset
= decode_rm00_address(rl
);
5395 destval
= fetch_data_long(destoffset
);
5396 imm
= fetch_long_imm();
5397 DECODE_PRINTF2("%x\n", imm
);
5399 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5401 store_data_long(destoffset
, destval
);
5405 DECODE_PRINTF("WORD PTR ");
5406 destoffset
= decode_rm00_address(rl
);
5408 destval
= fetch_data_word(destoffset
);
5409 imm
= fetch_word_imm();
5410 DECODE_PRINTF2("%x\n", imm
);
5412 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5414 store_data_word(destoffset
, destval
);
5418 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5421 DECODE_PRINTF("DWORD PTR ");
5422 destoffset
= decode_rm01_address(rl
);
5424 destval
= fetch_data_long(destoffset
);
5425 imm
= fetch_long_imm();
5426 DECODE_PRINTF2("%x\n", imm
);
5428 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5430 store_data_long(destoffset
, destval
);
5434 DECODE_PRINTF("WORD PTR ");
5435 destoffset
= decode_rm01_address(rl
);
5437 destval
= fetch_data_word(destoffset
);
5438 imm
= fetch_word_imm();
5439 DECODE_PRINTF2("%x\n", imm
);
5441 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5443 store_data_word(destoffset
, destval
);
5447 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5450 DECODE_PRINTF("DWORD PTR ");
5451 destoffset
= decode_rm10_address(rl
);
5453 destval
= fetch_data_long(destoffset
);
5454 imm
= fetch_long_imm();
5455 DECODE_PRINTF2("%x\n", imm
);
5457 destval
= (*opc81_long_operation
[rh
]) (destval
, imm
);
5459 store_data_long(destoffset
, destval
);
5463 DECODE_PRINTF("WORD PTR ");
5464 destoffset
= decode_rm10_address(rl
);
5466 destval
= fetch_data_word(destoffset
);
5467 imm
= fetch_word_imm();
5468 DECODE_PRINTF2("%x\n", imm
);
5470 destval
= (*opc81_word_operation
[rh
]) (destval
, imm
);
5472 store_data_word(destoffset
, destval
);
5475 case 3: /* register to register */
5476 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5480 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5482 imm
= fetch_long_imm();
5483 DECODE_PRINTF2("%x\n", imm
);
5485 destval
= (*opc81_long_operation
[rh
]) (*destreg
, imm
);
5492 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5494 imm
= fetch_word_imm();
5495 DECODE_PRINTF2("%x\n", imm
);
5497 destval
= (*opc81_word_operation
[rh
]) (*destreg
, imm
);
5503 DECODE_CLEAR_SEGOVR();
5507 static u8 (*opc82_byte_operation
[])(u8 s
, u8 d
) =
5510 or_byte
, /*01 *//*YYY UNUSED ???? */
5513 and_byte
, /*04 *//*YYY UNUSED ???? */
5515 xor_byte
, /*06 *//*YYY UNUSED ???? */
5519 /****************************************************************************
5522 ****************************************************************************/
5523 static void x86emuOp_opc82_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
5532 * Weirdo special case instruction format. Part of the opcode
5533 * held below in "RH". Doubly nested case would result, except
5534 * that the decoded instruction Similar to opcode 81, except that
5535 * the immediate byte is sign extended to a word length.
5538 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5540 if (DEBUG_DECODE()) {
5541 /* XXX DECODE_PRINTF may be changed to something more
5542 general, so that it is important to leave the strings
5543 in the same format, even though the result is that the
5544 above test is done twice. */
5547 DECODE_PRINTF("ADD\t");
5550 DECODE_PRINTF("OR\t");
5553 DECODE_PRINTF("ADC\t");
5556 DECODE_PRINTF("SBB\t");
5559 DECODE_PRINTF("AND\t");
5562 DECODE_PRINTF("SUB\t");
5565 DECODE_PRINTF("XOR\t");
5568 DECODE_PRINTF("CMP\t");
5573 /* know operation, decode the mod byte to find the addressing
5577 DECODE_PRINTF("BYTE PTR ");
5578 destoffset
= decode_rm00_address(rl
);
5579 destval
= fetch_data_byte(destoffset
);
5580 imm
= fetch_byte_imm();
5581 DECODE_PRINTF2(",%x\n", imm
);
5583 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5585 store_data_byte(destoffset
, destval
);
5588 DECODE_PRINTF("BYTE PTR ");
5589 destoffset
= decode_rm01_address(rl
);
5590 destval
= fetch_data_byte(destoffset
);
5591 imm
= fetch_byte_imm();
5592 DECODE_PRINTF2(",%x\n", imm
);
5594 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5596 store_data_byte(destoffset
, destval
);
5599 DECODE_PRINTF("BYTE PTR ");
5600 destoffset
= decode_rm10_address(rl
);
5601 destval
= fetch_data_byte(destoffset
);
5602 imm
= fetch_byte_imm();
5603 DECODE_PRINTF2(",%x\n", imm
);
5605 destval
= (*opc82_byte_operation
[rh
]) (destval
, imm
);
5607 store_data_byte(destoffset
, destval
);
5609 case 3: /* register to register */
5610 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5611 imm
= fetch_byte_imm();
5612 DECODE_PRINTF2(",%x\n", imm
);
5614 destval
= (*opc82_byte_operation
[rh
]) (*destreg
, imm
);
5619 DECODE_CLEAR_SEGOVR();
5623 static u16 (*opc83_word_operation
[])(u16 s
, u16 d
) =
5626 or_word
, /*01 *//*YYY UNUSED ???? */
5629 and_word
, /*04 *//*YYY UNUSED ???? */
5631 xor_word
, /*06 *//*YYY UNUSED ???? */
5635 static u32 (*opc83_long_operation
[])(u32 s
, u32 d
) =
5638 or_long
, /*01 *//*YYY UNUSED ???? */
5641 and_long
, /*04 *//*YYY UNUSED ???? */
5643 xor_long
, /*06 *//*YYY UNUSED ???? */
5647 /****************************************************************************
5650 ****************************************************************************/
5651 static void x86emuOp_opc83_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
5657 * Weirdo special case instruction format. Part of the opcode
5658 * held below in "RH". Doubly nested case would result, except
5659 * that the decoded instruction Similar to opcode 81, except that
5660 * the immediate byte is sign extended to a word length.
5663 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5665 if (DEBUG_DECODE()) {
5666 /* XXX DECODE_PRINTF may be changed to something more
5667 general, so that it is important to leave the strings
5668 in the same format, even though the result is that the
5669 above test is done twice. */
5672 DECODE_PRINTF("ADD\t");
5675 DECODE_PRINTF("OR\t");
5678 DECODE_PRINTF("ADC\t");
5681 DECODE_PRINTF("SBB\t");
5684 DECODE_PRINTF("AND\t");
5687 DECODE_PRINTF("SUB\t");
5690 DECODE_PRINTF("XOR\t");
5693 DECODE_PRINTF("CMP\t");
5698 /* know operation, decode the mod byte to find the addressing
5702 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5705 DECODE_PRINTF("DWORD PTR ");
5706 destoffset
= decode_rm00_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_rm00_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_rm01_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_rm01_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
);
5756 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5759 DECODE_PRINTF("DWORD PTR ");
5760 destoffset
= decode_rm10_address(rl
);
5761 destval
= fetch_data_long(destoffset
);
5762 imm
= (s8
) fetch_byte_imm();
5763 DECODE_PRINTF2(",%x\n", imm
);
5765 destval
= (*opc83_long_operation
[rh
]) (destval
, imm
);
5767 store_data_long(destoffset
, destval
);
5771 DECODE_PRINTF("WORD PTR ");
5772 destoffset
= decode_rm10_address(rl
);
5773 destval
= fetch_data_word(destoffset
);
5774 imm
= (s8
) fetch_byte_imm();
5775 DECODE_PRINTF2(",%x\n", imm
);
5777 destval
= (*opc83_word_operation
[rh
]) (destval
, imm
);
5779 store_data_word(destoffset
, destval
);
5782 case 3: /* register to register */
5783 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5787 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5788 imm
= (s8
) fetch_byte_imm();
5789 DECODE_PRINTF2(",%x\n", imm
);
5791 destval
= (*opc83_long_operation
[rh
]) (*destreg
, imm
);
5798 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5799 imm
= (s8
) fetch_byte_imm();
5800 DECODE_PRINTF2(",%x\n", imm
);
5802 destval
= (*opc83_word_operation
[rh
]) (*destreg
, imm
);
5808 DECODE_CLEAR_SEGOVR();
5812 /****************************************************************************
5815 ****************************************************************************/
5816 static void x86emuOp_test_byte_RM_R(u8
X86EMU_UNUSED(op1
))
5819 u8
*destreg
, *srcreg
;
5824 DECODE_PRINTF("TEST\t");
5825 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5828 destoffset
= decode_rm00_address(rl
);
5830 destval
= fetch_data_byte(destoffset
);
5831 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5832 DECODE_PRINTF("\n");
5834 test_byte(destval
, *srcreg
);
5837 destoffset
= decode_rm01_address(rl
);
5839 destval
= fetch_data_byte(destoffset
);
5840 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5841 DECODE_PRINTF("\n");
5843 test_byte(destval
, *srcreg
);
5846 destoffset
= decode_rm10_address(rl
);
5848 destval
= fetch_data_byte(destoffset
);
5849 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5850 DECODE_PRINTF("\n");
5852 test_byte(destval
, *srcreg
);
5854 case 3: /* register to register */
5855 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5857 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
5858 DECODE_PRINTF("\n");
5860 test_byte(*destreg
, *srcreg
);
5863 DECODE_CLEAR_SEGOVR();
5867 /****************************************************************************
5870 ****************************************************************************/
5871 static void x86emuOp_test_word_RM_R(u8
X86EMU_UNUSED(op1
))
5877 DECODE_PRINTF("TEST\t");
5878 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5881 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5885 destoffset
= decode_rm00_address(rl
);
5887 destval
= fetch_data_long(destoffset
);
5888 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5889 DECODE_PRINTF("\n");
5891 test_long(destval
, *srcreg
);
5896 destoffset
= decode_rm00_address(rl
);
5898 destval
= fetch_data_word(destoffset
);
5899 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5900 DECODE_PRINTF("\n");
5902 test_word(destval
, *srcreg
);
5906 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5910 destoffset
= decode_rm01_address(rl
);
5912 destval
= fetch_data_long(destoffset
);
5913 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5914 DECODE_PRINTF("\n");
5916 test_long(destval
, *srcreg
);
5921 destoffset
= decode_rm01_address(rl
);
5923 destval
= fetch_data_word(destoffset
);
5924 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5925 DECODE_PRINTF("\n");
5927 test_word(destval
, *srcreg
);
5931 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5935 destoffset
= decode_rm10_address(rl
);
5937 destval
= fetch_data_long(destoffset
);
5938 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5939 DECODE_PRINTF("\n");
5941 test_long(destval
, *srcreg
);
5946 destoffset
= decode_rm10_address(rl
);
5948 destval
= fetch_data_word(destoffset
);
5949 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5950 DECODE_PRINTF("\n");
5952 test_word(destval
, *srcreg
);
5955 case 3: /* register to register */
5956 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5957 u32
*destreg
,*srcreg
;
5959 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5961 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
5962 DECODE_PRINTF("\n");
5964 test_long(*destreg
, *srcreg
);
5966 u16
*destreg
,*srcreg
;
5968 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5970 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
5971 DECODE_PRINTF("\n");
5973 test_word(*destreg
, *srcreg
);
5977 DECODE_CLEAR_SEGOVR();
5981 /****************************************************************************
5984 ****************************************************************************/
5985 static void x86emuOp_xchg_byte_RM_R(u8
X86EMU_UNUSED(op1
))
5988 u8
*destreg
, *srcreg
;
5994 DECODE_PRINTF("XCHG\t");
5995 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5998 destoffset
= decode_rm00_address(rl
);
6000 destval
= fetch_data_byte(destoffset
);
6001 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6002 DECODE_PRINTF("\n");
6007 store_data_byte(destoffset
, destval
);
6010 destoffset
= decode_rm01_address(rl
);
6012 destval
= fetch_data_byte(destoffset
);
6013 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6014 DECODE_PRINTF("\n");
6019 store_data_byte(destoffset
, destval
);
6022 destoffset
= decode_rm10_address(rl
);
6024 destval
= fetch_data_byte(destoffset
);
6025 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6026 DECODE_PRINTF("\n");
6031 store_data_byte(destoffset
, destval
);
6033 case 3: /* register to register */
6034 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
6036 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6037 DECODE_PRINTF("\n");
6044 DECODE_CLEAR_SEGOVR();
6048 /****************************************************************************
6051 ****************************************************************************/
6052 static void x86emuOp_xchg_word_RM_R(u8
X86EMU_UNUSED(op1
))
6058 DECODE_PRINTF("XCHG\t");
6059 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6062 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6066 destoffset
= decode_rm00_address(rl
);
6068 destval
= fetch_data_long(destoffset
);
6069 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6070 DECODE_PRINTF("\n");
6075 store_data_long(destoffset
, destval
);
6080 destoffset
= decode_rm00_address(rl
);
6082 destval
= fetch_data_word(destoffset
);
6083 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6084 DECODE_PRINTF("\n");
6089 store_data_word(destoffset
, destval
);
6093 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6097 destoffset
= decode_rm01_address(rl
);
6099 destval
= fetch_data_long(destoffset
);
6100 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6101 DECODE_PRINTF("\n");
6106 store_data_long(destoffset
, destval
);
6111 destoffset
= decode_rm01_address(rl
);
6113 destval
= fetch_data_word(destoffset
);
6114 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6115 DECODE_PRINTF("\n");
6120 store_data_word(destoffset
, destval
);
6124 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6128 destoffset
= decode_rm10_address(rl
);
6130 destval
= fetch_data_long(destoffset
);
6131 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6132 DECODE_PRINTF("\n");
6137 store_data_long(destoffset
, destval
);
6142 destoffset
= decode_rm10_address(rl
);
6144 destval
= fetch_data_word(destoffset
);
6145 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6146 DECODE_PRINTF("\n");
6151 store_data_word(destoffset
, destval
);
6154 case 3: /* register to register */
6155 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6156 u32
*destreg
,*srcreg
;
6159 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6161 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6162 DECODE_PRINTF("\n");
6168 u16
*destreg
,*srcreg
;
6171 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6173 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6174 DECODE_PRINTF("\n");
6182 DECODE_CLEAR_SEGOVR();
6186 /****************************************************************************
6189 ****************************************************************************/
6190 static void x86emuOp_mov_byte_RM_R(u8
X86EMU_UNUSED(op1
))
6193 u8
*destreg
, *srcreg
;
6197 DECODE_PRINTF("MOV\t");
6198 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6201 destoffset
= decode_rm00_address(rl
);
6203 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6204 DECODE_PRINTF("\n");
6206 store_data_byte(destoffset
, *srcreg
);
6209 destoffset
= decode_rm01_address(rl
);
6211 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6212 DECODE_PRINTF("\n");
6214 store_data_byte(destoffset
, *srcreg
);
6217 destoffset
= decode_rm10_address(rl
);
6219 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6220 DECODE_PRINTF("\n");
6222 store_data_byte(destoffset
, *srcreg
);
6224 case 3: /* register to register */
6225 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
6227 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
6228 DECODE_PRINTF("\n");
6233 DECODE_CLEAR_SEGOVR();
6237 /****************************************************************************
6240 ****************************************************************************/
6241 static void x86emuOp_mov_word_RM_R(u8
X86EMU_UNUSED(op1
))
6247 DECODE_PRINTF("MOV\t");
6248 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6251 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6254 destoffset
= decode_rm00_address(rl
);
6256 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6257 DECODE_PRINTF("\n");
6259 store_data_long(destoffset
, *srcreg
);
6263 destoffset
= decode_rm00_address(rl
);
6265 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6266 DECODE_PRINTF("\n");
6268 store_data_word(destoffset
, *srcreg
);
6272 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6275 destoffset
= decode_rm01_address(rl
);
6277 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6278 DECODE_PRINTF("\n");
6280 store_data_long(destoffset
, *srcreg
);
6284 destoffset
= decode_rm01_address(rl
);
6286 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6287 DECODE_PRINTF("\n");
6289 store_data_word(destoffset
, *srcreg
);
6293 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6296 destoffset
= decode_rm10_address(rl
);
6298 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6299 DECODE_PRINTF("\n");
6301 store_data_long(destoffset
, *srcreg
);
6305 destoffset
= decode_rm10_address(rl
);
6307 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6308 DECODE_PRINTF("\n");
6310 store_data_word(destoffset
, *srcreg
);
6313 case 3: /* register to register */
6314 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6315 u32
*destreg
,*srcreg
;
6317 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6319 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
6320 DECODE_PRINTF("\n");
6324 u16
*destreg
,*srcreg
;
6326 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6328 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6329 DECODE_PRINTF("\n");
6335 DECODE_CLEAR_SEGOVR();
6339 /****************************************************************************
6342 ****************************************************************************/
6343 static void x86emuOp_mov_byte_R_RM(u8
X86EMU_UNUSED(op1
))
6346 u8
*destreg
, *srcreg
;
6351 DECODE_PRINTF("MOV\t");
6352 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6355 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6357 srcoffset
= decode_rm00_address(rl
);
6358 srcval
= fetch_data_byte(srcoffset
);
6359 DECODE_PRINTF("\n");
6364 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6366 srcoffset
= decode_rm01_address(rl
);
6367 srcval
= fetch_data_byte(srcoffset
);
6368 DECODE_PRINTF("\n");
6373 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6375 srcoffset
= decode_rm10_address(rl
);
6376 srcval
= fetch_data_byte(srcoffset
);
6377 DECODE_PRINTF("\n");
6381 case 3: /* register to register */
6382 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
6384 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
6385 DECODE_PRINTF("\n");
6390 DECODE_CLEAR_SEGOVR();
6394 /****************************************************************************
6397 ****************************************************************************/
6398 static void x86emuOp_mov_word_R_RM(u8
X86EMU_UNUSED(op1
))
6404 DECODE_PRINTF("MOV\t");
6405 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6408 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6412 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6414 srcoffset
= decode_rm00_address(rl
);
6415 srcval
= fetch_data_long(srcoffset
);
6416 DECODE_PRINTF("\n");
6423 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6425 srcoffset
= decode_rm00_address(rl
);
6426 srcval
= fetch_data_word(srcoffset
);
6427 DECODE_PRINTF("\n");
6433 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6437 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6439 srcoffset
= decode_rm01_address(rl
);
6440 srcval
= fetch_data_long(srcoffset
);
6441 DECODE_PRINTF("\n");
6448 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6450 srcoffset
= decode_rm01_address(rl
);
6451 srcval
= fetch_data_word(srcoffset
);
6452 DECODE_PRINTF("\n");
6458 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6462 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6464 srcoffset
= decode_rm10_address(rl
);
6465 srcval
= fetch_data_long(srcoffset
);
6466 DECODE_PRINTF("\n");
6473 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6475 srcoffset
= decode_rm10_address(rl
);
6476 srcval
= fetch_data_word(srcoffset
);
6477 DECODE_PRINTF("\n");
6482 case 3: /* register to register */
6483 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6484 u32
*destreg
, *srcreg
;
6486 destreg
= DECODE_RM_LONG_REGISTER(rh
);
6488 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
6489 DECODE_PRINTF("\n");
6493 u16
*destreg
, *srcreg
;
6495 destreg
= DECODE_RM_WORD_REGISTER(rh
);
6497 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
6498 DECODE_PRINTF("\n");
6504 DECODE_CLEAR_SEGOVR();
6508 /****************************************************************************
6511 ****************************************************************************/
6512 static void x86emuOp_mov_word_RM_SR(u8
X86EMU_UNUSED(op1
))
6515 u16
*destreg
, *srcreg
;
6520 DECODE_PRINTF("MOV\t");
6521 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6524 destoffset
= decode_rm00_address(rl
);
6526 srcreg
= decode_rm_seg_register(rh
);
6527 DECODE_PRINTF("\n");
6530 store_data_word(destoffset
, destval
);
6533 destoffset
= decode_rm01_address(rl
);
6535 srcreg
= decode_rm_seg_register(rh
);
6536 DECODE_PRINTF("\n");
6539 store_data_word(destoffset
, destval
);
6542 destoffset
= decode_rm10_address(rl
);
6544 srcreg
= decode_rm_seg_register(rh
);
6545 DECODE_PRINTF("\n");
6548 store_data_word(destoffset
, destval
);
6550 case 3: /* register to register */
6551 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6553 srcreg
= decode_rm_seg_register(rh
);
6554 DECODE_PRINTF("\n");
6559 DECODE_CLEAR_SEGOVR();
6563 /****************************************************************************
6566 ****************************************************************************/
6567 static void x86emuOp_lea_word_R_M(u8
X86EMU_UNUSED(op1
))
6574 * TODO: Need to handle address size prefix!
6576 * lea eax,[eax+ebx*2] ??
6580 DECODE_PRINTF("LEA\t");
6581 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6584 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6586 destoffset
= decode_rm00_address(rl
);
6587 DECODE_PRINTF("\n");
6589 *srcreg
= (u16
)destoffset
;
6592 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6594 destoffset
= decode_rm01_address(rl
);
6595 DECODE_PRINTF("\n");
6597 *srcreg
= (u16
)destoffset
;
6600 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
6602 destoffset
= decode_rm10_address(rl
);
6603 DECODE_PRINTF("\n");
6605 *srcreg
= (u16
)destoffset
;
6607 case 3: /* register to register */
6608 /* undefined. Do nothing. */
6611 DECODE_CLEAR_SEGOVR();
6615 /****************************************************************************
6618 ****************************************************************************/
6619 static void x86emuOp_mov_word_SR_RM(u8
X86EMU_UNUSED(op1
))
6622 u16
*destreg
, *srcreg
;
6627 DECODE_PRINTF("MOV\t");
6628 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6631 destreg
= decode_rm_seg_register(rh
);
6633 srcoffset
= decode_rm00_address(rl
);
6634 srcval
= fetch_data_word(srcoffset
);
6635 DECODE_PRINTF("\n");
6640 destreg
= decode_rm_seg_register(rh
);
6642 srcoffset
= decode_rm01_address(rl
);
6643 srcval
= fetch_data_word(srcoffset
);
6644 DECODE_PRINTF("\n");
6649 destreg
= decode_rm_seg_register(rh
);
6651 srcoffset
= decode_rm10_address(rl
);
6652 srcval
= fetch_data_word(srcoffset
);
6653 DECODE_PRINTF("\n");
6657 case 3: /* register to register */
6658 destreg
= decode_rm_seg_register(rh
);
6660 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
6661 DECODE_PRINTF("\n");
6667 * Clean up, and reset all the R_xSP pointers to the correct
6668 * locations. This is about 3x too much overhead (doing all the
6669 * segreg ptrs when only one is needed, but this instruction
6670 * *cannot* be that common, and this isn't too much work anyway.
6672 DECODE_CLEAR_SEGOVR();
6676 /****************************************************************************
6679 ****************************************************************************/
6680 static void x86emuOp_pop_RM(u8
X86EMU_UNUSED(op1
))
6686 DECODE_PRINTF("POP\t");
6687 FETCH_DECODE_MODRM(mod
, rh
, rl
);
6689 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6694 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6697 destoffset
= decode_rm00_address(rl
);
6698 DECODE_PRINTF("\n");
6700 destval
= pop_long();
6701 store_data_long(destoffset
, destval
);
6705 destoffset
= decode_rm00_address(rl
);
6706 DECODE_PRINTF("\n");
6708 destval
= pop_word();
6709 store_data_word(destoffset
, destval
);
6713 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6716 destoffset
= decode_rm01_address(rl
);
6717 DECODE_PRINTF("\n");
6719 destval
= pop_long();
6720 store_data_long(destoffset
, destval
);
6724 destoffset
= decode_rm01_address(rl
);
6725 DECODE_PRINTF("\n");
6727 destval
= pop_word();
6728 store_data_word(destoffset
, destval
);
6732 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6735 destoffset
= decode_rm10_address(rl
);
6736 DECODE_PRINTF("\n");
6738 destval
= pop_long();
6739 store_data_long(destoffset
, destval
);
6743 destoffset
= decode_rm10_address(rl
);
6744 DECODE_PRINTF("\n");
6746 destval
= pop_word();
6747 store_data_word(destoffset
, destval
);
6750 case 3: /* register to register */
6751 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6754 destreg
= DECODE_RM_LONG_REGISTER(rl
);
6755 DECODE_PRINTF("\n");
6757 *destreg
= pop_long();
6761 destreg
= DECODE_RM_WORD_REGISTER(rl
);
6762 DECODE_PRINTF("\n");
6764 *destreg
= pop_word();
6768 DECODE_CLEAR_SEGOVR();
6772 /****************************************************************************
6775 ****************************************************************************/
6776 static void x86emuOp_nop(u8
X86EMU_UNUSED(op1
))
6779 DECODE_PRINTF("NOP\n");
6781 DECODE_CLEAR_SEGOVR();
6785 /****************************************************************************
6788 ****************************************************************************/
6789 static void x86emuOp_xchg_word_AX_CX(u8
X86EMU_UNUSED(op1
))
6794 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6795 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6797 DECODE_PRINTF("XCHG\tAX,CX\n");
6800 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6802 M
.x86
.R_EAX
= M
.x86
.R_ECX
;
6806 M
.x86
.R_AX
= M
.x86
.R_CX
;
6807 M
.x86
.R_CX
= (u16
)tmp
;
6809 DECODE_CLEAR_SEGOVR();
6813 /****************************************************************************
6816 ****************************************************************************/
6817 static void x86emuOp_xchg_word_AX_DX(u8
X86EMU_UNUSED(op1
))
6822 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6823 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6825 DECODE_PRINTF("XCHG\tAX,DX\n");
6828 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6830 M
.x86
.R_EAX
= M
.x86
.R_EDX
;
6834 M
.x86
.R_AX
= M
.x86
.R_DX
;
6835 M
.x86
.R_DX
= (u16
)tmp
;
6837 DECODE_CLEAR_SEGOVR();
6841 /****************************************************************************
6844 ****************************************************************************/
6845 static void x86emuOp_xchg_word_AX_BX(u8
X86EMU_UNUSED(op1
))
6850 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6851 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6853 DECODE_PRINTF("XCHG\tAX,BX\n");
6856 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6858 M
.x86
.R_EAX
= M
.x86
.R_EBX
;
6862 M
.x86
.R_AX
= M
.x86
.R_BX
;
6863 M
.x86
.R_BX
= (u16
)tmp
;
6865 DECODE_CLEAR_SEGOVR();
6869 /****************************************************************************
6872 ****************************************************************************/
6873 static void x86emuOp_xchg_word_AX_SP(u8
X86EMU_UNUSED(op1
))
6878 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6879 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6881 DECODE_PRINTF("XCHG\tAX,SP\n");
6884 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6886 M
.x86
.R_EAX
= M
.x86
.R_ESP
;
6890 M
.x86
.R_AX
= M
.x86
.R_SP
;
6891 M
.x86
.R_SP
= (u16
)tmp
;
6893 DECODE_CLEAR_SEGOVR();
6897 /****************************************************************************
6900 ****************************************************************************/
6901 static void x86emuOp_xchg_word_AX_BP(u8
X86EMU_UNUSED(op1
))
6906 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6907 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6909 DECODE_PRINTF("XCHG\tAX,BP\n");
6912 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6914 M
.x86
.R_EAX
= M
.x86
.R_EBP
;
6918 M
.x86
.R_AX
= M
.x86
.R_BP
;
6919 M
.x86
.R_BP
= (u16
)tmp
;
6921 DECODE_CLEAR_SEGOVR();
6925 /****************************************************************************
6928 ****************************************************************************/
6929 static void x86emuOp_xchg_word_AX_SI(u8
X86EMU_UNUSED(op1
))
6934 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6935 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6937 DECODE_PRINTF("XCHG\tAX,SI\n");
6940 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6942 M
.x86
.R_EAX
= M
.x86
.R_ESI
;
6946 M
.x86
.R_AX
= M
.x86
.R_SI
;
6947 M
.x86
.R_SI
= (u16
)tmp
;
6949 DECODE_CLEAR_SEGOVR();
6953 /****************************************************************************
6956 ****************************************************************************/
6957 static void x86emuOp_xchg_word_AX_DI(u8
X86EMU_UNUSED(op1
))
6962 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6963 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6965 DECODE_PRINTF("XCHG\tAX,DI\n");
6968 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6970 M
.x86
.R_EAX
= M
.x86
.R_EDI
;
6974 M
.x86
.R_AX
= M
.x86
.R_DI
;
6975 M
.x86
.R_DI
= (u16
)tmp
;
6977 DECODE_CLEAR_SEGOVR();
6981 /****************************************************************************
6984 ****************************************************************************/
6985 static void x86emuOp_cbw(u8
X86EMU_UNUSED(op1
))
6988 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6989 DECODE_PRINTF("CWDE\n");
6991 DECODE_PRINTF("CBW\n");
6994 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
6995 if (M
.x86
.R_AX
& 0x8000) {
6996 M
.x86
.R_EAX
|= 0xffff0000;
6998 M
.x86
.R_EAX
&= 0x0000ffff;
7001 if (M
.x86
.R_AL
& 0x80) {
7007 DECODE_CLEAR_SEGOVR();
7011 /****************************************************************************
7014 ****************************************************************************/
7015 static void x86emuOp_cwd(u8
X86EMU_UNUSED(op1
))
7018 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7019 DECODE_PRINTF("CDQ\n");
7021 DECODE_PRINTF("CWD\n");
7023 DECODE_PRINTF("CWD\n");
7025 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7026 if (M
.x86
.R_EAX
& 0x80000000) {
7027 M
.x86
.R_EDX
= 0xffffffff;
7032 if (M
.x86
.R_AX
& 0x8000) {
7033 M
.x86
.R_DX
= 0xffff;
7038 DECODE_CLEAR_SEGOVR();
7042 /****************************************************************************
7045 ****************************************************************************/
7046 static void x86emuOp_call_far_IMM(u8
X86EMU_UNUSED(op1
))
7051 DECODE_PRINTF("CALL\t");
7052 faroff
= fetch_word_imm();
7053 farseg
= fetch_word_imm();
7054 DECODE_PRINTF2("%04x:", farseg
);
7055 DECODE_PRINTF2("%04x\n", faroff
);
7056 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, farseg
, faroff
, "FAR ");
7060 * Hooked interrupt vectors calling into our "BIOS" will cause
7061 * problems unless all intersegment stuff is checked for BIOS
7062 * access. Check needed here. For moment, let it alone.
7065 push_word(M
.x86
.R_CS
);
7066 M
.x86
.R_CS
= farseg
;
7067 push_word(M
.x86
.R_IP
);
7068 M
.x86
.R_IP
= faroff
;
7069 DECODE_CLEAR_SEGOVR();
7073 /****************************************************************************
7076 ****************************************************************************/
7077 static void x86emuOp_wait(u8
X86EMU_UNUSED(op1
))
7080 DECODE_PRINTF("WAIT");
7083 DECODE_CLEAR_SEGOVR();
7087 /****************************************************************************
7090 ****************************************************************************/
7091 static void x86emuOp_pushf_word(u8
X86EMU_UNUSED(op1
))
7096 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7097 DECODE_PRINTF("PUSHFD\n");
7099 DECODE_PRINTF("PUSHF\n");
7103 /* clear out *all* bits not representing flags, and turn on real bits */
7104 flags
= (M
.x86
.R_EFLG
& F_MSK
) | F_ALWAYS_ON
;
7105 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7108 push_word((u16
)flags
);
7110 DECODE_CLEAR_SEGOVR();
7114 /****************************************************************************
7117 ****************************************************************************/
7118 static void x86emuOp_popf_word(u8
X86EMU_UNUSED(op1
))
7121 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7122 DECODE_PRINTF("POPFD\n");
7124 DECODE_PRINTF("POPF\n");
7127 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7128 M
.x86
.R_EFLG
= pop_long();
7130 M
.x86
.R_FLG
= pop_word();
7132 DECODE_CLEAR_SEGOVR();
7136 /****************************************************************************
7139 ****************************************************************************/
7140 static void x86emuOp_sahf(u8
X86EMU_UNUSED(op1
))
7143 DECODE_PRINTF("SAHF\n");
7145 /* clear the lower bits of the flag register */
7146 M
.x86
.R_FLG
&= 0xffffff00;
7147 /* or in the AH register into the flags register */
7148 M
.x86
.R_FLG
|= M
.x86
.R_AH
;
7149 DECODE_CLEAR_SEGOVR();
7153 /****************************************************************************
7156 ****************************************************************************/
7157 static void x86emuOp_lahf(u8
X86EMU_UNUSED(op1
))
7160 DECODE_PRINTF("LAHF\n");
7162 M
.x86
.R_AH
= (u8
)(M
.x86
.R_FLG
& 0xff);
7163 /*undocumented TC++ behavior??? Nope. It's documented, but
7164 you have too look real hard to notice it. */
7166 DECODE_CLEAR_SEGOVR();
7170 /****************************************************************************
7173 ****************************************************************************/
7174 static void x86emuOp_mov_AL_M_IMM(u8
X86EMU_UNUSED(op1
))
7179 DECODE_PRINTF("MOV\tAL,");
7180 offset
= fetch_word_imm();
7181 DECODE_PRINTF2("[%04x]\n", offset
);
7183 M
.x86
.R_AL
= fetch_data_byte(offset
);
7184 DECODE_CLEAR_SEGOVR();
7188 /****************************************************************************
7191 ****************************************************************************/
7192 static void x86emuOp_mov_AX_M_IMM(u8
X86EMU_UNUSED(op1
))
7197 offset
= fetch_word_imm();
7198 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7199 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset
);
7201 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset
);
7204 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7205 M
.x86
.R_EAX
= fetch_data_long(offset
);
7207 M
.x86
.R_AX
= fetch_data_word(offset
);
7209 DECODE_CLEAR_SEGOVR();
7213 /****************************************************************************
7216 ****************************************************************************/
7217 static void x86emuOp_mov_M_AL_IMM(u8
X86EMU_UNUSED(op1
))
7222 DECODE_PRINTF("MOV\t");
7223 offset
= fetch_word_imm();
7224 DECODE_PRINTF2("[%04x],AL\n", offset
);
7226 store_data_byte(offset
, M
.x86
.R_AL
);
7227 DECODE_CLEAR_SEGOVR();
7231 /****************************************************************************
7234 ****************************************************************************/
7235 static void x86emuOp_mov_M_AX_IMM(u8
X86EMU_UNUSED(op1
))
7240 offset
= fetch_word_imm();
7241 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7242 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset
);
7244 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset
);
7247 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7248 store_data_long(offset
, M
.x86
.R_EAX
);
7250 store_data_word(offset
, M
.x86
.R_AX
);
7252 DECODE_CLEAR_SEGOVR();
7256 /****************************************************************************
7259 ****************************************************************************/
7260 static void x86emuOp_movs_byte(u8
X86EMU_UNUSED(op1
))
7267 DECODE_PRINTF("MOVS\tBYTE\n");
7268 if (ACCESS_FLAG(F_DF
)) /* down */
7274 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7275 /* dont care whether REPE or REPNE */
7276 /* move them until CX is ZERO. */
7279 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7282 val
= fetch_data_byte(M
.x86
.R_SI
);
7283 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
7287 DECODE_CLEAR_SEGOVR();
7291 /****************************************************************************
7294 ****************************************************************************/
7295 static void x86emuOp_movs_word(u8
X86EMU_UNUSED(op1
))
7302 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7303 DECODE_PRINTF("MOVS\tDWORD\n");
7304 if (ACCESS_FLAG(F_DF
)) /* down */
7309 DECODE_PRINTF("MOVS\tWORD\n");
7310 if (ACCESS_FLAG(F_DF
)) /* down */
7317 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7318 /* dont care whether REPE or REPNE */
7319 /* move them until CX is ZERO. */
7322 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7325 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7326 val
= fetch_data_long(M
.x86
.R_SI
);
7327 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
7329 val
= fetch_data_word(M
.x86
.R_SI
);
7330 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, (u16
)val
);
7335 DECODE_CLEAR_SEGOVR();
7339 /****************************************************************************
7342 ****************************************************************************/
7343 static void x86emuOp_cmps_byte(u8
X86EMU_UNUSED(op1
))
7349 DECODE_PRINTF("CMPS\tBYTE\n");
7351 if (ACCESS_FLAG(F_DF
)) /* down */
7356 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7358 /* move them until CX is ZERO. */
7359 while (M
.x86
.R_CX
!= 0) {
7360 val1
= fetch_data_byte(M
.x86
.R_SI
);
7361 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7362 cmp_byte(val1
, val2
);
7366 if (ACCESS_FLAG(F_ZF
) == 0)
7369 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7370 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7372 /* move them until CX is ZERO. */
7373 while (M
.x86
.R_CX
!= 0) {
7374 val1
= fetch_data_byte(M
.x86
.R_SI
);
7375 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7376 cmp_byte(val1
, val2
);
7380 if (ACCESS_FLAG(F_ZF
))
7381 break; /* zero flag set means equal */
7383 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7385 val1
= fetch_data_byte(M
.x86
.R_SI
);
7386 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7387 cmp_byte(val1
, val2
);
7391 DECODE_CLEAR_SEGOVR();
7395 /****************************************************************************
7398 ****************************************************************************/
7399 static void x86emuOp_cmps_word(u8
X86EMU_UNUSED(op1
))
7405 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7406 DECODE_PRINTF("CMPS\tDWORD\n");
7407 if (ACCESS_FLAG(F_DF
)) /* down */
7412 DECODE_PRINTF("CMPS\tWORD\n");
7413 if (ACCESS_FLAG(F_DF
)) /* down */
7419 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7421 /* move them until CX is ZERO. */
7422 while (M
.x86
.R_CX
!= 0) {
7423 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7424 val1
= fetch_data_long(M
.x86
.R_SI
);
7425 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7426 cmp_long(val1
, val2
);
7428 val1
= fetch_data_word(M
.x86
.R_SI
);
7429 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7430 cmp_word((u16
)val1
, (u16
)val2
);
7435 if (ACCESS_FLAG(F_ZF
) == 0)
7438 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7439 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7441 /* move them until CX is ZERO. */
7442 while (M
.x86
.R_CX
!= 0) {
7443 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7444 val1
= fetch_data_long(M
.x86
.R_SI
);
7445 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7446 cmp_long(val1
, val2
);
7448 val1
= fetch_data_word(M
.x86
.R_SI
);
7449 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7450 cmp_word((u16
)val1
, (u16
)val2
);
7455 if (ACCESS_FLAG(F_ZF
))
7456 break; /* zero flag set means equal */
7458 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7460 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7461 val1
= fetch_data_long(M
.x86
.R_SI
);
7462 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7463 cmp_long(val1
, val2
);
7465 val1
= fetch_data_word(M
.x86
.R_SI
);
7466 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7467 cmp_word((u16
)val1
, (u16
)val2
);
7472 DECODE_CLEAR_SEGOVR();
7476 /****************************************************************************
7479 ****************************************************************************/
7480 static void x86emuOp_test_AL_IMM(u8
X86EMU_UNUSED(op1
))
7485 DECODE_PRINTF("TEST\tAL,");
7486 imm
= fetch_byte_imm();
7487 DECODE_PRINTF2("%04x\n", imm
);
7489 test_byte(M
.x86
.R_AL
, (u8
)imm
);
7490 DECODE_CLEAR_SEGOVR();
7494 /****************************************************************************
7497 ****************************************************************************/
7498 static void x86emuOp_test_AX_IMM(u8
X86EMU_UNUSED(op1
))
7503 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7504 DECODE_PRINTF("TEST\tEAX,");
7505 srcval
= fetch_long_imm();
7507 DECODE_PRINTF("TEST\tAX,");
7508 srcval
= fetch_word_imm();
7510 DECODE_PRINTF2("%x\n", srcval
);
7512 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7513 test_long(M
.x86
.R_EAX
, srcval
);
7515 test_word(M
.x86
.R_AX
, (u16
)srcval
);
7517 DECODE_CLEAR_SEGOVR();
7521 /****************************************************************************
7524 ****************************************************************************/
7525 static void x86emuOp_stos_byte(u8
X86EMU_UNUSED(op1
))
7530 DECODE_PRINTF("STOS\tBYTE\n");
7531 if (ACCESS_FLAG(F_DF
)) /* down */
7536 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7537 /* dont care whether REPE or REPNE */
7538 /* move them until CX is ZERO. */
7539 while (M
.x86
.R_CX
!= 0) {
7540 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
7544 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7546 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
7549 DECODE_CLEAR_SEGOVR();
7553 /****************************************************************************
7556 ****************************************************************************/
7557 static void x86emuOp_stos_word(u8
X86EMU_UNUSED(op1
))
7563 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7564 DECODE_PRINTF("STOS\tDWORD\n");
7565 if (ACCESS_FLAG(F_DF
)) /* down */
7570 DECODE_PRINTF("STOS\tWORD\n");
7571 if (ACCESS_FLAG(F_DF
)) /* down */
7578 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7579 /* dont care whether REPE or REPNE */
7580 /* move them until CX is ZERO. */
7583 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7586 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7587 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_EAX
);
7589 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AX
);
7593 DECODE_CLEAR_SEGOVR();
7597 /****************************************************************************
7600 ****************************************************************************/
7601 static void x86emuOp_lods_byte(u8
X86EMU_UNUSED(op1
))
7606 DECODE_PRINTF("LODS\tBYTE\n");
7608 if (ACCESS_FLAG(F_DF
)) /* down */
7612 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7613 /* dont care whether REPE or REPNE */
7614 /* move them until CX is ZERO. */
7615 while (M
.x86
.R_CX
!= 0) {
7616 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
7620 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7622 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
7625 DECODE_CLEAR_SEGOVR();
7629 /****************************************************************************
7632 ****************************************************************************/
7633 static void x86emuOp_lods_word(u8
X86EMU_UNUSED(op1
))
7639 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7640 DECODE_PRINTF("LODS\tDWORD\n");
7641 if (ACCESS_FLAG(F_DF
)) /* down */
7646 DECODE_PRINTF("LODS\tWORD\n");
7647 if (ACCESS_FLAG(F_DF
)) /* down */
7654 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
7655 /* dont care whether REPE or REPNE */
7656 /* move them until CX is ZERO. */
7659 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
7662 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7663 M
.x86
.R_EAX
= fetch_data_long(M
.x86
.R_SI
);
7665 M
.x86
.R_AX
= fetch_data_word(M
.x86
.R_SI
);
7669 DECODE_CLEAR_SEGOVR();
7673 /****************************************************************************
7676 ****************************************************************************/
7677 static void x86emuOp_scas_byte(u8
X86EMU_UNUSED(op1
))
7683 DECODE_PRINTF("SCAS\tBYTE\n");
7685 if (ACCESS_FLAG(F_DF
)) /* down */
7689 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7691 /* move them until CX is ZERO. */
7692 while (M
.x86
.R_CX
!= 0) {
7693 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7694 cmp_byte(M
.x86
.R_AL
, val2
);
7697 if (ACCESS_FLAG(F_ZF
) == 0)
7700 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7701 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7703 /* move them until CX is ZERO. */
7704 while (M
.x86
.R_CX
!= 0) {
7705 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7706 cmp_byte(M
.x86
.R_AL
, val2
);
7709 if (ACCESS_FLAG(F_ZF
))
7710 break; /* zero flag set means equal */
7712 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7714 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7715 cmp_byte(M
.x86
.R_AL
, val2
);
7718 DECODE_CLEAR_SEGOVR();
7722 /****************************************************************************
7725 ****************************************************************************/
7726 static void x86emuOp_scas_word(u8
X86EMU_UNUSED(op1
))
7732 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7733 DECODE_PRINTF("SCAS\tDWORD\n");
7734 if (ACCESS_FLAG(F_DF
)) /* down */
7739 DECODE_PRINTF("SCAS\tWORD\n");
7740 if (ACCESS_FLAG(F_DF
)) /* down */
7746 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
7748 /* move them until CX is ZERO. */
7749 while (M
.x86
.R_CX
!= 0) {
7750 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7751 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7752 cmp_long(M
.x86
.R_EAX
, val
);
7754 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7755 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7759 if (ACCESS_FLAG(F_ZF
) == 0)
7762 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
7763 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
7765 /* move them until CX is ZERO. */
7766 while (M
.x86
.R_CX
!= 0) {
7767 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7768 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7769 cmp_long(M
.x86
.R_EAX
, val
);
7771 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7772 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7776 if (ACCESS_FLAG(F_ZF
))
7777 break; /* zero flag set means equal */
7779 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
7781 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7782 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7783 cmp_long(M
.x86
.R_EAX
, val
);
7785 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
7786 cmp_word(M
.x86
.R_AX
, (u16
)val
);
7790 DECODE_CLEAR_SEGOVR();
7794 /****************************************************************************
7797 ****************************************************************************/
7798 static void x86emuOp_mov_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
7803 DECODE_PRINTF("MOV\tAL,");
7804 imm
= fetch_byte_imm();
7805 DECODE_PRINTF2("%x\n", imm
);
7808 DECODE_CLEAR_SEGOVR();
7812 /****************************************************************************
7815 ****************************************************************************/
7816 static void x86emuOp_mov_byte_CL_IMM(u8
X86EMU_UNUSED(op1
))
7821 DECODE_PRINTF("MOV\tCL,");
7822 imm
= fetch_byte_imm();
7823 DECODE_PRINTF2("%x\n", imm
);
7826 DECODE_CLEAR_SEGOVR();
7830 /****************************************************************************
7833 ****************************************************************************/
7834 static void x86emuOp_mov_byte_DL_IMM(u8
X86EMU_UNUSED(op1
))
7839 DECODE_PRINTF("MOV\tDL,");
7840 imm
= fetch_byte_imm();
7841 DECODE_PRINTF2("%x\n", imm
);
7844 DECODE_CLEAR_SEGOVR();
7848 /****************************************************************************
7851 ****************************************************************************/
7852 static void x86emuOp_mov_byte_BL_IMM(u8
X86EMU_UNUSED(op1
))
7857 DECODE_PRINTF("MOV\tBL,");
7858 imm
= fetch_byte_imm();
7859 DECODE_PRINTF2("%x\n", imm
);
7862 DECODE_CLEAR_SEGOVR();
7866 /****************************************************************************
7869 ****************************************************************************/
7870 static void x86emuOp_mov_byte_AH_IMM(u8
X86EMU_UNUSED(op1
))
7875 DECODE_PRINTF("MOV\tAH,");
7876 imm
= fetch_byte_imm();
7877 DECODE_PRINTF2("%x\n", imm
);
7880 DECODE_CLEAR_SEGOVR();
7884 /****************************************************************************
7887 ****************************************************************************/
7888 static void x86emuOp_mov_byte_CH_IMM(u8
X86EMU_UNUSED(op1
))
7893 DECODE_PRINTF("MOV\tCH,");
7894 imm
= fetch_byte_imm();
7895 DECODE_PRINTF2("%x\n", imm
);
7898 DECODE_CLEAR_SEGOVR();
7902 /****************************************************************************
7905 ****************************************************************************/
7906 static void x86emuOp_mov_byte_DH_IMM(u8
X86EMU_UNUSED(op1
))
7911 DECODE_PRINTF("MOV\tDH,");
7912 imm
= fetch_byte_imm();
7913 DECODE_PRINTF2("%x\n", imm
);
7916 DECODE_CLEAR_SEGOVR();
7920 /****************************************************************************
7923 ****************************************************************************/
7924 static void x86emuOp_mov_byte_BH_IMM(u8
X86EMU_UNUSED(op1
))
7929 DECODE_PRINTF("MOV\tBH,");
7930 imm
= fetch_byte_imm();
7931 DECODE_PRINTF2("%x\n", imm
);
7934 DECODE_CLEAR_SEGOVR();
7938 /****************************************************************************
7941 ****************************************************************************/
7942 static void x86emuOp_mov_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
7947 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7948 DECODE_PRINTF("MOV\tEAX,");
7949 srcval
= fetch_long_imm();
7951 DECODE_PRINTF("MOV\tAX,");
7952 srcval
= fetch_word_imm();
7954 DECODE_PRINTF2("%x\n", srcval
);
7956 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7957 M
.x86
.R_EAX
= srcval
;
7959 M
.x86
.R_AX
= (u16
)srcval
;
7961 DECODE_CLEAR_SEGOVR();
7965 /****************************************************************************
7968 ****************************************************************************/
7969 static void x86emuOp_mov_word_CX_IMM(u8
X86EMU_UNUSED(op1
))
7974 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7975 DECODE_PRINTF("MOV\tECX,");
7976 srcval
= fetch_long_imm();
7978 DECODE_PRINTF("MOV\tCX,");
7979 srcval
= fetch_word_imm();
7981 DECODE_PRINTF2("%x\n", srcval
);
7983 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
7984 M
.x86
.R_ECX
= srcval
;
7986 M
.x86
.R_CX
= (u16
)srcval
;
7988 DECODE_CLEAR_SEGOVR();
7992 /****************************************************************************
7995 ****************************************************************************/
7996 static void x86emuOp_mov_word_DX_IMM(u8
X86EMU_UNUSED(op1
))
8001 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8002 DECODE_PRINTF("MOV\tEDX,");
8003 srcval
= fetch_long_imm();
8005 DECODE_PRINTF("MOV\tDX,");
8006 srcval
= fetch_word_imm();
8008 DECODE_PRINTF2("%x\n", srcval
);
8010 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8011 M
.x86
.R_EDX
= srcval
;
8013 M
.x86
.R_DX
= (u16
)srcval
;
8015 DECODE_CLEAR_SEGOVR();
8019 /****************************************************************************
8022 ****************************************************************************/
8023 static void x86emuOp_mov_word_BX_IMM(u8
X86EMU_UNUSED(op1
))
8028 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8029 DECODE_PRINTF("MOV\tEBX,");
8030 srcval
= fetch_long_imm();
8032 DECODE_PRINTF("MOV\tBX,");
8033 srcval
= fetch_word_imm();
8035 DECODE_PRINTF2("%x\n", srcval
);
8037 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8038 M
.x86
.R_EBX
= srcval
;
8040 M
.x86
.R_BX
= (u16
)srcval
;
8042 DECODE_CLEAR_SEGOVR();
8046 /****************************************************************************
8049 ****************************************************************************/
8050 static void x86emuOp_mov_word_SP_IMM(u8
X86EMU_UNUSED(op1
))
8055 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8056 DECODE_PRINTF("MOV\tESP,");
8057 srcval
= fetch_long_imm();
8059 DECODE_PRINTF("MOV\tSP,");
8060 srcval
= fetch_word_imm();
8062 DECODE_PRINTF2("%x\n", srcval
);
8064 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8065 M
.x86
.R_ESP
= srcval
;
8067 M
.x86
.R_SP
= (u16
)srcval
;
8069 DECODE_CLEAR_SEGOVR();
8073 /****************************************************************************
8076 ****************************************************************************/
8077 static void x86emuOp_mov_word_BP_IMM(u8
X86EMU_UNUSED(op1
))
8082 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8083 DECODE_PRINTF("MOV\tEBP,");
8084 srcval
= fetch_long_imm();
8086 DECODE_PRINTF("MOV\tBP,");
8087 srcval
= fetch_word_imm();
8089 DECODE_PRINTF2("%x\n", srcval
);
8091 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8092 M
.x86
.R_EBP
= srcval
;
8094 M
.x86
.R_BP
= (u16
)srcval
;
8096 DECODE_CLEAR_SEGOVR();
8100 /****************************************************************************
8103 ****************************************************************************/
8104 static void x86emuOp_mov_word_SI_IMM(u8
X86EMU_UNUSED(op1
))
8109 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8110 DECODE_PRINTF("MOV\tESI,");
8111 srcval
= fetch_long_imm();
8113 DECODE_PRINTF("MOV\tSI,");
8114 srcval
= fetch_word_imm();
8116 DECODE_PRINTF2("%x\n", srcval
);
8118 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8119 M
.x86
.R_ESI
= srcval
;
8121 M
.x86
.R_SI
= (u16
)srcval
;
8123 DECODE_CLEAR_SEGOVR();
8127 /****************************************************************************
8130 ****************************************************************************/
8131 static void x86emuOp_mov_word_DI_IMM(u8
X86EMU_UNUSED(op1
))
8136 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8137 DECODE_PRINTF("MOV\tEDI,");
8138 srcval
= fetch_long_imm();
8140 DECODE_PRINTF("MOV\tDI,");
8141 srcval
= fetch_word_imm();
8143 DECODE_PRINTF2("%x\n", srcval
);
8145 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8146 M
.x86
.R_EDI
= srcval
;
8148 M
.x86
.R_DI
= (u16
)srcval
;
8150 DECODE_CLEAR_SEGOVR();
8154 /* used by opcodes c0, d0, and d2. */
8155 static u8(*opcD0_byte_operation
[])(u8 d
, u8 s
) =
8163 shl_byte
, /* sal_byte === shl_byte by definition */
8167 /****************************************************************************
8170 ****************************************************************************/
8171 static void x86emuOp_opcC0_byte_RM_MEM(u8
X86EMU_UNUSED(op1
))
8180 * Yet another weirdo special case instruction format. Part of
8181 * the opcode held below in "RH". Doubly nested case would
8182 * result, except that the decoded instruction
8185 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8187 if (DEBUG_DECODE()) {
8188 /* XXX DECODE_PRINTF may be changed to something more
8189 general, so that it is important to leave the strings
8190 in the same format, even though the result is that the
8191 above test is done twice. */
8195 DECODE_PRINTF("ROL\t");
8198 DECODE_PRINTF("ROR\t");
8201 DECODE_PRINTF("RCL\t");
8204 DECODE_PRINTF("RCR\t");
8207 DECODE_PRINTF("SHL\t");
8210 DECODE_PRINTF("SHR\t");
8213 DECODE_PRINTF("SAL\t");
8216 DECODE_PRINTF("SAR\t");
8221 /* know operation, decode the mod byte to find the addressing
8225 DECODE_PRINTF("BYTE PTR ");
8226 destoffset
= decode_rm00_address(rl
);
8227 amt
= fetch_byte_imm();
8228 DECODE_PRINTF2(",%x\n", amt
);
8229 destval
= fetch_data_byte(destoffset
);
8231 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8232 store_data_byte(destoffset
, destval
);
8235 DECODE_PRINTF("BYTE PTR ");
8236 destoffset
= decode_rm01_address(rl
);
8237 amt
= fetch_byte_imm();
8238 DECODE_PRINTF2(",%x\n", amt
);
8239 destval
= fetch_data_byte(destoffset
);
8241 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8242 store_data_byte(destoffset
, destval
);
8245 DECODE_PRINTF("BYTE PTR ");
8246 destoffset
= decode_rm10_address(rl
);
8247 amt
= fetch_byte_imm();
8248 DECODE_PRINTF2(",%x\n", amt
);
8249 destval
= fetch_data_byte(destoffset
);
8251 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
8252 store_data_byte(destoffset
, destval
);
8254 case 3: /* register to register */
8255 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
8256 amt
= fetch_byte_imm();
8257 DECODE_PRINTF2(",%x\n", amt
);
8259 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
8263 DECODE_CLEAR_SEGOVR();
8267 /* used by opcodes c1, d1, and d3. */
8268 static u16(*opcD1_word_operation
[])(u16 s
, u8 d
) =
8276 shl_word
, /* sal_byte === shl_byte by definition */
8280 /* used by opcodes c1, d1, and d3. */
8281 static u32 (*opcD1_long_operation
[])(u32 s
, u8 d
) =
8289 shl_long
, /* sal_byte === shl_byte by definition */
8293 /****************************************************************************
8296 ****************************************************************************/
8297 static void x86emuOp_opcC1_word_RM_MEM(u8
X86EMU_UNUSED(op1
))
8304 * Yet another weirdo special case instruction format. Part of
8305 * the opcode held below in "RH". Doubly nested case would
8306 * result, except that the decoded instruction
8309 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8311 if (DEBUG_DECODE()) {
8312 /* XXX DECODE_PRINTF may be changed to something more
8313 general, so that it is important to leave the strings
8314 in the same format, even though the result is that the
8315 above test is done twice. */
8319 DECODE_PRINTF("ROL\t");
8322 DECODE_PRINTF("ROR\t");
8325 DECODE_PRINTF("RCL\t");
8328 DECODE_PRINTF("RCR\t");
8331 DECODE_PRINTF("SHL\t");
8334 DECODE_PRINTF("SHR\t");
8337 DECODE_PRINTF("SAL\t");
8340 DECODE_PRINTF("SAR\t");
8345 /* know operation, decode the mod byte to find the addressing
8349 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8352 DECODE_PRINTF("DWORD PTR ");
8353 destoffset
= decode_rm00_address(rl
);
8354 amt
= fetch_byte_imm();
8355 DECODE_PRINTF2(",%x\n", amt
);
8356 destval
= fetch_data_long(destoffset
);
8358 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8359 store_data_long(destoffset
, destval
);
8363 DECODE_PRINTF("WORD PTR ");
8364 destoffset
= decode_rm00_address(rl
);
8365 amt
= fetch_byte_imm();
8366 DECODE_PRINTF2(",%x\n", amt
);
8367 destval
= fetch_data_word(destoffset
);
8369 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8370 store_data_word(destoffset
, destval
);
8374 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8377 DECODE_PRINTF("DWORD PTR ");
8378 destoffset
= decode_rm01_address(rl
);
8379 amt
= fetch_byte_imm();
8380 DECODE_PRINTF2(",%x\n", amt
);
8381 destval
= fetch_data_long(destoffset
);
8383 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8384 store_data_long(destoffset
, destval
);
8388 DECODE_PRINTF("WORD PTR ");
8389 destoffset
= decode_rm01_address(rl
);
8390 amt
= fetch_byte_imm();
8391 DECODE_PRINTF2(",%x\n", amt
);
8392 destval
= fetch_data_word(destoffset
);
8394 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8395 store_data_word(destoffset
, destval
);
8399 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8402 DECODE_PRINTF("DWORD PTR ");
8403 destoffset
= decode_rm10_address(rl
);
8404 amt
= fetch_byte_imm();
8405 DECODE_PRINTF2(",%x\n", amt
);
8406 destval
= fetch_data_long(destoffset
);
8408 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
8409 store_data_long(destoffset
, destval
);
8413 DECODE_PRINTF("WORD PTR ");
8414 destoffset
= decode_rm10_address(rl
);
8415 amt
= fetch_byte_imm();
8416 DECODE_PRINTF2(",%x\n", amt
);
8417 destval
= fetch_data_word(destoffset
);
8419 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
8420 store_data_word(destoffset
, destval
);
8423 case 3: /* register to register */
8424 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8427 destreg
= DECODE_RM_LONG_REGISTER(rl
);
8428 amt
= fetch_byte_imm();
8429 DECODE_PRINTF2(",%x\n", amt
);
8431 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
8435 destreg
= DECODE_RM_WORD_REGISTER(rl
);
8436 amt
= fetch_byte_imm();
8437 DECODE_PRINTF2(",%x\n", amt
);
8439 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
8443 DECODE_CLEAR_SEGOVR();
8447 /****************************************************************************
8450 ****************************************************************************/
8451 static void x86emuOp_ret_near_IMM(u8
X86EMU_UNUSED(op1
))
8456 DECODE_PRINTF("RET\t");
8457 imm
= fetch_word_imm();
8458 DECODE_PRINTF2("%x\n", imm
);
8459 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8461 M
.x86
.R_IP
= pop_word();
8463 DECODE_CLEAR_SEGOVR();
8467 /****************************************************************************
8470 ****************************************************************************/
8471 static void x86emuOp_ret_near(u8
X86EMU_UNUSED(op1
))
8474 DECODE_PRINTF("RET\n");
8475 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8477 M
.x86
.R_IP
= pop_word();
8478 DECODE_CLEAR_SEGOVR();
8482 /****************************************************************************
8485 ****************************************************************************/
8486 static void x86emuOp_les_R_IMM(u8
X86EMU_UNUSED(op1
))
8493 DECODE_PRINTF("LES\t");
8494 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8497 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8499 srcoffset
= decode_rm00_address(rl
);
8500 DECODE_PRINTF("\n");
8502 *dstreg
= fetch_data_word(srcoffset
);
8503 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8506 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8508 srcoffset
= decode_rm01_address(rl
);
8509 DECODE_PRINTF("\n");
8511 *dstreg
= fetch_data_word(srcoffset
);
8512 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8515 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8517 srcoffset
= decode_rm10_address(rl
);
8518 DECODE_PRINTF("\n");
8520 *dstreg
= fetch_data_word(srcoffset
);
8521 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
8523 case 3: /* register to register */
8527 DECODE_CLEAR_SEGOVR();
8531 /****************************************************************************
8534 ****************************************************************************/
8535 static void x86emuOp_lds_R_IMM(u8
X86EMU_UNUSED(op1
))
8542 DECODE_PRINTF("LDS\t");
8543 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8546 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8548 srcoffset
= decode_rm00_address(rl
);
8549 DECODE_PRINTF("\n");
8551 *dstreg
= fetch_data_word(srcoffset
);
8552 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8555 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8557 srcoffset
= decode_rm01_address(rl
);
8558 DECODE_PRINTF("\n");
8560 *dstreg
= fetch_data_word(srcoffset
);
8561 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8564 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
8566 srcoffset
= decode_rm10_address(rl
);
8567 DECODE_PRINTF("\n");
8569 *dstreg
= fetch_data_word(srcoffset
);
8570 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
8572 case 3: /* register to register */
8576 DECODE_CLEAR_SEGOVR();
8580 /****************************************************************************
8583 ****************************************************************************/
8584 static void x86emuOp_mov_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
8592 DECODE_PRINTF("MOV\t");
8593 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8595 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8600 DECODE_PRINTF("BYTE PTR ");
8601 destoffset
= decode_rm00_address(rl
);
8602 imm
= fetch_byte_imm();
8603 DECODE_PRINTF2(",%2x\n", imm
);
8605 store_data_byte(destoffset
, imm
);
8608 DECODE_PRINTF("BYTE PTR ");
8609 destoffset
= decode_rm01_address(rl
);
8610 imm
= fetch_byte_imm();
8611 DECODE_PRINTF2(",%2x\n", imm
);
8613 store_data_byte(destoffset
, imm
);
8616 DECODE_PRINTF("BYTE PTR ");
8617 destoffset
= decode_rm10_address(rl
);
8618 imm
= fetch_byte_imm();
8619 DECODE_PRINTF2(",%2x\n", imm
);
8621 store_data_byte(destoffset
, imm
);
8623 case 3: /* register to register */
8624 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
8625 imm
= fetch_byte_imm();
8626 DECODE_PRINTF2(",%2x\n", imm
);
8631 DECODE_CLEAR_SEGOVR();
8635 /****************************************************************************
8638 ****************************************************************************/
8639 static void x86emuOp_mov_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
8645 DECODE_PRINTF("MOV\t");
8646 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8648 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8653 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8656 DECODE_PRINTF("DWORD PTR ");
8657 destoffset
= decode_rm00_address(rl
);
8658 imm
= fetch_long_imm();
8659 DECODE_PRINTF2(",%x\n", imm
);
8661 store_data_long(destoffset
, imm
);
8665 DECODE_PRINTF("WORD PTR ");
8666 destoffset
= decode_rm00_address(rl
);
8667 imm
= fetch_word_imm();
8668 DECODE_PRINTF2(",%x\n", imm
);
8670 store_data_word(destoffset
, imm
);
8674 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8677 DECODE_PRINTF("DWORD PTR ");
8678 destoffset
= decode_rm01_address(rl
);
8679 imm
= fetch_long_imm();
8680 DECODE_PRINTF2(",%x\n", imm
);
8682 store_data_long(destoffset
, imm
);
8686 DECODE_PRINTF("WORD PTR ");
8687 destoffset
= decode_rm01_address(rl
);
8688 imm
= fetch_word_imm();
8689 DECODE_PRINTF2(",%x\n", imm
);
8691 store_data_word(destoffset
, imm
);
8695 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8698 DECODE_PRINTF("DWORD PTR ");
8699 destoffset
= decode_rm10_address(rl
);
8700 imm
= fetch_long_imm();
8701 DECODE_PRINTF2(",%x\n", imm
);
8703 store_data_long(destoffset
, imm
);
8707 DECODE_PRINTF("WORD PTR ");
8708 destoffset
= decode_rm10_address(rl
);
8709 imm
= fetch_word_imm();
8710 DECODE_PRINTF2(",%x\n", imm
);
8712 store_data_word(destoffset
, imm
);
8715 case 3: /* register to register */
8716 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
8720 destreg
= DECODE_RM_LONG_REGISTER(rl
);
8721 imm
= fetch_long_imm();
8722 DECODE_PRINTF2(",%x\n", imm
);
8729 destreg
= DECODE_RM_WORD_REGISTER(rl
);
8730 imm
= fetch_word_imm();
8731 DECODE_PRINTF2(",%x\n", imm
);
8737 DECODE_CLEAR_SEGOVR();
8741 /****************************************************************************
8744 ****************************************************************************/
8745 static void x86emuOp_enter(u8
X86EMU_UNUSED(op1
))
8747 u16 local
,frame_pointer
;
8752 local
= fetch_word_imm();
8753 nesting
= fetch_byte_imm();
8754 DECODE_PRINTF2("ENTER %x\n", local
);
8755 DECODE_PRINTF2(",%x\n", nesting
);
8757 push_word(M
.x86
.R_BP
);
8758 frame_pointer
= M
.x86
.R_SP
;
8760 for (i
= 1; i
< nesting
; i
++) {
8762 push_word(fetch_data_word_abs(M
.x86
.R_SS
, M
.x86
.R_BP
));
8764 push_word(frame_pointer
);
8766 M
.x86
.R_BP
= frame_pointer
;
8767 M
.x86
.R_SP
= (u16
)(M
.x86
.R_SP
- local
);
8768 DECODE_CLEAR_SEGOVR();
8772 /****************************************************************************
8775 ****************************************************************************/
8776 static void x86emuOp_leave(u8
X86EMU_UNUSED(op1
))
8779 DECODE_PRINTF("LEAVE\n");
8781 M
.x86
.R_SP
= M
.x86
.R_BP
;
8782 M
.x86
.R_BP
= pop_word();
8783 DECODE_CLEAR_SEGOVR();
8787 /****************************************************************************
8790 ****************************************************************************/
8791 static void x86emuOp_ret_far_IMM(u8
X86EMU_UNUSED(op1
))
8796 DECODE_PRINTF("RETF\t");
8797 imm
= fetch_word_imm();
8798 DECODE_PRINTF2("%x\n", imm
);
8799 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8801 M
.x86
.R_IP
= pop_word();
8802 M
.x86
.R_CS
= pop_word();
8804 DECODE_CLEAR_SEGOVR();
8808 /****************************************************************************
8811 ****************************************************************************/
8812 static void x86emuOp_ret_far(u8
X86EMU_UNUSED(op1
))
8815 DECODE_PRINTF("RETF\n");
8816 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
8818 M
.x86
.R_IP
= pop_word();
8819 M
.x86
.R_CS
= pop_word();
8820 DECODE_CLEAR_SEGOVR();
8824 /****************************************************************************
8827 ****************************************************************************/
8828 static void x86emuOp_int3(u8
X86EMU_UNUSED(op1
))
8831 DECODE_PRINTF("INT 3\n");
8833 if (_X86EMU_intrTab
[3]) {
8834 (*_X86EMU_intrTab
[3])(3);
8836 push_word((u16
)M
.x86
.R_FLG
);
8839 push_word(M
.x86
.R_CS
);
8840 M
.x86
.R_CS
= mem_access_word(3 * 4 + 2);
8841 push_word(M
.x86
.R_IP
);
8842 M
.x86
.R_IP
= mem_access_word(3 * 4);
8844 DECODE_CLEAR_SEGOVR();
8848 /****************************************************************************
8851 ****************************************************************************/
8852 static void x86emuOp_int_IMM(u8
X86EMU_UNUSED(op1
))
8857 DECODE_PRINTF("INT\t");
8858 intnum
= fetch_byte_imm();
8859 DECODE_PRINTF2("%x\n", intnum
);
8861 if (_X86EMU_intrTab
[intnum
]) {
8862 (*_X86EMU_intrTab
[intnum
])(intnum
);
8864 push_word((u16
)M
.x86
.R_FLG
);
8867 push_word(M
.x86
.R_CS
);
8868 M
.x86
.R_CS
= mem_access_word(intnum
* 4 + 2);
8869 push_word(M
.x86
.R_IP
);
8870 M
.x86
.R_IP
= mem_access_word(intnum
* 4);
8872 DECODE_CLEAR_SEGOVR();
8876 /****************************************************************************
8879 ****************************************************************************/
8880 static void x86emuOp_into(u8
X86EMU_UNUSED(op1
))
8883 DECODE_PRINTF("INTO\n");
8885 if (ACCESS_FLAG(F_OF
)) {
8886 if (_X86EMU_intrTab
[4]) {
8887 (*_X86EMU_intrTab
[4])(4);
8889 push_word((u16
)M
.x86
.R_FLG
);
8892 push_word(M
.x86
.R_CS
);
8893 M
.x86
.R_CS
= mem_access_word(4 * 4 + 2);
8894 push_word(M
.x86
.R_IP
);
8895 M
.x86
.R_IP
= mem_access_word(4 * 4);
8898 DECODE_CLEAR_SEGOVR();
8902 /****************************************************************************
8905 ****************************************************************************/
8906 static void x86emuOp_iret(u8
X86EMU_UNUSED(op1
))
8909 DECODE_PRINTF("IRET\n");
8913 M
.x86
.R_IP
= pop_word();
8914 M
.x86
.R_CS
= pop_word();
8915 M
.x86
.R_FLG
= pop_word();
8916 DECODE_CLEAR_SEGOVR();
8920 /****************************************************************************
8923 ****************************************************************************/
8924 static void x86emuOp_opcD0_byte_RM_1(u8
X86EMU_UNUSED(op1
))
8932 * Yet another weirdo special case instruction format. Part of
8933 * the opcode held below in "RH". Doubly nested case would
8934 * result, except that the decoded instruction
8937 FETCH_DECODE_MODRM(mod
, rh
, rl
);
8939 if (DEBUG_DECODE()) {
8940 /* XXX DECODE_PRINTF may be changed to something more
8941 general, so that it is important to leave the strings
8942 in the same format, even though the result is that the
8943 above test is done twice. */
8946 DECODE_PRINTF("ROL\t");
8949 DECODE_PRINTF("ROR\t");
8952 DECODE_PRINTF("RCL\t");
8955 DECODE_PRINTF("RCR\t");
8958 DECODE_PRINTF("SHL\t");
8961 DECODE_PRINTF("SHR\t");
8964 DECODE_PRINTF("SAL\t");
8967 DECODE_PRINTF("SAR\t");
8972 /* know operation, decode the mod byte to find the addressing
8976 DECODE_PRINTF("BYTE PTR ");
8977 destoffset
= decode_rm00_address(rl
);
8978 DECODE_PRINTF(",1\n");
8979 destval
= fetch_data_byte(destoffset
);
8981 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
8982 store_data_byte(destoffset
, destval
);
8985 DECODE_PRINTF("BYTE PTR ");
8986 destoffset
= decode_rm01_address(rl
);
8987 DECODE_PRINTF(",1\n");
8988 destval
= fetch_data_byte(destoffset
);
8990 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
8991 store_data_byte(destoffset
, destval
);
8994 DECODE_PRINTF("BYTE PTR ");
8995 destoffset
= decode_rm10_address(rl
);
8996 DECODE_PRINTF(",1\n");
8997 destval
= fetch_data_byte(destoffset
);
8999 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
9000 store_data_byte(destoffset
, destval
);
9002 case 3: /* register to register */
9003 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
9004 DECODE_PRINTF(",1\n");
9006 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, 1);
9010 DECODE_CLEAR_SEGOVR();
9014 /****************************************************************************
9017 ****************************************************************************/
9018 static void x86emuOp_opcD1_word_RM_1(u8
X86EMU_UNUSED(op1
))
9024 * Yet another weirdo special case instruction format. Part of
9025 * the opcode held below in "RH". Doubly nested case would
9026 * result, except that the decoded instruction
9029 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9031 if (DEBUG_DECODE()) {
9032 /* XXX DECODE_PRINTF may be changed to something more
9033 general, so that it is important to leave the strings
9034 in the same format, even though the result is that the
9035 above test is done twice. */
9038 DECODE_PRINTF("ROL\t");
9041 DECODE_PRINTF("ROR\t");
9044 DECODE_PRINTF("RCL\t");
9047 DECODE_PRINTF("RCR\t");
9050 DECODE_PRINTF("SHL\t");
9053 DECODE_PRINTF("SHR\t");
9056 DECODE_PRINTF("SAL\t");
9059 DECODE_PRINTF("SAR\t");
9064 /* know operation, decode the mod byte to find the addressing
9068 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9071 DECODE_PRINTF("DWORD PTR ");
9072 destoffset
= decode_rm00_address(rl
);
9073 DECODE_PRINTF(",1\n");
9074 destval
= fetch_data_long(destoffset
);
9076 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9077 store_data_long(destoffset
, destval
);
9081 DECODE_PRINTF("WORD PTR ");
9082 destoffset
= decode_rm00_address(rl
);
9083 DECODE_PRINTF(",1\n");
9084 destval
= fetch_data_word(destoffset
);
9086 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9087 store_data_word(destoffset
, destval
);
9091 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9094 DECODE_PRINTF("DWORD PTR ");
9095 destoffset
= decode_rm01_address(rl
);
9096 DECODE_PRINTF(",1\n");
9097 destval
= fetch_data_long(destoffset
);
9099 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9100 store_data_long(destoffset
, destval
);
9104 DECODE_PRINTF("WORD PTR ");
9105 destoffset
= decode_rm01_address(rl
);
9106 DECODE_PRINTF(",1\n");
9107 destval
= fetch_data_word(destoffset
);
9109 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9110 store_data_word(destoffset
, destval
);
9114 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9117 DECODE_PRINTF("DWORD PTR ");
9118 destoffset
= decode_rm10_address(rl
);
9119 DECODE_PRINTF(",1\n");
9120 destval
= fetch_data_long(destoffset
);
9122 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
9123 store_data_long(destoffset
, destval
);
9127 DECODE_PRINTF("BYTE PTR ");
9128 destoffset
= decode_rm10_address(rl
);
9129 DECODE_PRINTF(",1\n");
9130 destval
= fetch_data_word(destoffset
);
9132 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
9133 store_data_word(destoffset
, destval
);
9136 case 3: /* register to register */
9137 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9141 destreg
= DECODE_RM_LONG_REGISTER(rl
);
9142 DECODE_PRINTF(",1\n");
9144 destval
= (*opcD1_long_operation
[rh
]) (*destreg
, 1);
9150 destreg
= DECODE_RM_WORD_REGISTER(rl
);
9151 DECODE_PRINTF(",1\n");
9153 destval
= (*opcD1_word_operation
[rh
]) (*destreg
, 1);
9158 DECODE_CLEAR_SEGOVR();
9162 /****************************************************************************
9165 ****************************************************************************/
9166 static void x86emuOp_opcD2_byte_RM_CL(u8
X86EMU_UNUSED(op1
))
9175 * Yet another weirdo special case instruction format. Part of
9176 * the opcode held below in "RH". Doubly nested case would
9177 * result, except that the decoded instruction
9180 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9182 if (DEBUG_DECODE()) {
9183 /* XXX DECODE_PRINTF may be changed to something more
9184 general, so that it is important to leave the strings
9185 in the same format, even though the result is that the
9186 above test is done twice. */
9189 DECODE_PRINTF("ROL\t");
9192 DECODE_PRINTF("ROR\t");
9195 DECODE_PRINTF("RCL\t");
9198 DECODE_PRINTF("RCR\t");
9201 DECODE_PRINTF("SHL\t");
9204 DECODE_PRINTF("SHR\t");
9207 DECODE_PRINTF("SAL\t");
9210 DECODE_PRINTF("SAR\t");
9215 /* know operation, decode the mod byte to find the addressing
9220 DECODE_PRINTF("BYTE PTR ");
9221 destoffset
= decode_rm00_address(rl
);
9222 DECODE_PRINTF(",CL\n");
9223 destval
= fetch_data_byte(destoffset
);
9225 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9226 store_data_byte(destoffset
, destval
);
9229 DECODE_PRINTF("BYTE PTR ");
9230 destoffset
= decode_rm01_address(rl
);
9231 DECODE_PRINTF(",CL\n");
9232 destval
= fetch_data_byte(destoffset
);
9234 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9235 store_data_byte(destoffset
, destval
);
9238 DECODE_PRINTF("BYTE PTR ");
9239 destoffset
= decode_rm10_address(rl
);
9240 DECODE_PRINTF(",CL\n");
9241 destval
= fetch_data_byte(destoffset
);
9243 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
9244 store_data_byte(destoffset
, destval
);
9246 case 3: /* register to register */
9247 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
9248 DECODE_PRINTF(",CL\n");
9250 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
9254 DECODE_CLEAR_SEGOVR();
9258 /****************************************************************************
9261 ****************************************************************************/
9262 static void x86emuOp_opcD3_word_RM_CL(u8
X86EMU_UNUSED(op1
))
9269 * Yet another weirdo special case instruction format. Part of
9270 * the opcode held below in "RH". Doubly nested case would
9271 * result, except that the decoded instruction
9274 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9276 if (DEBUG_DECODE()) {
9277 /* XXX DECODE_PRINTF may be changed to something more
9278 general, so that it is important to leave the strings
9279 in the same format, even though the result is that the
9280 above test is done twice. */
9283 DECODE_PRINTF("ROL\t");
9286 DECODE_PRINTF("ROR\t");
9289 DECODE_PRINTF("RCL\t");
9292 DECODE_PRINTF("RCR\t");
9295 DECODE_PRINTF("SHL\t");
9298 DECODE_PRINTF("SHR\t");
9301 DECODE_PRINTF("SAL\t");
9304 DECODE_PRINTF("SAR\t");
9309 /* know operation, decode the mod byte to find the addressing
9314 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9317 DECODE_PRINTF("DWORD PTR ");
9318 destoffset
= decode_rm00_address(rl
);
9319 DECODE_PRINTF(",CL\n");
9320 destval
= fetch_data_long(destoffset
);
9322 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9323 store_data_long(destoffset
, destval
);
9327 DECODE_PRINTF("WORD PTR ");
9328 destoffset
= decode_rm00_address(rl
);
9329 DECODE_PRINTF(",CL\n");
9330 destval
= fetch_data_word(destoffset
);
9332 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9333 store_data_word(destoffset
, destval
);
9337 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9340 DECODE_PRINTF("DWORD PTR ");
9341 destoffset
= decode_rm01_address(rl
);
9342 DECODE_PRINTF(",CL\n");
9343 destval
= fetch_data_long(destoffset
);
9345 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9346 store_data_long(destoffset
, destval
);
9350 DECODE_PRINTF("WORD PTR ");
9351 destoffset
= decode_rm01_address(rl
);
9352 DECODE_PRINTF(",CL\n");
9353 destval
= fetch_data_word(destoffset
);
9355 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9356 store_data_word(destoffset
, destval
);
9360 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9363 DECODE_PRINTF("DWORD PTR ");
9364 destoffset
= decode_rm10_address(rl
);
9365 DECODE_PRINTF(",CL\n");
9366 destval
= fetch_data_long(destoffset
);
9368 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
9369 store_data_long(destoffset
, destval
);
9373 DECODE_PRINTF("WORD PTR ");
9374 destoffset
= decode_rm10_address(rl
);
9375 DECODE_PRINTF(",CL\n");
9376 destval
= fetch_data_word(destoffset
);
9378 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
9379 store_data_word(destoffset
, destval
);
9382 case 3: /* register to register */
9383 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9386 destreg
= DECODE_RM_LONG_REGISTER(rl
);
9387 DECODE_PRINTF(",CL\n");
9389 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
9393 destreg
= DECODE_RM_WORD_REGISTER(rl
);
9394 DECODE_PRINTF(",CL\n");
9396 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
9400 DECODE_CLEAR_SEGOVR();
9404 /****************************************************************************
9407 ****************************************************************************/
9408 static void x86emuOp_aam(u8
X86EMU_UNUSED(op1
))
9413 DECODE_PRINTF("AAM\n");
9414 a
= fetch_byte_imm(); /* this is a stupid encoding. */
9416 /* fix: add base decoding
9417 aam_word(u8 val, int base a) */
9418 DECODE_PRINTF("ERROR DECODING AAM\n");
9423 /* note the type change here --- returning AL and AH in AX. */
9424 M
.x86
.R_AX
= aam_word(M
.x86
.R_AL
);
9425 DECODE_CLEAR_SEGOVR();
9429 /****************************************************************************
9432 ****************************************************************************/
9433 static void x86emuOp_aad(u8
X86EMU_UNUSED(op1
))
9438 DECODE_PRINTF("AAD\n");
9439 a
= fetch_byte_imm();
9441 /* fix: add base decoding
9442 aad_word(u16 val, int base a) */
9443 DECODE_PRINTF("ERROR DECODING AAM\n");
9448 M
.x86
.R_AX
= aad_word(M
.x86
.R_AX
);
9449 DECODE_CLEAR_SEGOVR();
9453 /* opcode 0xd6 ILLEGAL OPCODE */
9455 /****************************************************************************
9458 ****************************************************************************/
9459 static void x86emuOp_xlat(u8
X86EMU_UNUSED(op1
))
9464 DECODE_PRINTF("XLAT\n");
9466 addr
= (u16
)(M
.x86
.R_BX
+ (u8
)M
.x86
.R_AL
);
9467 M
.x86
.R_AL
= fetch_data_byte(addr
);
9468 DECODE_CLEAR_SEGOVR();
9472 /* instuctions D8 .. DF are in i87_ops.c */
9474 /****************************************************************************
9477 ****************************************************************************/
9478 static void x86emuOp_loopne(u8
X86EMU_UNUSED(op1
))
9483 DECODE_PRINTF("LOOPNE\t");
9484 ip
= (s8
) fetch_byte_imm();
9485 ip
+= (s16
) M
.x86
.R_IP
;
9486 DECODE_PRINTF2("%04x\n", ip
);
9489 if (M
.x86
.R_CX
!= 0 && !ACCESS_FLAG(F_ZF
)) /* CX != 0 and !ZF */
9491 DECODE_CLEAR_SEGOVR();
9495 /****************************************************************************
9498 ****************************************************************************/
9499 static void x86emuOp_loope(u8
X86EMU_UNUSED(op1
))
9504 DECODE_PRINTF("LOOPE\t");
9505 ip
= (s8
) fetch_byte_imm();
9506 ip
+= (s16
) M
.x86
.R_IP
;
9507 DECODE_PRINTF2("%04x\n", ip
);
9510 if (M
.x86
.R_CX
!= 0 && ACCESS_FLAG(F_ZF
)) /* CX != 0 and ZF */
9512 DECODE_CLEAR_SEGOVR();
9516 /****************************************************************************
9519 ****************************************************************************/
9520 static void x86emuOp_loop(u8
X86EMU_UNUSED(op1
))
9525 DECODE_PRINTF("LOOP\t");
9526 ip
= (s8
) fetch_byte_imm();
9527 ip
+= (s16
) M
.x86
.R_IP
;
9528 DECODE_PRINTF2("%04x\n", ip
);
9531 if (M
.x86
.R_CX
!= 0)
9533 DECODE_CLEAR_SEGOVR();
9537 /****************************************************************************
9540 ****************************************************************************/
9541 static void x86emuOp_jcxz(u8
X86EMU_UNUSED(op1
))
9546 /* jump to byte offset if overflow flag is set */
9548 DECODE_PRINTF("JCXZ\t");
9549 offset
= (s8
)fetch_byte_imm();
9550 target
= (u16
)(M
.x86
.R_IP
+ offset
);
9551 DECODE_PRINTF2("%x\n", target
);
9553 if (M
.x86
.R_CX
== 0)
9554 M
.x86
.R_IP
= target
;
9555 DECODE_CLEAR_SEGOVR();
9559 /****************************************************************************
9562 ****************************************************************************/
9563 static void x86emuOp_in_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
9568 DECODE_PRINTF("IN\t");
9569 port
= (u8
) fetch_byte_imm();
9570 DECODE_PRINTF2("%x,AL\n", port
);
9572 M
.x86
.R_AL
= (*sys_inb
)(port
);
9573 DECODE_CLEAR_SEGOVR();
9577 /****************************************************************************
9580 ****************************************************************************/
9581 static void x86emuOp_in_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
9586 DECODE_PRINTF("IN\t");
9587 port
= (u8
) fetch_byte_imm();
9588 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9589 DECODE_PRINTF2("EAX,%x\n", port
);
9591 DECODE_PRINTF2("AX,%x\n", port
);
9594 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9595 M
.x86
.R_EAX
= (*sys_inl
)(port
);
9597 M
.x86
.R_AX
= (*sys_inw
)(port
);
9599 DECODE_CLEAR_SEGOVR();
9603 /****************************************************************************
9606 ****************************************************************************/
9607 static void x86emuOp_out_byte_IMM_AL(u8
X86EMU_UNUSED(op1
))
9612 DECODE_PRINTF("OUT\t");
9613 port
= (u8
) fetch_byte_imm();
9614 DECODE_PRINTF2("%x,AL\n", port
);
9616 (*sys_outb
)(port
, M
.x86
.R_AL
);
9617 DECODE_CLEAR_SEGOVR();
9621 /****************************************************************************
9624 ****************************************************************************/
9625 static void x86emuOp_out_word_IMM_AX(u8
X86EMU_UNUSED(op1
))
9630 DECODE_PRINTF("OUT\t");
9631 port
= (u8
) fetch_byte_imm();
9632 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9633 DECODE_PRINTF2("%x,EAX\n", port
);
9635 DECODE_PRINTF2("%x,AX\n", port
);
9638 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9639 (*sys_outl
)(port
, M
.x86
.R_EAX
);
9641 (*sys_outw
)(port
, M
.x86
.R_AX
);
9643 DECODE_CLEAR_SEGOVR();
9647 /****************************************************************************
9650 ****************************************************************************/
9651 static void x86emuOp_call_near_IMM(u8
X86EMU_UNUSED(op1
))
9656 DECODE_PRINTF("CALL\t");
9657 ip
= (s16
) fetch_word_imm();
9658 ip
+= (s16
) M
.x86
.R_IP
; /* CHECK SIGN */
9659 DECODE_PRINTF2("%04x\n", (u16
)ip
);
9660 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip
, "");
9662 push_word(M
.x86
.R_IP
);
9664 DECODE_CLEAR_SEGOVR();
9668 /****************************************************************************
9671 ****************************************************************************/
9672 static void x86emuOp_jump_near_IMM(u8
X86EMU_UNUSED(op1
))
9677 DECODE_PRINTF("JMP\t");
9678 ip
= (s16
)fetch_word_imm();
9679 ip
+= (s16
)M
.x86
.R_IP
;
9680 DECODE_PRINTF2("%04x\n", (u16
)ip
);
9682 M
.x86
.R_IP
= (u16
)ip
;
9683 DECODE_CLEAR_SEGOVR();
9687 /****************************************************************************
9690 ****************************************************************************/
9691 static void x86emuOp_jump_far_IMM(u8
X86EMU_UNUSED(op1
))
9696 DECODE_PRINTF("JMP\tFAR ");
9697 ip
= fetch_word_imm();
9698 cs
= fetch_word_imm();
9699 DECODE_PRINTF2("%04x:", cs
);
9700 DECODE_PRINTF2("%04x\n", ip
);
9704 DECODE_CLEAR_SEGOVR();
9708 /****************************************************************************
9711 ****************************************************************************/
9712 static void x86emuOp_jump_byte_IMM(u8
X86EMU_UNUSED(op1
))
9718 DECODE_PRINTF("JMP\t");
9719 offset
= (s8
)fetch_byte_imm();
9720 target
= (u16
)(M
.x86
.R_IP
+ offset
);
9721 DECODE_PRINTF2("%x\n", target
);
9723 M
.x86
.R_IP
= target
;
9724 DECODE_CLEAR_SEGOVR();
9728 /****************************************************************************
9731 ****************************************************************************/
9732 static void x86emuOp_in_byte_AL_DX(u8
X86EMU_UNUSED(op1
))
9735 DECODE_PRINTF("IN\tAL,DX\n");
9737 M
.x86
.R_AL
= (*sys_inb
)(M
.x86
.R_DX
);
9738 DECODE_CLEAR_SEGOVR();
9742 /****************************************************************************
9745 ****************************************************************************/
9746 static void x86emuOp_in_word_AX_DX(u8
X86EMU_UNUSED(op1
))
9749 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9750 DECODE_PRINTF("IN\tEAX,DX\n");
9752 DECODE_PRINTF("IN\tAX,DX\n");
9755 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9756 M
.x86
.R_EAX
= (*sys_inl
)(M
.x86
.R_DX
);
9758 M
.x86
.R_AX
= (*sys_inw
)(M
.x86
.R_DX
);
9760 DECODE_CLEAR_SEGOVR();
9764 /****************************************************************************
9767 ****************************************************************************/
9768 static void x86emuOp_out_byte_DX_AL(u8
X86EMU_UNUSED(op1
))
9771 DECODE_PRINTF("OUT\tDX,AL\n");
9773 (*sys_outb
)(M
.x86
.R_DX
, M
.x86
.R_AL
);
9774 DECODE_CLEAR_SEGOVR();
9778 /****************************************************************************
9781 ****************************************************************************/
9782 static void x86emuOp_out_word_DX_AX(u8
X86EMU_UNUSED(op1
))
9785 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9786 DECODE_PRINTF("OUT\tDX,EAX\n");
9788 DECODE_PRINTF("OUT\tDX,AX\n");
9791 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
9792 (*sys_outl
)(M
.x86
.R_DX
, M
.x86
.R_EAX
);
9794 (*sys_outw
)(M
.x86
.R_DX
, M
.x86
.R_AX
);
9796 DECODE_CLEAR_SEGOVR();
9800 /****************************************************************************
9803 ****************************************************************************/
9804 static void x86emuOp_lock(u8
X86EMU_UNUSED(op1
))
9807 DECODE_PRINTF("LOCK:\n");
9809 DECODE_CLEAR_SEGOVR();
9813 /*opcode 0xf1 ILLEGAL OPERATION */
9815 /****************************************************************************
9818 ****************************************************************************/
9819 static void x86emuOp_repne(u8
X86EMU_UNUSED(op1
))
9822 DECODE_PRINTF("REPNE\n");
9824 M
.x86
.mode
|= SYSMODE_PREFIX_REPNE
;
9825 DECODE_CLEAR_SEGOVR();
9829 /****************************************************************************
9832 ****************************************************************************/
9833 static void x86emuOp_repe(u8
X86EMU_UNUSED(op1
))
9836 DECODE_PRINTF("REPE\n");
9838 M
.x86
.mode
|= SYSMODE_PREFIX_REPE
;
9839 DECODE_CLEAR_SEGOVR();
9843 /****************************************************************************
9846 ****************************************************************************/
9847 static void x86emuOp_halt(u8
X86EMU_UNUSED(op1
))
9850 DECODE_PRINTF("HALT\n");
9853 DECODE_CLEAR_SEGOVR();
9857 /****************************************************************************
9860 ****************************************************************************/
9861 static void x86emuOp_cmc(u8
X86EMU_UNUSED(op1
))
9863 /* complement the carry flag. */
9865 DECODE_PRINTF("CMC\n");
9868 DECODE_CLEAR_SEGOVR();
9872 /****************************************************************************
9875 ****************************************************************************/
9876 static void x86emuOp_opcF6_byte_RM(u8
X86EMU_UNUSED(op1
))
9883 /* long, drawn out code follows. Double switch for a total
9886 FETCH_DECODE_MODRM(mod
, rh
, rl
);
9888 case 0: /* mod=00 */
9890 case 0: /* test byte imm */
9891 DECODE_PRINTF("TEST\tBYTE PTR ");
9892 destoffset
= decode_rm00_address(rl
);
9894 srcval
= fetch_byte_imm();
9895 DECODE_PRINTF2("%02x\n", srcval
);
9896 destval
= fetch_data_byte(destoffset
);
9898 test_byte(destval
, srcval
);
9901 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9905 DECODE_PRINTF("NOT\tBYTE PTR ");
9906 destoffset
= decode_rm00_address(rl
);
9907 DECODE_PRINTF("\n");
9908 destval
= fetch_data_byte(destoffset
);
9910 destval
= not_byte(destval
);
9911 store_data_byte(destoffset
, destval
);
9914 DECODE_PRINTF("NEG\tBYTE PTR ");
9915 destoffset
= decode_rm00_address(rl
);
9916 DECODE_PRINTF("\n");
9917 destval
= fetch_data_byte(destoffset
);
9919 destval
= neg_byte(destval
);
9920 store_data_byte(destoffset
, destval
);
9923 DECODE_PRINTF("MUL\tBYTE PTR ");
9924 destoffset
= decode_rm00_address(rl
);
9925 DECODE_PRINTF("\n");
9926 destval
= fetch_data_byte(destoffset
);
9931 DECODE_PRINTF("IMUL\tBYTE PTR ");
9932 destoffset
= decode_rm00_address(rl
);
9933 DECODE_PRINTF("\n");
9934 destval
= fetch_data_byte(destoffset
);
9939 DECODE_PRINTF("DIV\tBYTE PTR ");
9940 destoffset
= decode_rm00_address(rl
);
9941 DECODE_PRINTF("\n");
9942 destval
= fetch_data_byte(destoffset
);
9947 DECODE_PRINTF("IDIV\tBYTE PTR ");
9948 destoffset
= decode_rm00_address(rl
);
9949 DECODE_PRINTF("\n");
9950 destval
= fetch_data_byte(destoffset
);
9955 break; /* end mod==00 */
9956 case 1: /* mod=01 */
9958 case 0: /* test byte imm */
9959 DECODE_PRINTF("TEST\tBYTE PTR ");
9960 destoffset
= decode_rm01_address(rl
);
9962 srcval
= fetch_byte_imm();
9963 DECODE_PRINTF2("%02x\n", srcval
);
9964 destval
= fetch_data_byte(destoffset
);
9966 test_byte(destval
, srcval
);
9969 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9973 DECODE_PRINTF("NOT\tBYTE PTR ");
9974 destoffset
= decode_rm01_address(rl
);
9975 DECODE_PRINTF("\n");
9976 destval
= fetch_data_byte(destoffset
);
9978 destval
= not_byte(destval
);
9979 store_data_byte(destoffset
, destval
);
9982 DECODE_PRINTF("NEG\tBYTE PTR ");
9983 destoffset
= decode_rm01_address(rl
);
9984 DECODE_PRINTF("\n");
9985 destval
= fetch_data_byte(destoffset
);
9987 destval
= neg_byte(destval
);
9988 store_data_byte(destoffset
, destval
);
9991 DECODE_PRINTF("MUL\tBYTE PTR ");
9992 destoffset
= decode_rm01_address(rl
);
9993 DECODE_PRINTF("\n");
9994 destval
= fetch_data_byte(destoffset
);
9999 DECODE_PRINTF("IMUL\tBYTE PTR ");
10000 destoffset
= decode_rm01_address(rl
);
10001 DECODE_PRINTF("\n");
10002 destval
= fetch_data_byte(destoffset
);
10004 imul_byte(destval
);
10007 DECODE_PRINTF("DIV\tBYTE PTR ");
10008 destoffset
= decode_rm01_address(rl
);
10009 DECODE_PRINTF("\n");
10010 destval
= fetch_data_byte(destoffset
);
10015 DECODE_PRINTF("IDIV\tBYTE PTR ");
10016 destoffset
= decode_rm01_address(rl
);
10017 DECODE_PRINTF("\n");
10018 destval
= fetch_data_byte(destoffset
);
10020 idiv_byte(destval
);
10023 break; /* end mod==01 */
10024 case 2: /* mod=10 */
10026 case 0: /* test byte imm */
10027 DECODE_PRINTF("TEST\tBYTE PTR ");
10028 destoffset
= decode_rm10_address(rl
);
10029 DECODE_PRINTF(",");
10030 srcval
= fetch_byte_imm();
10031 DECODE_PRINTF2("%02x\n", srcval
);
10032 destval
= fetch_data_byte(destoffset
);
10034 test_byte(destval
, srcval
);
10037 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10041 DECODE_PRINTF("NOT\tBYTE PTR ");
10042 destoffset
= decode_rm10_address(rl
);
10043 DECODE_PRINTF("\n");
10044 destval
= fetch_data_byte(destoffset
);
10046 destval
= not_byte(destval
);
10047 store_data_byte(destoffset
, destval
);
10050 DECODE_PRINTF("NEG\tBYTE PTR ");
10051 destoffset
= decode_rm10_address(rl
);
10052 DECODE_PRINTF("\n");
10053 destval
= fetch_data_byte(destoffset
);
10055 destval
= neg_byte(destval
);
10056 store_data_byte(destoffset
, destval
);
10059 DECODE_PRINTF("MUL\tBYTE PTR ");
10060 destoffset
= decode_rm10_address(rl
);
10061 DECODE_PRINTF("\n");
10062 destval
= fetch_data_byte(destoffset
);
10067 DECODE_PRINTF("IMUL\tBYTE PTR ");
10068 destoffset
= decode_rm10_address(rl
);
10069 DECODE_PRINTF("\n");
10070 destval
= fetch_data_byte(destoffset
);
10072 imul_byte(destval
);
10075 DECODE_PRINTF("DIV\tBYTE PTR ");
10076 destoffset
= decode_rm10_address(rl
);
10077 DECODE_PRINTF("\n");
10078 destval
= fetch_data_byte(destoffset
);
10083 DECODE_PRINTF("IDIV\tBYTE PTR ");
10084 destoffset
= decode_rm10_address(rl
);
10085 DECODE_PRINTF("\n");
10086 destval
= fetch_data_byte(destoffset
);
10088 idiv_byte(destval
);
10091 break; /* end mod==10 */
10092 case 3: /* mod=11 */
10094 case 0: /* test byte imm */
10095 DECODE_PRINTF("TEST\t");
10096 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10097 DECODE_PRINTF(",");
10098 srcval
= fetch_byte_imm();
10099 DECODE_PRINTF2("%02x\n", srcval
);
10101 test_byte(*destreg
, srcval
);
10104 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10108 DECODE_PRINTF("NOT\t");
10109 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10110 DECODE_PRINTF("\n");
10112 *destreg
= not_byte(*destreg
);
10115 DECODE_PRINTF("NEG\t");
10116 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10117 DECODE_PRINTF("\n");
10119 *destreg
= neg_byte(*destreg
);
10122 DECODE_PRINTF("MUL\t");
10123 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10124 DECODE_PRINTF("\n");
10126 mul_byte(*destreg
); /*!!! */
10129 DECODE_PRINTF("IMUL\t");
10130 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10131 DECODE_PRINTF("\n");
10133 imul_byte(*destreg
);
10136 DECODE_PRINTF("DIV\t");
10137 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10138 DECODE_PRINTF("\n");
10140 div_byte(*destreg
);
10143 DECODE_PRINTF("IDIV\t");
10144 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
10145 DECODE_PRINTF("\n");
10147 idiv_byte(*destreg
);
10150 break; /* end mod==11 */
10152 DECODE_CLEAR_SEGOVR();
10156 /****************************************************************************
10158 Handles opcode 0xf7
10159 ****************************************************************************/
10160 static void x86emuOp_opcF7_word_RM(u8
X86EMU_UNUSED(op1
))
10165 /* long, drawn out code follows. Double switch for a total
10168 FETCH_DECODE_MODRM(mod
, rh
, rl
);
10170 case 0: /* mod=00 */
10172 case 0: /* test word imm */
10173 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10174 u32 destval
,srcval
;
10176 DECODE_PRINTF("TEST\tDWORD PTR ");
10177 destoffset
= decode_rm00_address(rl
);
10178 DECODE_PRINTF(",");
10179 srcval
= fetch_long_imm();
10180 DECODE_PRINTF2("%x\n", srcval
);
10181 destval
= fetch_data_long(destoffset
);
10183 test_long(destval
, srcval
);
10185 u16 destval
,srcval
;
10187 DECODE_PRINTF("TEST\tWORD PTR ");
10188 destoffset
= decode_rm00_address(rl
);
10189 DECODE_PRINTF(",");
10190 srcval
= fetch_word_imm();
10191 DECODE_PRINTF2("%x\n", srcval
);
10192 destval
= fetch_data_word(destoffset
);
10194 test_word(destval
, srcval
);
10198 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10202 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10205 DECODE_PRINTF("NOT\tDWORD PTR ");
10206 destoffset
= decode_rm00_address(rl
);
10207 DECODE_PRINTF("\n");
10208 destval
= fetch_data_long(destoffset
);
10210 destval
= not_long(destval
);
10211 store_data_long(destoffset
, destval
);
10215 DECODE_PRINTF("NOT\tWORD PTR ");
10216 destoffset
= decode_rm00_address(rl
);
10217 DECODE_PRINTF("\n");
10218 destval
= fetch_data_word(destoffset
);
10220 destval
= not_word(destval
);
10221 store_data_word(destoffset
, destval
);
10225 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10228 DECODE_PRINTF("NEG\tDWORD PTR ");
10229 destoffset
= decode_rm00_address(rl
);
10230 DECODE_PRINTF("\n");
10231 destval
= fetch_data_long(destoffset
);
10233 destval
= neg_long(destval
);
10234 store_data_long(destoffset
, destval
);
10238 DECODE_PRINTF("NEG\tWORD PTR ");
10239 destoffset
= decode_rm00_address(rl
);
10240 DECODE_PRINTF("\n");
10241 destval
= fetch_data_word(destoffset
);
10243 destval
= neg_word(destval
);
10244 store_data_word(destoffset
, destval
);
10248 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10251 DECODE_PRINTF("MUL\tDWORD PTR ");
10252 destoffset
= decode_rm00_address(rl
);
10253 DECODE_PRINTF("\n");
10254 destval
= fetch_data_long(destoffset
);
10260 DECODE_PRINTF("MUL\tWORD PTR ");
10261 destoffset
= decode_rm00_address(rl
);
10262 DECODE_PRINTF("\n");
10263 destval
= fetch_data_word(destoffset
);
10269 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10272 DECODE_PRINTF("IMUL\tDWORD PTR ");
10273 destoffset
= decode_rm00_address(rl
);
10274 DECODE_PRINTF("\n");
10275 destval
= fetch_data_long(destoffset
);
10277 imul_long(destval
);
10281 DECODE_PRINTF("IMUL\tWORD PTR ");
10282 destoffset
= decode_rm00_address(rl
);
10283 DECODE_PRINTF("\n");
10284 destval
= fetch_data_word(destoffset
);
10286 imul_word(destval
);
10290 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10293 DECODE_PRINTF("DIV\tDWORD PTR ");
10294 destoffset
= decode_rm00_address(rl
);
10295 DECODE_PRINTF("\n");
10296 destval
= fetch_data_long(destoffset
);
10302 DECODE_PRINTF("DIV\tWORD PTR ");
10303 destoffset
= decode_rm00_address(rl
);
10304 DECODE_PRINTF("\n");
10305 destval
= fetch_data_word(destoffset
);
10311 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10314 DECODE_PRINTF("IDIV\tDWORD PTR ");
10315 destoffset
= decode_rm00_address(rl
);
10316 DECODE_PRINTF("\n");
10317 destval
= fetch_data_long(destoffset
);
10319 idiv_long(destval
);
10323 DECODE_PRINTF("IDIV\tWORD PTR ");
10324 destoffset
= decode_rm00_address(rl
);
10325 DECODE_PRINTF("\n");
10326 destval
= fetch_data_word(destoffset
);
10328 idiv_word(destval
);
10332 break; /* end mod==00 */
10333 case 1: /* mod=01 */
10335 case 0: /* test word imm */
10336 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10337 u32 destval
,srcval
;
10339 DECODE_PRINTF("TEST\tDWORD PTR ");
10340 destoffset
= decode_rm01_address(rl
);
10341 DECODE_PRINTF(",");
10342 srcval
= fetch_long_imm();
10343 DECODE_PRINTF2("%x\n", srcval
);
10344 destval
= fetch_data_long(destoffset
);
10346 test_long(destval
, srcval
);
10348 u16 destval
,srcval
;
10350 DECODE_PRINTF("TEST\tWORD PTR ");
10351 destoffset
= decode_rm01_address(rl
);
10352 DECODE_PRINTF(",");
10353 srcval
= fetch_word_imm();
10354 DECODE_PRINTF2("%x\n", srcval
);
10355 destval
= fetch_data_word(destoffset
);
10357 test_word(destval
, srcval
);
10361 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10365 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10368 DECODE_PRINTF("NOT\tDWORD PTR ");
10369 destoffset
= decode_rm01_address(rl
);
10370 DECODE_PRINTF("\n");
10371 destval
= fetch_data_long(destoffset
);
10373 destval
= not_long(destval
);
10374 store_data_long(destoffset
, destval
);
10378 DECODE_PRINTF("NOT\tWORD PTR ");
10379 destoffset
= decode_rm01_address(rl
);
10380 DECODE_PRINTF("\n");
10381 destval
= fetch_data_word(destoffset
);
10383 destval
= not_word(destval
);
10384 store_data_word(destoffset
, destval
);
10388 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10391 DECODE_PRINTF("NEG\tDWORD PTR ");
10392 destoffset
= decode_rm01_address(rl
);
10393 DECODE_PRINTF("\n");
10394 destval
= fetch_data_long(destoffset
);
10396 destval
= neg_long(destval
);
10397 store_data_long(destoffset
, destval
);
10401 DECODE_PRINTF("NEG\tWORD PTR ");
10402 destoffset
= decode_rm01_address(rl
);
10403 DECODE_PRINTF("\n");
10404 destval
= fetch_data_word(destoffset
);
10406 destval
= neg_word(destval
);
10407 store_data_word(destoffset
, destval
);
10411 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10414 DECODE_PRINTF("MUL\tDWORD PTR ");
10415 destoffset
= decode_rm01_address(rl
);
10416 DECODE_PRINTF("\n");
10417 destval
= fetch_data_long(destoffset
);
10423 DECODE_PRINTF("MUL\tWORD PTR ");
10424 destoffset
= decode_rm01_address(rl
);
10425 DECODE_PRINTF("\n");
10426 destval
= fetch_data_word(destoffset
);
10432 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10435 DECODE_PRINTF("IMUL\tDWORD PTR ");
10436 destoffset
= decode_rm01_address(rl
);
10437 DECODE_PRINTF("\n");
10438 destval
= fetch_data_long(destoffset
);
10440 imul_long(destval
);
10444 DECODE_PRINTF("IMUL\tWORD PTR ");
10445 destoffset
= decode_rm01_address(rl
);
10446 DECODE_PRINTF("\n");
10447 destval
= fetch_data_word(destoffset
);
10449 imul_word(destval
);
10453 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10456 DECODE_PRINTF("DIV\tDWORD PTR ");
10457 destoffset
= decode_rm01_address(rl
);
10458 DECODE_PRINTF("\n");
10459 destval
= fetch_data_long(destoffset
);
10465 DECODE_PRINTF("DIV\tWORD PTR ");
10466 destoffset
= decode_rm01_address(rl
);
10467 DECODE_PRINTF("\n");
10468 destval
= fetch_data_word(destoffset
);
10474 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10477 DECODE_PRINTF("IDIV\tDWORD PTR ");
10478 destoffset
= decode_rm01_address(rl
);
10479 DECODE_PRINTF("\n");
10480 destval
= fetch_data_long(destoffset
);
10482 idiv_long(destval
);
10486 DECODE_PRINTF("IDIV\tWORD PTR ");
10487 destoffset
= decode_rm01_address(rl
);
10488 DECODE_PRINTF("\n");
10489 destval
= fetch_data_word(destoffset
);
10491 idiv_word(destval
);
10495 break; /* end mod==01 */
10496 case 2: /* mod=10 */
10498 case 0: /* test word imm */
10499 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10500 u32 destval
,srcval
;
10502 DECODE_PRINTF("TEST\tDWORD PTR ");
10503 destoffset
= decode_rm10_address(rl
);
10504 DECODE_PRINTF(",");
10505 srcval
= fetch_long_imm();
10506 DECODE_PRINTF2("%x\n", srcval
);
10507 destval
= fetch_data_long(destoffset
);
10509 test_long(destval
, srcval
);
10511 u16 destval
,srcval
;
10513 DECODE_PRINTF("TEST\tWORD PTR ");
10514 destoffset
= decode_rm10_address(rl
);
10515 DECODE_PRINTF(",");
10516 srcval
= fetch_word_imm();
10517 DECODE_PRINTF2("%x\n", srcval
);
10518 destval
= fetch_data_word(destoffset
);
10520 test_word(destval
, srcval
);
10524 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10528 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10531 DECODE_PRINTF("NOT\tDWORD PTR ");
10532 destoffset
= decode_rm10_address(rl
);
10533 DECODE_PRINTF("\n");
10534 destval
= fetch_data_long(destoffset
);
10536 destval
= not_long(destval
);
10537 store_data_long(destoffset
, destval
);
10541 DECODE_PRINTF("NOT\tWORD PTR ");
10542 destoffset
= decode_rm10_address(rl
);
10543 DECODE_PRINTF("\n");
10544 destval
= fetch_data_word(destoffset
);
10546 destval
= not_word(destval
);
10547 store_data_word(destoffset
, destval
);
10551 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10554 DECODE_PRINTF("NEG\tDWORD PTR ");
10555 destoffset
= decode_rm10_address(rl
);
10556 DECODE_PRINTF("\n");
10557 destval
= fetch_data_long(destoffset
);
10559 destval
= neg_long(destval
);
10560 store_data_long(destoffset
, destval
);
10564 DECODE_PRINTF("NEG\tWORD PTR ");
10565 destoffset
= decode_rm10_address(rl
);
10566 DECODE_PRINTF("\n");
10567 destval
= fetch_data_word(destoffset
);
10569 destval
= neg_word(destval
);
10570 store_data_word(destoffset
, destval
);
10574 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10577 DECODE_PRINTF("MUL\tDWORD PTR ");
10578 destoffset
= decode_rm10_address(rl
);
10579 DECODE_PRINTF("\n");
10580 destval
= fetch_data_long(destoffset
);
10586 DECODE_PRINTF("MUL\tWORD PTR ");
10587 destoffset
= decode_rm10_address(rl
);
10588 DECODE_PRINTF("\n");
10589 destval
= fetch_data_word(destoffset
);
10595 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10598 DECODE_PRINTF("IMUL\tDWORD PTR ");
10599 destoffset
= decode_rm10_address(rl
);
10600 DECODE_PRINTF("\n");
10601 destval
= fetch_data_long(destoffset
);
10603 imul_long(destval
);
10607 DECODE_PRINTF("IMUL\tWORD PTR ");
10608 destoffset
= decode_rm10_address(rl
);
10609 DECODE_PRINTF("\n");
10610 destval
= fetch_data_word(destoffset
);
10612 imul_word(destval
);
10616 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10619 DECODE_PRINTF("DIV\tDWORD PTR ");
10620 destoffset
= decode_rm10_address(rl
);
10621 DECODE_PRINTF("\n");
10622 destval
= fetch_data_long(destoffset
);
10628 DECODE_PRINTF("DIV\tWORD PTR ");
10629 destoffset
= decode_rm10_address(rl
);
10630 DECODE_PRINTF("\n");
10631 destval
= fetch_data_word(destoffset
);
10637 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10640 DECODE_PRINTF("IDIV\tDWORD PTR ");
10641 destoffset
= decode_rm10_address(rl
);
10642 DECODE_PRINTF("\n");
10643 destval
= fetch_data_long(destoffset
);
10645 idiv_long(destval
);
10649 DECODE_PRINTF("IDIV\tWORD PTR ");
10650 destoffset
= decode_rm10_address(rl
);
10651 DECODE_PRINTF("\n");
10652 destval
= fetch_data_word(destoffset
);
10654 idiv_word(destval
);
10658 break; /* end mod==10 */
10659 case 3: /* mod=11 */
10661 case 0: /* test word imm */
10662 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10666 DECODE_PRINTF("TEST\t");
10667 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10668 DECODE_PRINTF(",");
10669 srcval
= fetch_long_imm();
10670 DECODE_PRINTF2("%x\n", srcval
);
10672 test_long(*destreg
, srcval
);
10677 DECODE_PRINTF("TEST\t");
10678 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10679 DECODE_PRINTF(",");
10680 srcval
= fetch_word_imm();
10681 DECODE_PRINTF2("%x\n", srcval
);
10683 test_word(*destreg
, srcval
);
10687 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10691 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10694 DECODE_PRINTF("NOT\t");
10695 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10696 DECODE_PRINTF("\n");
10698 *destreg
= not_long(*destreg
);
10702 DECODE_PRINTF("NOT\t");
10703 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10704 DECODE_PRINTF("\n");
10706 *destreg
= not_word(*destreg
);
10710 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10713 DECODE_PRINTF("NEG\t");
10714 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10715 DECODE_PRINTF("\n");
10717 *destreg
= neg_long(*destreg
);
10721 DECODE_PRINTF("NEG\t");
10722 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10723 DECODE_PRINTF("\n");
10725 *destreg
= neg_word(*destreg
);
10729 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10732 DECODE_PRINTF("MUL\t");
10733 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10734 DECODE_PRINTF("\n");
10736 mul_long(*destreg
); /*!!! */
10740 DECODE_PRINTF("MUL\t");
10741 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10742 DECODE_PRINTF("\n");
10744 mul_word(*destreg
); /*!!! */
10748 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10751 DECODE_PRINTF("IMUL\t");
10752 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10753 DECODE_PRINTF("\n");
10755 imul_long(*destreg
);
10759 DECODE_PRINTF("IMUL\t");
10760 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10761 DECODE_PRINTF("\n");
10763 imul_word(*destreg
);
10767 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10770 DECODE_PRINTF("DIV\t");
10771 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10772 DECODE_PRINTF("\n");
10774 div_long(*destreg
);
10778 DECODE_PRINTF("DIV\t");
10779 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10780 DECODE_PRINTF("\n");
10782 div_word(*destreg
);
10786 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
10789 DECODE_PRINTF("IDIV\t");
10790 destreg
= DECODE_RM_LONG_REGISTER(rl
);
10791 DECODE_PRINTF("\n");
10793 idiv_long(*destreg
);
10797 DECODE_PRINTF("IDIV\t");
10798 destreg
= DECODE_RM_WORD_REGISTER(rl
);
10799 DECODE_PRINTF("\n");
10801 idiv_word(*destreg
);
10805 break; /* end mod==11 */
10807 DECODE_CLEAR_SEGOVR();
10811 /****************************************************************************
10813 Handles opcode 0xf8
10814 ****************************************************************************/
10815 static void x86emuOp_clc(u8
X86EMU_UNUSED(op1
))
10817 /* clear the carry flag. */
10819 DECODE_PRINTF("CLC\n");
10822 DECODE_CLEAR_SEGOVR();
10826 /****************************************************************************
10828 Handles opcode 0xf9
10829 ****************************************************************************/
10830 static void x86emuOp_stc(u8
X86EMU_UNUSED(op1
))
10832 /* set the carry flag. */
10834 DECODE_PRINTF("STC\n");
10837 DECODE_CLEAR_SEGOVR();
10841 /****************************************************************************
10843 Handles opcode 0xfa
10844 ****************************************************************************/
10845 static void x86emuOp_cli(u8
X86EMU_UNUSED(op1
))
10847 /* clear interrupts. */
10849 DECODE_PRINTF("CLI\n");
10852 DECODE_CLEAR_SEGOVR();
10856 /****************************************************************************
10858 Handles opcode 0xfb
10859 ****************************************************************************/
10860 static void x86emuOp_sti(u8
X86EMU_UNUSED(op1
))
10862 /* enable interrupts. */
10864 DECODE_PRINTF("STI\n");
10867 DECODE_CLEAR_SEGOVR();
10871 /****************************************************************************
10873 Handles opcode 0xfc
10874 ****************************************************************************/
10875 static void x86emuOp_cld(u8
X86EMU_UNUSED(op1
))
10877 /* clear interrupts. */
10879 DECODE_PRINTF("CLD\n");
10882 DECODE_CLEAR_SEGOVR();
10886 /****************************************************************************
10888 Handles opcode 0xfd
10889 ****************************************************************************/
10890 static void x86emuOp_std(u8
X86EMU_UNUSED(op1
))
10892 /* clear interrupts. */
10894 DECODE_PRINTF("STD\n");
10897 DECODE_CLEAR_SEGOVR();
10901 /****************************************************************************
10903 Handles opcode 0xfe
10904 ****************************************************************************/
10905 static void x86emuOp_opcFE_byte_RM(u8
X86EMU_UNUSED(op1
))
10912 /* Yet another special case instruction. */
10914 FETCH_DECODE_MODRM(mod
, rh
, rl
);
10916 if (DEBUG_DECODE()) {
10917 /* XXX DECODE_PRINTF may be changed to something more
10918 general, so that it is important to leave the strings
10919 in the same format, even though the result is that the
10920 above test is done twice. */
10924 DECODE_PRINTF("INC\t");
10927 DECODE_PRINTF("DEC\t");
10935 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod
);
10943 DECODE_PRINTF("BYTE PTR ");
10944 destoffset
= decode_rm00_address(rl
);
10945 DECODE_PRINTF("\n");
10947 case 0: /* inc word ptr ... */
10948 destval
= fetch_data_byte(destoffset
);
10950 destval
= inc_byte(destval
);
10951 store_data_byte(destoffset
, destval
);
10953 case 1: /* dec word ptr ... */
10954 destval
= fetch_data_byte(destoffset
);
10956 destval
= dec_byte(destval
);
10957 store_data_byte(destoffset
, destval
);
10962 DECODE_PRINTF("BYTE PTR ");
10963 destoffset
= decode_rm01_address(rl
);
10964 DECODE_PRINTF("\n");
10967 destval
= fetch_data_byte(destoffset
);
10969 destval
= inc_byte(destval
);
10970 store_data_byte(destoffset
, destval
);
10973 destval
= fetch_data_byte(destoffset
);
10975 destval
= dec_byte(destval
);
10976 store_data_byte(destoffset
, destval
);
10981 DECODE_PRINTF("BYTE PTR ");
10982 destoffset
= decode_rm10_address(rl
);
10983 DECODE_PRINTF("\n");
10986 destval
= fetch_data_byte(destoffset
);
10988 destval
= inc_byte(destval
);
10989 store_data_byte(destoffset
, destval
);
10992 destval
= fetch_data_byte(destoffset
);
10994 destval
= dec_byte(destval
);
10995 store_data_byte(destoffset
, destval
);
11000 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
11001 DECODE_PRINTF("\n");
11005 *destreg
= inc_byte(*destreg
);
11009 *destreg
= dec_byte(*destreg
);
11014 DECODE_CLEAR_SEGOVR();
11018 /****************************************************************************
11020 Handles opcode 0xff
11021 ****************************************************************************/
11022 static void x86emuOp_opcFF_word_RM(u8
X86EMU_UNUSED(op1
))
11025 uint destoffset
= 0;
11027 u16 destval
,destval2
;
11029 /* Yet another special case instruction. */
11031 FETCH_DECODE_MODRM(mod
, rh
, rl
);
11033 if (DEBUG_DECODE()) {
11034 /* XXX DECODE_PRINTF may be changed to something more
11035 general, so that it is important to leave the strings
11036 in the same format, even though the result is that the
11037 above test is done twice. */
11041 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11042 DECODE_PRINTF("INC\tDWORD PTR ");
11044 DECODE_PRINTF("INC\tWORD PTR ");
11048 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11049 DECODE_PRINTF("DEC\tDWORD PTR ");
11051 DECODE_PRINTF("DEC\tWORD PTR ");
11055 DECODE_PRINTF("CALL\t");
11058 DECODE_PRINTF("CALL\tFAR ");
11061 DECODE_PRINTF("JMP\t");
11064 DECODE_PRINTF("JMP\tFAR ");
11067 DECODE_PRINTF("PUSH\t");
11070 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11078 destoffset
= decode_rm00_address(rl
);
11079 DECODE_PRINTF("\n");
11081 case 0: /* inc word ptr ... */
11082 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11085 destval
= fetch_data_long(destoffset
);
11087 destval
= inc_long(destval
);
11088 store_data_long(destoffset
, destval
);
11092 destval
= fetch_data_word(destoffset
);
11094 destval
= inc_word(destval
);
11095 store_data_word(destoffset
, destval
);
11098 case 1: /* dec word ptr ... */
11099 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11102 destval
= fetch_data_long(destoffset
);
11104 destval
= dec_long(destval
);
11105 store_data_long(destoffset
, destval
);
11109 destval
= fetch_data_word(destoffset
);
11111 destval
= dec_word(destval
);
11112 store_data_word(destoffset
, destval
);
11115 case 2: /* call word ptr ... */
11116 destval
= fetch_data_word(destoffset
);
11118 push_word(M
.x86
.R_IP
);
11119 M
.x86
.R_IP
= destval
;
11121 case 3: /* call far ptr ... */
11122 destval
= fetch_data_word(destoffset
);
11123 destval2
= fetch_data_word(destoffset
+ 2);
11125 push_word(M
.x86
.R_CS
);
11126 M
.x86
.R_CS
= destval2
;
11127 push_word(M
.x86
.R_IP
);
11128 M
.x86
.R_IP
= destval
;
11130 case 4: /* jmp word ptr ... */
11131 destval
= fetch_data_word(destoffset
);
11133 M
.x86
.R_IP
= destval
;
11135 case 5: /* jmp far ptr ... */
11136 destval
= fetch_data_word(destoffset
);
11137 destval2
= fetch_data_word(destoffset
+ 2);
11139 M
.x86
.R_IP
= destval
;
11140 M
.x86
.R_CS
= destval2
;
11142 case 6: /* push word ptr ... */
11143 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11146 destval
= fetch_data_long(destoffset
);
11148 push_long(destval
);
11152 destval
= fetch_data_word(destoffset
);
11154 push_word(destval
);
11160 destoffset
= decode_rm01_address(rl
);
11161 DECODE_PRINTF("\n");
11164 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11167 destval
= fetch_data_long(destoffset
);
11169 destval
= inc_long(destval
);
11170 store_data_long(destoffset
, destval
);
11174 destval
= fetch_data_word(destoffset
);
11176 destval
= inc_word(destval
);
11177 store_data_word(destoffset
, destval
);
11181 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11184 destval
= fetch_data_long(destoffset
);
11186 destval
= dec_long(destval
);
11187 store_data_long(destoffset
, destval
);
11191 destval
= fetch_data_word(destoffset
);
11193 destval
= dec_word(destval
);
11194 store_data_word(destoffset
, destval
);
11197 case 2: /* call word ptr ... */
11198 destval
= fetch_data_word(destoffset
);
11200 push_word(M
.x86
.R_IP
);
11201 M
.x86
.R_IP
= destval
;
11203 case 3: /* call far ptr ... */
11204 destval
= fetch_data_word(destoffset
);
11205 destval2
= fetch_data_word(destoffset
+ 2);
11207 push_word(M
.x86
.R_CS
);
11208 M
.x86
.R_CS
= destval2
;
11209 push_word(M
.x86
.R_IP
);
11210 M
.x86
.R_IP
= destval
;
11212 case 4: /* jmp word ptr ... */
11213 destval
= fetch_data_word(destoffset
);
11215 M
.x86
.R_IP
= destval
;
11217 case 5: /* jmp far ptr ... */
11218 destval
= fetch_data_word(destoffset
);
11219 destval2
= fetch_data_word(destoffset
+ 2);
11221 M
.x86
.R_IP
= destval
;
11222 M
.x86
.R_CS
= destval2
;
11224 case 6: /* push word ptr ... */
11225 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11228 destval
= fetch_data_long(destoffset
);
11230 push_long(destval
);
11234 destval
= fetch_data_word(destoffset
);
11236 push_word(destval
);
11242 destoffset
= decode_rm10_address(rl
);
11243 DECODE_PRINTF("\n");
11246 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11249 destval
= fetch_data_long(destoffset
);
11251 destval
= inc_long(destval
);
11252 store_data_long(destoffset
, destval
);
11256 destval
= fetch_data_word(destoffset
);
11258 destval
= inc_word(destval
);
11259 store_data_word(destoffset
, destval
);
11263 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11266 destval
= fetch_data_long(destoffset
);
11268 destval
= dec_long(destval
);
11269 store_data_long(destoffset
, destval
);
11273 destval
= fetch_data_word(destoffset
);
11275 destval
= dec_word(destval
);
11276 store_data_word(destoffset
, destval
);
11279 case 2: /* call word ptr ... */
11280 destval
= fetch_data_word(destoffset
);
11282 push_word(M
.x86
.R_IP
);
11283 M
.x86
.R_IP
= destval
;
11285 case 3: /* call far ptr ... */
11286 destval
= fetch_data_word(destoffset
);
11287 destval2
= fetch_data_word(destoffset
+ 2);
11289 push_word(M
.x86
.R_CS
);
11290 M
.x86
.R_CS
= destval2
;
11291 push_word(M
.x86
.R_IP
);
11292 M
.x86
.R_IP
= destval
;
11294 case 4: /* jmp word ptr ... */
11295 destval
= fetch_data_word(destoffset
);
11297 M
.x86
.R_IP
= destval
;
11299 case 5: /* jmp far ptr ... */
11300 destval
= fetch_data_word(destoffset
);
11301 destval2
= fetch_data_word(destoffset
+ 2);
11303 M
.x86
.R_IP
= destval
;
11304 M
.x86
.R_CS
= destval2
;
11306 case 6: /* push word ptr ... */
11307 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11310 destval
= fetch_data_long(destoffset
);
11312 push_long(destval
);
11316 destval
= fetch_data_word(destoffset
);
11318 push_word(destval
);
11326 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11329 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11330 DECODE_PRINTF("\n");
11332 *destreg
= inc_long(*destreg
);
11336 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11337 DECODE_PRINTF("\n");
11339 *destreg
= inc_word(*destreg
);
11343 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11346 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11347 DECODE_PRINTF("\n");
11349 *destreg
= dec_long(*destreg
);
11353 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11354 DECODE_PRINTF("\n");
11356 *destreg
= dec_word(*destreg
);
11359 case 2: /* call word ptr ... */
11360 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11361 DECODE_PRINTF("\n");
11363 push_word(M
.x86
.R_IP
);
11364 M
.x86
.R_IP
= *destreg
;
11366 case 3: /* jmp far ptr ... */
11367 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11372 case 4: /* jmp ... */
11373 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11374 DECODE_PRINTF("\n");
11376 M
.x86
.R_IP
= (u16
) (*destreg
);
11378 case 5: /* jmp far ptr ... */
11379 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11384 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
11387 destreg
= DECODE_RM_LONG_REGISTER(rl
);
11388 DECODE_PRINTF("\n");
11390 push_long(*destreg
);
11394 destreg
= DECODE_RM_WORD_REGISTER(rl
);
11395 DECODE_PRINTF("\n");
11397 push_word(*destreg
);
11403 DECODE_CLEAR_SEGOVR();
11407 /***************************************************************************
11408 * Single byte operation code table:
11409 **************************************************************************/
11410 void (*x86emu_optab
[256])(u8
) =
11412 /* 0x00 */ x86emuOp_add_byte_RM_R
,
11413 /* 0x01 */ x86emuOp_add_word_RM_R
,
11414 /* 0x02 */ x86emuOp_add_byte_R_RM
,
11415 /* 0x03 */ x86emuOp_add_word_R_RM
,
11416 /* 0x04 */ x86emuOp_add_byte_AL_IMM
,
11417 /* 0x05 */ x86emuOp_add_word_AX_IMM
,
11418 /* 0x06 */ x86emuOp_push_ES
,
11419 /* 0x07 */ x86emuOp_pop_ES
,
11421 /* 0x08 */ x86emuOp_or_byte_RM_R
,
11422 /* 0x09 */ x86emuOp_or_word_RM_R
,
11423 /* 0x0a */ x86emuOp_or_byte_R_RM
,
11424 /* 0x0b */ x86emuOp_or_word_R_RM
,
11425 /* 0x0c */ x86emuOp_or_byte_AL_IMM
,
11426 /* 0x0d */ x86emuOp_or_word_AX_IMM
,
11427 /* 0x0e */ x86emuOp_push_CS
,
11428 /* 0x0f */ x86emuOp_two_byte
,
11430 /* 0x10 */ x86emuOp_adc_byte_RM_R
,
11431 /* 0x11 */ x86emuOp_adc_word_RM_R
,
11432 /* 0x12 */ x86emuOp_adc_byte_R_RM
,
11433 /* 0x13 */ x86emuOp_adc_word_R_RM
,
11434 /* 0x14 */ x86emuOp_adc_byte_AL_IMM
,
11435 /* 0x15 */ x86emuOp_adc_word_AX_IMM
,
11436 /* 0x16 */ x86emuOp_push_SS
,
11437 /* 0x17 */ x86emuOp_pop_SS
,
11439 /* 0x18 */ x86emuOp_sbb_byte_RM_R
,
11440 /* 0x19 */ x86emuOp_sbb_word_RM_R
,
11441 /* 0x1a */ x86emuOp_sbb_byte_R_RM
,
11442 /* 0x1b */ x86emuOp_sbb_word_R_RM
,
11443 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM
,
11444 /* 0x1d */ x86emuOp_sbb_word_AX_IMM
,
11445 /* 0x1e */ x86emuOp_push_DS
,
11446 /* 0x1f */ x86emuOp_pop_DS
,
11448 /* 0x20 */ x86emuOp_and_byte_RM_R
,
11449 /* 0x21 */ x86emuOp_and_word_RM_R
,
11450 /* 0x22 */ x86emuOp_and_byte_R_RM
,
11451 /* 0x23 */ x86emuOp_and_word_R_RM
,
11452 /* 0x24 */ x86emuOp_and_byte_AL_IMM
,
11453 /* 0x25 */ x86emuOp_and_word_AX_IMM
,
11454 /* 0x26 */ x86emuOp_segovr_ES
,
11455 /* 0x27 */ x86emuOp_daa
,
11457 /* 0x28 */ x86emuOp_sub_byte_RM_R
,
11458 /* 0x29 */ x86emuOp_sub_word_RM_R
,
11459 /* 0x2a */ x86emuOp_sub_byte_R_RM
,
11460 /* 0x2b */ x86emuOp_sub_word_R_RM
,
11461 /* 0x2c */ x86emuOp_sub_byte_AL_IMM
,
11462 /* 0x2d */ x86emuOp_sub_word_AX_IMM
,
11463 /* 0x2e */ x86emuOp_segovr_CS
,
11464 /* 0x2f */ x86emuOp_das
,
11466 /* 0x30 */ x86emuOp_xor_byte_RM_R
,
11467 /* 0x31 */ x86emuOp_xor_word_RM_R
,
11468 /* 0x32 */ x86emuOp_xor_byte_R_RM
,
11469 /* 0x33 */ x86emuOp_xor_word_R_RM
,
11470 /* 0x34 */ x86emuOp_xor_byte_AL_IMM
,
11471 /* 0x35 */ x86emuOp_xor_word_AX_IMM
,
11472 /* 0x36 */ x86emuOp_segovr_SS
,
11473 /* 0x37 */ x86emuOp_aaa
,
11475 /* 0x38 */ x86emuOp_cmp_byte_RM_R
,
11476 /* 0x39 */ x86emuOp_cmp_word_RM_R
,
11477 /* 0x3a */ x86emuOp_cmp_byte_R_RM
,
11478 /* 0x3b */ x86emuOp_cmp_word_R_RM
,
11479 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM
,
11480 /* 0x3d */ x86emuOp_cmp_word_AX_IMM
,
11481 /* 0x3e */ x86emuOp_segovr_DS
,
11482 /* 0x3f */ x86emuOp_aas
,
11484 /* 0x40 */ x86emuOp_inc_AX
,
11485 /* 0x41 */ x86emuOp_inc_CX
,
11486 /* 0x42 */ x86emuOp_inc_DX
,
11487 /* 0x43 */ x86emuOp_inc_BX
,
11488 /* 0x44 */ x86emuOp_inc_SP
,
11489 /* 0x45 */ x86emuOp_inc_BP
,
11490 /* 0x46 */ x86emuOp_inc_SI
,
11491 /* 0x47 */ x86emuOp_inc_DI
,
11493 /* 0x48 */ x86emuOp_dec_AX
,
11494 /* 0x49 */ x86emuOp_dec_CX
,
11495 /* 0x4a */ x86emuOp_dec_DX
,
11496 /* 0x4b */ x86emuOp_dec_BX
,
11497 /* 0x4c */ x86emuOp_dec_SP
,
11498 /* 0x4d */ x86emuOp_dec_BP
,
11499 /* 0x4e */ x86emuOp_dec_SI
,
11500 /* 0x4f */ x86emuOp_dec_DI
,
11502 /* 0x50 */ x86emuOp_push_AX
,
11503 /* 0x51 */ x86emuOp_push_CX
,
11504 /* 0x52 */ x86emuOp_push_DX
,
11505 /* 0x53 */ x86emuOp_push_BX
,
11506 /* 0x54 */ x86emuOp_push_SP
,
11507 /* 0x55 */ x86emuOp_push_BP
,
11508 /* 0x56 */ x86emuOp_push_SI
,
11509 /* 0x57 */ x86emuOp_push_DI
,
11511 /* 0x58 */ x86emuOp_pop_AX
,
11512 /* 0x59 */ x86emuOp_pop_CX
,
11513 /* 0x5a */ x86emuOp_pop_DX
,
11514 /* 0x5b */ x86emuOp_pop_BX
,
11515 /* 0x5c */ x86emuOp_pop_SP
,
11516 /* 0x5d */ x86emuOp_pop_BP
,
11517 /* 0x5e */ x86emuOp_pop_SI
,
11518 /* 0x5f */ x86emuOp_pop_DI
,
11520 /* 0x60 */ x86emuOp_push_all
,
11521 /* 0x61 */ x86emuOp_pop_all
,
11522 /* 0x62 */ x86emuOp_illegal_op
, /* bound */
11523 /* 0x63 */ x86emuOp_illegal_op
, /* arpl */
11524 /* 0x64 */ x86emuOp_segovr_FS
,
11525 /* 0x65 */ x86emuOp_segovr_GS
,
11526 /* 0x66 */ x86emuOp_prefix_data
,
11527 /* 0x67 */ x86emuOp_prefix_addr
,
11529 /* 0x68 */ x86emuOp_push_word_IMM
,
11530 /* 0x69 */ x86emuOp_imul_word_IMM
,
11531 /* 0x6a */ x86emuOp_push_byte_IMM
,
11532 /* 0x6b */ x86emuOp_imul_byte_IMM
,
11533 /* 0x6c */ x86emuOp_ins_byte
,
11534 /* 0x6d */ x86emuOp_ins_word
,
11535 /* 0x6e */ x86emuOp_outs_byte
,
11536 /* 0x6f */ x86emuOp_outs_word
,
11538 /* 0x70 */ x86emuOp_jump_near_O
,
11539 /* 0x71 */ x86emuOp_jump_near_NO
,
11540 /* 0x72 */ x86emuOp_jump_near_B
,
11541 /* 0x73 */ x86emuOp_jump_near_NB
,
11542 /* 0x74 */ x86emuOp_jump_near_Z
,
11543 /* 0x75 */ x86emuOp_jump_near_NZ
,
11544 /* 0x76 */ x86emuOp_jump_near_BE
,
11545 /* 0x77 */ x86emuOp_jump_near_NBE
,
11547 /* 0x78 */ x86emuOp_jump_near_S
,
11548 /* 0x79 */ x86emuOp_jump_near_NS
,
11549 /* 0x7a */ x86emuOp_jump_near_P
,
11550 /* 0x7b */ x86emuOp_jump_near_NP
,
11551 /* 0x7c */ x86emuOp_jump_near_L
,
11552 /* 0x7d */ x86emuOp_jump_near_NL
,
11553 /* 0x7e */ x86emuOp_jump_near_LE
,
11554 /* 0x7f */ x86emuOp_jump_near_NLE
,
11556 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM
,
11557 /* 0x81 */ x86emuOp_opc81_word_RM_IMM
,
11558 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM
,
11559 /* 0x83 */ x86emuOp_opc83_word_RM_IMM
,
11560 /* 0x84 */ x86emuOp_test_byte_RM_R
,
11561 /* 0x85 */ x86emuOp_test_word_RM_R
,
11562 /* 0x86 */ x86emuOp_xchg_byte_RM_R
,
11563 /* 0x87 */ x86emuOp_xchg_word_RM_R
,
11565 /* 0x88 */ x86emuOp_mov_byte_RM_R
,
11566 /* 0x89 */ x86emuOp_mov_word_RM_R
,
11567 /* 0x8a */ x86emuOp_mov_byte_R_RM
,
11568 /* 0x8b */ x86emuOp_mov_word_R_RM
,
11569 /* 0x8c */ x86emuOp_mov_word_RM_SR
,
11570 /* 0x8d */ x86emuOp_lea_word_R_M
,
11571 /* 0x8e */ x86emuOp_mov_word_SR_RM
,
11572 /* 0x8f */ x86emuOp_pop_RM
,
11574 /* 0x90 */ x86emuOp_nop
,
11575 /* 0x91 */ x86emuOp_xchg_word_AX_CX
,
11576 /* 0x92 */ x86emuOp_xchg_word_AX_DX
,
11577 /* 0x93 */ x86emuOp_xchg_word_AX_BX
,
11578 /* 0x94 */ x86emuOp_xchg_word_AX_SP
,
11579 /* 0x95 */ x86emuOp_xchg_word_AX_BP
,
11580 /* 0x96 */ x86emuOp_xchg_word_AX_SI
,
11581 /* 0x97 */ x86emuOp_xchg_word_AX_DI
,
11583 /* 0x98 */ x86emuOp_cbw
,
11584 /* 0x99 */ x86emuOp_cwd
,
11585 /* 0x9a */ x86emuOp_call_far_IMM
,
11586 /* 0x9b */ x86emuOp_wait
,
11587 /* 0x9c */ x86emuOp_pushf_word
,
11588 /* 0x9d */ x86emuOp_popf_word
,
11589 /* 0x9e */ x86emuOp_sahf
,
11590 /* 0x9f */ x86emuOp_lahf
,
11592 /* 0xa0 */ x86emuOp_mov_AL_M_IMM
,
11593 /* 0xa1 */ x86emuOp_mov_AX_M_IMM
,
11594 /* 0xa2 */ x86emuOp_mov_M_AL_IMM
,
11595 /* 0xa3 */ x86emuOp_mov_M_AX_IMM
,
11596 /* 0xa4 */ x86emuOp_movs_byte
,
11597 /* 0xa5 */ x86emuOp_movs_word
,
11598 /* 0xa6 */ x86emuOp_cmps_byte
,
11599 /* 0xa7 */ x86emuOp_cmps_word
,
11600 /* 0xa8 */ x86emuOp_test_AL_IMM
,
11601 /* 0xa9 */ x86emuOp_test_AX_IMM
,
11602 /* 0xaa */ x86emuOp_stos_byte
,
11603 /* 0xab */ x86emuOp_stos_word
,
11604 /* 0xac */ x86emuOp_lods_byte
,
11605 /* 0xad */ x86emuOp_lods_word
,
11606 /* 0xac */ x86emuOp_scas_byte
,
11607 /* 0xad */ x86emuOp_scas_word
,
11610 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM
,
11611 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM
,
11612 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM
,
11613 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM
,
11614 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM
,
11615 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM
,
11616 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM
,
11617 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM
,
11619 /* 0xb8 */ x86emuOp_mov_word_AX_IMM
,
11620 /* 0xb9 */ x86emuOp_mov_word_CX_IMM
,
11621 /* 0xba */ x86emuOp_mov_word_DX_IMM
,
11622 /* 0xbb */ x86emuOp_mov_word_BX_IMM
,
11623 /* 0xbc */ x86emuOp_mov_word_SP_IMM
,
11624 /* 0xbd */ x86emuOp_mov_word_BP_IMM
,
11625 /* 0xbe */ x86emuOp_mov_word_SI_IMM
,
11626 /* 0xbf */ x86emuOp_mov_word_DI_IMM
,
11628 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM
,
11629 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM
,
11630 /* 0xc2 */ x86emuOp_ret_near_IMM
,
11631 /* 0xc3 */ x86emuOp_ret_near
,
11632 /* 0xc4 */ x86emuOp_les_R_IMM
,
11633 /* 0xc5 */ x86emuOp_lds_R_IMM
,
11634 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM
,
11635 /* 0xc7 */ x86emuOp_mov_word_RM_IMM
,
11636 /* 0xc8 */ x86emuOp_enter
,
11637 /* 0xc9 */ x86emuOp_leave
,
11638 /* 0xca */ x86emuOp_ret_far_IMM
,
11639 /* 0xcb */ x86emuOp_ret_far
,
11640 /* 0xcc */ x86emuOp_int3
,
11641 /* 0xcd */ x86emuOp_int_IMM
,
11642 /* 0xce */ x86emuOp_into
,
11643 /* 0xcf */ x86emuOp_iret
,
11645 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1
,
11646 /* 0xd1 */ x86emuOp_opcD1_word_RM_1
,
11647 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL
,
11648 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL
,
11649 /* 0xd4 */ x86emuOp_aam
,
11650 /* 0xd5 */ x86emuOp_aad
,
11651 /* 0xd6 */ x86emuOp_illegal_op
, /* Undocumented SETALC instruction */
11652 /* 0xd7 */ x86emuOp_xlat
,
11653 /* 0xd8 */ x86emuOp_esc_coprocess_d8
,
11654 /* 0xd9 */ x86emuOp_esc_coprocess_d9
,
11655 /* 0xda */ x86emuOp_esc_coprocess_da
,
11656 /* 0xdb */ x86emuOp_esc_coprocess_db
,
11657 /* 0xdc */ x86emuOp_esc_coprocess_dc
,
11658 /* 0xdd */ x86emuOp_esc_coprocess_dd
,
11659 /* 0xde */ x86emuOp_esc_coprocess_de
,
11660 /* 0xdf */ x86emuOp_esc_coprocess_df
,
11662 /* 0xe0 */ x86emuOp_loopne
,
11663 /* 0xe1 */ x86emuOp_loope
,
11664 /* 0xe2 */ x86emuOp_loop
,
11665 /* 0xe3 */ x86emuOp_jcxz
,
11666 /* 0xe4 */ x86emuOp_in_byte_AL_IMM
,
11667 /* 0xe5 */ x86emuOp_in_word_AX_IMM
,
11668 /* 0xe6 */ x86emuOp_out_byte_IMM_AL
,
11669 /* 0xe7 */ x86emuOp_out_word_IMM_AX
,
11671 /* 0xe8 */ x86emuOp_call_near_IMM
,
11672 /* 0xe9 */ x86emuOp_jump_near_IMM
,
11673 /* 0xea */ x86emuOp_jump_far_IMM
,
11674 /* 0xeb */ x86emuOp_jump_byte_IMM
,
11675 /* 0xec */ x86emuOp_in_byte_AL_DX
,
11676 /* 0xed */ x86emuOp_in_word_AX_DX
,
11677 /* 0xee */ x86emuOp_out_byte_DX_AL
,
11678 /* 0xef */ x86emuOp_out_word_DX_AX
,
11680 /* 0xf0 */ x86emuOp_lock
,
11681 /* 0xf1 */ x86emuOp_illegal_op
,
11682 /* 0xf2 */ x86emuOp_repne
,
11683 /* 0xf3 */ x86emuOp_repe
,
11684 /* 0xf4 */ x86emuOp_halt
,
11685 /* 0xf5 */ x86emuOp_cmc
,
11686 /* 0xf6 */ x86emuOp_opcF6_byte_RM
,
11687 /* 0xf7 */ x86emuOp_opcF7_word_RM
,
11689 /* 0xf8 */ x86emuOp_clc
,
11690 /* 0xf9 */ x86emuOp_stc
,
11691 /* 0xfa */ x86emuOp_cli
,
11692 /* 0xfb */ x86emuOp_sti
,
11693 /* 0xfc */ x86emuOp_cld
,
11694 /* 0xfd */ x86emuOp_std
,
11695 /* 0xfe */ x86emuOp_opcFE_byte_RM
,
11696 /* 0xff */ x86emuOp_opcFF_word_RM
,