1 /****************************************************************************
2 * Realmode X86 Emulator Library
4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
5 * Jason Jin <Jason.jin@freescale.com>
7 * Copyright (C) 1991-2004 SciTech Software, Inc.
8 * Copyright (C) David Mosberger-Tang
9 * Copyright (C) 1999 Egbert Eich
11 * ========================================================================
13 * Permission to use, copy, modify, distribute, and sell this software and
14 * its documentation for any purpose is hereby granted without fee,
15 * provided that the above copyright notice appear in all copies and that
16 * both that copyright notice and this permission notice appear in
17 * supporting documentation, and that the name of the authors not be used
18 * in advertising or publicity pertaining to distribution of the software
19 * without specific, written prior permission. The authors makes no
20 * representations about the suitability of this software for any purpose.
21 * It is provided "as is" without express or implied warranty.
23 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
27 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
28 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29 * PERFORMANCE OF THIS SOFTWARE.
31 * ========================================================================
35 * Developer: Kendall Bennett
37 * Description: This file includes subroutines to implement the decoding
38 * and emulation of all the x86 processor instructions.
40 * There are approximately 250 subroutines in here, which correspond
41 * to the 256 byte-"opcodes" found on the 8086. The table which
42 * dispatches this is found in the files optab.[ch].
44 * Each opcode proc has a comment preceeding it which gives it's table
45 * address. Several opcodes are missing (undefined) in the table.
47 * Each proc includes information for decoding (DECODE_PRINTF and
48 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
49 * functions (START_OF_INSTR, END_OF_INSTR).
51 * Many of the procedures are *VERY* similar in coding. This has
52 * allowed for a very large amount of code to be generated in a fairly
53 * short amount of time (i.e. cut, paste, and modify). The result is
54 * that much of the code below could have been folded into subroutines
55 * for a large reduction in size of this file. The downside would be
56 * that there would be a penalty in execution speed. The file could
57 * also have been *MUCH* larger by inlining certain functions which
58 * were called. This could have resulted even faster execution. The
59 * prime directive I used to decide whether to inline the code or to
60 * modularize it, was basically: 1) no unnecessary subroutine calls,
61 * 2) no routines more than about 200 lines in size, and 3) modularize
62 * any code that I might not get right the first time. The fetch_*
63 * subroutines fall into the latter category. The The decode_* fall
64 * into the second category. The coding of the "switch(mod){ .... }"
65 * in many of the subroutines below falls into the first category.
66 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
67 * subroutines are an especially glaring case of the third guideline.
68 * Since so much of the code is cloned from other modules (compare
69 * opcode #00 to opcode #01), making the basic operations subroutine
70 * calls is especially important; otherwise mistakes in coding an
71 * "add" would represent a nightmare in maintenance.
73 * Jason ported this file to u-boot. place all the function pointer in
74 * the got2 sector. Removed some opcode.
76 ****************************************************************************/
80 #if defined(CONFIG_BIOSEMU)
82 #include "x86emu/x86emui.h"
84 /*----------------------------- Implementation ----------------------------*/
86 /* constant arrays to do several instructions in just one function */
89 static char *x86emu_GenOpName
[8] = {
90 "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
93 /* used by several opcodes */
94 static u8 (*genop_byte_operation
[])(u8 d
, u8 s
) __attribute__ ((section(GOT2_TYPE
))) =
106 static u16 (*genop_word_operation
[])(u16 d
, u16 s
) __attribute__ ((section(GOT2_TYPE
))) =
118 static u32 (*genop_long_operation
[])(u32 d
, u32 s
) __attribute__ ((section(GOT2_TYPE
))) =
130 /* used by opcodes 80, c0, d0, and d2. */
131 static u8(*opcD0_byte_operation
[])(u8 d
, u8 s
) __attribute__ ((section(GOT2_TYPE
))) =
139 shl_byte
, /* sal_byte === shl_byte by definition */
143 /* used by opcodes c1, d1, and d3. */
144 static u16(*opcD1_word_operation
[])(u16 s
, u8 d
) __attribute__ ((section(GOT2_TYPE
))) =
152 shl_word
, /* sal_byte === shl_byte by definition */
156 /* used by opcodes c1, d1, and d3. */
157 static u32 (*opcD1_long_operation
[])(u32 s
, u8 d
) __attribute__ ((section(GOT2_TYPE
))) =
165 shl_long
, /* sal_byte === shl_byte by definition */
171 static char *opF6_names
[8] =
172 { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
176 /****************************************************************************
178 op1 - Instruction op code
181 Handles illegal opcodes.
182 ****************************************************************************/
183 void x86emuOp_illegal_op(
187 if (M
.x86
.R_SP
!= 0) {
188 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
190 DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
191 M
.x86
.R_CS
, M
.x86
.R_IP
-1,op1
));
195 /* If we get here, it means the stack pointer is back to zero
196 * so we are just returning from an emulator service call
197 * so therte is no need to display an error message. We trap
198 * the emulator with an 0xF1 opcode to finish the service
206 /****************************************************************************
208 Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
209 ****************************************************************************/
210 void x86emuOp_genop_byte_RM_R(u8 op1
)
214 u8
*destreg
, *srcreg
;
217 op1
= (op1
>> 3) & 0x7;
220 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
222 FETCH_DECODE_MODRM(mod
, rh
, rl
);
224 { destoffset
= decode_rmXX_address(mod
,rl
);
226 destval
= fetch_data_byte(destoffset
);
227 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
230 destval
= genop_byte_operation
[op1
](destval
, *srcreg
);
231 store_data_byte(destoffset
, destval
);
234 { /* register to register */
235 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
237 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
240 *destreg
= genop_byte_operation
[op1
](*destreg
, *srcreg
);
242 DECODE_CLEAR_SEGOVR();
246 /****************************************************************************
248 Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
249 ****************************************************************************/
250 void x86emuOp_genop_word_RM_R(u8 op1
)
255 op1
= (op1
>> 3) & 0x7;
258 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
260 FETCH_DECODE_MODRM(mod
, rh
, rl
);
263 destoffset
= decode_rmXX_address(mod
,rl
);
264 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
269 destval
= fetch_data_long(destoffset
);
270 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
273 destval
= genop_long_operation
[op1
](destval
, *srcreg
);
274 store_data_long(destoffset
, destval
);
280 destval
= fetch_data_word(destoffset
);
281 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
284 destval
= genop_word_operation
[op1
](destval
, *srcreg
);
285 store_data_word(destoffset
, destval
);
287 } else { /* register to register */
288 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
289 u32
*destreg
,*srcreg
;
291 destreg
= DECODE_RM_LONG_REGISTER(rl
);
293 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
296 *destreg
= genop_long_operation
[op1
](*destreg
, *srcreg
);
298 u16
*destreg
,*srcreg
;
300 destreg
= DECODE_RM_WORD_REGISTER(rl
);
302 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
305 *destreg
= genop_word_operation
[op1
](*destreg
, *srcreg
);
308 DECODE_CLEAR_SEGOVR();
312 /****************************************************************************
314 Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
315 ****************************************************************************/
316 void x86emuOp_genop_byte_R_RM(u8 op1
)
319 u8
*destreg
, *srcreg
;
323 op1
= (op1
>> 3) & 0x7;
326 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
328 FETCH_DECODE_MODRM(mod
, rh
, rl
);
330 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
332 srcoffset
= decode_rmXX_address(mod
,rl
);
333 srcval
= fetch_data_byte(srcoffset
);
334 } else { /* register to register */
335 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
337 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
342 *destreg
= genop_byte_operation
[op1
](*destreg
, srcval
);
344 DECODE_CLEAR_SEGOVR();
348 /****************************************************************************
350 Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
351 ****************************************************************************/
352 void x86emuOp_genop_word_R_RM(u8 op1
)
356 u32
*destreg32
, srcval
;
359 op1
= (op1
>> 3) & 0x7;
362 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
364 FETCH_DECODE_MODRM(mod
, rh
, rl
);
366 srcoffset
= decode_rmXX_address(mod
,rl
);
367 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
368 destreg32
= DECODE_RM_LONG_REGISTER(rh
);
370 srcval
= fetch_data_long(srcoffset
);
373 *destreg32
= genop_long_operation
[op1
](*destreg32
, srcval
);
375 destreg
= DECODE_RM_WORD_REGISTER(rh
);
377 srcval
= fetch_data_word(srcoffset
);
380 *destreg
= genop_word_operation
[op1
](*destreg
, srcval
);
382 } else { /* register to register */
383 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
385 destreg32
= DECODE_RM_LONG_REGISTER(rh
);
387 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
390 *destreg32
= genop_long_operation
[op1
](*destreg32
, *srcreg
);
393 destreg
= DECODE_RM_WORD_REGISTER(rh
);
395 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
398 *destreg
= genop_word_operation
[op1
](*destreg
, *srcreg
);
401 DECODE_CLEAR_SEGOVR();
405 /****************************************************************************
407 Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
408 ****************************************************************************/
409 void x86emuOp_genop_byte_AL_IMM(u8 op1
)
413 op1
= (op1
>> 3) & 0x7;
416 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
417 DECODE_PRINTF("\tAL,");
418 srcval
= fetch_byte_imm();
419 DECODE_PRINTF2("%x\n", srcval
);
421 M
.x86
.R_AL
= genop_byte_operation
[op1
](M
.x86
.R_AL
, srcval
);
422 DECODE_CLEAR_SEGOVR();
426 /****************************************************************************
428 Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
429 ****************************************************************************/
430 void x86emuOp_genop_word_AX_IMM(u8 op1
)
434 op1
= (op1
>> 3) & 0x7;
437 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
438 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
439 DECODE_PRINTF("\tEAX,");
440 srcval
= fetch_long_imm();
442 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
443 DECODE_PRINTF("\tAX,");
444 srcval
= fetch_word_imm();
446 DECODE_PRINTF2("%x\n", srcval
);
448 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
449 M
.x86
.R_EAX
= genop_long_operation
[op1
](M
.x86
.R_EAX
, srcval
);
451 M
.x86
.R_AX
= genop_word_operation
[op1
](M
.x86
.R_AX
, (u16
)srcval
);
453 DECODE_CLEAR_SEGOVR();
457 /****************************************************************************
460 ****************************************************************************/
461 void x86emuOp_push_ES(u8
X86EMU_UNUSED(op1
))
464 DECODE_PRINTF("PUSH\tES\n");
466 push_word(M
.x86
.R_ES
);
467 DECODE_CLEAR_SEGOVR();
471 /****************************************************************************
474 ****************************************************************************/
475 void x86emuOp_pop_ES(u8
X86EMU_UNUSED(op1
))
478 DECODE_PRINTF("POP\tES\n");
480 M
.x86
.R_ES
= pop_word();
481 DECODE_CLEAR_SEGOVR();
485 /****************************************************************************
488 ****************************************************************************/
489 void x86emuOp_push_CS(u8
X86EMU_UNUSED(op1
))
492 DECODE_PRINTF("PUSH\tCS\n");
494 push_word(M
.x86
.R_CS
);
495 DECODE_CLEAR_SEGOVR();
499 /****************************************************************************
501 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
502 ****************************************************************************/
503 void x86emuOp_two_byte(u8
X86EMU_UNUSED(op1
))
505 u8 op2
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
506 INC_DECODED_INST_LEN(1);
507 (*x86emu_optab2
[op2
])(op2
);
510 /****************************************************************************
513 ****************************************************************************/
514 void x86emuOp_push_SS(u8
X86EMU_UNUSED(op1
))
517 DECODE_PRINTF("PUSH\tSS\n");
519 push_word(M
.x86
.R_SS
);
520 DECODE_CLEAR_SEGOVR();
524 /****************************************************************************
527 ****************************************************************************/
528 void x86emuOp_pop_SS(u8
X86EMU_UNUSED(op1
))
531 DECODE_PRINTF("POP\tSS\n");
533 M
.x86
.R_SS
= pop_word();
534 DECODE_CLEAR_SEGOVR();
538 /****************************************************************************
541 ****************************************************************************/
542 void x86emuOp_push_DS(u8
X86EMU_UNUSED(op1
))
545 DECODE_PRINTF("PUSH\tDS\n");
547 push_word(M
.x86
.R_DS
);
548 DECODE_CLEAR_SEGOVR();
552 /****************************************************************************
555 ****************************************************************************/
556 void x86emuOp_pop_DS(u8
X86EMU_UNUSED(op1
))
559 DECODE_PRINTF("POP\tDS\n");
561 M
.x86
.R_DS
= pop_word();
562 DECODE_CLEAR_SEGOVR();
566 /****************************************************************************
569 ****************************************************************************/
570 void x86emuOp_segovr_ES(u8
X86EMU_UNUSED(op1
))
573 DECODE_PRINTF("ES:\n");
575 M
.x86
.mode
|= SYSMODE_SEGOVR_ES
;
577 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
578 * opcode subroutines we do not want to do this.
583 /****************************************************************************
586 ****************************************************************************/
587 void x86emuOp_daa(u8
X86EMU_UNUSED(op1
))
590 DECODE_PRINTF("DAA\n");
592 M
.x86
.R_AL
= daa_byte(M
.x86
.R_AL
);
593 DECODE_CLEAR_SEGOVR();
597 /****************************************************************************
600 ****************************************************************************/
601 void x86emuOp_segovr_CS(u8
X86EMU_UNUSED(op1
))
604 DECODE_PRINTF("CS:\n");
606 M
.x86
.mode
|= SYSMODE_SEGOVR_CS
;
607 /* note no DECODE_CLEAR_SEGOVR here. */
611 /****************************************************************************
614 ****************************************************************************/
615 void x86emuOp_das(u8
X86EMU_UNUSED(op1
))
618 DECODE_PRINTF("DAS\n");
620 M
.x86
.R_AL
= das_byte(M
.x86
.R_AL
);
621 DECODE_CLEAR_SEGOVR();
625 /****************************************************************************
628 ****************************************************************************/
629 void x86emuOp_segovr_SS(u8
X86EMU_UNUSED(op1
))
632 DECODE_PRINTF("SS:\n");
634 M
.x86
.mode
|= SYSMODE_SEGOVR_SS
;
635 /* no DECODE_CLEAR_SEGOVR ! */
639 /****************************************************************************
642 ****************************************************************************/
643 void x86emuOp_aaa(u8
X86EMU_UNUSED(op1
))
646 DECODE_PRINTF("AAA\n");
648 M
.x86
.R_AX
= aaa_word(M
.x86
.R_AX
);
649 DECODE_CLEAR_SEGOVR();
653 /****************************************************************************
656 ****************************************************************************/
657 void x86emuOp_segovr_DS(u8
X86EMU_UNUSED(op1
))
660 DECODE_PRINTF("DS:\n");
662 M
.x86
.mode
|= SYSMODE_SEGOVR_DS
;
663 /* NO DECODE_CLEAR_SEGOVR! */
667 /****************************************************************************
670 ****************************************************************************/
671 void x86emuOp_aas(u8
X86EMU_UNUSED(op1
))
674 DECODE_PRINTF("AAS\n");
676 M
.x86
.R_AX
= aas_word(M
.x86
.R_AX
);
677 DECODE_CLEAR_SEGOVR();
681 /****************************************************************************
683 Handles opcode 0x40 - 0x47
684 ****************************************************************************/
685 void x86emuOp_inc_register(u8 op1
)
689 DECODE_PRINTF("INC\t");
690 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
692 reg
= DECODE_RM_LONG_REGISTER(op1
);
695 *reg
= inc_long(*reg
);
698 reg
= DECODE_RM_WORD_REGISTER(op1
);
701 *reg
= inc_word(*reg
);
703 DECODE_CLEAR_SEGOVR();
707 /****************************************************************************
709 Handles opcode 0x48 - 0x4F
710 ****************************************************************************/
711 void x86emuOp_dec_register(u8 op1
)
715 DECODE_PRINTF("DEC\t");
716 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
718 reg
= DECODE_RM_LONG_REGISTER(op1
);
721 *reg
= dec_long(*reg
);
724 reg
= DECODE_RM_WORD_REGISTER(op1
);
727 *reg
= dec_word(*reg
);
729 DECODE_CLEAR_SEGOVR();
733 /****************************************************************************
735 Handles opcode 0x50 - 0x57
736 ****************************************************************************/
737 void x86emuOp_push_register(u8 op1
)
741 DECODE_PRINTF("PUSH\t");
742 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
744 reg
= DECODE_RM_LONG_REGISTER(op1
);
750 reg
= DECODE_RM_WORD_REGISTER(op1
);
755 DECODE_CLEAR_SEGOVR();
759 /****************************************************************************
761 Handles opcode 0x58 - 0x5F
762 ****************************************************************************/
763 void x86emuOp_pop_register(u8 op1
)
767 DECODE_PRINTF("POP\t");
768 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
770 reg
= DECODE_RM_LONG_REGISTER(op1
);
776 reg
= DECODE_RM_WORD_REGISTER(op1
);
781 DECODE_CLEAR_SEGOVR();
785 /****************************************************************************
788 ****************************************************************************/
789 void x86emuOp_push_all(u8
X86EMU_UNUSED(op1
))
792 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
793 DECODE_PRINTF("PUSHAD\n");
795 DECODE_PRINTF("PUSHA\n");
798 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
799 u32 old_sp
= M
.x86
.R_ESP
;
801 push_long(M
.x86
.R_EAX
);
802 push_long(M
.x86
.R_ECX
);
803 push_long(M
.x86
.R_EDX
);
804 push_long(M
.x86
.R_EBX
);
806 push_long(M
.x86
.R_EBP
);
807 push_long(M
.x86
.R_ESI
);
808 push_long(M
.x86
.R_EDI
);
810 u16 old_sp
= M
.x86
.R_SP
;
812 push_word(M
.x86
.R_AX
);
813 push_word(M
.x86
.R_CX
);
814 push_word(M
.x86
.R_DX
);
815 push_word(M
.x86
.R_BX
);
817 push_word(M
.x86
.R_BP
);
818 push_word(M
.x86
.R_SI
);
819 push_word(M
.x86
.R_DI
);
821 DECODE_CLEAR_SEGOVR();
825 /****************************************************************************
828 ****************************************************************************/
829 void x86emuOp_pop_all(u8
X86EMU_UNUSED(op1
))
832 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
833 DECODE_PRINTF("POPAD\n");
835 DECODE_PRINTF("POPA\n");
838 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
839 M
.x86
.R_EDI
= pop_long();
840 M
.x86
.R_ESI
= pop_long();
841 M
.x86
.R_EBP
= pop_long();
842 M
.x86
.R_ESP
+= 4; /* skip ESP */
843 M
.x86
.R_EBX
= pop_long();
844 M
.x86
.R_EDX
= pop_long();
845 M
.x86
.R_ECX
= pop_long();
846 M
.x86
.R_EAX
= pop_long();
848 M
.x86
.R_DI
= pop_word();
849 M
.x86
.R_SI
= pop_word();
850 M
.x86
.R_BP
= pop_word();
851 M
.x86
.R_SP
+= 2; /* skip SP */
852 M
.x86
.R_BX
= pop_word();
853 M
.x86
.R_DX
= pop_word();
854 M
.x86
.R_CX
= pop_word();
855 M
.x86
.R_AX
= pop_word();
857 DECODE_CLEAR_SEGOVR();
861 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
862 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
864 /****************************************************************************
867 ****************************************************************************/
868 void x86emuOp_segovr_FS(u8
X86EMU_UNUSED(op1
))
871 DECODE_PRINTF("FS:\n");
873 M
.x86
.mode
|= SYSMODE_SEGOVR_FS
;
875 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
876 * opcode subroutines we do not want to do this.
881 /****************************************************************************
884 ****************************************************************************/
885 void x86emuOp_segovr_GS(u8
X86EMU_UNUSED(op1
))
888 DECODE_PRINTF("GS:\n");
890 M
.x86
.mode
|= SYSMODE_SEGOVR_GS
;
892 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
893 * opcode subroutines we do not want to do this.
898 /****************************************************************************
900 Handles opcode 0x66 - prefix for 32-bit register
901 ****************************************************************************/
902 void x86emuOp_prefix_data(u8
X86EMU_UNUSED(op1
))
905 DECODE_PRINTF("DATA:\n");
907 M
.x86
.mode
|= SYSMODE_PREFIX_DATA
;
908 /* note no DECODE_CLEAR_SEGOVR here. */
912 /****************************************************************************
914 Handles opcode 0x67 - prefix for 32-bit address
915 ****************************************************************************/
916 void x86emuOp_prefix_addr(u8
X86EMU_UNUSED(op1
))
919 DECODE_PRINTF("ADDR:\n");
921 M
.x86
.mode
|= SYSMODE_PREFIX_ADDR
;
922 /* note no DECODE_CLEAR_SEGOVR here. */
926 /****************************************************************************
929 ****************************************************************************/
930 void x86emuOp_push_word_IMM(u8
X86EMU_UNUSED(op1
))
935 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
936 imm
= fetch_long_imm();
938 imm
= fetch_word_imm();
940 DECODE_PRINTF2("PUSH\t%x\n", imm
);
942 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
947 DECODE_CLEAR_SEGOVR();
951 /****************************************************************************
954 ****************************************************************************/
955 void x86emuOp_imul_word_IMM(u8
X86EMU_UNUSED(op1
))
961 DECODE_PRINTF("IMUL\t");
962 FETCH_DECODE_MODRM(mod
, rh
, rl
);
964 srcoffset
= decode_rmXX_address(mod
, rl
);
965 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
971 destreg
= DECODE_RM_LONG_REGISTER(rh
);
973 srcval
= fetch_data_long(srcoffset
);
974 imm
= fetch_long_imm();
975 DECODE_PRINTF2(",%d\n", (s32
)imm
);
977 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
978 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
979 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
986 *destreg
= (u32
)res_lo
;
993 destreg
= DECODE_RM_WORD_REGISTER(rh
);
995 srcval
= fetch_data_word(srcoffset
);
996 imm
= fetch_word_imm();
997 DECODE_PRINTF2(",%d\n", (s32
)imm
);
999 res
= (s16
)srcval
* (s16
)imm
;
1000 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1001 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1008 *destreg
= (u16
)res
;
1010 } else { /* register to register */
1011 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1012 u32
*destreg
,*srcreg
;
1016 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1018 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1019 imm
= fetch_long_imm();
1020 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1022 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
1023 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1024 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1031 *destreg
= (u32
)res_lo
;
1033 u16
*destreg
,*srcreg
;
1037 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1039 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1040 imm
= fetch_word_imm();
1041 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1042 res
= (s16
)*srcreg
* (s16
)imm
;
1043 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1044 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1051 *destreg
= (u16
)res
;
1054 DECODE_CLEAR_SEGOVR();
1058 /****************************************************************************
1061 ****************************************************************************/
1062 void x86emuOp_push_byte_IMM(u8
X86EMU_UNUSED(op1
))
1067 imm
= (s8
)fetch_byte_imm();
1068 DECODE_PRINTF2("PUSH\t%d\n", imm
);
1071 DECODE_CLEAR_SEGOVR();
1075 /****************************************************************************
1078 ****************************************************************************/
1079 void x86emuOp_imul_byte_IMM(u8
X86EMU_UNUSED(op1
))
1086 DECODE_PRINTF("IMUL\t");
1087 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1089 srcoffset
= decode_rmXX_address(mod
, rl
);
1090 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1095 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1097 srcval
= fetch_data_long(srcoffset
);
1098 imm
= fetch_byte_imm();
1099 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1101 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
1102 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1103 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1110 *destreg
= (u32
)res_lo
;
1116 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1118 srcval
= fetch_data_word(srcoffset
);
1119 imm
= fetch_byte_imm();
1120 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1122 res
= (s16
)srcval
* (s16
)imm
;
1123 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1124 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1131 *destreg
= (u16
)res
;
1133 } else { /* register to register */
1134 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1135 u32
*destreg
,*srcreg
;
1138 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1140 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1141 imm
= fetch_byte_imm();
1142 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1144 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
1145 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1146 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1153 *destreg
= (u32
)res_lo
;
1155 u16
*destreg
,*srcreg
;
1158 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1160 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1161 imm
= fetch_byte_imm();
1162 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1164 res
= (s16
)*srcreg
* (s16
)imm
;
1165 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1166 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1173 *destreg
= (u16
)res
;
1176 DECODE_CLEAR_SEGOVR();
1180 /****************************************************************************
1183 ****************************************************************************/
1184 void x86emuOp_ins_byte(u8
X86EMU_UNUSED(op1
))
1187 DECODE_PRINTF("INSB\n");
1190 DECODE_CLEAR_SEGOVR();
1194 /****************************************************************************
1197 ****************************************************************************/
1198 void x86emuOp_ins_word(u8
X86EMU_UNUSED(op1
))
1201 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1202 DECODE_PRINTF("INSD\n");
1205 DECODE_PRINTF("INSW\n");
1209 DECODE_CLEAR_SEGOVR();
1213 /****************************************************************************
1216 ****************************************************************************/
1217 void x86emuOp_outs_byte(u8
X86EMU_UNUSED(op1
))
1220 DECODE_PRINTF("OUTSB\n");
1223 DECODE_CLEAR_SEGOVR();
1227 /****************************************************************************
1230 ****************************************************************************/
1231 void x86emuOp_outs_word(u8
X86EMU_UNUSED(op1
))
1234 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1235 DECODE_PRINTF("OUTSD\n");
1238 DECODE_PRINTF("OUTSW\n");
1242 DECODE_CLEAR_SEGOVR();
1246 /****************************************************************************
1248 Handles opcode 0x70 - 0x7F
1249 ****************************************************************************/
1250 int x86emu_check_jump_condition(u8 op
);
1252 void x86emuOp_jump_near_cond(u8 op1
)
1258 /* jump to byte offset if overflow flag is set */
1260 cond
= x86emu_check_jump_condition(op1
& 0xF);
1261 offset
= (s8
)fetch_byte_imm();
1262 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
1263 DECODE_PRINTF2("%x\n", target
);
1266 M
.x86
.R_IP
= target
;
1267 DECODE_CLEAR_SEGOVR();
1271 /****************************************************************************
1274 ****************************************************************************/
1275 void x86emuOp_opc80_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
1284 * Weirdo special case instruction format. Part of the opcode
1285 * held below in "RH". Doubly nested case would result, except
1286 * that the decoded instruction
1289 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1291 if (DEBUG_DECODE()) {
1292 /* XXX DECODE_PRINTF may be changed to something more
1293 general, so that it is important to leave the strings
1294 in the same format, even though the result is that the
1295 above test is done twice. */
1299 DECODE_PRINTF("ADD\t");
1302 DECODE_PRINTF("OR\t");
1305 DECODE_PRINTF("ADC\t");
1308 DECODE_PRINTF("SBB\t");
1311 DECODE_PRINTF("AND\t");
1314 DECODE_PRINTF("SUB\t");
1317 DECODE_PRINTF("XOR\t");
1320 DECODE_PRINTF("CMP\t");
1325 /* know operation, decode the mod byte to find the addressing
1328 DECODE_PRINTF("BYTE PTR ");
1329 destoffset
= decode_rmXX_address(mod
, rl
);
1331 destval
= fetch_data_byte(destoffset
);
1332 imm
= fetch_byte_imm();
1333 DECODE_PRINTF2("%x\n", imm
);
1335 destval
= (*genop_byte_operation
[rh
]) (destval
, imm
);
1337 store_data_byte(destoffset
, destval
);
1338 } else { /* register to register */
1339 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1341 imm
= fetch_byte_imm();
1342 DECODE_PRINTF2("%x\n", imm
);
1344 destval
= (*genop_byte_operation
[rh
]) (*destreg
, imm
);
1348 DECODE_CLEAR_SEGOVR();
1352 /****************************************************************************
1355 ****************************************************************************/
1356 void x86emuOp_opc81_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
1362 * Weirdo special case instruction format. Part of the opcode
1363 * held below in "RH". Doubly nested case would result, except
1364 * that the decoded instruction
1367 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1369 if (DEBUG_DECODE()) {
1370 /* XXX DECODE_PRINTF may be changed to something more
1371 general, so that it is important to leave the strings
1372 in the same format, even though the result is that the
1373 above test is done twice. */
1377 DECODE_PRINTF("ADD\t");
1380 DECODE_PRINTF("OR\t");
1383 DECODE_PRINTF("ADC\t");
1386 DECODE_PRINTF("SBB\t");
1389 DECODE_PRINTF("AND\t");
1392 DECODE_PRINTF("SUB\t");
1395 DECODE_PRINTF("XOR\t");
1398 DECODE_PRINTF("CMP\t");
1404 * Know operation, decode the mod byte to find the addressing
1408 DECODE_PRINTF("DWORD PTR ");
1409 destoffset
= decode_rmXX_address(mod
, rl
);
1410 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1414 destval
= fetch_data_long(destoffset
);
1415 imm
= fetch_long_imm();
1416 DECODE_PRINTF2("%x\n", imm
);
1418 destval
= (*genop_long_operation
[rh
]) (destval
, imm
);
1420 store_data_long(destoffset
, destval
);
1425 destval
= fetch_data_word(destoffset
);
1426 imm
= fetch_word_imm();
1427 DECODE_PRINTF2("%x\n", imm
);
1429 destval
= (*genop_word_operation
[rh
]) (destval
, imm
);
1431 store_data_word(destoffset
, destval
);
1433 } else { /* register to register */
1434 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1438 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1440 imm
= fetch_long_imm();
1441 DECODE_PRINTF2("%x\n", imm
);
1443 destval
= (*genop_long_operation
[rh
]) (*destreg
, imm
);
1450 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1452 imm
= fetch_word_imm();
1453 DECODE_PRINTF2("%x\n", imm
);
1455 destval
= (*genop_word_operation
[rh
]) (*destreg
, imm
);
1460 DECODE_CLEAR_SEGOVR();
1464 /****************************************************************************
1467 ****************************************************************************/
1468 void x86emuOp_opc82_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
1477 * Weirdo special case instruction format. Part of the opcode
1478 * held below in "RH". Doubly nested case would result, except
1479 * that the decoded instruction Similar to opcode 81, except that
1480 * the immediate byte is sign extended to a word length.
1483 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1485 if (DEBUG_DECODE()) {
1486 /* XXX DECODE_PRINTF may be changed to something more
1487 general, so that it is important to leave the strings
1488 in the same format, even though the result is that the
1489 above test is done twice. */
1492 DECODE_PRINTF("ADD\t");
1495 DECODE_PRINTF("OR\t");
1498 DECODE_PRINTF("ADC\t");
1501 DECODE_PRINTF("SBB\t");
1504 DECODE_PRINTF("AND\t");
1507 DECODE_PRINTF("SUB\t");
1510 DECODE_PRINTF("XOR\t");
1513 DECODE_PRINTF("CMP\t");
1518 /* know operation, decode the mod byte to find the addressing
1521 DECODE_PRINTF("BYTE PTR ");
1522 destoffset
= decode_rmXX_address(mod
, rl
);
1523 destval
= fetch_data_byte(destoffset
);
1524 imm
= fetch_byte_imm();
1525 DECODE_PRINTF2(",%x\n", imm
);
1527 destval
= (*genop_byte_operation
[rh
]) (destval
, imm
);
1529 store_data_byte(destoffset
, destval
);
1530 } else { /* register to register */
1531 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1532 imm
= fetch_byte_imm();
1533 DECODE_PRINTF2(",%x\n", imm
);
1535 destval
= (*genop_byte_operation
[rh
]) (*destreg
, imm
);
1539 DECODE_CLEAR_SEGOVR();
1543 /****************************************************************************
1546 ****************************************************************************/
1547 void x86emuOp_opc83_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
1553 * Weirdo special case instruction format. Part of the opcode
1554 * held below in "RH". Doubly nested case would result, except
1555 * that the decoded instruction Similar to opcode 81, except that
1556 * the immediate byte is sign extended to a word length.
1559 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1561 if (DEBUG_DECODE()) {
1562 /* XXX DECODE_PRINTF may be changed to something more
1563 general, so that it is important to leave the strings
1564 in the same format, even though the result is that the
1565 above test is done twice. */
1568 DECODE_PRINTF("ADD\t");
1571 DECODE_PRINTF("OR\t");
1574 DECODE_PRINTF("ADC\t");
1577 DECODE_PRINTF("SBB\t");
1580 DECODE_PRINTF("AND\t");
1583 DECODE_PRINTF("SUB\t");
1586 DECODE_PRINTF("XOR\t");
1589 DECODE_PRINTF("CMP\t");
1594 /* know operation, decode the mod byte to find the addressing
1597 DECODE_PRINTF("DWORD PTR ");
1598 destoffset
= decode_rmXX_address(mod
,rl
);
1600 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1603 destval
= fetch_data_long(destoffset
);
1604 imm
= (s8
) fetch_byte_imm();
1605 DECODE_PRINTF2(",%x\n", imm
);
1607 destval
= (*genop_long_operation
[rh
]) (destval
, imm
);
1609 store_data_long(destoffset
, destval
);
1613 destval
= fetch_data_word(destoffset
);
1614 imm
= (s8
) fetch_byte_imm();
1615 DECODE_PRINTF2(",%x\n", imm
);
1617 destval
= (*genop_word_operation
[rh
]) (destval
, imm
);
1619 store_data_word(destoffset
, destval
);
1621 } else { /* register to register */
1622 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1626 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1627 imm
= (s8
) fetch_byte_imm();
1628 DECODE_PRINTF2(",%x\n", imm
);
1630 destval
= (*genop_long_operation
[rh
]) (*destreg
, imm
);
1637 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1638 imm
= (s8
) fetch_byte_imm();
1639 DECODE_PRINTF2(",%x\n", imm
);
1641 destval
= (*genop_word_operation
[rh
]) (*destreg
, imm
);
1646 DECODE_CLEAR_SEGOVR();
1650 /****************************************************************************
1653 ****************************************************************************/
1654 void x86emuOp_test_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1657 u8
*destreg
, *srcreg
;
1662 DECODE_PRINTF("TEST\t");
1663 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1665 destoffset
= decode_rmXX_address(mod
, rl
);
1667 destval
= fetch_data_byte(destoffset
);
1668 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1669 DECODE_PRINTF("\n");
1671 test_byte(destval
, *srcreg
);
1672 } else { /* register to register */
1673 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1675 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1676 DECODE_PRINTF("\n");
1678 test_byte(*destreg
, *srcreg
);
1680 DECODE_CLEAR_SEGOVR();
1684 /****************************************************************************
1687 ****************************************************************************/
1688 void x86emuOp_test_word_RM_R(u8
X86EMU_UNUSED(op1
))
1694 DECODE_PRINTF("TEST\t");
1695 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1697 destoffset
= decode_rmXX_address(mod
, rl
);
1698 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1703 destval
= fetch_data_long(destoffset
);
1704 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1705 DECODE_PRINTF("\n");
1707 test_long(destval
, *srcreg
);
1713 destval
= fetch_data_word(destoffset
);
1714 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1715 DECODE_PRINTF("\n");
1717 test_word(destval
, *srcreg
);
1719 } else { /* register to register */
1720 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1721 u32
*destreg
,*srcreg
;
1723 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1725 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1726 DECODE_PRINTF("\n");
1728 test_long(*destreg
, *srcreg
);
1730 u16
*destreg
,*srcreg
;
1732 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1734 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1735 DECODE_PRINTF("\n");
1737 test_word(*destreg
, *srcreg
);
1740 DECODE_CLEAR_SEGOVR();
1744 /****************************************************************************
1747 ****************************************************************************/
1748 void x86emuOp_xchg_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1751 u8
*destreg
, *srcreg
;
1757 DECODE_PRINTF("XCHG\t");
1758 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1760 destoffset
= decode_rmXX_address(mod
, rl
);
1762 destval
= fetch_data_byte(destoffset
);
1763 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1764 DECODE_PRINTF("\n");
1769 store_data_byte(destoffset
, destval
);
1770 } else { /* register to register */
1771 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1773 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1774 DECODE_PRINTF("\n");
1780 DECODE_CLEAR_SEGOVR();
1784 /****************************************************************************
1787 ****************************************************************************/
1788 void x86emuOp_xchg_word_RM_R(u8
X86EMU_UNUSED(op1
))
1794 DECODE_PRINTF("XCHG\t");
1795 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1797 destoffset
= decode_rmXX_address(mod
, rl
);
1799 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1803 destval
= fetch_data_long(destoffset
);
1804 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1805 DECODE_PRINTF("\n");
1810 store_data_long(destoffset
, destval
);
1815 destval
= fetch_data_word(destoffset
);
1816 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1817 DECODE_PRINTF("\n");
1822 store_data_word(destoffset
, destval
);
1824 } else { /* register to register */
1825 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1826 u32
*destreg
,*srcreg
;
1829 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1831 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1832 DECODE_PRINTF("\n");
1838 u16
*destreg
,*srcreg
;
1841 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1843 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1844 DECODE_PRINTF("\n");
1851 DECODE_CLEAR_SEGOVR();
1855 /****************************************************************************
1858 ****************************************************************************/
1859 void x86emuOp_mov_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1862 u8
*destreg
, *srcreg
;
1866 DECODE_PRINTF("MOV\t");
1867 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1869 destoffset
= decode_rmXX_address(mod
, rl
);
1871 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1872 DECODE_PRINTF("\n");
1874 store_data_byte(destoffset
, *srcreg
);
1875 } else { /* register to register */
1876 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1878 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1879 DECODE_PRINTF("\n");
1883 DECODE_CLEAR_SEGOVR();
1887 /****************************************************************************
1890 ****************************************************************************/
1891 void x86emuOp_mov_word_RM_R(u8
X86EMU_UNUSED(op1
))
1897 DECODE_PRINTF("MOV\t");
1898 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1900 destoffset
= decode_rmXX_address(mod
, rl
);
1901 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1905 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1906 DECODE_PRINTF("\n");
1908 store_data_long(destoffset
, *srcreg
);
1913 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1914 DECODE_PRINTF("\n");
1916 store_data_word(destoffset
, *srcreg
);
1918 } else { /* register to register */
1919 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1920 u32
*destreg
,*srcreg
;
1922 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1924 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1925 DECODE_PRINTF("\n");
1929 u16
*destreg
,*srcreg
;
1931 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1933 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1934 DECODE_PRINTF("\n");
1939 DECODE_CLEAR_SEGOVR();
1943 /****************************************************************************
1946 ****************************************************************************/
1947 void x86emuOp_mov_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1950 u8
*destreg
, *srcreg
;
1955 DECODE_PRINTF("MOV\t");
1956 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1958 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1960 srcoffset
= decode_rmXX_address(mod
, rl
);
1961 srcval
= fetch_data_byte(srcoffset
);
1962 DECODE_PRINTF("\n");
1965 } else { /* register to register */
1966 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1968 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1969 DECODE_PRINTF("\n");
1973 DECODE_CLEAR_SEGOVR();
1977 /****************************************************************************
1980 ****************************************************************************/
1981 void x86emuOp_mov_word_R_RM(u8
X86EMU_UNUSED(op1
))
1987 DECODE_PRINTF("MOV\t");
1988 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1990 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1994 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1996 srcoffset
= decode_rmXX_address(mod
, rl
);
1997 srcval
= fetch_data_long(srcoffset
);
1998 DECODE_PRINTF("\n");
2005 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2007 srcoffset
= decode_rmXX_address(mod
, rl
);
2008 srcval
= fetch_data_word(srcoffset
);
2009 DECODE_PRINTF("\n");
2013 } else { /* register to register */
2014 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2015 u32
*destreg
, *srcreg
;
2017 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2019 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2020 DECODE_PRINTF("\n");
2024 u16
*destreg
, *srcreg
;
2026 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2028 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2029 DECODE_PRINTF("\n");
2034 DECODE_CLEAR_SEGOVR();
2038 /****************************************************************************
2041 ****************************************************************************/
2042 void x86emuOp_mov_word_RM_SR(u8
X86EMU_UNUSED(op1
))
2045 u16
*destreg
, *srcreg
;
2050 DECODE_PRINTF("MOV\t");
2051 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2053 destoffset
= decode_rmXX_address(mod
, rl
);
2055 srcreg
= decode_rm_seg_register(rh
);
2056 DECODE_PRINTF("\n");
2059 store_data_word(destoffset
, destval
);
2060 } else { /* register to register */
2061 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2063 srcreg
= decode_rm_seg_register(rh
);
2064 DECODE_PRINTF("\n");
2068 DECODE_CLEAR_SEGOVR();
2072 /****************************************************************************
2075 ****************************************************************************/
2076 void x86emuOp_lea_word_R_M(u8
X86EMU_UNUSED(op1
))
2083 * TODO: Need to handle address size prefix!
2085 * lea eax,[eax+ebx*2] ??
2089 DECODE_PRINTF("LEA\t");
2090 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2092 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2094 destoffset
= decode_rmXX_address(mod
, rl
);
2095 DECODE_PRINTF("\n");
2097 *srcreg
= (u16
)destoffset
;
2099 /* } else { undefined. Do nothing. } */
2100 DECODE_CLEAR_SEGOVR();
2104 /****************************************************************************
2107 ****************************************************************************/
2108 void x86emuOp_mov_word_SR_RM(u8
X86EMU_UNUSED(op1
))
2111 u16
*destreg
, *srcreg
;
2116 DECODE_PRINTF("MOV\t");
2117 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2119 destreg
= decode_rm_seg_register(rh
);
2121 srcoffset
= decode_rmXX_address(mod
, rl
);
2122 srcval
= fetch_data_word(srcoffset
);
2123 DECODE_PRINTF("\n");
2126 } else { /* register to register */
2127 destreg
= decode_rm_seg_register(rh
);
2129 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2130 DECODE_PRINTF("\n");
2135 * Clean up, and reset all the R_xSP pointers to the correct
2136 * locations. This is about 3x too much overhead (doing all the
2137 * segreg ptrs when only one is needed, but this instruction
2138 * *cannot* be that common, and this isn't too much work anyway.
2140 DECODE_CLEAR_SEGOVR();
2144 /****************************************************************************
2147 ****************************************************************************/
2148 void x86emuOp_pop_RM(u8
X86EMU_UNUSED(op1
))
2154 DECODE_PRINTF("POP\t");
2155 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2157 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
2161 destoffset
= decode_rmXX_address(mod
, rl
);
2162 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2165 DECODE_PRINTF("\n");
2167 destval
= pop_long();
2168 store_data_long(destoffset
, destval
);
2172 DECODE_PRINTF("\n");
2174 destval
= pop_word();
2175 store_data_word(destoffset
, destval
);
2177 } else { /* register to register */
2178 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2181 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2182 DECODE_PRINTF("\n");
2184 *destreg
= pop_long();
2188 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2189 DECODE_PRINTF("\n");
2191 *destreg
= pop_word();
2194 DECODE_CLEAR_SEGOVR();
2198 /****************************************************************************
2201 ****************************************************************************/
2202 void x86emuOp_nop(u8
X86EMU_UNUSED(op1
))
2205 DECODE_PRINTF("NOP\n");
2207 DECODE_CLEAR_SEGOVR();
2211 /****************************************************************************
2213 Handles opcode 0x91-0x97
2214 ****************************************************************************/
2215 void x86emuOp_xchg_word_AX_register(u8
X86EMU_UNUSED(op1
))
2223 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2225 DECODE_PRINTF("XCHG\tEAX,");
2226 reg32
= DECODE_RM_LONG_REGISTER(op1
);
2227 DECODE_PRINTF("\n");
2230 M
.x86
.R_EAX
= *reg32
;
2234 DECODE_PRINTF("XCHG\tAX,");
2235 reg16
= DECODE_RM_WORD_REGISTER(op1
);
2236 DECODE_PRINTF("\n");
2239 M
.x86
.R_EAX
= *reg16
;
2242 DECODE_CLEAR_SEGOVR();
2246 /****************************************************************************
2249 ****************************************************************************/
2250 void x86emuOp_cbw(u8
X86EMU_UNUSED(op1
))
2253 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2254 DECODE_PRINTF("CWDE\n");
2256 DECODE_PRINTF("CBW\n");
2259 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2260 if (M
.x86
.R_AX
& 0x8000) {
2261 M
.x86
.R_EAX
|= 0xffff0000;
2263 M
.x86
.R_EAX
&= 0x0000ffff;
2266 if (M
.x86
.R_AL
& 0x80) {
2272 DECODE_CLEAR_SEGOVR();
2276 /****************************************************************************
2279 ****************************************************************************/
2280 void x86emuOp_cwd(u8
X86EMU_UNUSED(op1
))
2283 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2284 DECODE_PRINTF("CDQ\n");
2286 DECODE_PRINTF("CWD\n");
2288 DECODE_PRINTF("CWD\n");
2290 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2291 if (M
.x86
.R_EAX
& 0x80000000) {
2292 M
.x86
.R_EDX
= 0xffffffff;
2297 if (M
.x86
.R_AX
& 0x8000) {
2298 M
.x86
.R_DX
= 0xffff;
2303 DECODE_CLEAR_SEGOVR();
2307 /****************************************************************************
2310 ****************************************************************************/
2311 void x86emuOp_call_far_IMM(u8
X86EMU_UNUSED(op1
))
2316 DECODE_PRINTF("CALL\t");
2317 faroff
= fetch_word_imm();
2318 farseg
= fetch_word_imm();
2319 DECODE_PRINTF2("%04x:", farseg
);
2320 DECODE_PRINTF2("%04x\n", faroff
);
2321 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, farseg
, faroff
, "FAR ");
2325 * Hooked interrupt vectors calling into our "BIOS" will cause
2326 * problems unless all intersegment stuff is checked for BIOS
2327 * access. Check needed here. For moment, let it alone.
2330 push_word(M
.x86
.R_CS
);
2331 M
.x86
.R_CS
= farseg
;
2332 push_word(M
.x86
.R_IP
);
2333 M
.x86
.R_IP
= faroff
;
2334 DECODE_CLEAR_SEGOVR();
2338 /****************************************************************************
2341 ****************************************************************************/
2342 void x86emuOp_wait(u8
X86EMU_UNUSED(op1
))
2345 DECODE_PRINTF("WAIT");
2348 DECODE_CLEAR_SEGOVR();
2352 /****************************************************************************
2355 ****************************************************************************/
2356 void x86emuOp_pushf_word(u8
X86EMU_UNUSED(op1
))
2361 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2362 DECODE_PRINTF("PUSHFD\n");
2364 DECODE_PRINTF("PUSHF\n");
2368 /* clear out *all* bits not representing flags, and turn on real bits */
2369 flags
= (M
.x86
.R_EFLG
& F_MSK
) | F_ALWAYS_ON
;
2370 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2373 push_word((u16
)flags
);
2375 DECODE_CLEAR_SEGOVR();
2379 /****************************************************************************
2382 ****************************************************************************/
2383 void x86emuOp_popf_word(u8
X86EMU_UNUSED(op1
))
2386 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2387 DECODE_PRINTF("POPFD\n");
2389 DECODE_PRINTF("POPF\n");
2392 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2393 M
.x86
.R_EFLG
= pop_long();
2395 M
.x86
.R_FLG
= pop_word();
2397 DECODE_CLEAR_SEGOVR();
2401 /****************************************************************************
2404 ****************************************************************************/
2405 void x86emuOp_sahf(u8
X86EMU_UNUSED(op1
))
2408 DECODE_PRINTF("SAHF\n");
2410 /* clear the lower bits of the flag register */
2411 M
.x86
.R_FLG
&= 0xffffff00;
2412 /* or in the AH register into the flags register */
2413 M
.x86
.R_FLG
|= M
.x86
.R_AH
;
2414 DECODE_CLEAR_SEGOVR();
2418 /****************************************************************************
2421 ****************************************************************************/
2422 void x86emuOp_lahf(u8
X86EMU_UNUSED(op1
))
2425 DECODE_PRINTF("LAHF\n");
2427 M
.x86
.R_AH
= (u8
)(M
.x86
.R_FLG
& 0xff);
2428 /*undocumented TC++ behavior??? Nope. It's documented, but
2429 you have too look real hard to notice it. */
2431 DECODE_CLEAR_SEGOVR();
2435 /****************************************************************************
2438 ****************************************************************************/
2439 void x86emuOp_mov_AL_M_IMM(u8
X86EMU_UNUSED(op1
))
2444 DECODE_PRINTF("MOV\tAL,");
2445 offset
= fetch_word_imm();
2446 DECODE_PRINTF2("[%04x]\n", offset
);
2448 M
.x86
.R_AL
= fetch_data_byte(offset
);
2449 DECODE_CLEAR_SEGOVR();
2453 /****************************************************************************
2456 ****************************************************************************/
2457 void x86emuOp_mov_AX_M_IMM(u8
X86EMU_UNUSED(op1
))
2462 offset
= fetch_word_imm();
2463 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2464 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset
);
2466 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset
);
2469 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2470 M
.x86
.R_EAX
= fetch_data_long(offset
);
2472 M
.x86
.R_AX
= fetch_data_word(offset
);
2474 DECODE_CLEAR_SEGOVR();
2478 /****************************************************************************
2481 ****************************************************************************/
2482 void x86emuOp_mov_M_AL_IMM(u8
X86EMU_UNUSED(op1
))
2487 DECODE_PRINTF("MOV\t");
2488 offset
= fetch_word_imm();
2489 DECODE_PRINTF2("[%04x],AL\n", offset
);
2491 store_data_byte(offset
, M
.x86
.R_AL
);
2492 DECODE_CLEAR_SEGOVR();
2496 /****************************************************************************
2499 ****************************************************************************/
2500 void x86emuOp_mov_M_AX_IMM(u8
X86EMU_UNUSED(op1
))
2505 offset
= fetch_word_imm();
2506 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2507 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset
);
2509 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset
);
2512 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2513 store_data_long(offset
, M
.x86
.R_EAX
);
2515 store_data_word(offset
, M
.x86
.R_AX
);
2517 DECODE_CLEAR_SEGOVR();
2521 /****************************************************************************
2524 ****************************************************************************/
2525 void x86emuOp_movs_byte(u8
X86EMU_UNUSED(op1
))
2532 DECODE_PRINTF("MOVS\tBYTE\n");
2533 if (ACCESS_FLAG(F_DF
)) /* down */
2539 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2540 /* dont care whether REPE or REPNE */
2541 /* move them until CX is ZERO. */
2544 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2547 val
= fetch_data_byte(M
.x86
.R_SI
);
2548 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
2552 DECODE_CLEAR_SEGOVR();
2556 /****************************************************************************
2559 ****************************************************************************/
2560 void x86emuOp_movs_word(u8
X86EMU_UNUSED(op1
))
2567 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2568 DECODE_PRINTF("MOVS\tDWORD\n");
2569 if (ACCESS_FLAG(F_DF
)) /* down */
2574 DECODE_PRINTF("MOVS\tWORD\n");
2575 if (ACCESS_FLAG(F_DF
)) /* down */
2582 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2583 /* dont care whether REPE or REPNE */
2584 /* move them until CX is ZERO. */
2587 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2590 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2591 val
= fetch_data_long(M
.x86
.R_SI
);
2592 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
2594 val
= fetch_data_word(M
.x86
.R_SI
);
2595 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, (u16
)val
);
2600 DECODE_CLEAR_SEGOVR();
2604 /****************************************************************************
2607 ****************************************************************************/
2608 void x86emuOp_cmps_byte(u8
X86EMU_UNUSED(op1
))
2614 DECODE_PRINTF("CMPS\tBYTE\n");
2616 if (ACCESS_FLAG(F_DF
)) /* down */
2621 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2623 /* move them until CX is ZERO. */
2624 while (M
.x86
.R_CX
!= 0) {
2625 val1
= fetch_data_byte(M
.x86
.R_SI
);
2626 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2627 cmp_byte(val1
, val2
);
2631 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) && (ACCESS_FLAG(F_ZF
) == 0) ) break;
2632 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) && ACCESS_FLAG(F_ZF
) ) break;
2634 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2636 val1
= fetch_data_byte(M
.x86
.R_SI
);
2637 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2638 cmp_byte(val1
, val2
);
2642 DECODE_CLEAR_SEGOVR();
2646 /****************************************************************************
2649 ****************************************************************************/
2650 void x86emuOp_cmps_word(u8
X86EMU_UNUSED(op1
))
2656 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2657 DECODE_PRINTF("CMPS\tDWORD\n");
2660 DECODE_PRINTF("CMPS\tWORD\n");
2663 if (ACCESS_FLAG(F_DF
)) /* down */
2667 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2669 /* move them until CX is ZERO. */
2670 while (M
.x86
.R_CX
!= 0) {
2671 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2672 val1
= fetch_data_long(M
.x86
.R_SI
);
2673 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2674 cmp_long(val1
, val2
);
2676 val1
= fetch_data_word(M
.x86
.R_SI
);
2677 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2678 cmp_word((u16
)val1
, (u16
)val2
);
2683 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) && ACCESS_FLAG(F_ZF
) == 0 ) break;
2684 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) && ACCESS_FLAG(F_ZF
) ) break;
2686 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2688 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2689 val1
= fetch_data_long(M
.x86
.R_SI
);
2690 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2691 cmp_long(val1
, val2
);
2693 val1
= fetch_data_word(M
.x86
.R_SI
);
2694 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2695 cmp_word((u16
)val1
, (u16
)val2
);
2700 DECODE_CLEAR_SEGOVR();
2704 /****************************************************************************
2707 ****************************************************************************/
2708 void x86emuOp_test_AL_IMM(u8
X86EMU_UNUSED(op1
))
2713 DECODE_PRINTF("TEST\tAL,");
2714 imm
= fetch_byte_imm();
2715 DECODE_PRINTF2("%04x\n", imm
);
2717 test_byte(M
.x86
.R_AL
, (u8
)imm
);
2718 DECODE_CLEAR_SEGOVR();
2722 /****************************************************************************
2725 ****************************************************************************/
2726 void x86emuOp_test_AX_IMM(u8
X86EMU_UNUSED(op1
))
2731 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2732 DECODE_PRINTF("TEST\tEAX,");
2733 srcval
= fetch_long_imm();
2735 DECODE_PRINTF("TEST\tAX,");
2736 srcval
= fetch_word_imm();
2738 DECODE_PRINTF2("%x\n", srcval
);
2740 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2741 test_long(M
.x86
.R_EAX
, srcval
);
2743 test_word(M
.x86
.R_AX
, (u16
)srcval
);
2745 DECODE_CLEAR_SEGOVR();
2749 /****************************************************************************
2752 ****************************************************************************/
2753 void x86emuOp_stos_byte(u8
X86EMU_UNUSED(op1
))
2758 DECODE_PRINTF("STOS\tBYTE\n");
2759 if (ACCESS_FLAG(F_DF
)) /* down */
2764 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2765 /* dont care whether REPE or REPNE */
2766 /* move them until CX is ZERO. */
2767 while (M
.x86
.R_CX
!= 0) {
2768 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
2772 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2774 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
2777 DECODE_CLEAR_SEGOVR();
2781 /****************************************************************************
2784 ****************************************************************************/
2785 void x86emuOp_stos_word(u8
X86EMU_UNUSED(op1
))
2791 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2792 DECODE_PRINTF("STOS\tDWORD\n");
2793 if (ACCESS_FLAG(F_DF
)) /* down */
2798 DECODE_PRINTF("STOS\tWORD\n");
2799 if (ACCESS_FLAG(F_DF
)) /* down */
2806 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2807 /* dont care whether REPE or REPNE */
2808 /* move them until CX is ZERO. */
2811 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2814 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2815 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_EAX
);
2817 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AX
);
2821 DECODE_CLEAR_SEGOVR();
2825 /****************************************************************************
2828 ****************************************************************************/
2829 void x86emuOp_lods_byte(u8
X86EMU_UNUSED(op1
))
2834 DECODE_PRINTF("LODS\tBYTE\n");
2836 if (ACCESS_FLAG(F_DF
)) /* down */
2840 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2841 /* dont care whether REPE or REPNE */
2842 /* move them until CX is ZERO. */
2843 while (M
.x86
.R_CX
!= 0) {
2844 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
2848 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2850 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
2853 DECODE_CLEAR_SEGOVR();
2857 /****************************************************************************
2860 ****************************************************************************/
2861 void x86emuOp_lods_word(u8
X86EMU_UNUSED(op1
))
2867 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2868 DECODE_PRINTF("LODS\tDWORD\n");
2869 if (ACCESS_FLAG(F_DF
)) /* down */
2874 DECODE_PRINTF("LODS\tWORD\n");
2875 if (ACCESS_FLAG(F_DF
)) /* down */
2882 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2883 /* dont care whether REPE or REPNE */
2884 /* move them until CX is ZERO. */
2887 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2890 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2891 M
.x86
.R_EAX
= fetch_data_long(M
.x86
.R_SI
);
2893 M
.x86
.R_AX
= fetch_data_word(M
.x86
.R_SI
);
2897 DECODE_CLEAR_SEGOVR();
2901 /****************************************************************************
2904 ****************************************************************************/
2905 void x86emuOp_scas_byte(u8
X86EMU_UNUSED(op1
))
2911 DECODE_PRINTF("SCAS\tBYTE\n");
2913 if (ACCESS_FLAG(F_DF
)) /* down */
2917 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
2919 /* move them until CX is ZERO. */
2920 while (M
.x86
.R_CX
!= 0) {
2921 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2922 cmp_byte(M
.x86
.R_AL
, val2
);
2925 if (ACCESS_FLAG(F_ZF
) == 0)
2928 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
2929 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
2931 /* move them until CX is ZERO. */
2932 while (M
.x86
.R_CX
!= 0) {
2933 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2934 cmp_byte(M
.x86
.R_AL
, val2
);
2937 if (ACCESS_FLAG(F_ZF
))
2938 break; /* zero flag set means equal */
2940 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
2942 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2943 cmp_byte(M
.x86
.R_AL
, val2
);
2946 DECODE_CLEAR_SEGOVR();
2950 /****************************************************************************
2953 ****************************************************************************/
2954 void x86emuOp_scas_word(u8
X86EMU_UNUSED(op1
))
2960 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2961 DECODE_PRINTF("SCAS\tDWORD\n");
2962 if (ACCESS_FLAG(F_DF
)) /* down */
2967 DECODE_PRINTF("SCAS\tWORD\n");
2968 if (ACCESS_FLAG(F_DF
)) /* down */
2974 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
2976 /* move them until CX is ZERO. */
2977 while (M
.x86
.R_CX
!= 0) {
2978 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2979 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2980 cmp_long(M
.x86
.R_EAX
, val
);
2982 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2983 cmp_word(M
.x86
.R_AX
, (u16
)val
);
2987 if (ACCESS_FLAG(F_ZF
) == 0)
2990 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
2991 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
2993 /* move them until CX is ZERO. */
2994 while (M
.x86
.R_CX
!= 0) {
2995 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2996 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2997 cmp_long(M
.x86
.R_EAX
, val
);
2999 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3000 cmp_word(M
.x86
.R_AX
, (u16
)val
);
3004 if (ACCESS_FLAG(F_ZF
))
3005 break; /* zero flag set means equal */
3007 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
3009 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3010 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3011 cmp_long(M
.x86
.R_EAX
, val
);
3013 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3014 cmp_word(M
.x86
.R_AX
, (u16
)val
);
3018 DECODE_CLEAR_SEGOVR();
3022 /****************************************************************************
3024 Handles opcode 0xb0 - 0xb7
3025 ****************************************************************************/
3026 void x86emuOp_mov_byte_register_IMM(u8 op1
)
3031 DECODE_PRINTF("MOV\t");
3032 ptr
= DECODE_RM_BYTE_REGISTER(op1
& 0x7);
3034 imm
= fetch_byte_imm();
3035 DECODE_PRINTF2("%x\n", imm
);
3038 DECODE_CLEAR_SEGOVR();
3042 /****************************************************************************
3044 Handles opcode 0xb8 - 0xbf
3045 ****************************************************************************/
3046 void x86emuOp_mov_word_register_IMM(u8
X86EMU_UNUSED(op1
))
3053 DECODE_PRINTF("MOV\t");
3054 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3056 reg32
= DECODE_RM_LONG_REGISTER(op1
);
3057 srcval
= fetch_long_imm();
3058 DECODE_PRINTF2(",%x\n", srcval
);
3063 reg16
= DECODE_RM_WORD_REGISTER(op1
);
3064 srcval
= fetch_word_imm();
3065 DECODE_PRINTF2(",%x\n", srcval
);
3067 *reg16
= (u16
)srcval
;
3069 DECODE_CLEAR_SEGOVR();
3073 /****************************************************************************
3076 ****************************************************************************/
3077 void x86emuOp_opcC0_byte_RM_MEM(u8
X86EMU_UNUSED(op1
))
3086 * Yet another weirdo special case instruction format. Part of
3087 * the opcode held below in "RH". Doubly nested case would
3088 * result, except that the decoded instruction
3091 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3093 if (DEBUG_DECODE()) {
3094 /* XXX DECODE_PRINTF may be changed to something more
3095 general, so that it is important to leave the strings
3096 in the same format, even though the result is that the
3097 above test is done twice. */
3101 DECODE_PRINTF("ROL\t");
3104 DECODE_PRINTF("ROR\t");
3107 DECODE_PRINTF("RCL\t");
3110 DECODE_PRINTF("RCR\t");
3113 DECODE_PRINTF("SHL\t");
3116 DECODE_PRINTF("SHR\t");
3119 DECODE_PRINTF("SAL\t");
3122 DECODE_PRINTF("SAR\t");
3127 /* know operation, decode the mod byte to find the addressing
3130 DECODE_PRINTF("BYTE PTR ");
3131 destoffset
= decode_rmXX_address(mod
, rl
);
3132 amt
= fetch_byte_imm();
3133 DECODE_PRINTF2(",%x\n", amt
);
3134 destval
= fetch_data_byte(destoffset
);
3136 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
3137 store_data_byte(destoffset
, destval
);
3138 } else { /* register to register */
3139 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3140 amt
= fetch_byte_imm();
3141 DECODE_PRINTF2(",%x\n", amt
);
3143 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
3146 DECODE_CLEAR_SEGOVR();
3150 /****************************************************************************
3153 ****************************************************************************/
3154 void x86emuOp_opcC1_word_RM_MEM(u8
X86EMU_UNUSED(op1
))
3161 * Yet another weirdo special case instruction format. Part of
3162 * the opcode held below in "RH". Doubly nested case would
3163 * result, except that the decoded instruction
3166 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3168 if (DEBUG_DECODE()) {
3169 /* XXX DECODE_PRINTF may be changed to something more
3170 general, so that it is important to leave the strings
3171 in the same format, even though the result is that the
3172 above test is done twice. */
3176 DECODE_PRINTF("ROL\t");
3179 DECODE_PRINTF("ROR\t");
3182 DECODE_PRINTF("RCL\t");
3185 DECODE_PRINTF("RCR\t");
3188 DECODE_PRINTF("SHL\t");
3191 DECODE_PRINTF("SHR\t");
3194 DECODE_PRINTF("SAL\t");
3197 DECODE_PRINTF("SAR\t");
3202 /* know operation, decode the mod byte to find the addressing
3205 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3208 DECODE_PRINTF("DWORD PTR ");
3209 destoffset
= decode_rmXX_address(mod
, rl
);
3210 amt
= fetch_byte_imm();
3211 DECODE_PRINTF2(",%x\n", amt
);
3212 destval
= fetch_data_long(destoffset
);
3214 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
3215 store_data_long(destoffset
, destval
);
3219 DECODE_PRINTF("WORD PTR ");
3220 destoffset
= decode_rmXX_address(mod
, rl
);
3221 amt
= fetch_byte_imm();
3222 DECODE_PRINTF2(",%x\n", amt
);
3223 destval
= fetch_data_word(destoffset
);
3225 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
3226 store_data_word(destoffset
, destval
);
3228 } else { /* register to register */
3229 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3232 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3233 amt
= fetch_byte_imm();
3234 DECODE_PRINTF2(",%x\n", amt
);
3236 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
3240 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3241 amt
= fetch_byte_imm();
3242 DECODE_PRINTF2(",%x\n", amt
);
3244 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
3247 DECODE_CLEAR_SEGOVR();
3251 /****************************************************************************
3254 ****************************************************************************/
3255 void x86emuOp_ret_near_IMM(u8
X86EMU_UNUSED(op1
))
3260 DECODE_PRINTF("RET\t");
3261 imm
= fetch_word_imm();
3262 DECODE_PRINTF2("%x\n", imm
);
3263 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
3265 M
.x86
.R_IP
= pop_word();
3267 DECODE_CLEAR_SEGOVR();
3271 /****************************************************************************
3274 ****************************************************************************/
3275 void x86emuOp_ret_near(u8
X86EMU_UNUSED(op1
))
3278 DECODE_PRINTF("RET\n");
3279 RETURN_TRACE("RET",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
3281 M
.x86
.R_IP
= pop_word();
3282 DECODE_CLEAR_SEGOVR();
3286 /****************************************************************************
3289 ****************************************************************************/
3290 void x86emuOp_les_R_IMM(u8
X86EMU_UNUSED(op1
))
3297 DECODE_PRINTF("LES\t");
3298 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3300 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
3302 srcoffset
= decode_rmXX_address(mod
, rl
);
3303 DECODE_PRINTF("\n");
3305 *dstreg
= fetch_data_word(srcoffset
);
3306 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
3308 /* else UNDEFINED! register to register */
3310 DECODE_CLEAR_SEGOVR();
3314 /****************************************************************************
3317 ****************************************************************************/
3318 void x86emuOp_lds_R_IMM(u8
X86EMU_UNUSED(op1
))
3325 DECODE_PRINTF("LDS\t");
3326 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3328 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
3330 srcoffset
= decode_rmXX_address(mod
, rl
);
3331 DECODE_PRINTF("\n");
3333 *dstreg
= fetch_data_word(srcoffset
);
3334 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
3336 /* else UNDEFINED! */
3337 DECODE_CLEAR_SEGOVR();
3341 /****************************************************************************
3344 ****************************************************************************/
3345 void x86emuOp_mov_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
3353 DECODE_PRINTF("MOV\t");
3354 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3356 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
3360 DECODE_PRINTF("BYTE PTR ");
3361 destoffset
= decode_rmXX_address(mod
, rl
);
3362 imm
= fetch_byte_imm();
3363 DECODE_PRINTF2(",%2x\n", imm
);
3365 store_data_byte(destoffset
, imm
);
3366 } else { /* register to register */
3367 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3368 imm
= fetch_byte_imm();
3369 DECODE_PRINTF2(",%2x\n", imm
);
3373 DECODE_CLEAR_SEGOVR();
3377 /****************************************************************************
3380 ****************************************************************************/
3381 void x86emuOp_mov_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
3387 DECODE_PRINTF("MOV\t");
3388 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3390 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
3394 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3397 DECODE_PRINTF("DWORD PTR ");
3398 destoffset
= decode_rmXX_address(mod
, rl
);
3399 imm
= fetch_long_imm();
3400 DECODE_PRINTF2(",%x\n", imm
);
3402 store_data_long(destoffset
, imm
);
3406 DECODE_PRINTF("WORD PTR ");
3407 destoffset
= decode_rmXX_address(mod
, rl
);
3408 imm
= fetch_word_imm();
3409 DECODE_PRINTF2(",%x\n", imm
);
3411 store_data_word(destoffset
, imm
);
3413 } else { /* register to register */
3414 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3418 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3419 imm
= fetch_long_imm();
3420 DECODE_PRINTF2(",%x\n", imm
);
3427 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3428 imm
= fetch_word_imm();
3429 DECODE_PRINTF2(",%x\n", imm
);
3434 DECODE_CLEAR_SEGOVR();
3438 /****************************************************************************
3441 ****************************************************************************/
3442 void x86emuOp_enter(u8
X86EMU_UNUSED(op1
))
3444 u16 local
,frame_pointer
;
3449 local
= fetch_word_imm();
3450 nesting
= fetch_byte_imm();
3451 DECODE_PRINTF2("ENTER %x\n", local
);
3452 DECODE_PRINTF2(",%x\n", nesting
);
3454 push_word(M
.x86
.R_BP
);
3455 frame_pointer
= M
.x86
.R_SP
;
3457 for (i
= 1; i
< nesting
; i
++) {
3459 push_word(fetch_data_word_abs(M
.x86
.R_SS
, M
.x86
.R_BP
));
3461 push_word(frame_pointer
);
3463 M
.x86
.R_BP
= frame_pointer
;
3464 M
.x86
.R_SP
= (u16
)(M
.x86
.R_SP
- local
);
3465 DECODE_CLEAR_SEGOVR();
3469 /****************************************************************************
3472 ****************************************************************************/
3473 void x86emuOp_leave(u8
X86EMU_UNUSED(op1
))
3476 DECODE_PRINTF("LEAVE\n");
3478 M
.x86
.R_SP
= M
.x86
.R_BP
;
3479 M
.x86
.R_BP
= pop_word();
3480 DECODE_CLEAR_SEGOVR();
3484 /****************************************************************************
3487 ****************************************************************************/
3488 void x86emuOp_ret_far_IMM(u8
X86EMU_UNUSED(op1
))
3493 DECODE_PRINTF("RETF\t");
3494 imm
= fetch_word_imm();
3495 DECODE_PRINTF2("%x\n", imm
);
3496 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
3498 M
.x86
.R_IP
= pop_word();
3499 M
.x86
.R_CS
= pop_word();
3501 DECODE_CLEAR_SEGOVR();
3505 /****************************************************************************
3508 ****************************************************************************/
3509 void x86emuOp_ret_far(u8
X86EMU_UNUSED(op1
))
3512 DECODE_PRINTF("RETF\n");
3513 RETURN_TRACE("RETF",M
.x86
.saved_cs
,M
.x86
.saved_ip
);
3515 M
.x86
.R_IP
= pop_word();
3516 M
.x86
.R_CS
= pop_word();
3517 DECODE_CLEAR_SEGOVR();
3521 /****************************************************************************
3524 ****************************************************************************/
3525 void x86emuOp_int3(u8
X86EMU_UNUSED(op1
))
3530 DECODE_PRINTF("INT 3\n");
3531 tmp
= (u16
) mem_access_word(3 * 4 + 2);
3532 /* access the segment register */
3534 if (_X86EMU_intrTab
[3]) {
3535 (*_X86EMU_intrTab
[3])(3);
3537 push_word((u16
)M
.x86
.R_FLG
);
3540 push_word(M
.x86
.R_CS
);
3541 M
.x86
.R_CS
= mem_access_word(3 * 4 + 2);
3542 push_word(M
.x86
.R_IP
);
3543 M
.x86
.R_IP
= mem_access_word(3 * 4);
3545 DECODE_CLEAR_SEGOVR();
3549 /****************************************************************************
3552 ****************************************************************************/
3553 void x86emuOp_int_IMM(u8
X86EMU_UNUSED(op1
))
3559 DECODE_PRINTF("INT\t");
3560 intnum
= fetch_byte_imm();
3561 DECODE_PRINTF2("%x\n", intnum
);
3562 tmp
= mem_access_word(intnum
* 4 + 2);
3564 if (_X86EMU_intrTab
[intnum
]) {
3565 (*_X86EMU_intrTab
[intnum
])(intnum
);
3567 push_word((u16
)M
.x86
.R_FLG
);
3570 push_word(M
.x86
.R_CS
);
3571 M
.x86
.R_CS
= mem_access_word(intnum
* 4 + 2);
3572 push_word(M
.x86
.R_IP
);
3573 M
.x86
.R_IP
= mem_access_word(intnum
* 4);
3575 DECODE_CLEAR_SEGOVR();
3579 /****************************************************************************
3582 ****************************************************************************/
3583 void x86emuOp_into(u8
X86EMU_UNUSED(op1
))
3588 DECODE_PRINTF("INTO\n");
3590 if (ACCESS_FLAG(F_OF
)) {
3591 tmp
= mem_access_word(4 * 4 + 2);
3592 if (_X86EMU_intrTab
[4]) {
3593 (*_X86EMU_intrTab
[4])(4);
3595 push_word((u16
)M
.x86
.R_FLG
);
3598 push_word(M
.x86
.R_CS
);
3599 M
.x86
.R_CS
= mem_access_word(4 * 4 + 2);
3600 push_word(M
.x86
.R_IP
);
3601 M
.x86
.R_IP
= mem_access_word(4 * 4);
3604 DECODE_CLEAR_SEGOVR();
3608 /****************************************************************************
3611 ****************************************************************************/
3612 void x86emuOp_iret(u8
X86EMU_UNUSED(op1
))
3615 DECODE_PRINTF("IRET\n");
3619 M
.x86
.R_IP
= pop_word();
3620 M
.x86
.R_CS
= pop_word();
3621 M
.x86
.R_FLG
= pop_word();
3622 DECODE_CLEAR_SEGOVR();
3626 /****************************************************************************
3629 ****************************************************************************/
3630 void x86emuOp_opcD0_byte_RM_1(u8
X86EMU_UNUSED(op1
))
3638 * Yet another weirdo special case instruction format. Part of
3639 * the opcode held below in "RH". Doubly nested case would
3640 * result, except that the decoded instruction
3643 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3645 if (DEBUG_DECODE()) {
3646 /* XXX DECODE_PRINTF may be changed to something more
3647 general, so that it is important to leave the strings
3648 in the same format, even though the result is that the
3649 above test is done twice. */
3652 DECODE_PRINTF("ROL\t");
3655 DECODE_PRINTF("ROR\t");
3658 DECODE_PRINTF("RCL\t");
3661 DECODE_PRINTF("RCR\t");
3664 DECODE_PRINTF("SHL\t");
3667 DECODE_PRINTF("SHR\t");
3670 DECODE_PRINTF("SAL\t");
3673 DECODE_PRINTF("SAR\t");
3678 /* know operation, decode the mod byte to find the addressing
3681 DECODE_PRINTF("BYTE PTR ");
3682 destoffset
= decode_rmXX_address(mod
, rl
);
3683 DECODE_PRINTF(",1\n");
3684 destval
= fetch_data_byte(destoffset
);
3686 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
3687 store_data_byte(destoffset
, destval
);
3688 } else { /* register to register */
3689 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3690 DECODE_PRINTF(",1\n");
3692 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, 1);
3695 DECODE_CLEAR_SEGOVR();
3699 /****************************************************************************
3702 ****************************************************************************/
3703 void x86emuOp_opcD1_word_RM_1(u8
X86EMU_UNUSED(op1
))
3709 * Yet another weirdo special case instruction format. Part of
3710 * the opcode held below in "RH". Doubly nested case would
3711 * result, except that the decoded instruction
3714 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3716 if (DEBUG_DECODE()) {
3717 /* XXX DECODE_PRINTF may be changed to something more
3718 general, so that it is important to leave the strings
3719 in the same format, even though the result is that the
3720 above test is done twice. */
3723 DECODE_PRINTF("ROL\t");
3726 DECODE_PRINTF("ROR\t");
3729 DECODE_PRINTF("RCL\t");
3732 DECODE_PRINTF("RCR\t");
3735 DECODE_PRINTF("SHL\t");
3738 DECODE_PRINTF("SHR\t");
3741 DECODE_PRINTF("SAL\t");
3744 DECODE_PRINTF("SAR\t");
3749 /* know operation, decode the mod byte to find the addressing
3752 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3755 DECODE_PRINTF("DWORD PTR ");
3756 destoffset
= decode_rmXX_address(mod
, rl
);
3757 DECODE_PRINTF(",1\n");
3758 destval
= fetch_data_long(destoffset
);
3760 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
3761 store_data_long(destoffset
, destval
);
3765 DECODE_PRINTF("WORD PTR ");
3766 destoffset
= decode_rmXX_address(mod
, rl
);
3767 DECODE_PRINTF(",1\n");
3768 destval
= fetch_data_word(destoffset
);
3770 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
3771 store_data_word(destoffset
, destval
);
3773 } else { /* register to register */
3774 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3778 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3779 DECODE_PRINTF(",1\n");
3781 destval
= (*opcD1_long_operation
[rh
]) (*destreg
, 1);
3787 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3788 DECODE_PRINTF(",1\n");
3790 destval
= (*opcD1_word_operation
[rh
]) (*destreg
, 1);
3794 DECODE_CLEAR_SEGOVR();
3798 /****************************************************************************
3801 ****************************************************************************/
3802 void x86emuOp_opcD2_byte_RM_CL(u8
X86EMU_UNUSED(op1
))
3811 * Yet another weirdo special case instruction format. Part of
3812 * the opcode held below in "RH". Doubly nested case would
3813 * result, except that the decoded instruction
3816 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3818 if (DEBUG_DECODE()) {
3819 /* XXX DECODE_PRINTF may be changed to something more
3820 general, so that it is important to leave the strings
3821 in the same format, even though the result is that the
3822 above test is done twice. */
3825 DECODE_PRINTF("ROL\t");
3828 DECODE_PRINTF("ROR\t");
3831 DECODE_PRINTF("RCL\t");
3834 DECODE_PRINTF("RCR\t");
3837 DECODE_PRINTF("SHL\t");
3840 DECODE_PRINTF("SHR\t");
3843 DECODE_PRINTF("SAL\t");
3846 DECODE_PRINTF("SAR\t");
3851 /* know operation, decode the mod byte to find the addressing
3855 DECODE_PRINTF("BYTE PTR ");
3856 destoffset
= decode_rmXX_address(mod
, rl
);
3857 DECODE_PRINTF(",CL\n");
3858 destval
= fetch_data_byte(destoffset
);
3860 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
3861 store_data_byte(destoffset
, destval
);
3862 } else { /* register to register */
3863 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3864 DECODE_PRINTF(",CL\n");
3866 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
3869 DECODE_CLEAR_SEGOVR();
3873 /****************************************************************************
3876 ****************************************************************************/
3877 void x86emuOp_opcD3_word_RM_CL(u8
X86EMU_UNUSED(op1
))
3884 * Yet another weirdo special case instruction format. Part of
3885 * the opcode held below in "RH". Doubly nested case would
3886 * result, except that the decoded instruction
3889 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3891 if (DEBUG_DECODE()) {
3892 /* XXX DECODE_PRINTF may be changed to something more
3893 general, so that it is important to leave the strings
3894 in the same format, even though the result is that the
3895 above test is done twice. */
3898 DECODE_PRINTF("ROL\t");
3901 DECODE_PRINTF("ROR\t");
3904 DECODE_PRINTF("RCL\t");
3907 DECODE_PRINTF("RCR\t");
3910 DECODE_PRINTF("SHL\t");
3913 DECODE_PRINTF("SHR\t");
3916 DECODE_PRINTF("SAL\t");
3919 DECODE_PRINTF("SAR\t");
3924 /* know operation, decode the mod byte to find the addressing
3928 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3931 DECODE_PRINTF("DWORD PTR ");
3932 destoffset
= decode_rmXX_address(mod
, rl
);
3933 DECODE_PRINTF(",CL\n");
3934 destval
= fetch_data_long(destoffset
);
3936 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
3937 store_data_long(destoffset
, destval
);
3941 DECODE_PRINTF("WORD PTR ");
3942 destoffset
= decode_rmXX_address(mod
, rl
);
3943 DECODE_PRINTF(",CL\n");
3944 destval
= fetch_data_word(destoffset
);
3946 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
3947 store_data_word(destoffset
, destval
);
3949 } else { /* register to register */
3950 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3953 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3954 DECODE_PRINTF(",CL\n");
3956 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
3960 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3961 DECODE_PRINTF(",CL\n");
3963 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
3966 DECODE_CLEAR_SEGOVR();
3970 /****************************************************************************
3973 ****************************************************************************/
3974 void x86emuOp_aam(u8
X86EMU_UNUSED(op1
))
3979 DECODE_PRINTF("AAM\n");
3980 a
= fetch_byte_imm(); /* this is a stupid encoding. */
3982 DECODE_PRINTF("ERROR DECODING AAM\n");
3987 /* note the type change here --- returning AL and AH in AX. */
3988 M
.x86
.R_AX
= aam_word(M
.x86
.R_AL
);
3989 DECODE_CLEAR_SEGOVR();
3993 /****************************************************************************
3996 ****************************************************************************/
3997 void x86emuOp_aad(u8
X86EMU_UNUSED(op1
))
4002 DECODE_PRINTF("AAD\n");
4003 a
= fetch_byte_imm();
4005 M
.x86
.R_AX
= aad_word(M
.x86
.R_AX
);
4006 DECODE_CLEAR_SEGOVR();
4010 /* opcode 0xd6 ILLEGAL OPCODE */
4012 /****************************************************************************
4015 ****************************************************************************/
4016 void x86emuOp_xlat(u8
X86EMU_UNUSED(op1
))
4021 DECODE_PRINTF("XLAT\n");
4023 addr
= (u16
)(M
.x86
.R_BX
+ (u8
)M
.x86
.R_AL
);
4024 M
.x86
.R_AL
= fetch_data_byte(addr
);
4025 DECODE_CLEAR_SEGOVR();
4029 /* instuctions D8 .. DF are in i87_ops.c */
4031 /****************************************************************************
4034 ****************************************************************************/
4035 void x86emuOp_loopne(u8
X86EMU_UNUSED(op1
))
4040 DECODE_PRINTF("LOOPNE\t");
4041 ip
= (s8
) fetch_byte_imm();
4042 ip
+= (s16
) M
.x86
.R_IP
;
4043 DECODE_PRINTF2("%04x\n", ip
);
4046 if (M
.x86
.R_CX
!= 0 && !ACCESS_FLAG(F_ZF
)) /* CX != 0 and !ZF */
4048 DECODE_CLEAR_SEGOVR();
4052 /****************************************************************************
4055 ****************************************************************************/
4056 void x86emuOp_loope(u8
X86EMU_UNUSED(op1
))
4061 DECODE_PRINTF("LOOPE\t");
4062 ip
= (s8
) fetch_byte_imm();
4063 ip
+= (s16
) M
.x86
.R_IP
;
4064 DECODE_PRINTF2("%04x\n", ip
);
4067 if (M
.x86
.R_CX
!= 0 && ACCESS_FLAG(F_ZF
)) /* CX != 0 and ZF */
4069 DECODE_CLEAR_SEGOVR();
4073 /****************************************************************************
4076 ****************************************************************************/
4077 void x86emuOp_loop(u8
X86EMU_UNUSED(op1
))
4082 DECODE_PRINTF("LOOP\t");
4083 ip
= (s8
) fetch_byte_imm();
4084 ip
+= (s16
) M
.x86
.R_IP
;
4085 DECODE_PRINTF2("%04x\n", ip
);
4088 if (M
.x86
.R_CX
!= 0)
4090 DECODE_CLEAR_SEGOVR();
4094 /****************************************************************************
4097 ****************************************************************************/
4098 void x86emuOp_jcxz(u8
X86EMU_UNUSED(op1
))
4103 /* jump to byte offset if overflow flag is set */
4105 DECODE_PRINTF("JCXZ\t");
4106 offset
= (s8
)fetch_byte_imm();
4107 target
= (u16
)(M
.x86
.R_IP
+ offset
);
4108 DECODE_PRINTF2("%x\n", target
);
4110 if (M
.x86
.R_CX
== 0)
4111 M
.x86
.R_IP
= target
;
4112 DECODE_CLEAR_SEGOVR();
4116 /****************************************************************************
4119 ****************************************************************************/
4120 void x86emuOp_in_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
4125 DECODE_PRINTF("IN\t");
4126 port
= (u8
) fetch_byte_imm();
4127 DECODE_PRINTF2("%x,AL\n", port
);
4129 M
.x86
.R_AL
= (*sys_inb
)(port
);
4130 DECODE_CLEAR_SEGOVR();
4134 /****************************************************************************
4137 ****************************************************************************/
4138 void x86emuOp_in_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
4143 DECODE_PRINTF("IN\t");
4144 port
= (u8
) fetch_byte_imm();
4145 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4146 DECODE_PRINTF2("EAX,%x\n", port
);
4148 DECODE_PRINTF2("AX,%x\n", port
);
4151 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4152 M
.x86
.R_EAX
= (*sys_inl
)(port
);
4154 M
.x86
.R_AX
= (*sys_inw
)(port
);
4156 DECODE_CLEAR_SEGOVR();
4160 /****************************************************************************
4163 ****************************************************************************/
4164 void x86emuOp_out_byte_IMM_AL(u8
X86EMU_UNUSED(op1
))
4169 DECODE_PRINTF("OUT\t");
4170 port
= (u8
) fetch_byte_imm();
4171 DECODE_PRINTF2("%x,AL\n", port
);
4173 (*sys_outb
)(port
, M
.x86
.R_AL
);
4174 DECODE_CLEAR_SEGOVR();
4178 /****************************************************************************
4181 ****************************************************************************/
4182 void x86emuOp_out_word_IMM_AX(u8
X86EMU_UNUSED(op1
))
4187 DECODE_PRINTF("OUT\t");
4188 port
= (u8
) fetch_byte_imm();
4189 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4190 DECODE_PRINTF2("%x,EAX\n", port
);
4192 DECODE_PRINTF2("%x,AX\n", port
);
4195 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4196 (*sys_outl
)(port
, M
.x86
.R_EAX
);
4198 (*sys_outw
)(port
, M
.x86
.R_AX
);
4200 DECODE_CLEAR_SEGOVR();
4204 /****************************************************************************
4207 ****************************************************************************/
4208 void x86emuOp_call_near_IMM(u8
X86EMU_UNUSED(op1
))
4213 DECODE_PRINTF("CALL\t");
4214 ip
= (s16
) fetch_word_imm();
4215 ip
+= (s16
) M
.x86
.R_IP
; /* CHECK SIGN */
4216 DECODE_PRINTF2("%04x\n", ip
);
4217 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip
, "");
4219 push_word(M
.x86
.R_IP
);
4221 DECODE_CLEAR_SEGOVR();
4225 /****************************************************************************
4228 ****************************************************************************/
4229 void x86emuOp_jump_near_IMM(u8
X86EMU_UNUSED(op1
))
4234 DECODE_PRINTF("JMP\t");
4235 ip
= (s16
)fetch_word_imm();
4236 ip
+= (s16
)M
.x86
.R_IP
;
4237 DECODE_PRINTF2("%04x\n", ip
);
4239 M
.x86
.R_IP
= (u16
)ip
;
4240 DECODE_CLEAR_SEGOVR();
4244 /****************************************************************************
4247 ****************************************************************************/
4248 void x86emuOp_jump_far_IMM(u8
X86EMU_UNUSED(op1
))
4253 DECODE_PRINTF("JMP\tFAR ");
4254 ip
= fetch_word_imm();
4255 cs
= fetch_word_imm();
4256 DECODE_PRINTF2("%04x:", cs
);
4257 DECODE_PRINTF2("%04x\n", ip
);
4261 DECODE_CLEAR_SEGOVR();
4265 /****************************************************************************
4268 ****************************************************************************/
4269 void x86emuOp_jump_byte_IMM(u8
X86EMU_UNUSED(op1
))
4275 DECODE_PRINTF("JMP\t");
4276 offset
= (s8
)fetch_byte_imm();
4277 target
= (u16
)(M
.x86
.R_IP
+ offset
);
4278 DECODE_PRINTF2("%x\n", target
);
4280 M
.x86
.R_IP
= target
;
4281 DECODE_CLEAR_SEGOVR();
4285 /****************************************************************************
4288 ****************************************************************************/
4289 void x86emuOp_in_byte_AL_DX(u8
X86EMU_UNUSED(op1
))
4292 DECODE_PRINTF("IN\tAL,DX\n");
4294 M
.x86
.R_AL
= (*sys_inb
)(M
.x86
.R_DX
);
4295 DECODE_CLEAR_SEGOVR();
4299 /****************************************************************************
4302 ****************************************************************************/
4303 void x86emuOp_in_word_AX_DX(u8
X86EMU_UNUSED(op1
))
4306 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4307 DECODE_PRINTF("IN\tEAX,DX\n");
4309 DECODE_PRINTF("IN\tAX,DX\n");
4312 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4313 M
.x86
.R_EAX
= (*sys_inl
)(M
.x86
.R_DX
);
4315 M
.x86
.R_AX
= (*sys_inw
)(M
.x86
.R_DX
);
4317 DECODE_CLEAR_SEGOVR();
4321 /****************************************************************************
4324 ****************************************************************************/
4325 void x86emuOp_out_byte_DX_AL(u8
X86EMU_UNUSED(op1
))
4328 DECODE_PRINTF("OUT\tDX,AL\n");
4330 (*sys_outb
)(M
.x86
.R_DX
, M
.x86
.R_AL
);
4331 DECODE_CLEAR_SEGOVR();
4335 /****************************************************************************
4338 ****************************************************************************/
4339 void x86emuOp_out_word_DX_AX(u8
X86EMU_UNUSED(op1
))
4342 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4343 DECODE_PRINTF("OUT\tDX,EAX\n");
4345 DECODE_PRINTF("OUT\tDX,AX\n");
4348 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4349 (*sys_outl
)(M
.x86
.R_DX
, M
.x86
.R_EAX
);
4351 (*sys_outw
)(M
.x86
.R_DX
, M
.x86
.R_AX
);
4353 DECODE_CLEAR_SEGOVR();
4357 /****************************************************************************
4360 ****************************************************************************/
4361 void x86emuOp_lock(u8
X86EMU_UNUSED(op1
))
4364 DECODE_PRINTF("LOCK:\n");
4366 DECODE_CLEAR_SEGOVR();
4370 /*opcode 0xf1 ILLEGAL OPERATION */
4372 /****************************************************************************
4375 ****************************************************************************/
4376 void x86emuOp_repne(u8
X86EMU_UNUSED(op1
))
4379 DECODE_PRINTF("REPNE\n");
4381 M
.x86
.mode
|= SYSMODE_PREFIX_REPNE
;
4382 DECODE_CLEAR_SEGOVR();
4386 /****************************************************************************
4389 ****************************************************************************/
4390 void x86emuOp_repe(u8
X86EMU_UNUSED(op1
))
4393 DECODE_PRINTF("REPE\n");
4395 M
.x86
.mode
|= SYSMODE_PREFIX_REPE
;
4396 DECODE_CLEAR_SEGOVR();
4400 /****************************************************************************
4403 ****************************************************************************/
4404 void x86emuOp_halt(u8
X86EMU_UNUSED(op1
))
4407 DECODE_PRINTF("HALT\n");
4410 DECODE_CLEAR_SEGOVR();
4414 /****************************************************************************
4417 ****************************************************************************/
4418 void x86emuOp_cmc(u8
X86EMU_UNUSED(op1
))
4420 /* complement the carry flag. */
4422 DECODE_PRINTF("CMC\n");
4425 DECODE_CLEAR_SEGOVR();
4429 /****************************************************************************
4432 ****************************************************************************/
4433 void x86emuOp_opcF6_byte_RM(u8
X86EMU_UNUSED(op1
))
4440 /* long, drawn out code follows. Double switch for a total
4443 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4444 DECODE_PRINTF(opF6_names
[rh
]);
4446 DECODE_PRINTF("BYTE PTR ");
4447 destoffset
= decode_rmXX_address(mod
, rl
);
4448 destval
= fetch_data_byte(destoffset
);
4451 case 0: /* test byte imm */
4453 srcval
= fetch_byte_imm();
4454 DECODE_PRINTF2("%02x\n", srcval
);
4456 test_byte(destval
, srcval
);
4459 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4463 DECODE_PRINTF("\n");
4465 destval
= not_byte(destval
);
4466 store_data_byte(destoffset
, destval
);
4469 DECODE_PRINTF("\n");
4471 destval
= neg_byte(destval
);
4472 store_data_byte(destoffset
, destval
);
4475 DECODE_PRINTF("\n");
4480 DECODE_PRINTF("\n");
4485 DECODE_PRINTF("\n");
4490 DECODE_PRINTF("\n");
4495 } else { /* mod=11 */
4496 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
4498 case 0: /* test byte imm */
4500 srcval
= fetch_byte_imm();
4501 DECODE_PRINTF2("%02x\n", srcval
);
4503 test_byte(*destreg
, srcval
);
4506 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4510 DECODE_PRINTF("\n");
4512 *destreg
= not_byte(*destreg
);
4515 DECODE_PRINTF("\n");
4517 *destreg
= neg_byte(*destreg
);
4520 DECODE_PRINTF("\n");
4522 mul_byte(*destreg
); /*!!! */
4525 DECODE_PRINTF("\n");
4527 imul_byte(*destreg
);
4530 DECODE_PRINTF("\n");
4535 DECODE_PRINTF("\n");
4537 idiv_byte(*destreg
);
4541 DECODE_CLEAR_SEGOVR();
4545 /****************************************************************************
4548 ****************************************************************************/
4549 void x86emuOp_opcF7_word_RM(u8
X86EMU_UNUSED(op1
))
4555 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4556 DECODE_PRINTF(opF6_names
[rh
]);
4559 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4560 u32 destval
, srcval
;
4562 DECODE_PRINTF("DWORD PTR ");
4563 destoffset
= decode_rmXX_address(mod
, rl
);
4564 destval
= fetch_data_long(destoffset
);
4569 srcval
= fetch_long_imm();
4570 DECODE_PRINTF2("%x\n", srcval
);
4572 test_long(destval
, srcval
);
4575 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4579 DECODE_PRINTF("\n");
4581 destval
= not_long(destval
);
4582 store_data_long(destoffset
, destval
);
4585 DECODE_PRINTF("\n");
4587 destval
= neg_long(destval
);
4588 store_data_long(destoffset
, destval
);
4591 DECODE_PRINTF("\n");
4596 DECODE_PRINTF("\n");
4601 DECODE_PRINTF("\n");
4606 DECODE_PRINTF("\n");
4612 u16 destval
, srcval
;
4614 DECODE_PRINTF("WORD PTR ");
4615 destoffset
= decode_rmXX_address(mod
, rl
);
4616 destval
= fetch_data_word(destoffset
);
4619 case 0: /* test word imm */
4621 srcval
= fetch_word_imm();
4622 DECODE_PRINTF2("%x\n", srcval
);
4624 test_word(destval
, srcval
);
4627 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4631 DECODE_PRINTF("\n");
4633 destval
= not_word(destval
);
4634 store_data_word(destoffset
, destval
);
4637 DECODE_PRINTF("\n");
4639 destval
= neg_word(destval
);
4640 store_data_word(destoffset
, destval
);
4643 DECODE_PRINTF("\n");
4648 DECODE_PRINTF("\n");
4653 DECODE_PRINTF("\n");
4658 DECODE_PRINTF("\n");
4665 } else { /* mod=11 */
4667 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4671 destreg
= DECODE_RM_LONG_REGISTER(rl
);
4674 case 0: /* test word imm */
4676 srcval
= fetch_long_imm();
4677 DECODE_PRINTF2("%x\n", srcval
);
4679 test_long(*destreg
, srcval
);
4682 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4686 DECODE_PRINTF("\n");
4688 *destreg
= not_long(*destreg
);
4691 DECODE_PRINTF("\n");
4693 *destreg
= neg_long(*destreg
);
4696 DECODE_PRINTF("\n");
4698 mul_long(*destreg
); /*!!! */
4701 DECODE_PRINTF("\n");
4703 imul_long(*destreg
);
4706 DECODE_PRINTF("\n");
4711 DECODE_PRINTF("\n");
4713 idiv_long(*destreg
);
4720 destreg
= DECODE_RM_WORD_REGISTER(rl
);
4723 case 0: /* test word imm */
4725 srcval
= fetch_word_imm();
4726 DECODE_PRINTF2("%x\n", srcval
);
4728 test_word(*destreg
, srcval
);
4731 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4735 DECODE_PRINTF("\n");
4737 *destreg
= not_word(*destreg
);
4740 DECODE_PRINTF("\n");
4742 *destreg
= neg_word(*destreg
);
4745 DECODE_PRINTF("\n");
4747 mul_word(*destreg
); /*!!! */
4750 DECODE_PRINTF("\n");
4752 imul_word(*destreg
);
4755 DECODE_PRINTF("\n");
4760 DECODE_PRINTF("\n");
4762 idiv_word(*destreg
);
4767 DECODE_CLEAR_SEGOVR();
4771 /****************************************************************************
4774 ****************************************************************************/
4775 void x86emuOp_clc(u8
X86EMU_UNUSED(op1
))
4777 /* clear the carry flag. */
4779 DECODE_PRINTF("CLC\n");
4782 DECODE_CLEAR_SEGOVR();
4786 /****************************************************************************
4789 ****************************************************************************/
4790 void x86emuOp_stc(u8
X86EMU_UNUSED(op1
))
4792 /* set the carry flag. */
4794 DECODE_PRINTF("STC\n");
4797 DECODE_CLEAR_SEGOVR();
4801 /****************************************************************************
4804 ****************************************************************************/
4805 void x86emuOp_cli(u8
X86EMU_UNUSED(op1
))
4807 /* clear interrupts. */
4809 DECODE_PRINTF("CLI\n");
4812 DECODE_CLEAR_SEGOVR();
4816 /****************************************************************************
4819 ****************************************************************************/
4820 void x86emuOp_sti(u8
X86EMU_UNUSED(op1
))
4822 /* enable interrupts. */
4824 DECODE_PRINTF("STI\n");
4827 DECODE_CLEAR_SEGOVR();
4831 /****************************************************************************
4834 ****************************************************************************/
4835 void x86emuOp_cld(u8
X86EMU_UNUSED(op1
))
4837 /* clear interrupts. */
4839 DECODE_PRINTF("CLD\n");
4842 DECODE_CLEAR_SEGOVR();
4846 /****************************************************************************
4849 ****************************************************************************/
4850 void x86emuOp_std(u8
X86EMU_UNUSED(op1
))
4852 /* clear interrupts. */
4854 DECODE_PRINTF("STD\n");
4857 DECODE_CLEAR_SEGOVR();
4861 /****************************************************************************
4864 ****************************************************************************/
4865 void x86emuOp_opcFE_byte_RM(u8
X86EMU_UNUSED(op1
))
4872 /* Yet another special case instruction. */
4874 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4876 if (DEBUG_DECODE()) {
4877 /* XXX DECODE_PRINTF may be changed to something more
4878 general, so that it is important to leave the strings
4879 in the same format, even though the result is that the
4880 above test is done twice. */
4884 DECODE_PRINTF("INC\t");
4887 DECODE_PRINTF("DEC\t");
4895 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod
);
4902 DECODE_PRINTF("BYTE PTR ");
4903 destoffset
= decode_rmXX_address(mod
, rl
);
4904 DECODE_PRINTF("\n");
4905 destval
= fetch_data_byte(destoffset
);
4908 destval
= inc_byte(destval
);
4910 destval
= dec_byte(destval
);
4911 store_data_byte(destoffset
, destval
);
4913 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
4914 DECODE_PRINTF("\n");
4917 *destreg
= inc_byte(*destreg
);
4919 *destreg
= dec_byte(*destreg
);
4921 DECODE_CLEAR_SEGOVR();
4925 /****************************************************************************
4928 ****************************************************************************/
4929 void x86emuOp_opcFF_word_RM(u8
X86EMU_UNUSED(op1
))
4932 uint destoffset
= 0;
4934 u16 destval
,destval2
;
4936 /* Yet another special case instruction. */
4938 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4940 if (DEBUG_DECODE()) {
4941 /* XXX DECODE_PRINTF may be changed to something more
4942 general, so that it is important to leave the strings
4943 in the same format, even though the result is that the
4944 above test is done twice. */
4948 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4949 DECODE_PRINTF("INC\tDWORD PTR ");
4951 DECODE_PRINTF("INC\tWORD PTR ");
4955 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4956 DECODE_PRINTF("DEC\tDWORD PTR ");
4958 DECODE_PRINTF("DEC\tWORD PTR ");
4962 DECODE_PRINTF("CALL\t ");
4965 DECODE_PRINTF("CALL\tFAR ");
4968 DECODE_PRINTF("JMP\t");
4971 DECODE_PRINTF("JMP\tFAR ");
4974 DECODE_PRINTF("PUSH\t");
4977 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
4984 destoffset
= decode_rmXX_address(mod
, rl
);
4985 DECODE_PRINTF("\n");
4987 case 0: /* inc word ptr ... */
4988 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4991 destval
= fetch_data_long(destoffset
);
4993 destval
= inc_long(destval
);
4994 store_data_long(destoffset
, destval
);
4998 destval
= fetch_data_word(destoffset
);
5000 destval
= inc_word(destval
);
5001 store_data_word(destoffset
, destval
);
5004 case 1: /* dec word ptr ... */
5005 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5008 destval
= fetch_data_long(destoffset
);
5010 destval
= dec_long(destval
);
5011 store_data_long(destoffset
, destval
);
5015 destval
= fetch_data_word(destoffset
);
5017 destval
= dec_word(destval
);
5018 store_data_word(destoffset
, destval
);
5021 case 2: /* call word ptr ... */
5022 destval
= fetch_data_word(destoffset
);
5024 push_word(M
.x86
.R_IP
);
5025 M
.x86
.R_IP
= destval
;
5027 case 3: /* call far ptr ... */
5028 destval
= fetch_data_word(destoffset
);
5029 destval2
= fetch_data_word(destoffset
+ 2);
5031 push_word(M
.x86
.R_CS
);
5032 M
.x86
.R_CS
= destval2
;
5033 push_word(M
.x86
.R_IP
);
5034 M
.x86
.R_IP
= destval
;
5036 case 4: /* jmp word ptr ... */
5037 destval
= fetch_data_word(destoffset
);
5039 M
.x86
.R_IP
= destval
;
5041 case 5: /* jmp far ptr ... */
5042 destval
= fetch_data_word(destoffset
);
5043 destval2
= fetch_data_word(destoffset
+ 2);
5045 M
.x86
.R_IP
= destval
;
5046 M
.x86
.R_CS
= destval2
;
5048 case 6: /* push word ptr ... */
5049 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5052 destval
= fetch_data_long(destoffset
);
5058 destval
= fetch_data_word(destoffset
);
5067 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5070 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5071 DECODE_PRINTF("\n");
5073 *destreg
= inc_long(*destreg
);
5077 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5078 DECODE_PRINTF("\n");
5080 *destreg
= inc_word(*destreg
);
5084 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5087 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5088 DECODE_PRINTF("\n");
5090 *destreg
= dec_long(*destreg
);
5094 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5095 DECODE_PRINTF("\n");
5097 *destreg
= dec_word(*destreg
);
5100 case 2: /* call word ptr ... */
5101 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5102 DECODE_PRINTF("\n");
5104 push_word(M
.x86
.R_IP
);
5105 M
.x86
.R_IP
= *destreg
;
5107 case 3: /* jmp far ptr ... */
5108 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5113 case 4: /* jmp ... */
5114 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5115 DECODE_PRINTF("\n");
5117 M
.x86
.R_IP
= (u16
) (*destreg
);
5119 case 5: /* jmp far ptr ... */
5120 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5125 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5128 destreg
= DECODE_RM_LONG_REGISTER(rl
);
5129 DECODE_PRINTF("\n");
5131 push_long(*destreg
);
5135 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5136 DECODE_PRINTF("\n");
5138 push_word(*destreg
);
5143 DECODE_CLEAR_SEGOVR();
5147 /***************************************************************************
5148 * Single byte operation code table:
5149 **************************************************************************/
5150 void (*x86emu_optab
[256])(u8
) __attribute__ ((section(GOT2_TYPE
))) =
5152 /* 0x00 */ x86emuOp_genop_byte_RM_R
,
5153 /* 0x01 */ x86emuOp_genop_word_RM_R
,
5154 /* 0x02 */ x86emuOp_genop_byte_R_RM
,
5155 /* 0x03 */ x86emuOp_genop_word_R_RM
,
5156 /* 0x04 */ x86emuOp_genop_byte_AL_IMM
,
5157 /* 0x05 */ x86emuOp_genop_word_AX_IMM
,
5158 /* 0x06 */ x86emuOp_push_ES
,
5159 /* 0x07 */ x86emuOp_pop_ES
,
5161 /* 0x08 */ x86emuOp_genop_byte_RM_R
,
5162 /* 0x09 */ x86emuOp_genop_word_RM_R
,
5163 /* 0x0a */ x86emuOp_genop_byte_R_RM
,
5164 /* 0x0b */ x86emuOp_genop_word_R_RM
,
5165 /* 0x0c */ x86emuOp_genop_byte_AL_IMM
,
5166 /* 0x0d */ x86emuOp_genop_word_AX_IMM
,
5167 /* 0x0e */ x86emuOp_push_CS
,
5168 /* 0x0f */ x86emuOp_two_byte
,
5170 /* 0x10 */ x86emuOp_genop_byte_RM_R
,
5171 /* 0x11 */ x86emuOp_genop_word_RM_R
,
5172 /* 0x12 */ x86emuOp_genop_byte_R_RM
,
5173 /* 0x13 */ x86emuOp_genop_word_R_RM
,
5174 /* 0x14 */ x86emuOp_genop_byte_AL_IMM
,
5175 /* 0x15 */ x86emuOp_genop_word_AX_IMM
,
5176 /* 0x16 */ x86emuOp_push_SS
,
5177 /* 0x17 */ x86emuOp_pop_SS
,
5179 /* 0x18 */ x86emuOp_genop_byte_RM_R
,
5180 /* 0x19 */ x86emuOp_genop_word_RM_R
,
5181 /* 0x1a */ x86emuOp_genop_byte_R_RM
,
5182 /* 0x1b */ x86emuOp_genop_word_R_RM
,
5183 /* 0x1c */ x86emuOp_genop_byte_AL_IMM
,
5184 /* 0x1d */ x86emuOp_genop_word_AX_IMM
,
5185 /* 0x1e */ x86emuOp_push_DS
,
5186 /* 0x1f */ x86emuOp_pop_DS
,
5188 /* 0x20 */ x86emuOp_genop_byte_RM_R
,
5189 /* 0x21 */ x86emuOp_genop_word_RM_R
,
5190 /* 0x22 */ x86emuOp_genop_byte_R_RM
,
5191 /* 0x23 */ x86emuOp_genop_word_R_RM
,
5192 /* 0x24 */ x86emuOp_genop_byte_AL_IMM
,
5193 /* 0x25 */ x86emuOp_genop_word_AX_IMM
,
5194 /* 0x26 */ x86emuOp_segovr_ES
,
5195 /* 0x27 */ x86emuOp_daa
,
5197 /* 0x28 */ x86emuOp_genop_byte_RM_R
,
5198 /* 0x29 */ x86emuOp_genop_word_RM_R
,
5199 /* 0x2a */ x86emuOp_genop_byte_R_RM
,
5200 /* 0x2b */ x86emuOp_genop_word_R_RM
,
5201 /* 0x2c */ x86emuOp_genop_byte_AL_IMM
,
5202 /* 0x2d */ x86emuOp_genop_word_AX_IMM
,
5203 /* 0x2e */ x86emuOp_segovr_CS
,
5204 /* 0x2f */ x86emuOp_das
,
5206 /* 0x30 */ x86emuOp_genop_byte_RM_R
,
5207 /* 0x31 */ x86emuOp_genop_word_RM_R
,
5208 /* 0x32 */ x86emuOp_genop_byte_R_RM
,
5209 /* 0x33 */ x86emuOp_genop_word_R_RM
,
5210 /* 0x34 */ x86emuOp_genop_byte_AL_IMM
,
5211 /* 0x35 */ x86emuOp_genop_word_AX_IMM
,
5212 /* 0x36 */ x86emuOp_segovr_SS
,
5213 /* 0x37 */ x86emuOp_aaa
,
5215 /* 0x38 */ x86emuOp_genop_byte_RM_R
,
5216 /* 0x39 */ x86emuOp_genop_word_RM_R
,
5217 /* 0x3a */ x86emuOp_genop_byte_R_RM
,
5218 /* 0x3b */ x86emuOp_genop_word_R_RM
,
5219 /* 0x3c */ x86emuOp_genop_byte_AL_IMM
,
5220 /* 0x3d */ x86emuOp_genop_word_AX_IMM
,
5221 /* 0x3e */ x86emuOp_segovr_DS
,
5222 /* 0x3f */ x86emuOp_aas
,
5224 /* 0x40 */ x86emuOp_inc_register
,
5225 /* 0x41 */ x86emuOp_inc_register
,
5226 /* 0x42 */ x86emuOp_inc_register
,
5227 /* 0x43 */ x86emuOp_inc_register
,
5228 /* 0x44 */ x86emuOp_inc_register
,
5229 /* 0x45 */ x86emuOp_inc_register
,
5230 /* 0x46 */ x86emuOp_inc_register
,
5231 /* 0x47 */ x86emuOp_inc_register
,
5233 /* 0x48 */ x86emuOp_dec_register
,
5234 /* 0x49 */ x86emuOp_dec_register
,
5235 /* 0x4a */ x86emuOp_dec_register
,
5236 /* 0x4b */ x86emuOp_dec_register
,
5237 /* 0x4c */ x86emuOp_dec_register
,
5238 /* 0x4d */ x86emuOp_dec_register
,
5239 /* 0x4e */ x86emuOp_dec_register
,
5240 /* 0x4f */ x86emuOp_dec_register
,
5242 /* 0x50 */ x86emuOp_push_register
,
5243 /* 0x51 */ x86emuOp_push_register
,
5244 /* 0x52 */ x86emuOp_push_register
,
5245 /* 0x53 */ x86emuOp_push_register
,
5246 /* 0x54 */ x86emuOp_push_register
,
5247 /* 0x55 */ x86emuOp_push_register
,
5248 /* 0x56 */ x86emuOp_push_register
,
5249 /* 0x57 */ x86emuOp_push_register
,
5251 /* 0x58 */ x86emuOp_pop_register
,
5252 /* 0x59 */ x86emuOp_pop_register
,
5253 /* 0x5a */ x86emuOp_pop_register
,
5254 /* 0x5b */ x86emuOp_pop_register
,
5255 /* 0x5c */ x86emuOp_pop_register
,
5256 /* 0x5d */ x86emuOp_pop_register
,
5257 /* 0x5e */ x86emuOp_pop_register
,
5258 /* 0x5f */ x86emuOp_pop_register
,
5260 /* 0x60 */ x86emuOp_push_all
,
5261 /* 0x61 */ x86emuOp_pop_all
,
5262 /* 0x62 */ x86emuOp_illegal_op
, /* bound */
5263 /* 0x63 */ x86emuOp_illegal_op
, /* arpl */
5264 /* 0x64 */ x86emuOp_segovr_FS
,
5265 /* 0x65 */ x86emuOp_segovr_GS
,
5266 /* 0x66 */ x86emuOp_prefix_data
,
5267 /* 0x67 */ x86emuOp_prefix_addr
,
5269 /* 0x68 */ x86emuOp_push_word_IMM
,
5270 /* 0x69 */ x86emuOp_imul_word_IMM
,
5271 /* 0x6a */ x86emuOp_push_byte_IMM
,
5272 /* 0x6b */ x86emuOp_imul_byte_IMM
,
5273 /* 0x6c */ x86emuOp_ins_byte
,
5274 /* 0x6d */ x86emuOp_ins_word
,
5275 /* 0x6e */ x86emuOp_outs_byte
,
5276 /* 0x6f */ x86emuOp_outs_word
,
5278 /* 0x70 */ x86emuOp_jump_near_cond
,
5279 /* 0x71 */ x86emuOp_jump_near_cond
,
5280 /* 0x72 */ x86emuOp_jump_near_cond
,
5281 /* 0x73 */ x86emuOp_jump_near_cond
,
5282 /* 0x74 */ x86emuOp_jump_near_cond
,
5283 /* 0x75 */ x86emuOp_jump_near_cond
,
5284 /* 0x76 */ x86emuOp_jump_near_cond
,
5285 /* 0x77 */ x86emuOp_jump_near_cond
,
5287 /* 0x78 */ x86emuOp_jump_near_cond
,
5288 /* 0x79 */ x86emuOp_jump_near_cond
,
5289 /* 0x7a */ x86emuOp_jump_near_cond
,
5290 /* 0x7b */ x86emuOp_jump_near_cond
,
5291 /* 0x7c */ x86emuOp_jump_near_cond
,
5292 /* 0x7d */ x86emuOp_jump_near_cond
,
5293 /* 0x7e */ x86emuOp_jump_near_cond
,
5294 /* 0x7f */ x86emuOp_jump_near_cond
,
5296 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM
,
5297 /* 0x81 */ x86emuOp_opc81_word_RM_IMM
,
5298 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM
,
5299 /* 0x83 */ x86emuOp_opc83_word_RM_IMM
,
5300 /* 0x84 */ x86emuOp_test_byte_RM_R
,
5301 /* 0x85 */ x86emuOp_test_word_RM_R
,
5302 /* 0x86 */ x86emuOp_xchg_byte_RM_R
,
5303 /* 0x87 */ x86emuOp_xchg_word_RM_R
,
5305 /* 0x88 */ x86emuOp_mov_byte_RM_R
,
5306 /* 0x89 */ x86emuOp_mov_word_RM_R
,
5307 /* 0x8a */ x86emuOp_mov_byte_R_RM
,
5308 /* 0x8b */ x86emuOp_mov_word_R_RM
,
5309 /* 0x8c */ x86emuOp_mov_word_RM_SR
,
5310 /* 0x8d */ x86emuOp_lea_word_R_M
,
5311 /* 0x8e */ x86emuOp_mov_word_SR_RM
,
5312 /* 0x8f */ x86emuOp_pop_RM
,
5314 /* 0x90 */ x86emuOp_nop
,
5315 /* 0x91 */ x86emuOp_xchg_word_AX_register
,
5316 /* 0x92 */ x86emuOp_xchg_word_AX_register
,
5317 /* 0x93 */ x86emuOp_xchg_word_AX_register
,
5318 /* 0x94 */ x86emuOp_xchg_word_AX_register
,
5319 /* 0x95 */ x86emuOp_xchg_word_AX_register
,
5320 /* 0x96 */ x86emuOp_xchg_word_AX_register
,
5321 /* 0x97 */ x86emuOp_xchg_word_AX_register
,
5323 /* 0x98 */ x86emuOp_cbw
,
5324 /* 0x99 */ x86emuOp_cwd
,
5325 /* 0x9a */ x86emuOp_call_far_IMM
,
5326 /* 0x9b */ x86emuOp_wait
,
5327 /* 0x9c */ x86emuOp_pushf_word
,
5328 /* 0x9d */ x86emuOp_popf_word
,
5329 /* 0x9e */ x86emuOp_sahf
,
5330 /* 0x9f */ x86emuOp_lahf
,
5332 /* 0xa0 */ x86emuOp_mov_AL_M_IMM
,
5333 /* 0xa1 */ x86emuOp_mov_AX_M_IMM
,
5334 /* 0xa2 */ x86emuOp_mov_M_AL_IMM
,
5335 /* 0xa3 */ x86emuOp_mov_M_AX_IMM
,
5336 /* 0xa4 */ x86emuOp_movs_byte
,
5337 /* 0xa5 */ x86emuOp_movs_word
,
5338 /* 0xa6 */ x86emuOp_cmps_byte
,
5339 /* 0xa7 */ x86emuOp_cmps_word
,
5340 /* 0xa8 */ x86emuOp_test_AL_IMM
,
5341 /* 0xa9 */ x86emuOp_test_AX_IMM
,
5342 /* 0xaa */ x86emuOp_stos_byte
,
5343 /* 0xab */ x86emuOp_stos_word
,
5344 /* 0xac */ x86emuOp_lods_byte
,
5345 /* 0xad */ x86emuOp_lods_word
,
5346 /* 0xac */ x86emuOp_scas_byte
,
5347 /* 0xad */ x86emuOp_scas_word
,
5349 /* 0xb0 */ x86emuOp_mov_byte_register_IMM
,
5350 /* 0xb1 */ x86emuOp_mov_byte_register_IMM
,
5351 /* 0xb2 */ x86emuOp_mov_byte_register_IMM
,
5352 /* 0xb3 */ x86emuOp_mov_byte_register_IMM
,
5353 /* 0xb4 */ x86emuOp_mov_byte_register_IMM
,
5354 /* 0xb5 */ x86emuOp_mov_byte_register_IMM
,
5355 /* 0xb6 */ x86emuOp_mov_byte_register_IMM
,
5356 /* 0xb7 */ x86emuOp_mov_byte_register_IMM
,
5358 /* 0xb8 */ x86emuOp_mov_word_register_IMM
,
5359 /* 0xb9 */ x86emuOp_mov_word_register_IMM
,
5360 /* 0xba */ x86emuOp_mov_word_register_IMM
,
5361 /* 0xbb */ x86emuOp_mov_word_register_IMM
,
5362 /* 0xbc */ x86emuOp_mov_word_register_IMM
,
5363 /* 0xbd */ x86emuOp_mov_word_register_IMM
,
5364 /* 0xbe */ x86emuOp_mov_word_register_IMM
,
5365 /* 0xbf */ x86emuOp_mov_word_register_IMM
,
5367 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM
,
5368 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM
,
5369 /* 0xc2 */ x86emuOp_ret_near_IMM
,
5370 /* 0xc3 */ x86emuOp_ret_near
,
5371 /* 0xc4 */ x86emuOp_les_R_IMM
,
5372 /* 0xc5 */ x86emuOp_lds_R_IMM
,
5373 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM
,
5374 /* 0xc7 */ x86emuOp_mov_word_RM_IMM
,
5375 /* 0xc8 */ x86emuOp_enter
,
5376 /* 0xc9 */ x86emuOp_leave
,
5377 /* 0xca */ x86emuOp_ret_far_IMM
,
5378 /* 0xcb */ x86emuOp_ret_far
,
5379 /* 0xcc */ x86emuOp_int3
,
5380 /* 0xcd */ x86emuOp_int_IMM
,
5381 /* 0xce */ x86emuOp_into
,
5382 /* 0xcf */ x86emuOp_iret
,
5384 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1
,
5385 /* 0xd1 */ x86emuOp_opcD1_word_RM_1
,
5386 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL
,
5387 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL
,
5388 /* 0xd4 */ x86emuOp_aam
,
5389 /* 0xd5 */ x86emuOp_aad
,
5390 /* 0xd6 */ x86emuOp_illegal_op
, /* Undocumented SETALC instruction */
5391 /* 0xd7 */ x86emuOp_xlat
,
5392 /* 0xd8 */ NULL
, /*x86emuOp_esc_coprocess_d8,*/
5393 /* 0xd9 */ NULL
, /*x86emuOp_esc_coprocess_d9,*/
5394 /* 0xda */ NULL
, /*x86emuOp_esc_coprocess_da,*/
5395 /* 0xdb */ NULL
, /*x86emuOp_esc_coprocess_db,*/
5396 /* 0xdc */ NULL
, /*x86emuOp_esc_coprocess_dc,*/
5397 /* 0xdd */ NULL
, /*x86emuOp_esc_coprocess_dd,*/
5398 /* 0xde */ NULL
, /*x86emuOp_esc_coprocess_de,*/
5399 /* 0xdf */ NULL
, /*x86emuOp_esc_coprocess_df,*/
5401 /* 0xe0 */ x86emuOp_loopne
,
5402 /* 0xe1 */ x86emuOp_loope
,
5403 /* 0xe2 */ x86emuOp_loop
,
5404 /* 0xe3 */ x86emuOp_jcxz
,
5405 /* 0xe4 */ x86emuOp_in_byte_AL_IMM
,
5406 /* 0xe5 */ x86emuOp_in_word_AX_IMM
,
5407 /* 0xe6 */ x86emuOp_out_byte_IMM_AL
,
5408 /* 0xe7 */ x86emuOp_out_word_IMM_AX
,
5410 /* 0xe8 */ x86emuOp_call_near_IMM
,
5411 /* 0xe9 */ x86emuOp_jump_near_IMM
,
5412 /* 0xea */ x86emuOp_jump_far_IMM
,
5413 /* 0xeb */ x86emuOp_jump_byte_IMM
,
5414 /* 0xec */ x86emuOp_in_byte_AL_DX
,
5415 /* 0xed */ x86emuOp_in_word_AX_DX
,
5416 /* 0xee */ x86emuOp_out_byte_DX_AL
,
5417 /* 0xef */ x86emuOp_out_word_DX_AX
,
5419 /* 0xf0 */ x86emuOp_lock
,
5420 /* 0xf1 */ x86emuOp_illegal_op
,
5421 /* 0xf2 */ x86emuOp_repne
,
5422 /* 0xf3 */ x86emuOp_repe
,
5423 /* 0xf4 */ x86emuOp_halt
,
5424 /* 0xf5 */ x86emuOp_cmc
,
5425 /* 0xf6 */ x86emuOp_opcF6_byte_RM
,
5426 /* 0xf7 */ x86emuOp_opcF7_word_RM
,
5428 /* 0xf8 */ x86emuOp_clc
,
5429 /* 0xf9 */ x86emuOp_stc
,
5430 /* 0xfa */ x86emuOp_cli
,
5431 /* 0xfb */ x86emuOp_sti
,
5432 /* 0xfc */ x86emuOp_cld
,
5433 /* 0xfd */ x86emuOp_std
,
5434 /* 0xfe */ x86emuOp_opcFE_byte_RM
,
5435 /* 0xff */ x86emuOp_opcFF_word_RM
,