1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1991-2004 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 processor instructions.
38 * There are approximately 250 subroutines in here, which correspond
39 * to the 256 byte-"opcodes" found on the 8086. The table which
40 * dispatches this is found in the files optab.[ch].
42 * Each opcode proc has a comment preceding it which gives it's table
43 * address. Several opcodes are missing (undefined) in the table.
45 * Each proc includes information for decoding (DECODE_PRINTF and
46 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47 * functions (START_OF_INSTR, END_OF_INSTR).
49 * Many of the procedures are *VERY* similar in coding. This has
50 * allowed for a very large amount of code to be generated in a fairly
51 * short amount of time (i.e. cut, paste, and modify). The result is
52 * that much of the code below could have been folded into subroutines
53 * for a large reduction in size of this file. The downside would be
54 * that there would be a penalty in execution speed. The file could
55 * also have been *MUCH* larger by inlining certain functions which
56 * were called. This could have resulted even faster execution. The
57 * prime directive I used to decide whether to inline the code or to
58 * modularize it, was basically: 1) no unnecessary subroutine calls,
59 * 2) no routines more than about 200 lines in size, and 3) modularize
60 * any code that I might not get right the first time. The fetch_*
61 * subroutines fall into the latter category. The decode_* fall
62 * into the second category. The coding of the "switch(mod){ .... }"
63 * in many of the subroutines below falls into the first category.
64 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
65 * subroutines are an especially glaring case of the third guideline.
66 * Since so much of the code is cloned from other modules (compare
67 * opcode #00 to opcode #01), making the basic operations subroutine
68 * calls is especially important; otherwise mistakes in coding an
69 * "add" would represent a nightmare in maintenance.
71 ****************************************************************************/
75 /*----------------------------- Implementation ----------------------------*/
77 /* constant arrays to do several instructions in just one function */
80 static const char *x86emu_GenOpName
[8] = {
81 "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
84 /* used by several opcodes */
85 static u8 (*genop_byte_operation
[])(u8 d
, u8 s
) =
97 static u16 (*genop_word_operation
[])(u16 d
, u16 s
) =
109 static u32 (*genop_long_operation
[])(u32 d
, u32 s
) =
121 /* used by opcodes 80, c0, d0, and d2. */
122 static u8(*opcD0_byte_operation
[])(u8 d
, u8 s
) =
130 shl_byte
, /* sal_byte === shl_byte by definition */
134 /* used by opcodes c1, d1, and d3. */
135 static u16(*opcD1_word_operation
[])(u16 s
, u8 d
) =
143 shl_word
, /* sal_byte === shl_byte by definition */
147 /* used by opcodes c1, d1, and d3. */
148 static u32 (*opcD1_long_operation
[])(u32 s
, u8 d
) =
156 shl_long
, /* sal_byte === shl_byte by definition */
162 static const char *opF6_names
[8] =
163 { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
167 /****************************************************************************
169 op1 - Instruction op code
172 Handles illegal opcodes.
173 ****************************************************************************/
174 static void x86emuOp_illegal_op(
178 if (M
.x86
.R_SP
!= 0) {
179 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
181 DB( printf("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
182 M
.x86
.R_CS
, M
.x86
.R_IP
-1,op1
));
186 /* If we get here, it means the stack pointer is back to zero
187 * so we are just returning from an emulator service call
188 * so therte is no need to display an error message. We trap
189 * the emulator with an 0xF1 opcode to finish the service
197 /****************************************************************************
199 Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
200 ****************************************************************************/
201 static void x86emuOp_genop_byte_RM_R(u8 op1
)
205 u8
*destreg
, *srcreg
;
208 op1
= (op1
>> 3) & 0x7;
211 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
213 FETCH_DECODE_MODRM(mod
, rh
, rl
);
215 { destoffset
= decode_rmXX_address(mod
,rl
);
217 destval
= fetch_data_byte(destoffset
);
218 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
221 destval
= genop_byte_operation
[op1
](destval
, *srcreg
);
223 store_data_byte(destoffset
, destval
);
226 { /* register to register */
227 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
229 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
232 *destreg
= genop_byte_operation
[op1
](*destreg
, *srcreg
);
234 DECODE_CLEAR_SEGOVR();
238 /****************************************************************************
240 Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
241 ****************************************************************************/
242 static void x86emuOp_genop_word_RM_R(u8 op1
)
247 op1
= (op1
>> 3) & 0x7;
250 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
252 FETCH_DECODE_MODRM(mod
, rh
, rl
);
255 destoffset
= decode_rmXX_address(mod
,rl
);
256 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
261 destval
= fetch_data_long(destoffset
);
262 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
265 destval
= genop_long_operation
[op1
](destval
, *srcreg
);
267 store_data_long(destoffset
, destval
);
273 destval
= fetch_data_word(destoffset
);
274 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
277 destval
= genop_word_operation
[op1
](destval
, *srcreg
);
279 store_data_word(destoffset
, destval
);
281 } else { /* register to register */
282 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
283 u32
*destreg
, *srcreg
;
285 destreg
= DECODE_RM_LONG_REGISTER(rl
);
287 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
290 *destreg
= genop_long_operation
[op1
](*destreg
, *srcreg
);
292 u16
*destreg
, *srcreg
;
294 destreg
= DECODE_RM_WORD_REGISTER(rl
);
296 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
299 *destreg
= genop_word_operation
[op1
](*destreg
, *srcreg
);
302 DECODE_CLEAR_SEGOVR();
306 /****************************************************************************
308 Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
309 ****************************************************************************/
310 static void x86emuOp_genop_byte_R_RM(u8 op1
)
313 u8
*destreg
, *srcreg
;
317 op1
= (op1
>> 3) & 0x7;
320 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
322 FETCH_DECODE_MODRM(mod
, rh
, rl
);
324 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
326 srcoffset
= decode_rmXX_address(mod
,rl
);
327 srcval
= fetch_data_byte(srcoffset
);
328 } else { /* register to register */
329 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
331 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
336 *destreg
= genop_byte_operation
[op1
](*destreg
, srcval
);
338 DECODE_CLEAR_SEGOVR();
342 /****************************************************************************
344 Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
345 ****************************************************************************/
346 static void x86emuOp_genop_word_R_RM(u8 op1
)
350 u32
*destreg32
, srcval
;
353 op1
= (op1
>> 3) & 0x7;
356 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
358 FETCH_DECODE_MODRM(mod
, rh
, rl
);
360 srcoffset
= decode_rmXX_address(mod
,rl
);
361 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
362 destreg32
= DECODE_RM_LONG_REGISTER(rh
);
364 srcval
= fetch_data_long(srcoffset
);
367 *destreg32
= genop_long_operation
[op1
](*destreg32
, srcval
);
369 destreg
= DECODE_RM_WORD_REGISTER(rh
);
371 srcval
= fetch_data_word(srcoffset
);
374 *destreg
= genop_word_operation
[op1
](*destreg
, srcval
);
376 } else { /* register to register */
377 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
379 destreg32
= DECODE_RM_LONG_REGISTER(rh
);
381 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
384 *destreg32
= genop_long_operation
[op1
](*destreg32
, *srcreg
);
387 destreg
= DECODE_RM_WORD_REGISTER(rh
);
389 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
392 *destreg
= genop_word_operation
[op1
](*destreg
, *srcreg
);
395 DECODE_CLEAR_SEGOVR();
399 /****************************************************************************
401 Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
402 ****************************************************************************/
403 static void x86emuOp_genop_byte_AL_IMM(u8 op1
)
407 op1
= (op1
>> 3) & 0x7;
410 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
411 DECODE_PRINTF("\tAL,");
412 srcval
= fetch_byte_imm();
413 DECODE_PRINTF2("%x\n", srcval
);
415 M
.x86
.R_AL
= genop_byte_operation
[op1
](M
.x86
.R_AL
, srcval
);
416 DECODE_CLEAR_SEGOVR();
420 /****************************************************************************
422 Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
423 ****************************************************************************/
424 static void x86emuOp_genop_word_AX_IMM(u8 op1
)
428 op1
= (op1
>> 3) & 0x7;
431 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
432 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
433 DECODE_PRINTF("\tEAX,");
434 srcval
= fetch_long_imm();
436 DECODE_PRINTF(x86emu_GenOpName
[op1
]);
437 DECODE_PRINTF("\tAX,");
438 srcval
= fetch_word_imm();
440 DECODE_PRINTF2("%x\n", srcval
);
442 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
443 M
.x86
.R_EAX
= genop_long_operation
[op1
](M
.x86
.R_EAX
, srcval
);
445 M
.x86
.R_AX
= genop_word_operation
[op1
](M
.x86
.R_AX
, (u16
)srcval
);
447 DECODE_CLEAR_SEGOVR();
451 /****************************************************************************
454 ****************************************************************************/
455 static void x86emuOp_push_ES(u8
X86EMU_UNUSED(op1
))
458 DECODE_PRINTF("PUSH\tES\n");
460 push_word(M
.x86
.R_ES
);
461 DECODE_CLEAR_SEGOVR();
465 /****************************************************************************
468 ****************************************************************************/
469 static void x86emuOp_pop_ES(u8
X86EMU_UNUSED(op1
))
472 DECODE_PRINTF("POP\tES\n");
474 M
.x86
.R_ES
= pop_word();
475 DECODE_CLEAR_SEGOVR();
479 /****************************************************************************
482 ****************************************************************************/
483 static void x86emuOp_push_CS(u8
X86EMU_UNUSED(op1
))
486 DECODE_PRINTF("PUSH\tCS\n");
488 push_word(M
.x86
.R_CS
);
489 DECODE_CLEAR_SEGOVR();
493 /****************************************************************************
495 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
496 ****************************************************************************/
497 static void x86emuOp_two_byte(u8
X86EMU_UNUSED(op1
))
499 u8 op2
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
500 INC_DECODED_INST_LEN(1);
501 (*x86emu_optab2
[op2
])(op2
);
504 /****************************************************************************
507 ****************************************************************************/
508 static void x86emuOp_push_SS(u8
X86EMU_UNUSED(op1
))
511 DECODE_PRINTF("PUSH\tSS\n");
513 push_word(M
.x86
.R_SS
);
514 DECODE_CLEAR_SEGOVR();
518 /****************************************************************************
521 ****************************************************************************/
522 static void x86emuOp_pop_SS(u8
X86EMU_UNUSED(op1
))
525 DECODE_PRINTF("POP\tSS\n");
527 M
.x86
.R_SS
= pop_word();
528 DECODE_CLEAR_SEGOVR();
532 /****************************************************************************
535 ****************************************************************************/
536 static void x86emuOp_push_DS(u8
X86EMU_UNUSED(op1
))
539 DECODE_PRINTF("PUSH\tDS\n");
541 push_word(M
.x86
.R_DS
);
542 DECODE_CLEAR_SEGOVR();
546 /****************************************************************************
549 ****************************************************************************/
550 static void x86emuOp_pop_DS(u8
X86EMU_UNUSED(op1
))
553 DECODE_PRINTF("POP\tDS\n");
555 M
.x86
.R_DS
= pop_word();
556 DECODE_CLEAR_SEGOVR();
560 /****************************************************************************
563 ****************************************************************************/
564 static void x86emuOp_segovr_ES(u8
X86EMU_UNUSED(op1
))
567 DECODE_PRINTF("ES:\n");
569 M
.x86
.mode
|= SYSMODE_SEGOVR_ES
;
571 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
572 * opcode subroutines we do not want to do this.
577 /****************************************************************************
580 ****************************************************************************/
581 static void x86emuOp_daa(u8
X86EMU_UNUSED(op1
))
584 DECODE_PRINTF("DAA\n");
586 M
.x86
.R_AL
= daa_byte(M
.x86
.R_AL
);
587 DECODE_CLEAR_SEGOVR();
591 /****************************************************************************
594 ****************************************************************************/
595 static void x86emuOp_segovr_CS(u8
X86EMU_UNUSED(op1
))
598 DECODE_PRINTF("CS:\n");
600 M
.x86
.mode
|= SYSMODE_SEGOVR_CS
;
601 /* note no DECODE_CLEAR_SEGOVR here. */
605 /****************************************************************************
608 ****************************************************************************/
609 static void x86emuOp_das(u8
X86EMU_UNUSED(op1
))
612 DECODE_PRINTF("DAS\n");
614 M
.x86
.R_AL
= das_byte(M
.x86
.R_AL
);
615 DECODE_CLEAR_SEGOVR();
619 /****************************************************************************
622 ****************************************************************************/
623 static void x86emuOp_segovr_SS(u8
X86EMU_UNUSED(op1
))
626 DECODE_PRINTF("SS:\n");
628 M
.x86
.mode
|= SYSMODE_SEGOVR_SS
;
629 /* no DECODE_CLEAR_SEGOVR ! */
633 /****************************************************************************
636 ****************************************************************************/
637 static void x86emuOp_aaa(u8
X86EMU_UNUSED(op1
))
640 DECODE_PRINTF("AAA\n");
642 M
.x86
.R_AX
= aaa_word(M
.x86
.R_AX
);
643 DECODE_CLEAR_SEGOVR();
647 /****************************************************************************
650 ****************************************************************************/
651 static void x86emuOp_segovr_DS(u8
X86EMU_UNUSED(op1
))
654 DECODE_PRINTF("DS:\n");
656 M
.x86
.mode
|= SYSMODE_SEGOVR_DS
;
657 /* NO DECODE_CLEAR_SEGOVR! */
661 /****************************************************************************
664 ****************************************************************************/
665 static void x86emuOp_aas(u8
X86EMU_UNUSED(op1
))
668 DECODE_PRINTF("AAS\n");
670 M
.x86
.R_AX
= aas_word(M
.x86
.R_AX
);
671 DECODE_CLEAR_SEGOVR();
675 /****************************************************************************
677 Handles opcode 0x40 - 0x47
678 ****************************************************************************/
679 static void x86emuOp_inc_register(u8 op1
)
683 DECODE_PRINTF("INC\t");
684 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
686 reg
= DECODE_RM_LONG_REGISTER(op1
);
689 *reg
= inc_long(*reg
);
692 reg
= DECODE_RM_WORD_REGISTER(op1
);
695 *reg
= inc_word(*reg
);
697 DECODE_CLEAR_SEGOVR();
701 /****************************************************************************
703 Handles opcode 0x48 - 0x4F
704 ****************************************************************************/
705 static void x86emuOp_dec_register(u8 op1
)
709 DECODE_PRINTF("DEC\t");
710 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
712 reg
= DECODE_RM_LONG_REGISTER(op1
);
715 *reg
= dec_long(*reg
);
718 reg
= DECODE_RM_WORD_REGISTER(op1
);
721 *reg
= dec_word(*reg
);
723 DECODE_CLEAR_SEGOVR();
727 /****************************************************************************
729 Handles opcode 0x50 - 0x57
730 ****************************************************************************/
731 static void x86emuOp_push_register(u8 op1
)
735 DECODE_PRINTF("PUSH\t");
736 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
738 reg
= DECODE_RM_LONG_REGISTER(op1
);
744 reg
= DECODE_RM_WORD_REGISTER(op1
);
749 DECODE_CLEAR_SEGOVR();
753 /****************************************************************************
755 Handles opcode 0x58 - 0x5F
756 ****************************************************************************/
757 static void x86emuOp_pop_register(u8 op1
)
761 DECODE_PRINTF("POP\t");
762 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
764 reg
= DECODE_RM_LONG_REGISTER(op1
);
770 reg
= DECODE_RM_WORD_REGISTER(op1
);
775 DECODE_CLEAR_SEGOVR();
779 /****************************************************************************
782 ****************************************************************************/
783 static void x86emuOp_push_all(u8
X86EMU_UNUSED(op1
))
786 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
787 DECODE_PRINTF("PUSHAD\n");
789 DECODE_PRINTF("PUSHA\n");
792 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
793 u32 old_sp
= M
.x86
.R_ESP
;
795 push_long(M
.x86
.R_EAX
);
796 push_long(M
.x86
.R_ECX
);
797 push_long(M
.x86
.R_EDX
);
798 push_long(M
.x86
.R_EBX
);
800 push_long(M
.x86
.R_EBP
);
801 push_long(M
.x86
.R_ESI
);
802 push_long(M
.x86
.R_EDI
);
804 u16 old_sp
= M
.x86
.R_SP
;
806 push_word(M
.x86
.R_AX
);
807 push_word(M
.x86
.R_CX
);
808 push_word(M
.x86
.R_DX
);
809 push_word(M
.x86
.R_BX
);
811 push_word(M
.x86
.R_BP
);
812 push_word(M
.x86
.R_SI
);
813 push_word(M
.x86
.R_DI
);
815 DECODE_CLEAR_SEGOVR();
819 /****************************************************************************
822 ****************************************************************************/
823 static void x86emuOp_pop_all(u8
X86EMU_UNUSED(op1
))
826 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
827 DECODE_PRINTF("POPAD\n");
829 DECODE_PRINTF("POPA\n");
832 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
833 M
.x86
.R_EDI
= pop_long();
834 M
.x86
.R_ESI
= pop_long();
835 M
.x86
.R_EBP
= pop_long();
836 M
.x86
.R_ESP
+= 4; /* skip ESP */
837 M
.x86
.R_EBX
= pop_long();
838 M
.x86
.R_EDX
= pop_long();
839 M
.x86
.R_ECX
= pop_long();
840 M
.x86
.R_EAX
= pop_long();
842 M
.x86
.R_DI
= pop_word();
843 M
.x86
.R_SI
= pop_word();
844 M
.x86
.R_BP
= pop_word();
845 M
.x86
.R_SP
+= 2; /* skip SP */
846 M
.x86
.R_BX
= pop_word();
847 M
.x86
.R_DX
= pop_word();
848 M
.x86
.R_CX
= pop_word();
849 M
.x86
.R_AX
= pop_word();
851 DECODE_CLEAR_SEGOVR();
855 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
856 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
858 /****************************************************************************
861 ****************************************************************************/
862 static void x86emuOp_segovr_FS(u8
X86EMU_UNUSED(op1
))
865 DECODE_PRINTF("FS:\n");
867 M
.x86
.mode
|= SYSMODE_SEGOVR_FS
;
869 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
870 * opcode subroutines we do not want to do this.
875 /****************************************************************************
878 ****************************************************************************/
879 static void x86emuOp_segovr_GS(u8
X86EMU_UNUSED(op1
))
882 DECODE_PRINTF("GS:\n");
884 M
.x86
.mode
|= SYSMODE_SEGOVR_GS
;
886 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
887 * opcode subroutines we do not want to do this.
892 /****************************************************************************
894 Handles opcode 0x66 - prefix for 32-bit register
895 ****************************************************************************/
896 static void x86emuOp_prefix_data(u8
X86EMU_UNUSED(op1
))
899 DECODE_PRINTF("DATA:\n");
901 M
.x86
.mode
|= SYSMODE_PREFIX_DATA
;
902 /* note no DECODE_CLEAR_SEGOVR here. */
906 /****************************************************************************
908 Handles opcode 0x67 - prefix for 32-bit address
909 ****************************************************************************/
910 static void x86emuOp_prefix_addr(u8
X86EMU_UNUSED(op1
))
913 DECODE_PRINTF("ADDR:\n");
915 M
.x86
.mode
|= SYSMODE_PREFIX_ADDR
;
916 /* note no DECODE_CLEAR_SEGOVR here. */
920 /****************************************************************************
923 ****************************************************************************/
924 static void x86emuOp_push_word_IMM(u8
X86EMU_UNUSED(op1
))
929 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
930 imm
= fetch_long_imm();
932 imm
= fetch_word_imm();
934 DECODE_PRINTF2("PUSH\t%x\n", imm
);
936 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
941 DECODE_CLEAR_SEGOVR();
945 /****************************************************************************
948 ****************************************************************************/
949 static void x86emuOp_imul_word_IMM(u8
X86EMU_UNUSED(op1
))
955 DECODE_PRINTF("IMUL\t");
956 FETCH_DECODE_MODRM(mod
, rh
, rl
);
958 srcoffset
= decode_rmXX_address(mod
, rl
);
959 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
965 destreg
= DECODE_RM_LONG_REGISTER(rh
);
967 srcval
= fetch_data_long(srcoffset
);
968 imm
= fetch_long_imm();
969 DECODE_PRINTF2(",%d\n", (s32
)imm
);
971 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
972 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
973 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
980 *destreg
= (u32
)res_lo
;
987 destreg
= DECODE_RM_WORD_REGISTER(rh
);
989 srcval
= fetch_data_word(srcoffset
);
990 imm
= fetch_word_imm();
991 DECODE_PRINTF2(",%d\n", (s32
)imm
);
993 res
= (s16
)srcval
* (s16
)imm
;
994 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
995 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1002 *destreg
= (u16
)res
;
1004 } else { /* register to register */
1005 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1006 u32
*destreg
,*srcreg
;
1010 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1012 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1013 imm
= fetch_long_imm();
1014 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1016 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
1017 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1018 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1025 *destreg
= (u32
)res_lo
;
1027 u16
*destreg
,*srcreg
;
1031 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1033 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1034 imm
= fetch_word_imm();
1035 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1036 res
= (s16
)*srcreg
* (s16
)imm
;
1037 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1038 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1045 *destreg
= (u16
)res
;
1048 DECODE_CLEAR_SEGOVR();
1052 /****************************************************************************
1055 ****************************************************************************/
1056 static void x86emuOp_push_byte_IMM(u8
X86EMU_UNUSED(op1
))
1061 imm
= (s8
)fetch_byte_imm();
1062 DECODE_PRINTF2("PUSH\t%d\n", imm
);
1064 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1069 DECODE_CLEAR_SEGOVR();
1073 /****************************************************************************
1076 ****************************************************************************/
1077 static void x86emuOp_imul_byte_IMM(u8
X86EMU_UNUSED(op1
))
1084 DECODE_PRINTF("IMUL\t");
1085 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1087 srcoffset
= decode_rmXX_address(mod
, rl
);
1088 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1093 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1095 srcval
= fetch_data_long(srcoffset
);
1096 imm
= fetch_byte_imm();
1097 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1099 imul_long_direct(&res_lo
,&res_hi
,(s32
)srcval
,(s32
)imm
);
1100 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1101 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1108 *destreg
= (u32
)res_lo
;
1114 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1116 srcval
= fetch_data_word(srcoffset
);
1117 imm
= fetch_byte_imm();
1118 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1120 res
= (s16
)srcval
* (s16
)imm
;
1121 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1122 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1129 *destreg
= (u16
)res
;
1131 } else { /* register to register */
1132 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1133 u32
*destreg
,*srcreg
;
1136 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1138 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1139 imm
= fetch_byte_imm();
1140 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1142 imul_long_direct(&res_lo
,&res_hi
,(s32
)*srcreg
,(s32
)imm
);
1143 if ((((res_lo
& 0x80000000) == 0) && (res_hi
== 0x00000000)) ||
1144 (((res_lo
& 0x80000000) != 0) && (res_hi
== 0xFFFFFFFF))) {
1151 *destreg
= (u32
)res_lo
;
1153 u16
*destreg
,*srcreg
;
1156 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1158 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1159 imm
= fetch_byte_imm();
1160 DECODE_PRINTF2(",%d\n", (s32
)imm
);
1162 res
= (s16
)*srcreg
* (s16
)imm
;
1163 if ((((res
& 0x8000) == 0) && ((res
>> 16) == 0x0000)) ||
1164 (((res
& 0x8000) != 0) && ((res
>> 16) == 0xFFFF))) {
1171 *destreg
= (u16
)res
;
1174 DECODE_CLEAR_SEGOVR();
1178 /****************************************************************************
1181 ****************************************************************************/
1182 static void x86emuOp_ins_byte(u8
X86EMU_UNUSED(op1
))
1185 DECODE_PRINTF("INSB\n");
1188 DECODE_CLEAR_SEGOVR();
1192 /****************************************************************************
1195 ****************************************************************************/
1196 static void x86emuOp_ins_word(u8
X86EMU_UNUSED(op1
))
1199 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1200 DECODE_PRINTF("INSD\n");
1203 DECODE_PRINTF("INSW\n");
1207 DECODE_CLEAR_SEGOVR();
1211 /****************************************************************************
1214 ****************************************************************************/
1215 static void x86emuOp_outs_byte(u8
X86EMU_UNUSED(op1
))
1218 DECODE_PRINTF("OUTSB\n");
1221 DECODE_CLEAR_SEGOVR();
1225 /****************************************************************************
1228 ****************************************************************************/
1229 static void x86emuOp_outs_word(u8
X86EMU_UNUSED(op1
))
1232 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1233 DECODE_PRINTF("OUTSD\n");
1236 DECODE_PRINTF("OUTSW\n");
1240 DECODE_CLEAR_SEGOVR();
1244 /****************************************************************************
1246 Handles opcode 0x70 - 0x7F
1247 ****************************************************************************/
1248 static void x86emuOp_jump_near_cond(u8 op1
)
1254 /* jump to byte offset if overflow flag is set */
1256 cond
= x86emu_check_jump_condition(op1
& 0xF);
1257 offset
= (s8
)fetch_byte_imm();
1258 target
= (u16
)(M
.x86
.R_IP
+ (s16
)offset
);
1259 DECODE_PRINTF2("%x\n", target
);
1262 M
.x86
.R_IP
= target
;
1263 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, " NEAR COND ");
1265 DECODE_CLEAR_SEGOVR();
1269 /****************************************************************************
1272 ****************************************************************************/
1273 static void x86emuOp_opc80_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
1282 * Weirdo special case instruction format. Part of the opcode
1283 * held below in "RH". Doubly nested case would result, except
1284 * that the decoded instruction
1287 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1289 if (DEBUG_DECODE()) {
1290 /* XXX DECODE_PRINTF may be changed to something more
1291 general, so that it is important to leave the strings
1292 in the same format, even though the result is that the
1293 above test is done twice. */
1297 DECODE_PRINTF("ADD\t");
1300 DECODE_PRINTF("OR\t");
1303 DECODE_PRINTF("ADC\t");
1306 DECODE_PRINTF("SBB\t");
1309 DECODE_PRINTF("AND\t");
1312 DECODE_PRINTF("SUB\t");
1315 DECODE_PRINTF("XOR\t");
1318 DECODE_PRINTF("CMP\t");
1323 /* know operation, decode the mod byte to find the addressing
1326 DECODE_PRINTF("BYTE PTR ");
1327 destoffset
= decode_rmXX_address(mod
, rl
);
1329 destval
= fetch_data_byte(destoffset
);
1330 imm
= fetch_byte_imm();
1331 DECODE_PRINTF2("%x\n", imm
);
1333 destval
= (*genop_byte_operation
[rh
]) (destval
, imm
);
1335 store_data_byte(destoffset
, destval
);
1336 } else { /* register to register */
1337 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1339 imm
= fetch_byte_imm();
1340 DECODE_PRINTF2("%x\n", imm
);
1342 *destreg
= (*genop_byte_operation
[rh
]) (*destreg
, imm
);
1344 DECODE_CLEAR_SEGOVR();
1348 /****************************************************************************
1351 ****************************************************************************/
1352 static void x86emuOp_opc81_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
1358 * Weirdo special case instruction format. Part of the opcode
1359 * held below in "RH". Doubly nested case would result, except
1360 * that the decoded instruction
1363 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1365 if (DEBUG_DECODE()) {
1366 /* XXX DECODE_PRINTF may be changed to something more
1367 general, so that it is important to leave the strings
1368 in the same format, even though the result is that the
1369 above test is done twice. */
1373 DECODE_PRINTF("ADD\t");
1376 DECODE_PRINTF("OR\t");
1379 DECODE_PRINTF("ADC\t");
1382 DECODE_PRINTF("SBB\t");
1385 DECODE_PRINTF("AND\t");
1388 DECODE_PRINTF("SUB\t");
1391 DECODE_PRINTF("XOR\t");
1394 DECODE_PRINTF("CMP\t");
1400 * Know operation, decode the mod byte to find the addressing
1404 DECODE_PRINTF("DWORD PTR ");
1405 destoffset
= decode_rmXX_address(mod
, rl
);
1406 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1410 destval
= fetch_data_long(destoffset
);
1411 imm
= fetch_long_imm();
1412 DECODE_PRINTF2("%x\n", imm
);
1414 destval
= (*genop_long_operation
[rh
]) (destval
, imm
);
1416 store_data_long(destoffset
, destval
);
1421 destval
= fetch_data_word(destoffset
);
1422 imm
= fetch_word_imm();
1423 DECODE_PRINTF2("%x\n", imm
);
1425 destval
= (*genop_word_operation
[rh
]) (destval
, imm
);
1427 store_data_word(destoffset
, destval
);
1429 } else { /* register to register */
1430 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1433 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1435 imm
= fetch_long_imm();
1436 DECODE_PRINTF2("%x\n", imm
);
1438 *destreg
= (*genop_long_operation
[rh
]) (*destreg
, imm
);
1442 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1444 imm
= fetch_word_imm();
1445 DECODE_PRINTF2("%x\n", imm
);
1447 *destreg
= (*genop_word_operation
[rh
]) (*destreg
, imm
);
1450 DECODE_CLEAR_SEGOVR();
1454 /****************************************************************************
1457 ****************************************************************************/
1458 static void x86emuOp_opc82_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
1467 * Weirdo special case instruction format. Part of the opcode
1468 * held below in "RH". Doubly nested case would result, except
1469 * that the decoded instruction Similar to opcode 81, except that
1470 * the immediate byte is sign extended to a word length.
1473 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1475 if (DEBUG_DECODE()) {
1476 /* XXX DECODE_PRINTF may be changed to something more
1477 general, so that it is important to leave the strings
1478 in the same format, even though the result is that the
1479 above test is done twice. */
1482 DECODE_PRINTF("ADD\t");
1485 DECODE_PRINTF("OR\t");
1488 DECODE_PRINTF("ADC\t");
1491 DECODE_PRINTF("SBB\t");
1494 DECODE_PRINTF("AND\t");
1497 DECODE_PRINTF("SUB\t");
1500 DECODE_PRINTF("XOR\t");
1503 DECODE_PRINTF("CMP\t");
1508 /* know operation, decode the mod byte to find the addressing
1511 DECODE_PRINTF("BYTE PTR ");
1512 destoffset
= decode_rmXX_address(mod
, rl
);
1513 destval
= fetch_data_byte(destoffset
);
1514 imm
= fetch_byte_imm();
1515 DECODE_PRINTF2(",%x\n", imm
);
1517 destval
= (*genop_byte_operation
[rh
]) (destval
, imm
);
1519 store_data_byte(destoffset
, destval
);
1520 } else { /* register to register */
1521 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1522 imm
= fetch_byte_imm();
1523 DECODE_PRINTF2(",%x\n", imm
);
1525 *destreg
= (*genop_byte_operation
[rh
]) (*destreg
, imm
);
1527 DECODE_CLEAR_SEGOVR();
1531 /****************************************************************************
1534 ****************************************************************************/
1535 static void x86emuOp_opc83_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
1541 * Weirdo special case instruction format. Part of the opcode
1542 * held below in "RH". Doubly nested case would result, except
1543 * that the decoded instruction Similar to opcode 81, except that
1544 * the immediate byte is sign extended to a word length.
1547 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1549 if (DEBUG_DECODE()) {
1550 /* XXX DECODE_PRINTF may be changed to something more
1551 general, so that it is important to leave the strings
1552 in the same format, even though the result is that the
1553 above test is done twice. */
1556 DECODE_PRINTF("ADD\t");
1559 DECODE_PRINTF("OR\t");
1562 DECODE_PRINTF("ADC\t");
1565 DECODE_PRINTF("SBB\t");
1568 DECODE_PRINTF("AND\t");
1571 DECODE_PRINTF("SUB\t");
1574 DECODE_PRINTF("XOR\t");
1577 DECODE_PRINTF("CMP\t");
1582 /* know operation, decode the mod byte to find the addressing
1585 DECODE_PRINTF("DWORD PTR ");
1586 destoffset
= decode_rmXX_address(mod
,rl
);
1588 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1591 destval
= fetch_data_long(destoffset
);
1592 imm
= (s8
) fetch_byte_imm();
1593 DECODE_PRINTF2(",%x\n", imm
);
1595 destval
= (*genop_long_operation
[rh
]) (destval
, imm
);
1597 store_data_long(destoffset
, destval
);
1601 destval
= fetch_data_word(destoffset
);
1602 imm
= (s8
) fetch_byte_imm();
1603 DECODE_PRINTF2(",%x\n", imm
);
1605 destval
= (*genop_word_operation
[rh
]) (destval
, imm
);
1607 store_data_word(destoffset
, destval
);
1609 } else { /* register to register */
1610 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1613 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1614 imm
= (s8
) fetch_byte_imm();
1615 DECODE_PRINTF2(",%x\n", imm
);
1617 *destreg
= (*genop_long_operation
[rh
]) (*destreg
, imm
);
1621 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1622 imm
= (s8
) fetch_byte_imm();
1623 DECODE_PRINTF2(",%x\n", imm
);
1625 *destreg
= (*genop_word_operation
[rh
]) (*destreg
, imm
);
1628 DECODE_CLEAR_SEGOVR();
1632 /****************************************************************************
1635 ****************************************************************************/
1636 static void x86emuOp_test_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1639 u8
*destreg
, *srcreg
;
1644 DECODE_PRINTF("TEST\t");
1645 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1647 destoffset
= decode_rmXX_address(mod
, rl
);
1649 destval
= fetch_data_byte(destoffset
);
1650 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1651 DECODE_PRINTF("\n");
1653 test_byte(destval
, *srcreg
);
1654 } else { /* register to register */
1655 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1657 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1658 DECODE_PRINTF("\n");
1660 test_byte(*destreg
, *srcreg
);
1662 DECODE_CLEAR_SEGOVR();
1666 /****************************************************************************
1669 ****************************************************************************/
1670 static void x86emuOp_test_word_RM_R(u8
X86EMU_UNUSED(op1
))
1676 DECODE_PRINTF("TEST\t");
1677 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1679 destoffset
= decode_rmXX_address(mod
, rl
);
1680 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1685 destval
= fetch_data_long(destoffset
);
1686 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1687 DECODE_PRINTF("\n");
1689 test_long(destval
, *srcreg
);
1695 destval
= fetch_data_word(destoffset
);
1696 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1697 DECODE_PRINTF("\n");
1699 test_word(destval
, *srcreg
);
1701 } else { /* register to register */
1702 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1703 u32
*destreg
,*srcreg
;
1705 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1707 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1708 DECODE_PRINTF("\n");
1710 test_long(*destreg
, *srcreg
);
1712 u16
*destreg
,*srcreg
;
1714 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1716 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1717 DECODE_PRINTF("\n");
1719 test_word(*destreg
, *srcreg
);
1722 DECODE_CLEAR_SEGOVR();
1726 /****************************************************************************
1729 ****************************************************************************/
1730 static void x86emuOp_xchg_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1733 u8
*destreg
, *srcreg
;
1739 DECODE_PRINTF("XCHG\t");
1740 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1742 destoffset
= decode_rmXX_address(mod
, rl
);
1744 destval
= fetch_data_byte(destoffset
);
1745 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1746 DECODE_PRINTF("\n");
1751 store_data_byte(destoffset
, destval
);
1752 } else { /* register to register */
1753 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1755 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1756 DECODE_PRINTF("\n");
1762 DECODE_CLEAR_SEGOVR();
1766 /****************************************************************************
1769 ****************************************************************************/
1770 static void x86emuOp_xchg_word_RM_R(u8
X86EMU_UNUSED(op1
))
1776 DECODE_PRINTF("XCHG\t");
1777 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1779 destoffset
= decode_rmXX_address(mod
, rl
);
1781 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1785 destval
= fetch_data_long(destoffset
);
1786 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1787 DECODE_PRINTF("\n");
1792 store_data_long(destoffset
, destval
);
1797 destval
= fetch_data_word(destoffset
);
1798 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1799 DECODE_PRINTF("\n");
1804 store_data_word(destoffset
, destval
);
1806 } else { /* register to register */
1807 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1808 u32
*destreg
,*srcreg
;
1811 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1813 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1814 DECODE_PRINTF("\n");
1820 u16
*destreg
,*srcreg
;
1823 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1825 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1826 DECODE_PRINTF("\n");
1833 DECODE_CLEAR_SEGOVR();
1837 /****************************************************************************
1840 ****************************************************************************/
1841 static void x86emuOp_mov_byte_RM_R(u8
X86EMU_UNUSED(op1
))
1844 u8
*destreg
, *srcreg
;
1848 DECODE_PRINTF("MOV\t");
1849 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1851 destoffset
= decode_rmXX_address(mod
, rl
);
1853 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1854 DECODE_PRINTF("\n");
1856 store_data_byte(destoffset
, *srcreg
);
1857 } else { /* register to register */
1858 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
1860 srcreg
= DECODE_RM_BYTE_REGISTER(rh
);
1861 DECODE_PRINTF("\n");
1865 DECODE_CLEAR_SEGOVR();
1869 /****************************************************************************
1872 ****************************************************************************/
1873 static void x86emuOp_mov_word_RM_R(u8
X86EMU_UNUSED(op1
))
1879 DECODE_PRINTF("MOV\t");
1880 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1882 destoffset
= decode_rmXX_address(mod
, rl
);
1883 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1887 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1888 DECODE_PRINTF("\n");
1890 store_data_long(destoffset
, *srcreg
);
1895 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1896 DECODE_PRINTF("\n");
1898 store_data_word(destoffset
, *srcreg
);
1900 } else { /* register to register */
1901 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1902 u32
*destreg
,*srcreg
;
1904 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1906 srcreg
= DECODE_RM_LONG_REGISTER(rh
);
1907 DECODE_PRINTF("\n");
1911 u16
*destreg
,*srcreg
;
1913 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1915 srcreg
= DECODE_RM_WORD_REGISTER(rh
);
1916 DECODE_PRINTF("\n");
1921 DECODE_CLEAR_SEGOVR();
1925 /****************************************************************************
1928 ****************************************************************************/
1929 static void x86emuOp_mov_byte_R_RM(u8
X86EMU_UNUSED(op1
))
1932 u8
*destreg
, *srcreg
;
1937 DECODE_PRINTF("MOV\t");
1938 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1940 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1942 srcoffset
= decode_rmXX_address(mod
, rl
);
1943 srcval
= fetch_data_byte(srcoffset
);
1944 DECODE_PRINTF("\n");
1947 } else { /* register to register */
1948 destreg
= DECODE_RM_BYTE_REGISTER(rh
);
1950 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1951 DECODE_PRINTF("\n");
1955 DECODE_CLEAR_SEGOVR();
1959 /****************************************************************************
1962 ****************************************************************************/
1963 static void x86emuOp_mov_word_R_RM(u8
X86EMU_UNUSED(op1
))
1969 DECODE_PRINTF("MOV\t");
1970 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1972 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1976 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1978 srcoffset
= decode_rmXX_address(mod
, rl
);
1979 srcval
= fetch_data_long(srcoffset
);
1980 DECODE_PRINTF("\n");
1987 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1989 srcoffset
= decode_rmXX_address(mod
, rl
);
1990 srcval
= fetch_data_word(srcoffset
);
1991 DECODE_PRINTF("\n");
1995 } else { /* register to register */
1996 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1997 u32
*destreg
, *srcreg
;
1999 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2001 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2002 DECODE_PRINTF("\n");
2006 u16
*destreg
, *srcreg
;
2008 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2010 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2011 DECODE_PRINTF("\n");
2016 DECODE_CLEAR_SEGOVR();
2020 /****************************************************************************
2023 ****************************************************************************/
2024 static void x86emuOp_mov_word_RM_SR(u8
X86EMU_UNUSED(op1
))
2027 u16
*destreg
, *srcreg
;
2032 DECODE_PRINTF("MOV\t");
2033 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2035 destoffset
= decode_rmXX_address(mod
, rl
);
2037 srcreg
= decode_rm_seg_register(rh
);
2038 DECODE_PRINTF("\n");
2041 store_data_word(destoffset
, destval
);
2042 } else { /* register to register */
2043 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2045 srcreg
= decode_rm_seg_register(rh
);
2046 DECODE_PRINTF("\n");
2050 DECODE_CLEAR_SEGOVR();
2054 /****************************************************************************
2057 ****************************************************************************/
2058 static void x86emuOp_lea_word_R_M(u8
X86EMU_UNUSED(op1
))
2064 DECODE_PRINTF("LEA\t");
2065 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2067 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
2068 u32
*srcreg
= DECODE_RM_LONG_REGISTER(rh
);
2070 destoffset
= decode_rmXX_address(mod
, rl
);
2071 DECODE_PRINTF("\n");
2073 *srcreg
= (u32
)destoffset
;
2075 u16
*srcreg
= DECODE_RM_WORD_REGISTER(rh
);
2077 destoffset
= decode_rmXX_address(mod
, rl
);
2078 DECODE_PRINTF("\n");
2080 *srcreg
= (u16
)destoffset
;
2083 /* else { undefined. Do nothing. } */
2084 DECODE_CLEAR_SEGOVR();
2088 /****************************************************************************
2091 ****************************************************************************/
2092 static void x86emuOp_mov_word_SR_RM(u8
X86EMU_UNUSED(op1
))
2095 u16
*destreg
, *srcreg
;
2100 DECODE_PRINTF("MOV\t");
2101 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2103 destreg
= decode_rm_seg_register(rh
);
2105 srcoffset
= decode_rmXX_address(mod
, rl
);
2106 srcval
= fetch_data_word(srcoffset
);
2107 DECODE_PRINTF("\n");
2110 } else { /* register to register */
2111 destreg
= decode_rm_seg_register(rh
);
2113 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2114 DECODE_PRINTF("\n");
2119 * Clean up, and reset all the R_xSP pointers to the correct
2120 * locations. This is about 3x too much overhead (doing all the
2121 * segreg ptrs when only one is needed, but this instruction
2122 * *cannot* be that common, and this isn't too much work anyway.
2124 DECODE_CLEAR_SEGOVR();
2128 /****************************************************************************
2131 ****************************************************************************/
2132 static void x86emuOp_pop_RM(u8
X86EMU_UNUSED(op1
))
2138 DECODE_PRINTF("POP\t");
2139 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2141 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
2145 destoffset
= decode_rmXX_address(mod
, rl
);
2146 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2149 DECODE_PRINTF("\n");
2151 destval
= pop_long();
2152 store_data_long(destoffset
, destval
);
2156 DECODE_PRINTF("\n");
2158 destval
= pop_word();
2159 store_data_word(destoffset
, destval
);
2161 } else { /* register to register */
2162 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2165 destreg
= DECODE_RM_LONG_REGISTER(rl
);
2166 DECODE_PRINTF("\n");
2168 *destreg
= pop_long();
2172 destreg
= DECODE_RM_WORD_REGISTER(rl
);
2173 DECODE_PRINTF("\n");
2175 *destreg
= pop_word();
2178 DECODE_CLEAR_SEGOVR();
2182 /****************************************************************************
2185 ****************************************************************************/
2186 static void x86emuOp_nop(u8
X86EMU_UNUSED(op1
))
2189 DECODE_PRINTF("NOP\n");
2191 DECODE_CLEAR_SEGOVR();
2195 /****************************************************************************
2197 Handles opcode 0x91-0x97
2198 ****************************************************************************/
2199 static void x86emuOp_xchg_word_AX_register(u8
X86EMU_UNUSED(op1
))
2207 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2209 DECODE_PRINTF("XCHG\tEAX,");
2210 reg32
= DECODE_RM_LONG_REGISTER(op1
);
2211 DECODE_PRINTF("\n");
2214 M
.x86
.R_EAX
= *reg32
;
2218 DECODE_PRINTF("XCHG\tAX,");
2219 reg16
= DECODE_RM_WORD_REGISTER(op1
);
2220 DECODE_PRINTF("\n");
2223 M
.x86
.R_AX
= *reg16
;
2226 DECODE_CLEAR_SEGOVR();
2230 /****************************************************************************
2233 ****************************************************************************/
2234 static void x86emuOp_cbw(u8
X86EMU_UNUSED(op1
))
2237 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2238 DECODE_PRINTF("CWDE\n");
2240 DECODE_PRINTF("CBW\n");
2243 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2244 if (M
.x86
.R_AX
& 0x8000) {
2245 M
.x86
.R_EAX
|= 0xffff0000;
2247 M
.x86
.R_EAX
&= 0x0000ffff;
2250 if (M
.x86
.R_AL
& 0x80) {
2256 DECODE_CLEAR_SEGOVR();
2260 /****************************************************************************
2263 ****************************************************************************/
2264 static void x86emuOp_cwd(u8
X86EMU_UNUSED(op1
))
2267 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2268 DECODE_PRINTF("CDQ\n");
2270 DECODE_PRINTF("CWD\n");
2272 DECODE_PRINTF("CWD\n");
2274 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2275 if (M
.x86
.R_EAX
& 0x80000000) {
2276 M
.x86
.R_EDX
= 0xffffffff;
2281 if (M
.x86
.R_AX
& 0x8000) {
2282 M
.x86
.R_DX
= 0xffff;
2287 DECODE_CLEAR_SEGOVR();
2291 /****************************************************************************
2294 ****************************************************************************/
2295 static void x86emuOp_call_far_IMM(u8
X86EMU_UNUSED(op1
))
2300 DECODE_PRINTF("CALL\t");
2301 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2302 faroff
= fetch_long_imm();
2303 farseg
= fetch_word_imm();
2305 faroff
= fetch_word_imm();
2306 farseg
= fetch_word_imm();
2308 DECODE_PRINTF2("%04x:", farseg
);
2309 DECODE_PRINTF2("%04x\n", faroff
);
2310 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, farseg
, faroff
, "FAR ");
2314 * Hooked interrupt vectors calling into our "BIOS" will cause
2315 * problems unless all intersegment stuff is checked for BIOS
2316 * access. Check needed here. For moment, let it alone.
2319 push_word(M
.x86
.R_CS
);
2320 M
.x86
.R_CS
= farseg
;
2321 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2322 push_long(M
.x86
.R_EIP
);
2324 push_word(M
.x86
.R_IP
);
2326 M
.x86
.R_EIP
= faroff
& 0xffff;
2327 DECODE_CLEAR_SEGOVR();
2331 /****************************************************************************
2334 ****************************************************************************/
2335 static void x86emuOp_wait(u8
X86EMU_UNUSED(op1
))
2338 DECODE_PRINTF("WAIT");
2341 DECODE_CLEAR_SEGOVR();
2345 /****************************************************************************
2348 ****************************************************************************/
2349 static void x86emuOp_pushf_word(u8
X86EMU_UNUSED(op1
))
2354 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2355 DECODE_PRINTF("PUSHFD\n");
2357 DECODE_PRINTF("PUSHF\n");
2361 /* clear out *all* bits not representing flags, and turn on real bits */
2362 flags
= (M
.x86
.R_EFLG
& F_MSK
) | F_ALWAYS_ON
;
2363 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2366 push_word((u16
)flags
);
2368 DECODE_CLEAR_SEGOVR();
2372 /****************************************************************************
2375 ****************************************************************************/
2376 static void x86emuOp_popf_word(u8
X86EMU_UNUSED(op1
))
2379 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2380 DECODE_PRINTF("POPFD\n");
2382 DECODE_PRINTF("POPF\n");
2385 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2386 M
.x86
.R_EFLG
= pop_long();
2388 M
.x86
.R_FLG
= pop_word();
2390 DECODE_CLEAR_SEGOVR();
2394 /****************************************************************************
2397 ****************************************************************************/
2398 static void x86emuOp_sahf(u8
X86EMU_UNUSED(op1
))
2401 DECODE_PRINTF("SAHF\n");
2403 /* clear the lower bits of the flag register */
2404 M
.x86
.R_FLG
&= 0xffffff00;
2405 /* or in the AH register into the flags register */
2406 M
.x86
.R_FLG
|= M
.x86
.R_AH
;
2407 DECODE_CLEAR_SEGOVR();
2411 /****************************************************************************
2414 ****************************************************************************/
2415 static void x86emuOp_lahf(u8
X86EMU_UNUSED(op1
))
2418 DECODE_PRINTF("LAHF\n");
2420 M
.x86
.R_AH
= (u8
)(M
.x86
.R_FLG
& 0xff);
2421 /*undocumented TC++ behavior??? Nope. It's documented, but
2422 you have too look real hard to notice it. */
2424 DECODE_CLEAR_SEGOVR();
2428 /****************************************************************************
2431 ****************************************************************************/
2432 static void x86emuOp_mov_AL_M_IMM(u8
X86EMU_UNUSED(op1
))
2437 DECODE_PRINTF("MOV\tAL,");
2438 offset
= fetch_word_imm();
2439 DECODE_PRINTF2("[%04x]\n", offset
);
2441 M
.x86
.R_AL
= fetch_data_byte(offset
);
2442 DECODE_CLEAR_SEGOVR();
2446 /****************************************************************************
2449 ****************************************************************************/
2450 static void x86emuOp_mov_AX_M_IMM(u8
X86EMU_UNUSED(op1
))
2455 offset
= fetch_word_imm();
2456 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2457 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset
);
2459 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset
);
2462 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2463 M
.x86
.R_EAX
= fetch_data_long(offset
);
2465 M
.x86
.R_AX
= fetch_data_word(offset
);
2467 DECODE_CLEAR_SEGOVR();
2471 /****************************************************************************
2474 ****************************************************************************/
2475 static void x86emuOp_mov_M_AL_IMM(u8
X86EMU_UNUSED(op1
))
2480 DECODE_PRINTF("MOV\t");
2481 offset
= fetch_word_imm();
2482 DECODE_PRINTF2("[%04x],AL\n", offset
);
2484 store_data_byte(offset
, M
.x86
.R_AL
);
2485 DECODE_CLEAR_SEGOVR();
2489 /****************************************************************************
2492 ****************************************************************************/
2493 static void x86emuOp_mov_M_AX_IMM(u8
X86EMU_UNUSED(op1
))
2498 offset
= fetch_word_imm();
2499 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2500 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset
);
2502 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset
);
2505 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2506 store_data_long(offset
, M
.x86
.R_EAX
);
2508 store_data_word(offset
, M
.x86
.R_AX
);
2510 DECODE_CLEAR_SEGOVR();
2514 /****************************************************************************
2517 ****************************************************************************/
2518 static void x86emuOp_movs_byte(u8
X86EMU_UNUSED(op1
))
2525 DECODE_PRINTF("MOVS\tBYTE\n");
2526 if (ACCESS_FLAG(F_DF
)) /* down */
2532 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2533 /* don't care whether REPE or REPNE */
2534 /* move them until (E)CX is ZERO. */
2535 count
= (M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
;
2537 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2539 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2542 val
= fetch_data_byte(M
.x86
.R_SI
);
2543 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
2546 if (M
.x86
.intr
& INTR_HALTED
)
2549 DECODE_CLEAR_SEGOVR();
2553 /****************************************************************************
2556 ****************************************************************************/
2557 static void x86emuOp_movs_word(u8
X86EMU_UNUSED(op1
))
2564 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2565 DECODE_PRINTF("MOVS\tDWORD\n");
2566 if (ACCESS_FLAG(F_DF
)) /* down */
2571 DECODE_PRINTF("MOVS\tWORD\n");
2572 if (ACCESS_FLAG(F_DF
)) /* down */
2579 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2580 /* don't care whether REPE or REPNE */
2581 /* move them until (E)CX is ZERO. */
2582 count
= (M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
;
2584 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2586 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2589 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2590 val
= fetch_data_long(M
.x86
.R_SI
);
2591 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, val
);
2593 val
= fetch_data_word(M
.x86
.R_SI
);
2594 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, (u16
)val
);
2598 if (M
.x86
.intr
& INTR_HALTED
)
2601 DECODE_CLEAR_SEGOVR();
2605 /****************************************************************************
2608 ****************************************************************************/
2609 static void x86emuOp_cmps_byte(u8
X86EMU_UNUSED(op1
))
2615 DECODE_PRINTF("CMPS\tBYTE\n");
2617 if (ACCESS_FLAG(F_DF
)) /* down */
2622 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2624 /* move them until (E)CX is ZERO. */
2625 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2626 val1
= fetch_data_byte(M
.x86
.R_SI
);
2627 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2628 cmp_byte(val1
, val2
);
2629 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2635 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) && (ACCESS_FLAG(F_ZF
) == 0) ) break;
2636 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) && ACCESS_FLAG(F_ZF
) ) break;
2637 if (M
.x86
.intr
& INTR_HALTED
)
2640 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2642 val1
= fetch_data_byte(M
.x86
.R_SI
);
2643 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2644 cmp_byte(val1
, val2
);
2648 DECODE_CLEAR_SEGOVR();
2652 /****************************************************************************
2655 ****************************************************************************/
2656 static void x86emuOp_cmps_word(u8
X86EMU_UNUSED(op1
))
2662 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2663 DECODE_PRINTF("CMPS\tDWORD\n");
2666 DECODE_PRINTF("CMPS\tWORD\n");
2669 if (ACCESS_FLAG(F_DF
)) /* down */
2673 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2675 /* move them until (E)CX is ZERO. */
2676 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2677 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2678 val1
= fetch_data_long(M
.x86
.R_SI
);
2679 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2680 cmp_long(val1
, val2
);
2682 val1
= fetch_data_word(M
.x86
.R_SI
);
2683 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2684 cmp_word((u16
)val1
, (u16
)val2
);
2686 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2692 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) && ACCESS_FLAG(F_ZF
) == 0 ) break;
2693 if ( (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) && ACCESS_FLAG(F_ZF
) ) break;
2694 if (M
.x86
.intr
& INTR_HALTED
)
2697 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2699 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2700 val1
= fetch_data_long(M
.x86
.R_SI
);
2701 val2
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2702 cmp_long(val1
, val2
);
2704 val1
= fetch_data_word(M
.x86
.R_SI
);
2705 val2
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2706 cmp_word((u16
)val1
, (u16
)val2
);
2711 DECODE_CLEAR_SEGOVR();
2715 /****************************************************************************
2718 ****************************************************************************/
2719 static void x86emuOp_test_AL_IMM(u8
X86EMU_UNUSED(op1
))
2724 DECODE_PRINTF("TEST\tAL,");
2725 imm
= fetch_byte_imm();
2726 DECODE_PRINTF2("%04x\n", imm
);
2728 test_byte(M
.x86
.R_AL
, (u8
)imm
);
2729 DECODE_CLEAR_SEGOVR();
2733 /****************************************************************************
2736 ****************************************************************************/
2737 static void x86emuOp_test_AX_IMM(u8
X86EMU_UNUSED(op1
))
2742 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2743 DECODE_PRINTF("TEST\tEAX,");
2744 srcval
= fetch_long_imm();
2746 DECODE_PRINTF("TEST\tAX,");
2747 srcval
= fetch_word_imm();
2749 DECODE_PRINTF2("%x\n", srcval
);
2751 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2752 test_long(M
.x86
.R_EAX
, srcval
);
2754 test_word(M
.x86
.R_AX
, (u16
)srcval
);
2756 DECODE_CLEAR_SEGOVR();
2760 /****************************************************************************
2763 ****************************************************************************/
2764 static void x86emuOp_stos_byte(u8
X86EMU_UNUSED(op1
))
2769 DECODE_PRINTF("STOS\tBYTE\n");
2770 if (ACCESS_FLAG(F_DF
)) /* down */
2775 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2776 /* don't care whether REPE or REPNE */
2777 /* move them until (E)CX is ZERO. */
2778 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2779 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
2780 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2785 if (M
.x86
.intr
& INTR_HALTED
)
2788 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2790 store_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AL
);
2793 DECODE_CLEAR_SEGOVR();
2797 /****************************************************************************
2800 ****************************************************************************/
2801 static void x86emuOp_stos_word(u8
X86EMU_UNUSED(op1
))
2807 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2808 DECODE_PRINTF("STOS\tDWORD\n");
2809 if (ACCESS_FLAG(F_DF
)) /* down */
2814 DECODE_PRINTF("STOS\tWORD\n");
2815 if (ACCESS_FLAG(F_DF
)) /* down */
2822 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2823 /* don't care whether REPE or REPNE */
2824 /* move them until (E)CX is ZERO. */
2825 count
= (M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
;
2827 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2829 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2832 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2833 store_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_EAX
);
2835 store_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
, M
.x86
.R_AX
);
2838 if (M
.x86
.intr
& INTR_HALTED
)
2841 DECODE_CLEAR_SEGOVR();
2845 /****************************************************************************
2848 ****************************************************************************/
2849 static void x86emuOp_lods_byte(u8
X86EMU_UNUSED(op1
))
2854 DECODE_PRINTF("LODS\tBYTE\n");
2856 if (ACCESS_FLAG(F_DF
)) /* down */
2860 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2861 /* don't care whether REPE or REPNE */
2862 /* move them until (E)CX is ZERO. */
2863 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2864 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
2865 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2870 if (M
.x86
.intr
& INTR_HALTED
)
2873 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2875 M
.x86
.R_AL
= fetch_data_byte(M
.x86
.R_SI
);
2878 DECODE_CLEAR_SEGOVR();
2882 /****************************************************************************
2885 ****************************************************************************/
2886 static void x86emuOp_lods_word(u8
X86EMU_UNUSED(op1
))
2892 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2893 DECODE_PRINTF("LODS\tDWORD\n");
2894 if (ACCESS_FLAG(F_DF
)) /* down */
2899 DECODE_PRINTF("LODS\tWORD\n");
2900 if (ACCESS_FLAG(F_DF
)) /* down */
2907 if (M
.x86
.mode
& (SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
)) {
2908 /* don't care whether REPE or REPNE */
2909 /* move them until (E)CX is ZERO. */
2910 count
= (M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
;
2912 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2914 M
.x86
.mode
&= ~(SYSMODE_PREFIX_REPE
| SYSMODE_PREFIX_REPNE
);
2917 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2918 M
.x86
.R_EAX
= fetch_data_long(M
.x86
.R_SI
);
2920 M
.x86
.R_AX
= fetch_data_word(M
.x86
.R_SI
);
2923 if (M
.x86
.intr
& INTR_HALTED
)
2926 DECODE_CLEAR_SEGOVR();
2930 /****************************************************************************
2933 ****************************************************************************/
2934 static void x86emuOp_scas_byte(u8
X86EMU_UNUSED(op1
))
2940 DECODE_PRINTF("SCAS\tBYTE\n");
2942 if (ACCESS_FLAG(F_DF
)) /* down */
2946 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
2948 /* move them until (E)CX is ZERO. */
2949 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2950 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2951 cmp_byte(M
.x86
.R_AL
, val2
);
2952 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2957 if (ACCESS_FLAG(F_ZF
) == 0)
2959 if (M
.x86
.intr
& INTR_HALTED
)
2962 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
2963 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
2965 /* move them until (E)CX is ZERO. */
2966 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
2967 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2968 cmp_byte(M
.x86
.R_AL
, val2
);
2969 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
2974 if (ACCESS_FLAG(F_ZF
))
2975 break; /* zero flag set means equal */
2976 if (M
.x86
.intr
& INTR_HALTED
)
2979 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
2981 val2
= fetch_data_byte_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
2982 cmp_byte(M
.x86
.R_AL
, val2
);
2985 DECODE_CLEAR_SEGOVR();
2989 /****************************************************************************
2992 ****************************************************************************/
2993 static void x86emuOp_scas_word(u8
X86EMU_UNUSED(op1
))
2999 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3000 DECODE_PRINTF("SCAS\tDWORD\n");
3001 if (ACCESS_FLAG(F_DF
)) /* down */
3006 DECODE_PRINTF("SCAS\tWORD\n");
3007 if (ACCESS_FLAG(F_DF
)) /* down */
3013 if (M
.x86
.mode
& SYSMODE_PREFIX_REPE
) {
3015 /* move them until (E)CX is ZERO. */
3016 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
3017 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3018 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3019 cmp_long(M
.x86
.R_EAX
, val
);
3021 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3022 cmp_word(M
.x86
.R_AX
, (u16
)val
);
3024 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
3029 if (ACCESS_FLAG(F_ZF
) == 0)
3031 if (M
.x86
.intr
& INTR_HALTED
)
3034 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPE
;
3035 } else if (M
.x86
.mode
& SYSMODE_PREFIX_REPNE
) {
3037 /* move them until (E)CX is ZERO. */
3038 while (((M
.x86
.mode
& SYSMODE_32BIT_REP
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) {
3039 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3040 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3041 cmp_long(M
.x86
.R_EAX
, val
);
3043 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3044 cmp_word(M
.x86
.R_AX
, (u16
)val
);
3046 if (M
.x86
.mode
& SYSMODE_32BIT_REP
)
3051 if (ACCESS_FLAG(F_ZF
))
3052 break; /* zero flag set means equal */
3053 if (M
.x86
.intr
& INTR_HALTED
)
3056 M
.x86
.mode
&= ~SYSMODE_PREFIX_REPNE
;
3058 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3059 val
= fetch_data_long_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3060 cmp_long(M
.x86
.R_EAX
, val
);
3062 val
= fetch_data_word_abs(M
.x86
.R_ES
, M
.x86
.R_DI
);
3063 cmp_word(M
.x86
.R_AX
, (u16
)val
);
3067 DECODE_CLEAR_SEGOVR();
3071 /****************************************************************************
3073 Handles opcode 0xb0 - 0xb7
3074 ****************************************************************************/
3075 static void x86emuOp_mov_byte_register_IMM(u8 op1
)
3080 DECODE_PRINTF("MOV\t");
3081 ptr
= DECODE_RM_BYTE_REGISTER(op1
& 0x7);
3083 imm
= fetch_byte_imm();
3084 DECODE_PRINTF2("%x\n", imm
);
3087 DECODE_CLEAR_SEGOVR();
3091 /****************************************************************************
3093 Handles opcode 0xb8 - 0xbf
3094 ****************************************************************************/
3095 static void x86emuOp_mov_word_register_IMM(u8
X86EMU_UNUSED(op1
))
3102 DECODE_PRINTF("MOV\t");
3103 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3105 reg32
= DECODE_RM_LONG_REGISTER(op1
);
3106 srcval
= fetch_long_imm();
3107 DECODE_PRINTF2(",%x\n", srcval
);
3112 reg16
= DECODE_RM_WORD_REGISTER(op1
);
3113 srcval
= fetch_word_imm();
3114 DECODE_PRINTF2(",%x\n", srcval
);
3116 *reg16
= (u16
)srcval
;
3118 DECODE_CLEAR_SEGOVR();
3122 /****************************************************************************
3125 ****************************************************************************/
3126 static void x86emuOp_opcC0_byte_RM_MEM(u8
X86EMU_UNUSED(op1
))
3135 * Yet another weirdo special case instruction format. Part of
3136 * the opcode held below in "RH". Doubly nested case would
3137 * result, except that the decoded instruction
3140 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3142 if (DEBUG_DECODE()) {
3143 /* XXX DECODE_PRINTF may be changed to something more
3144 general, so that it is important to leave the strings
3145 in the same format, even though the result is that the
3146 above test is done twice. */
3150 DECODE_PRINTF("ROL\t");
3153 DECODE_PRINTF("ROR\t");
3156 DECODE_PRINTF("RCL\t");
3159 DECODE_PRINTF("RCR\t");
3162 DECODE_PRINTF("SHL\t");
3165 DECODE_PRINTF("SHR\t");
3168 DECODE_PRINTF("SAL\t");
3171 DECODE_PRINTF("SAR\t");
3176 /* know operation, decode the mod byte to find the addressing
3179 DECODE_PRINTF("BYTE PTR ");
3180 destoffset
= decode_rmXX_address(mod
, rl
);
3181 amt
= fetch_byte_imm();
3182 DECODE_PRINTF2(",%x\n", amt
);
3183 destval
= fetch_data_byte(destoffset
);
3185 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
3186 store_data_byte(destoffset
, destval
);
3187 } else { /* register to register */
3188 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3189 amt
= fetch_byte_imm();
3190 DECODE_PRINTF2(",%x\n", amt
);
3192 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
3195 DECODE_CLEAR_SEGOVR();
3199 /****************************************************************************
3202 ****************************************************************************/
3203 static void x86emuOp_opcC1_word_RM_MEM(u8
X86EMU_UNUSED(op1
))
3210 * Yet another weirdo special case instruction format. Part of
3211 * the opcode held below in "RH". Doubly nested case would
3212 * result, except that the decoded instruction
3215 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3217 if (DEBUG_DECODE()) {
3218 /* XXX DECODE_PRINTF may be changed to something more
3219 general, so that it is important to leave the strings
3220 in the same format, even though the result is that the
3221 above test is done twice. */
3225 DECODE_PRINTF("ROL\t");
3228 DECODE_PRINTF("ROR\t");
3231 DECODE_PRINTF("RCL\t");
3234 DECODE_PRINTF("RCR\t");
3237 DECODE_PRINTF("SHL\t");
3240 DECODE_PRINTF("SHR\t");
3243 DECODE_PRINTF("SAL\t");
3246 DECODE_PRINTF("SAR\t");
3251 /* know operation, decode the mod byte to find the addressing
3254 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3257 DECODE_PRINTF("DWORD PTR ");
3258 destoffset
= decode_rmXX_address(mod
, rl
);
3259 amt
= fetch_byte_imm();
3260 DECODE_PRINTF2(",%x\n", amt
);
3261 destval
= fetch_data_long(destoffset
);
3263 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
3264 store_data_long(destoffset
, destval
);
3268 DECODE_PRINTF("WORD PTR ");
3269 destoffset
= decode_rmXX_address(mod
, rl
);
3270 amt
= fetch_byte_imm();
3271 DECODE_PRINTF2(",%x\n", amt
);
3272 destval
= fetch_data_word(destoffset
);
3274 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
3275 store_data_word(destoffset
, destval
);
3277 } else { /* register to register */
3278 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3281 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3282 amt
= fetch_byte_imm();
3283 DECODE_PRINTF2(",%x\n", amt
);
3285 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
3289 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3290 amt
= fetch_byte_imm();
3291 DECODE_PRINTF2(",%x\n", amt
);
3293 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
3296 DECODE_CLEAR_SEGOVR();
3300 /****************************************************************************
3303 ****************************************************************************/
3304 static void x86emuOp_ret_near_IMM(u8
X86EMU_UNUSED(op1
))
3309 DECODE_PRINTF("RET\t");
3310 imm
= fetch_word_imm();
3311 DECODE_PRINTF2("%x\n", imm
);
3313 M
.x86
.R_IP
= pop_word();
3314 RETURN_TRACE(M
.x86
.saved_cs
,M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, "NEAR");
3316 DECODE_CLEAR_SEGOVR();
3320 /****************************************************************************
3323 ****************************************************************************/
3324 static void x86emuOp_ret_near(u8
X86EMU_UNUSED(op1
))
3327 DECODE_PRINTF("RET\n");
3329 M
.x86
.R_IP
= pop_word();
3330 RETURN_TRACE(M
.x86
.saved_cs
,M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, "NEAR");
3331 DECODE_CLEAR_SEGOVR();
3335 /****************************************************************************
3338 ****************************************************************************/
3339 static void x86emuOp_les_R_IMM(u8
X86EMU_UNUSED(op1
))
3346 DECODE_PRINTF("LES\t");
3347 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3349 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
3351 srcoffset
= decode_rmXX_address(mod
, rl
);
3352 DECODE_PRINTF("\n");
3354 *dstreg
= fetch_data_word(srcoffset
);
3355 M
.x86
.R_ES
= fetch_data_word(srcoffset
+ 2);
3357 /* else UNDEFINED! register to register */
3359 DECODE_CLEAR_SEGOVR();
3363 /****************************************************************************
3366 ****************************************************************************/
3367 static void x86emuOp_lds_R_IMM(u8
X86EMU_UNUSED(op1
))
3374 DECODE_PRINTF("LDS\t");
3375 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3377 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
3379 srcoffset
= decode_rmXX_address(mod
, rl
);
3380 DECODE_PRINTF("\n");
3382 *dstreg
= fetch_data_word(srcoffset
);
3383 M
.x86
.R_DS
= fetch_data_word(srcoffset
+ 2);
3385 /* else UNDEFINED! */
3386 DECODE_CLEAR_SEGOVR();
3390 /****************************************************************************
3393 ****************************************************************************/
3394 static void x86emuOp_mov_byte_RM_IMM(u8
X86EMU_UNUSED(op1
))
3402 DECODE_PRINTF("MOV\t");
3403 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3405 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
3409 DECODE_PRINTF("BYTE PTR ");
3410 destoffset
= decode_rmXX_address(mod
, rl
);
3411 imm
= fetch_byte_imm();
3412 DECODE_PRINTF2(",%2x\n", imm
);
3414 store_data_byte(destoffset
, imm
);
3415 } else { /* register to register */
3416 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3417 imm
= fetch_byte_imm();
3418 DECODE_PRINTF2(",%2x\n", imm
);
3422 DECODE_CLEAR_SEGOVR();
3426 /****************************************************************************
3429 ****************************************************************************/
3430 static void x86emuOp_mov_word_RM_IMM(u8
X86EMU_UNUSED(op1
))
3436 DECODE_PRINTF("MOV\t");
3437 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3439 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
3443 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3446 DECODE_PRINTF("DWORD PTR ");
3447 destoffset
= decode_rmXX_address(mod
, rl
);
3448 imm
= fetch_long_imm();
3449 DECODE_PRINTF2(",%x\n", imm
);
3451 store_data_long(destoffset
, imm
);
3455 DECODE_PRINTF("WORD PTR ");
3456 destoffset
= decode_rmXX_address(mod
, rl
);
3457 imm
= fetch_word_imm();
3458 DECODE_PRINTF2(",%x\n", imm
);
3460 store_data_word(destoffset
, imm
);
3462 } else { /* register to register */
3463 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3467 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3468 imm
= fetch_long_imm();
3469 DECODE_PRINTF2(",%x\n", imm
);
3476 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3477 imm
= fetch_word_imm();
3478 DECODE_PRINTF2(",%x\n", imm
);
3483 DECODE_CLEAR_SEGOVR();
3487 /****************************************************************************
3490 ****************************************************************************/
3491 static void x86emuOp_enter(u8
X86EMU_UNUSED(op1
))
3493 u16 local
,frame_pointer
;
3498 local
= fetch_word_imm();
3499 nesting
= fetch_byte_imm();
3500 DECODE_PRINTF2("ENTER %x\n", local
);
3501 DECODE_PRINTF2(",%x\n", nesting
);
3503 push_word(M
.x86
.R_BP
);
3504 frame_pointer
= M
.x86
.R_SP
;
3506 for (i
= 1; i
< nesting
; i
++) {
3508 push_word(fetch_data_word_abs(M
.x86
.R_SS
, M
.x86
.R_BP
));
3510 push_word(frame_pointer
);
3512 M
.x86
.R_BP
= frame_pointer
;
3513 M
.x86
.R_SP
= (u16
)(M
.x86
.R_SP
- local
);
3514 DECODE_CLEAR_SEGOVR();
3518 /****************************************************************************
3521 ****************************************************************************/
3522 static void x86emuOp_leave(u8
X86EMU_UNUSED(op1
))
3525 DECODE_PRINTF("LEAVE\n");
3527 M
.x86
.R_SP
= M
.x86
.R_BP
;
3528 M
.x86
.R_BP
= pop_word();
3529 DECODE_CLEAR_SEGOVR();
3533 /****************************************************************************
3536 ****************************************************************************/
3537 static void x86emuOp_ret_far_IMM(u8
X86EMU_UNUSED(op1
))
3542 DECODE_PRINTF("RETF\t");
3543 imm
= fetch_word_imm();
3544 DECODE_PRINTF2("%x\n", imm
);
3546 M
.x86
.R_IP
= pop_word();
3547 M
.x86
.R_CS
= pop_word();
3548 RETURN_TRACE(M
.x86
.saved_cs
,M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, "FAR");
3550 DECODE_CLEAR_SEGOVR();
3554 /****************************************************************************
3557 ****************************************************************************/
3558 static void x86emuOp_ret_far(u8
X86EMU_UNUSED(op1
))
3561 DECODE_PRINTF("RETF\n");
3563 M
.x86
.R_IP
= pop_word();
3564 M
.x86
.R_CS
= pop_word();
3565 RETURN_TRACE(M
.x86
.saved_cs
,M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, "FAR");
3566 DECODE_CLEAR_SEGOVR();
3570 /****************************************************************************
3573 ****************************************************************************/
3574 static void x86emuOp_int3(u8
X86EMU_UNUSED(op1
))
3576 u16
X86EMU_UNUSED(tmp
);
3579 DECODE_PRINTF("INT 3\n");
3580 tmp
= (u16
) mem_access_word(3 * 4 + 2);
3581 /* access the segment register */
3583 if (_X86EMU_intrTab
[3]) {
3584 (*_X86EMU_intrTab
[3])(3);
3586 push_word((u16
)M
.x86
.R_FLG
);
3589 push_word(M
.x86
.R_CS
);
3590 M
.x86
.R_CS
= mem_access_word(3 * 4 + 2);
3591 push_word(M
.x86
.R_IP
);
3592 M
.x86
.R_IP
= mem_access_word(3 * 4);
3594 DECODE_CLEAR_SEGOVR();
3598 /****************************************************************************
3601 ****************************************************************************/
3602 static void x86emuOp_int_IMM(u8
X86EMU_UNUSED(op1
))
3604 u16
X86EMU_UNUSED(tmp
);
3608 DECODE_PRINTF("INT\t");
3609 intnum
= fetch_byte_imm();
3610 DECODE_PRINTF2("%x\n", intnum
);
3611 tmp
= mem_access_word(intnum
* 4 + 2);
3613 if (_X86EMU_intrTab
[intnum
]) {
3614 (*_X86EMU_intrTab
[intnum
])(intnum
);
3616 push_word((u16
)M
.x86
.R_FLG
);
3619 push_word(M
.x86
.R_CS
);
3620 M
.x86
.R_CS
= mem_access_word(intnum
* 4 + 2);
3621 push_word(M
.x86
.R_IP
);
3622 M
.x86
.R_IP
= mem_access_word(intnum
* 4);
3624 DECODE_CLEAR_SEGOVR();
3628 /****************************************************************************
3631 ****************************************************************************/
3632 static void x86emuOp_into(u8
X86EMU_UNUSED(op1
))
3634 u16
X86EMU_UNUSED(tmp
);
3637 DECODE_PRINTF("INTO\n");
3639 if (ACCESS_FLAG(F_OF
)) {
3640 tmp
= mem_access_word(4 * 4 + 2);
3641 if (_X86EMU_intrTab
[4]) {
3642 (*_X86EMU_intrTab
[4])(4);
3644 push_word((u16
)M
.x86
.R_FLG
);
3647 push_word(M
.x86
.R_CS
);
3648 M
.x86
.R_CS
= mem_access_word(4 * 4 + 2);
3649 push_word(M
.x86
.R_IP
);
3650 M
.x86
.R_IP
= mem_access_word(4 * 4);
3653 DECODE_CLEAR_SEGOVR();
3657 /****************************************************************************
3660 ****************************************************************************/
3661 static void x86emuOp_iret(u8
X86EMU_UNUSED(op1
))
3664 DECODE_PRINTF("IRET\n");
3668 M
.x86
.R_IP
= pop_word();
3669 M
.x86
.R_CS
= pop_word();
3670 M
.x86
.R_FLG
= pop_word();
3671 DECODE_CLEAR_SEGOVR();
3675 /****************************************************************************
3678 ****************************************************************************/
3679 static void x86emuOp_opcD0_byte_RM_1(u8
X86EMU_UNUSED(op1
))
3687 * Yet another weirdo special case instruction format. Part of
3688 * the opcode held below in "RH". Doubly nested case would
3689 * result, except that the decoded instruction
3692 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3694 if (DEBUG_DECODE()) {
3695 /* XXX DECODE_PRINTF may be changed to something more
3696 general, so that it is important to leave the strings
3697 in the same format, even though the result is that the
3698 above test is done twice. */
3701 DECODE_PRINTF("ROL\t");
3704 DECODE_PRINTF("ROR\t");
3707 DECODE_PRINTF("RCL\t");
3710 DECODE_PRINTF("RCR\t");
3713 DECODE_PRINTF("SHL\t");
3716 DECODE_PRINTF("SHR\t");
3719 DECODE_PRINTF("SAL\t");
3722 DECODE_PRINTF("SAR\t");
3727 /* know operation, decode the mod byte to find the addressing
3730 DECODE_PRINTF("BYTE PTR ");
3731 destoffset
= decode_rmXX_address(mod
, rl
);
3732 DECODE_PRINTF(",1\n");
3733 destval
= fetch_data_byte(destoffset
);
3735 destval
= (*opcD0_byte_operation
[rh
]) (destval
, 1);
3736 store_data_byte(destoffset
, destval
);
3737 } else { /* register to register */
3738 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3739 DECODE_PRINTF(",1\n");
3741 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, 1);
3744 DECODE_CLEAR_SEGOVR();
3748 /****************************************************************************
3751 ****************************************************************************/
3752 static void x86emuOp_opcD1_word_RM_1(u8
X86EMU_UNUSED(op1
))
3758 * Yet another weirdo special case instruction format. Part of
3759 * the opcode held below in "RH". Doubly nested case would
3760 * result, except that the decoded instruction
3763 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3765 if (DEBUG_DECODE()) {
3766 /* XXX DECODE_PRINTF may be changed to something more
3767 general, so that it is important to leave the strings
3768 in the same format, even though the result is that the
3769 above test is done twice. */
3772 DECODE_PRINTF("ROL\t");
3775 DECODE_PRINTF("ROR\t");
3778 DECODE_PRINTF("RCL\t");
3781 DECODE_PRINTF("RCR\t");
3784 DECODE_PRINTF("SHL\t");
3787 DECODE_PRINTF("SHR\t");
3790 DECODE_PRINTF("SAL\t");
3793 DECODE_PRINTF("SAR\t");
3798 /* know operation, decode the mod byte to find the addressing
3801 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3804 DECODE_PRINTF("DWORD PTR ");
3805 destoffset
= decode_rmXX_address(mod
, rl
);
3806 DECODE_PRINTF(",1\n");
3807 destval
= fetch_data_long(destoffset
);
3809 destval
= (*opcD1_long_operation
[rh
]) (destval
, 1);
3810 store_data_long(destoffset
, destval
);
3814 DECODE_PRINTF("WORD PTR ");
3815 destoffset
= decode_rmXX_address(mod
, rl
);
3816 DECODE_PRINTF(",1\n");
3817 destval
= fetch_data_word(destoffset
);
3819 destval
= (*opcD1_word_operation
[rh
]) (destval
, 1);
3820 store_data_word(destoffset
, destval
);
3822 } else { /* register to register */
3823 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3827 destreg
= DECODE_RM_LONG_REGISTER(rl
);
3828 DECODE_PRINTF(",1\n");
3830 destval
= (*opcD1_long_operation
[rh
]) (*destreg
, 1);
3836 destreg
= DECODE_RM_WORD_REGISTER(rl
);
3837 DECODE_PRINTF(",1\n");
3839 destval
= (*opcD1_word_operation
[rh
]) (*destreg
, 1);
3843 DECODE_CLEAR_SEGOVR();
3847 /****************************************************************************
3850 ****************************************************************************/
3851 static void x86emuOp_opcD2_byte_RM_CL(u8
X86EMU_UNUSED(op1
))
3860 * Yet another weirdo special case instruction format. Part of
3861 * the opcode held below in "RH". Doubly nested case would
3862 * result, except that the decoded instruction
3865 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3867 if (DEBUG_DECODE()) {
3868 /* XXX DECODE_PRINTF may be changed to something more
3869 general, so that it is important to leave the strings
3870 in the same format, even though the result is that the
3871 above test is done twice. */
3874 DECODE_PRINTF("ROL\t");
3877 DECODE_PRINTF("ROR\t");
3880 DECODE_PRINTF("RCL\t");
3883 DECODE_PRINTF("RCR\t");
3886 DECODE_PRINTF("SHL\t");
3889 DECODE_PRINTF("SHR\t");
3892 DECODE_PRINTF("SAL\t");
3895 DECODE_PRINTF("SAR\t");
3900 /* know operation, decode the mod byte to find the addressing
3904 DECODE_PRINTF("BYTE PTR ");
3905 destoffset
= decode_rmXX_address(mod
, rl
);
3906 DECODE_PRINTF(",CL\n");
3907 destval
= fetch_data_byte(destoffset
);
3909 destval
= (*opcD0_byte_operation
[rh
]) (destval
, amt
);
3910 store_data_byte(destoffset
, destval
);
3911 } else { /* register to register */
3912 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
3913 DECODE_PRINTF(",CL\n");
3915 destval
= (*opcD0_byte_operation
[rh
]) (*destreg
, amt
);
3918 DECODE_CLEAR_SEGOVR();
3922 /****************************************************************************
3925 ****************************************************************************/
3926 static void x86emuOp_opcD3_word_RM_CL(u8
X86EMU_UNUSED(op1
))
3933 * Yet another weirdo special case instruction format. Part of
3934 * the opcode held below in "RH". Doubly nested case would
3935 * result, except that the decoded instruction
3938 FETCH_DECODE_MODRM(mod
, rh
, rl
);
3940 if (DEBUG_DECODE()) {
3941 /* XXX DECODE_PRINTF may be changed to something more
3942 general, so that it is important to leave the strings
3943 in the same format, even though the result is that the
3944 above test is done twice. */
3947 DECODE_PRINTF("ROL\t");
3950 DECODE_PRINTF("ROR\t");
3953 DECODE_PRINTF("RCL\t");
3956 DECODE_PRINTF("RCR\t");
3959 DECODE_PRINTF("SHL\t");
3962 DECODE_PRINTF("SHR\t");
3965 DECODE_PRINTF("SAL\t");
3968 DECODE_PRINTF("SAR\t");
3973 /* know operation, decode the mod byte to find the addressing
3977 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
3980 DECODE_PRINTF("DWORD PTR ");
3981 destoffset
= decode_rmXX_address(mod
, rl
);
3982 DECODE_PRINTF(",CL\n");
3983 destval
= fetch_data_long(destoffset
);
3985 destval
= (*opcD1_long_operation
[rh
]) (destval
, amt
);
3986 store_data_long(destoffset
, destval
);
3990 DECODE_PRINTF("WORD PTR ");
3991 destoffset
= decode_rmXX_address(mod
, rl
);
3992 DECODE_PRINTF(",CL\n");
3993 destval
= fetch_data_word(destoffset
);
3995 destval
= (*opcD1_word_operation
[rh
]) (destval
, amt
);
3996 store_data_word(destoffset
, destval
);
3998 } else { /* register to register */
3999 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4002 destreg
= DECODE_RM_LONG_REGISTER(rl
);
4003 DECODE_PRINTF(",CL\n");
4005 *destreg
= (*opcD1_long_operation
[rh
]) (*destreg
, amt
);
4009 destreg
= DECODE_RM_WORD_REGISTER(rl
);
4010 DECODE_PRINTF(",CL\n");
4012 *destreg
= (*opcD1_word_operation
[rh
]) (*destreg
, amt
);
4015 DECODE_CLEAR_SEGOVR();
4019 /****************************************************************************
4022 ****************************************************************************/
4023 static void x86emuOp_aam(u8
X86EMU_UNUSED(op1
))
4028 DECODE_PRINTF("AAM\n");
4029 a
= fetch_byte_imm(); /* this is a stupid encoding. */
4031 DECODE_PRINTF("ERROR DECODING AAM\n");
4036 /* note the type change here --- returning AL and AH in AX. */
4037 M
.x86
.R_AX
= aam_word(M
.x86
.R_AL
);
4038 DECODE_CLEAR_SEGOVR();
4042 /****************************************************************************
4045 ****************************************************************************/
4046 static void x86emuOp_aad(u8
X86EMU_UNUSED(op1
))
4048 u8
X86EMU_UNUSED(a
);
4051 DECODE_PRINTF("AAD\n");
4052 a
= fetch_byte_imm();
4054 M
.x86
.R_AX
= aad_word(M
.x86
.R_AX
);
4055 DECODE_CLEAR_SEGOVR();
4059 /* opcode 0xd6 ILLEGAL OPCODE */
4061 /****************************************************************************
4064 ****************************************************************************/
4065 static void x86emuOp_xlat(u8
X86EMU_UNUSED(op1
))
4070 DECODE_PRINTF("XLAT\n");
4072 addr
= (u16
)(M
.x86
.R_BX
+ (u8
)M
.x86
.R_AL
);
4073 M
.x86
.R_AL
= fetch_data_byte(addr
);
4074 DECODE_CLEAR_SEGOVR();
4078 /* Instructions D8 .. DF are in i87_ops.c */
4080 /****************************************************************************
4083 ****************************************************************************/
4084 static void x86emuOp_loopne(u8
X86EMU_UNUSED(op1
))
4089 DECODE_PRINTF("LOOPNE\t");
4090 ip
= (s8
) fetch_byte_imm();
4091 ip
+= (s16
) M
.x86
.R_IP
;
4092 DECODE_PRINTF2("%04x\n", ip
);
4094 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
)
4098 if (((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0 && !ACCESS_FLAG(F_ZF
)) /* (E)CX != 0 and !ZF */
4100 DECODE_CLEAR_SEGOVR();
4104 /****************************************************************************
4107 ****************************************************************************/
4108 static void x86emuOp_loope(u8
X86EMU_UNUSED(op1
))
4113 DECODE_PRINTF("LOOPE\t");
4114 ip
= (s8
) fetch_byte_imm();
4115 ip
+= (s16
) M
.x86
.R_IP
;
4116 DECODE_PRINTF2("%04x\n", ip
);
4118 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
)
4122 if (((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0 && ACCESS_FLAG(F_ZF
)) /* (E)CX != 0 and ZF */
4124 DECODE_CLEAR_SEGOVR();
4128 /****************************************************************************
4131 ****************************************************************************/
4132 static void x86emuOp_loop(u8
X86EMU_UNUSED(op1
))
4137 DECODE_PRINTF("LOOP\t");
4138 ip
= (s8
) fetch_byte_imm();
4139 ip
+= (s16
) M
.x86
.R_IP
;
4140 DECODE_PRINTF2("%04x\n", ip
);
4142 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
)
4146 if (((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) ? M
.x86
.R_ECX
: M
.x86
.R_CX
) != 0) /* (E)CX != 0 */
4148 DECODE_CLEAR_SEGOVR();
4152 /****************************************************************************
4155 ****************************************************************************/
4156 static void x86emuOp_jcxz(u8
X86EMU_UNUSED(op1
))
4161 /* jump to byte offset if overflow flag is set */
4163 DECODE_PRINTF("JCXZ\t");
4164 offset
= (s8
)fetch_byte_imm();
4165 target
= (u16
)(M
.x86
.R_IP
+ offset
);
4166 DECODE_PRINTF2("%x\n", target
);
4168 if (M
.x86
.R_CX
== 0) {
4169 M
.x86
.R_IP
= target
;
4170 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, M
.x86
.R_IP
, " CXZ ");
4172 DECODE_CLEAR_SEGOVR();
4176 /****************************************************************************
4179 ****************************************************************************/
4180 static void x86emuOp_in_byte_AL_IMM(u8
X86EMU_UNUSED(op1
))
4185 DECODE_PRINTF("IN\t");
4186 port
= (u8
) fetch_byte_imm();
4187 DECODE_PRINTF2("%x,AL\n", port
);
4189 M
.x86
.R_AL
= (*sys_inb
)(port
);
4190 DECODE_CLEAR_SEGOVR();
4194 /****************************************************************************
4197 ****************************************************************************/
4198 static void x86emuOp_in_word_AX_IMM(u8
X86EMU_UNUSED(op1
))
4203 DECODE_PRINTF("IN\t");
4204 port
= (u8
) fetch_byte_imm();
4205 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4206 DECODE_PRINTF2("EAX,%x\n", port
);
4208 DECODE_PRINTF2("AX,%x\n", port
);
4211 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4212 M
.x86
.R_EAX
= (*sys_inl
)(port
);
4214 M
.x86
.R_AX
= (*sys_inw
)(port
);
4216 DECODE_CLEAR_SEGOVR();
4220 /****************************************************************************
4223 ****************************************************************************/
4224 static void x86emuOp_out_byte_IMM_AL(u8
X86EMU_UNUSED(op1
))
4229 DECODE_PRINTF("OUT\t");
4230 port
= (u8
) fetch_byte_imm();
4231 DECODE_PRINTF2("%x,AL\n", port
);
4233 (*sys_outb
)(port
, M
.x86
.R_AL
);
4234 DECODE_CLEAR_SEGOVR();
4238 /****************************************************************************
4241 ****************************************************************************/
4242 static void x86emuOp_out_word_IMM_AX(u8
X86EMU_UNUSED(op1
))
4247 DECODE_PRINTF("OUT\t");
4248 port
= (u8
) fetch_byte_imm();
4249 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4250 DECODE_PRINTF2("%x,EAX\n", port
);
4252 DECODE_PRINTF2("%x,AX\n", port
);
4255 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4256 (*sys_outl
)(port
, M
.x86
.R_EAX
);
4258 (*sys_outw
)(port
, M
.x86
.R_AX
);
4260 DECODE_CLEAR_SEGOVR();
4264 /****************************************************************************
4267 ****************************************************************************/
4268 static void x86emuOp_call_near_IMM(u8
X86EMU_UNUSED(op1
))
4270 s16 ip16
= 0; /* Initialize to keep GCC silent */
4274 DECODE_PRINTF("CALL\t");
4275 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4276 ip32
= (s32
) fetch_long_imm();
4277 ip32
+= (s16
) M
.x86
.R_IP
; /* CHECK SIGN */
4278 DECODE_PRINTF2("%04x\n", (u16
)ip32
);
4279 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip32
, "");
4281 ip16
= (s16
) fetch_word_imm();
4282 ip16
+= (s16
) M
.x86
.R_IP
; /* CHECK SIGN */
4283 DECODE_PRINTF2("%04x\n", ip16
);
4284 CALL_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip16
, "");
4287 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4288 push_long(M
.x86
.R_EIP
);
4289 M
.x86
.R_EIP
= ip32
& 0xffff;
4291 push_word(M
.x86
.R_IP
);
4294 DECODE_CLEAR_SEGOVR();
4298 /****************************************************************************
4301 ****************************************************************************/
4302 static void x86emuOp_jump_near_IMM(u8
X86EMU_UNUSED(op1
))
4307 DECODE_PRINTF("JMP\t");
4308 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4309 ip
= (u32
)fetch_long_imm();
4310 ip
+= (u32
)M
.x86
.R_EIP
;
4311 DECODE_PRINTF2("%08x\n", (u32
)ip
);
4312 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip
, " NEAR ");
4314 M
.x86
.R_EIP
= (u32
)ip
;
4316 ip
= (s16
)fetch_word_imm();
4317 ip
+= (s16
)M
.x86
.R_IP
;
4318 DECODE_PRINTF2("%04x\n", (u16
)ip
);
4319 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, ip
, " NEAR ");
4321 M
.x86
.R_IP
= (u16
)ip
;
4323 DECODE_CLEAR_SEGOVR();
4327 /****************************************************************************
4330 ****************************************************************************/
4331 static void x86emuOp_jump_far_IMM(u8
X86EMU_UNUSED(op1
))
4337 DECODE_PRINTF("JMP\tFAR ");
4338 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4339 ip
= fetch_long_imm();
4341 ip
= fetch_word_imm();
4343 cs
= fetch_word_imm();
4344 DECODE_PRINTF2("%04x:", cs
);
4345 DECODE_PRINTF2("%04x\n", ip
);
4346 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, cs
, ip
, " FAR ");
4348 M
.x86
.R_EIP
= ip
& 0xffff;
4350 DECODE_CLEAR_SEGOVR();
4354 /****************************************************************************
4357 ****************************************************************************/
4358 static void x86emuOp_jump_byte_IMM(u8
X86EMU_UNUSED(op1
))
4364 DECODE_PRINTF("JMP\t");
4365 offset
= (s8
)fetch_byte_imm();
4366 target
= (u16
)(M
.x86
.R_IP
+ offset
);
4367 DECODE_PRINTF2("%x\n", target
);
4368 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, target
, " BYTE ");
4370 M
.x86
.R_IP
= target
;
4371 DECODE_CLEAR_SEGOVR();
4375 /****************************************************************************
4378 ****************************************************************************/
4379 static void x86emuOp_in_byte_AL_DX(u8
X86EMU_UNUSED(op1
))
4382 DECODE_PRINTF("IN\tAL,DX\n");
4384 M
.x86
.R_AL
= (*sys_inb
)(M
.x86
.R_DX
);
4385 DECODE_CLEAR_SEGOVR();
4389 /****************************************************************************
4392 ****************************************************************************/
4393 static void x86emuOp_in_word_AX_DX(u8
X86EMU_UNUSED(op1
))
4396 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4397 DECODE_PRINTF("IN\tEAX,DX\n");
4399 DECODE_PRINTF("IN\tAX,DX\n");
4402 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4403 M
.x86
.R_EAX
= (*sys_inl
)(M
.x86
.R_DX
);
4405 M
.x86
.R_AX
= (*sys_inw
)(M
.x86
.R_DX
);
4407 DECODE_CLEAR_SEGOVR();
4411 /****************************************************************************
4414 ****************************************************************************/
4415 static void x86emuOp_out_byte_DX_AL(u8
X86EMU_UNUSED(op1
))
4418 DECODE_PRINTF("OUT\tDX,AL\n");
4420 (*sys_outb
)(M
.x86
.R_DX
, M
.x86
.R_AL
);
4421 DECODE_CLEAR_SEGOVR();
4425 /****************************************************************************
4428 ****************************************************************************/
4429 static void x86emuOp_out_word_DX_AX(u8
X86EMU_UNUSED(op1
))
4432 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4433 DECODE_PRINTF("OUT\tDX,EAX\n");
4435 DECODE_PRINTF("OUT\tDX,AX\n");
4438 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4439 (*sys_outl
)(M
.x86
.R_DX
, M
.x86
.R_EAX
);
4441 (*sys_outw
)(M
.x86
.R_DX
, M
.x86
.R_AX
);
4443 DECODE_CLEAR_SEGOVR();
4447 /****************************************************************************
4450 ****************************************************************************/
4451 static void x86emuOp_lock(u8
X86EMU_UNUSED(op1
))
4454 DECODE_PRINTF("LOCK:\n");
4456 DECODE_CLEAR_SEGOVR();
4460 /*opcode 0xf1 ILLEGAL OPERATION */
4462 /****************************************************************************
4465 ****************************************************************************/
4466 static void x86emuOp_repne(u8
X86EMU_UNUSED(op1
))
4469 DECODE_PRINTF("REPNE\n");
4471 M
.x86
.mode
|= SYSMODE_PREFIX_REPNE
;
4472 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
)
4473 M
.x86
.mode
|= SYSMODE_32BIT_REP
;
4474 DECODE_CLEAR_SEGOVR();
4478 /****************************************************************************
4481 ****************************************************************************/
4482 static void x86emuOp_repe(u8
X86EMU_UNUSED(op1
))
4485 DECODE_PRINTF("REPE\n");
4487 M
.x86
.mode
|= SYSMODE_PREFIX_REPE
;
4488 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
)
4489 M
.x86
.mode
|= SYSMODE_32BIT_REP
;
4490 DECODE_CLEAR_SEGOVR();
4494 /****************************************************************************
4497 ****************************************************************************/
4498 static void x86emuOp_halt(u8
X86EMU_UNUSED(op1
))
4501 DECODE_PRINTF("HALT\n");
4504 DECODE_CLEAR_SEGOVR();
4508 /****************************************************************************
4511 ****************************************************************************/
4512 static void x86emuOp_cmc(u8
X86EMU_UNUSED(op1
))
4514 /* complement the carry flag. */
4516 DECODE_PRINTF("CMC\n");
4519 DECODE_CLEAR_SEGOVR();
4523 /****************************************************************************
4526 ****************************************************************************/
4527 static void x86emuOp_opcF6_byte_RM(u8
X86EMU_UNUSED(op1
))
4534 /* long, drawn out code follows. Double switch for a total
4537 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4538 DECODE_PRINTF(opF6_names
[rh
]);
4540 DECODE_PRINTF("BYTE PTR ");
4541 destoffset
= decode_rmXX_address(mod
, rl
);
4542 destval
= fetch_data_byte(destoffset
);
4545 case 0: /* test byte imm */
4547 srcval
= fetch_byte_imm();
4548 DECODE_PRINTF2("%02x\n", srcval
);
4550 test_byte(destval
, srcval
);
4553 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4557 DECODE_PRINTF("\n");
4559 destval
= not_byte(destval
);
4560 store_data_byte(destoffset
, destval
);
4563 DECODE_PRINTF("\n");
4565 destval
= neg_byte(destval
);
4566 store_data_byte(destoffset
, destval
);
4569 DECODE_PRINTF("\n");
4574 DECODE_PRINTF("\n");
4579 DECODE_PRINTF("\n");
4584 DECODE_PRINTF("\n");
4589 } else { /* mod=11 */
4590 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
4592 case 0: /* test byte imm */
4594 srcval
= fetch_byte_imm();
4595 DECODE_PRINTF2("%02x\n", srcval
);
4597 test_byte(*destreg
, srcval
);
4600 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4604 DECODE_PRINTF("\n");
4606 *destreg
= not_byte(*destreg
);
4609 DECODE_PRINTF("\n");
4611 *destreg
= neg_byte(*destreg
);
4614 DECODE_PRINTF("\n");
4616 mul_byte(*destreg
); /*!!! */
4619 DECODE_PRINTF("\n");
4621 imul_byte(*destreg
);
4624 DECODE_PRINTF("\n");
4629 DECODE_PRINTF("\n");
4631 idiv_byte(*destreg
);
4635 DECODE_CLEAR_SEGOVR();
4639 /****************************************************************************
4642 ****************************************************************************/
4643 static void x86emuOp_opcF7_word_RM(u8
X86EMU_UNUSED(op1
))
4649 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4650 DECODE_PRINTF(opF6_names
[rh
]);
4653 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4654 u32 destval
, srcval
;
4656 DECODE_PRINTF("DWORD PTR ");
4657 destoffset
= decode_rmXX_address(mod
, rl
);
4658 destval
= fetch_data_long(destoffset
);
4663 srcval
= fetch_long_imm();
4664 DECODE_PRINTF2("%x\n", srcval
);
4666 test_long(destval
, srcval
);
4669 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4673 DECODE_PRINTF("\n");
4675 destval
= not_long(destval
);
4676 store_data_long(destoffset
, destval
);
4679 DECODE_PRINTF("\n");
4681 destval
= neg_long(destval
);
4682 store_data_long(destoffset
, destval
);
4685 DECODE_PRINTF("\n");
4690 DECODE_PRINTF("\n");
4695 DECODE_PRINTF("\n");
4700 DECODE_PRINTF("\n");
4706 u16 destval
, srcval
;
4708 DECODE_PRINTF("WORD PTR ");
4709 destoffset
= decode_rmXX_address(mod
, rl
);
4710 destval
= fetch_data_word(destoffset
);
4713 case 0: /* test word imm */
4715 srcval
= fetch_word_imm();
4716 DECODE_PRINTF2("%x\n", srcval
);
4718 test_word(destval
, srcval
);
4721 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4725 DECODE_PRINTF("\n");
4727 destval
= not_word(destval
);
4728 store_data_word(destoffset
, destval
);
4731 DECODE_PRINTF("\n");
4733 destval
= neg_word(destval
);
4734 store_data_word(destoffset
, destval
);
4737 DECODE_PRINTF("\n");
4742 DECODE_PRINTF("\n");
4747 DECODE_PRINTF("\n");
4752 DECODE_PRINTF("\n");
4759 } else { /* mod=11 */
4761 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
4765 destreg
= DECODE_RM_LONG_REGISTER(rl
);
4768 case 0: /* test word imm */
4770 srcval
= fetch_long_imm();
4771 DECODE_PRINTF2("%x\n", srcval
);
4773 test_long(*destreg
, srcval
);
4776 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4780 DECODE_PRINTF("\n");
4782 *destreg
= not_long(*destreg
);
4785 DECODE_PRINTF("\n");
4787 *destreg
= neg_long(*destreg
);
4790 DECODE_PRINTF("\n");
4792 mul_long(*destreg
); /*!!! */
4795 DECODE_PRINTF("\n");
4797 imul_long(*destreg
);
4800 DECODE_PRINTF("\n");
4805 DECODE_PRINTF("\n");
4807 idiv_long(*destreg
);
4814 destreg
= DECODE_RM_WORD_REGISTER(rl
);
4817 case 0: /* test word imm */
4819 srcval
= fetch_word_imm();
4820 DECODE_PRINTF2("%x\n", srcval
);
4822 test_word(*destreg
, srcval
);
4825 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4829 DECODE_PRINTF("\n");
4831 *destreg
= not_word(*destreg
);
4834 DECODE_PRINTF("\n");
4836 *destreg
= neg_word(*destreg
);
4839 DECODE_PRINTF("\n");
4841 mul_word(*destreg
); /*!!! */
4844 DECODE_PRINTF("\n");
4846 imul_word(*destreg
);
4849 DECODE_PRINTF("\n");
4854 DECODE_PRINTF("\n");
4856 idiv_word(*destreg
);
4861 DECODE_CLEAR_SEGOVR();
4865 /****************************************************************************
4868 ****************************************************************************/
4869 static void x86emuOp_clc(u8
X86EMU_UNUSED(op1
))
4871 /* clear the carry flag. */
4873 DECODE_PRINTF("CLC\n");
4876 DECODE_CLEAR_SEGOVR();
4880 /****************************************************************************
4883 ****************************************************************************/
4884 static void x86emuOp_stc(u8
X86EMU_UNUSED(op1
))
4886 /* set the carry flag. */
4888 DECODE_PRINTF("STC\n");
4891 DECODE_CLEAR_SEGOVR();
4895 /****************************************************************************
4898 ****************************************************************************/
4899 static void x86emuOp_cli(u8
X86EMU_UNUSED(op1
))
4901 /* clear interrupts. */
4903 DECODE_PRINTF("CLI\n");
4906 DECODE_CLEAR_SEGOVR();
4910 /****************************************************************************
4913 ****************************************************************************/
4914 static void x86emuOp_sti(u8
X86EMU_UNUSED(op1
))
4916 /* enable interrupts. */
4918 DECODE_PRINTF("STI\n");
4921 DECODE_CLEAR_SEGOVR();
4925 /****************************************************************************
4928 ****************************************************************************/
4929 static void x86emuOp_cld(u8
X86EMU_UNUSED(op1
))
4931 /* clear interrupts. */
4933 DECODE_PRINTF("CLD\n");
4936 DECODE_CLEAR_SEGOVR();
4940 /****************************************************************************
4943 ****************************************************************************/
4944 static void x86emuOp_std(u8
X86EMU_UNUSED(op1
))
4946 /* clear interrupts. */
4948 DECODE_PRINTF("STD\n");
4951 DECODE_CLEAR_SEGOVR();
4955 /****************************************************************************
4958 ****************************************************************************/
4959 static void x86emuOp_opcFE_byte_RM(u8
X86EMU_UNUSED(op1
))
4966 /* Yet another special case instruction. */
4968 FETCH_DECODE_MODRM(mod
, rh
, rl
);
4970 if (DEBUG_DECODE()) {
4971 /* XXX DECODE_PRINTF may be changed to something more
4972 general, so that it is important to leave the strings
4973 in the same format, even though the result is that the
4974 above test is done twice. */
4978 DECODE_PRINTF("INC\t");
4981 DECODE_PRINTF("DEC\t");
4989 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x\n", mod
);
4996 DECODE_PRINTF("BYTE PTR ");
4997 destoffset
= decode_rmXX_address(mod
, rl
);
4998 DECODE_PRINTF("\n");
4999 destval
= fetch_data_byte(destoffset
);
5002 destval
= inc_byte(destval
);
5004 destval
= dec_byte(destval
);
5005 store_data_byte(destoffset
, destval
);
5007 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
5008 DECODE_PRINTF("\n");
5011 *destreg
= inc_byte(*destreg
);
5013 *destreg
= dec_byte(*destreg
);
5015 DECODE_CLEAR_SEGOVR();
5019 /****************************************************************************
5022 ****************************************************************************/
5023 static void x86emuOp_opcFF_word_RM(u8
X86EMU_UNUSED(op1
))
5026 uint destoffset
= 0;
5029 u16 destval
,destval2
;
5032 /* Yet another special case instruction. */
5034 FETCH_DECODE_MODRM(mod
, rh
, rl
);
5036 if (DEBUG_DECODE()) {
5037 /* XXX DECODE_PRINTF may be changed to something more
5038 general, so that it is important to leave the strings
5039 in the same format, even though the result is that the
5040 above test is done twice. */
5044 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5045 DECODE_PRINTF("INC\tDWORD PTR ");
5047 DECODE_PRINTF("INC\tWORD PTR ");
5051 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5052 DECODE_PRINTF("DEC\tDWORD PTR ");
5054 DECODE_PRINTF("DEC\tWORD PTR ");
5058 DECODE_PRINTF("CALL\t ");
5061 DECODE_PRINTF("CALL\tFAR ");
5064 DECODE_PRINTF("JMP\t");
5067 DECODE_PRINTF("JMP\tFAR ");
5070 DECODE_PRINTF("PUSH\t");
5073 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
5080 destoffset
= decode_rmXX_address(mod
, rl
);
5081 DECODE_PRINTF("\n");
5083 case 0: /* inc word ptr ... */
5084 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5085 destval32
= fetch_data_long(destoffset
);
5087 destval32
= inc_long(destval32
);
5088 store_data_long(destoffset
, destval32
);
5090 destval
= fetch_data_word(destoffset
);
5092 destval
= inc_word(destval
);
5093 store_data_word(destoffset
, destval
);
5096 case 1: /* dec word ptr ... */
5097 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5098 destval32
= fetch_data_long(destoffset
);
5100 destval32
= dec_long(destval32
);
5101 store_data_long(destoffset
, destval32
);
5103 destval
= fetch_data_word(destoffset
);
5105 destval
= dec_word(destval
);
5106 store_data_word(destoffset
, destval
);
5109 case 2: /* call word ptr ... */
5110 destval
= fetch_data_word(destoffset
);
5112 push_word(M
.x86
.R_IP
);
5113 M
.x86
.R_IP
= destval
;
5115 case 3: /* call far ptr ... */
5116 destval
= fetch_data_word(destoffset
);
5117 destval2
= fetch_data_word(destoffset
+ 2);
5119 push_word(M
.x86
.R_CS
);
5120 M
.x86
.R_CS
= destval2
;
5121 push_word(M
.x86
.R_IP
);
5122 M
.x86
.R_IP
= destval
;
5124 case 4: /* jmp word ptr ... */
5125 destval
= fetch_data_word(destoffset
);
5126 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, M
.x86
.R_CS
, destval
, " WORD ");
5128 M
.x86
.R_IP
= destval
;
5130 case 5: /* jmp far ptr ... */
5131 destval
= fetch_data_word(destoffset
);
5132 destval2
= fetch_data_word(destoffset
+ 2);
5133 JMP_TRACE(M
.x86
.saved_cs
, M
.x86
.saved_ip
, destval2
, destval
, " FAR ");
5135 M
.x86
.R_IP
= destval
;
5136 M
.x86
.R_CS
= destval2
;
5138 case 6: /* push word ptr ... */
5139 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5140 destval32
= fetch_data_long(destoffset
);
5142 push_long(destval32
);
5144 destval
= fetch_data_word(destoffset
);
5153 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5154 destreg32
= DECODE_RM_LONG_REGISTER(rl
);
5155 DECODE_PRINTF("\n");
5157 *destreg32
= inc_long(*destreg32
);
5159 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5160 DECODE_PRINTF("\n");
5162 *destreg
= inc_word(*destreg
);
5166 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5167 destreg32
= DECODE_RM_LONG_REGISTER(rl
);
5168 DECODE_PRINTF("\n");
5170 *destreg32
= dec_long(*destreg32
);
5172 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5173 DECODE_PRINTF("\n");
5175 *destreg
= dec_word(*destreg
);
5178 case 2: /* call word ptr ... */
5179 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5180 DECODE_PRINTF("\n");
5182 push_word(M
.x86
.R_IP
);
5183 M
.x86
.R_IP
= *destreg
;
5185 case 3: /* jmp far ptr ... */
5186 DECODE_PRINTF("OPERATION UNDEFINED 0XFF\n");
5191 case 4: /* jmp ... */
5192 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5193 DECODE_PRINTF("\n");
5195 M
.x86
.R_IP
= (u16
) (*destreg
);
5197 case 5: /* jmp far ptr ... */
5198 DECODE_PRINTF("OPERATION UNDEFINED 0XFF\n");
5203 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
5204 destreg32
= DECODE_RM_LONG_REGISTER(rl
);
5205 DECODE_PRINTF("\n");
5207 push_long(*destreg32
);
5209 destreg
= DECODE_RM_WORD_REGISTER(rl
);
5210 DECODE_PRINTF("\n");
5212 push_word(*destreg
);
5217 DECODE_CLEAR_SEGOVR();
5221 /***************************************************************************
5222 * Single byte operation code table:
5223 **************************************************************************/
5224 void (*x86emu_optab
[256])(u8
) =
5226 /* 0x00 */ x86emuOp_genop_byte_RM_R
,
5227 /* 0x01 */ x86emuOp_genop_word_RM_R
,
5228 /* 0x02 */ x86emuOp_genop_byte_R_RM
,
5229 /* 0x03 */ x86emuOp_genop_word_R_RM
,
5230 /* 0x04 */ x86emuOp_genop_byte_AL_IMM
,
5231 /* 0x05 */ x86emuOp_genop_word_AX_IMM
,
5232 /* 0x06 */ x86emuOp_push_ES
,
5233 /* 0x07 */ x86emuOp_pop_ES
,
5235 /* 0x08 */ x86emuOp_genop_byte_RM_R
,
5236 /* 0x09 */ x86emuOp_genop_word_RM_R
,
5237 /* 0x0a */ x86emuOp_genop_byte_R_RM
,
5238 /* 0x0b */ x86emuOp_genop_word_R_RM
,
5239 /* 0x0c */ x86emuOp_genop_byte_AL_IMM
,
5240 /* 0x0d */ x86emuOp_genop_word_AX_IMM
,
5241 /* 0x0e */ x86emuOp_push_CS
,
5242 /* 0x0f */ x86emuOp_two_byte
,
5244 /* 0x10 */ x86emuOp_genop_byte_RM_R
,
5245 /* 0x11 */ x86emuOp_genop_word_RM_R
,
5246 /* 0x12 */ x86emuOp_genop_byte_R_RM
,
5247 /* 0x13 */ x86emuOp_genop_word_R_RM
,
5248 /* 0x14 */ x86emuOp_genop_byte_AL_IMM
,
5249 /* 0x15 */ x86emuOp_genop_word_AX_IMM
,
5250 /* 0x16 */ x86emuOp_push_SS
,
5251 /* 0x17 */ x86emuOp_pop_SS
,
5253 /* 0x18 */ x86emuOp_genop_byte_RM_R
,
5254 /* 0x19 */ x86emuOp_genop_word_RM_R
,
5255 /* 0x1a */ x86emuOp_genop_byte_R_RM
,
5256 /* 0x1b */ x86emuOp_genop_word_R_RM
,
5257 /* 0x1c */ x86emuOp_genop_byte_AL_IMM
,
5258 /* 0x1d */ x86emuOp_genop_word_AX_IMM
,
5259 /* 0x1e */ x86emuOp_push_DS
,
5260 /* 0x1f */ x86emuOp_pop_DS
,
5262 /* 0x20 */ x86emuOp_genop_byte_RM_R
,
5263 /* 0x21 */ x86emuOp_genop_word_RM_R
,
5264 /* 0x22 */ x86emuOp_genop_byte_R_RM
,
5265 /* 0x23 */ x86emuOp_genop_word_R_RM
,
5266 /* 0x24 */ x86emuOp_genop_byte_AL_IMM
,
5267 /* 0x25 */ x86emuOp_genop_word_AX_IMM
,
5268 /* 0x26 */ x86emuOp_segovr_ES
,
5269 /* 0x27 */ x86emuOp_daa
,
5271 /* 0x28 */ x86emuOp_genop_byte_RM_R
,
5272 /* 0x29 */ x86emuOp_genop_word_RM_R
,
5273 /* 0x2a */ x86emuOp_genop_byte_R_RM
,
5274 /* 0x2b */ x86emuOp_genop_word_R_RM
,
5275 /* 0x2c */ x86emuOp_genop_byte_AL_IMM
,
5276 /* 0x2d */ x86emuOp_genop_word_AX_IMM
,
5277 /* 0x2e */ x86emuOp_segovr_CS
,
5278 /* 0x2f */ x86emuOp_das
,
5280 /* 0x30 */ x86emuOp_genop_byte_RM_R
,
5281 /* 0x31 */ x86emuOp_genop_word_RM_R
,
5282 /* 0x32 */ x86emuOp_genop_byte_R_RM
,
5283 /* 0x33 */ x86emuOp_genop_word_R_RM
,
5284 /* 0x34 */ x86emuOp_genop_byte_AL_IMM
,
5285 /* 0x35 */ x86emuOp_genop_word_AX_IMM
,
5286 /* 0x36 */ x86emuOp_segovr_SS
,
5287 /* 0x37 */ x86emuOp_aaa
,
5289 /* 0x38 */ x86emuOp_genop_byte_RM_R
,
5290 /* 0x39 */ x86emuOp_genop_word_RM_R
,
5291 /* 0x3a */ x86emuOp_genop_byte_R_RM
,
5292 /* 0x3b */ x86emuOp_genop_word_R_RM
,
5293 /* 0x3c */ x86emuOp_genop_byte_AL_IMM
,
5294 /* 0x3d */ x86emuOp_genop_word_AX_IMM
,
5295 /* 0x3e */ x86emuOp_segovr_DS
,
5296 /* 0x3f */ x86emuOp_aas
,
5298 /* 0x40 */ x86emuOp_inc_register
,
5299 /* 0x41 */ x86emuOp_inc_register
,
5300 /* 0x42 */ x86emuOp_inc_register
,
5301 /* 0x43 */ x86emuOp_inc_register
,
5302 /* 0x44 */ x86emuOp_inc_register
,
5303 /* 0x45 */ x86emuOp_inc_register
,
5304 /* 0x46 */ x86emuOp_inc_register
,
5305 /* 0x47 */ x86emuOp_inc_register
,
5307 /* 0x48 */ x86emuOp_dec_register
,
5308 /* 0x49 */ x86emuOp_dec_register
,
5309 /* 0x4a */ x86emuOp_dec_register
,
5310 /* 0x4b */ x86emuOp_dec_register
,
5311 /* 0x4c */ x86emuOp_dec_register
,
5312 /* 0x4d */ x86emuOp_dec_register
,
5313 /* 0x4e */ x86emuOp_dec_register
,
5314 /* 0x4f */ x86emuOp_dec_register
,
5316 /* 0x50 */ x86emuOp_push_register
,
5317 /* 0x51 */ x86emuOp_push_register
,
5318 /* 0x52 */ x86emuOp_push_register
,
5319 /* 0x53 */ x86emuOp_push_register
,
5320 /* 0x54 */ x86emuOp_push_register
,
5321 /* 0x55 */ x86emuOp_push_register
,
5322 /* 0x56 */ x86emuOp_push_register
,
5323 /* 0x57 */ x86emuOp_push_register
,
5325 /* 0x58 */ x86emuOp_pop_register
,
5326 /* 0x59 */ x86emuOp_pop_register
,
5327 /* 0x5a */ x86emuOp_pop_register
,
5328 /* 0x5b */ x86emuOp_pop_register
,
5329 /* 0x5c */ x86emuOp_pop_register
,
5330 /* 0x5d */ x86emuOp_pop_register
,
5331 /* 0x5e */ x86emuOp_pop_register
,
5332 /* 0x5f */ x86emuOp_pop_register
,
5334 /* 0x60 */ x86emuOp_push_all
,
5335 /* 0x61 */ x86emuOp_pop_all
,
5336 /* 0x62 */ x86emuOp_illegal_op
, /* bound */
5337 /* 0x63 */ x86emuOp_illegal_op
, /* arpl */
5338 /* 0x64 */ x86emuOp_segovr_FS
,
5339 /* 0x65 */ x86emuOp_segovr_GS
,
5340 /* 0x66 */ x86emuOp_prefix_data
,
5341 /* 0x67 */ x86emuOp_prefix_addr
,
5343 /* 0x68 */ x86emuOp_push_word_IMM
,
5344 /* 0x69 */ x86emuOp_imul_word_IMM
,
5345 /* 0x6a */ x86emuOp_push_byte_IMM
,
5346 /* 0x6b */ x86emuOp_imul_byte_IMM
,
5347 /* 0x6c */ x86emuOp_ins_byte
,
5348 /* 0x6d */ x86emuOp_ins_word
,
5349 /* 0x6e */ x86emuOp_outs_byte
,
5350 /* 0x6f */ x86emuOp_outs_word
,
5352 /* 0x70 */ x86emuOp_jump_near_cond
,
5353 /* 0x71 */ x86emuOp_jump_near_cond
,
5354 /* 0x72 */ x86emuOp_jump_near_cond
,
5355 /* 0x73 */ x86emuOp_jump_near_cond
,
5356 /* 0x74 */ x86emuOp_jump_near_cond
,
5357 /* 0x75 */ x86emuOp_jump_near_cond
,
5358 /* 0x76 */ x86emuOp_jump_near_cond
,
5359 /* 0x77 */ x86emuOp_jump_near_cond
,
5361 /* 0x78 */ x86emuOp_jump_near_cond
,
5362 /* 0x79 */ x86emuOp_jump_near_cond
,
5363 /* 0x7a */ x86emuOp_jump_near_cond
,
5364 /* 0x7b */ x86emuOp_jump_near_cond
,
5365 /* 0x7c */ x86emuOp_jump_near_cond
,
5366 /* 0x7d */ x86emuOp_jump_near_cond
,
5367 /* 0x7e */ x86emuOp_jump_near_cond
,
5368 /* 0x7f */ x86emuOp_jump_near_cond
,
5370 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM
,
5371 /* 0x81 */ x86emuOp_opc81_word_RM_IMM
,
5372 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM
,
5373 /* 0x83 */ x86emuOp_opc83_word_RM_IMM
,
5374 /* 0x84 */ x86emuOp_test_byte_RM_R
,
5375 /* 0x85 */ x86emuOp_test_word_RM_R
,
5376 /* 0x86 */ x86emuOp_xchg_byte_RM_R
,
5377 /* 0x87 */ x86emuOp_xchg_word_RM_R
,
5379 /* 0x88 */ x86emuOp_mov_byte_RM_R
,
5380 /* 0x89 */ x86emuOp_mov_word_RM_R
,
5381 /* 0x8a */ x86emuOp_mov_byte_R_RM
,
5382 /* 0x8b */ x86emuOp_mov_word_R_RM
,
5383 /* 0x8c */ x86emuOp_mov_word_RM_SR
,
5384 /* 0x8d */ x86emuOp_lea_word_R_M
,
5385 /* 0x8e */ x86emuOp_mov_word_SR_RM
,
5386 /* 0x8f */ x86emuOp_pop_RM
,
5388 /* 0x90 */ x86emuOp_nop
,
5389 /* 0x91 */ x86emuOp_xchg_word_AX_register
,
5390 /* 0x92 */ x86emuOp_xchg_word_AX_register
,
5391 /* 0x93 */ x86emuOp_xchg_word_AX_register
,
5392 /* 0x94 */ x86emuOp_xchg_word_AX_register
,
5393 /* 0x95 */ x86emuOp_xchg_word_AX_register
,
5394 /* 0x96 */ x86emuOp_xchg_word_AX_register
,
5395 /* 0x97 */ x86emuOp_xchg_word_AX_register
,
5397 /* 0x98 */ x86emuOp_cbw
,
5398 /* 0x99 */ x86emuOp_cwd
,
5399 /* 0x9a */ x86emuOp_call_far_IMM
,
5400 /* 0x9b */ x86emuOp_wait
,
5401 /* 0x9c */ x86emuOp_pushf_word
,
5402 /* 0x9d */ x86emuOp_popf_word
,
5403 /* 0x9e */ x86emuOp_sahf
,
5404 /* 0x9f */ x86emuOp_lahf
,
5406 /* 0xa0 */ x86emuOp_mov_AL_M_IMM
,
5407 /* 0xa1 */ x86emuOp_mov_AX_M_IMM
,
5408 /* 0xa2 */ x86emuOp_mov_M_AL_IMM
,
5409 /* 0xa3 */ x86emuOp_mov_M_AX_IMM
,
5410 /* 0xa4 */ x86emuOp_movs_byte
,
5411 /* 0xa5 */ x86emuOp_movs_word
,
5412 /* 0xa6 */ x86emuOp_cmps_byte
,
5413 /* 0xa7 */ x86emuOp_cmps_word
,
5414 /* 0xa8 */ x86emuOp_test_AL_IMM
,
5415 /* 0xa9 */ x86emuOp_test_AX_IMM
,
5416 /* 0xaa */ x86emuOp_stos_byte
,
5417 /* 0xab */ x86emuOp_stos_word
,
5418 /* 0xac */ x86emuOp_lods_byte
,
5419 /* 0xad */ x86emuOp_lods_word
,
5420 /* 0xac */ x86emuOp_scas_byte
,
5421 /* 0xad */ x86emuOp_scas_word
,
5423 /* 0xb0 */ x86emuOp_mov_byte_register_IMM
,
5424 /* 0xb1 */ x86emuOp_mov_byte_register_IMM
,
5425 /* 0xb2 */ x86emuOp_mov_byte_register_IMM
,
5426 /* 0xb3 */ x86emuOp_mov_byte_register_IMM
,
5427 /* 0xb4 */ x86emuOp_mov_byte_register_IMM
,
5428 /* 0xb5 */ x86emuOp_mov_byte_register_IMM
,
5429 /* 0xb6 */ x86emuOp_mov_byte_register_IMM
,
5430 /* 0xb7 */ x86emuOp_mov_byte_register_IMM
,
5432 /* 0xb8 */ x86emuOp_mov_word_register_IMM
,
5433 /* 0xb9 */ x86emuOp_mov_word_register_IMM
,
5434 /* 0xba */ x86emuOp_mov_word_register_IMM
,
5435 /* 0xbb */ x86emuOp_mov_word_register_IMM
,
5436 /* 0xbc */ x86emuOp_mov_word_register_IMM
,
5437 /* 0xbd */ x86emuOp_mov_word_register_IMM
,
5438 /* 0xbe */ x86emuOp_mov_word_register_IMM
,
5439 /* 0xbf */ x86emuOp_mov_word_register_IMM
,
5441 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM
,
5442 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM
,
5443 /* 0xc2 */ x86emuOp_ret_near_IMM
,
5444 /* 0xc3 */ x86emuOp_ret_near
,
5445 /* 0xc4 */ x86emuOp_les_R_IMM
,
5446 /* 0xc5 */ x86emuOp_lds_R_IMM
,
5447 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM
,
5448 /* 0xc7 */ x86emuOp_mov_word_RM_IMM
,
5449 /* 0xc8 */ x86emuOp_enter
,
5450 /* 0xc9 */ x86emuOp_leave
,
5451 /* 0xca */ x86emuOp_ret_far_IMM
,
5452 /* 0xcb */ x86emuOp_ret_far
,
5453 /* 0xcc */ x86emuOp_int3
,
5454 /* 0xcd */ x86emuOp_int_IMM
,
5455 /* 0xce */ x86emuOp_into
,
5456 /* 0xcf */ x86emuOp_iret
,
5458 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1
,
5459 /* 0xd1 */ x86emuOp_opcD1_word_RM_1
,
5460 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL
,
5461 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL
,
5462 /* 0xd4 */ x86emuOp_aam
,
5463 /* 0xd5 */ x86emuOp_aad
,
5464 /* 0xd6 */ x86emuOp_illegal_op
, /* Undocumented SETALC instruction */
5465 /* 0xd7 */ x86emuOp_xlat
,
5466 /* 0xd8 */ x86emuOp_esc_coprocess_d8
,
5467 /* 0xd9 */ x86emuOp_esc_coprocess_d9
,
5468 /* 0xda */ x86emuOp_esc_coprocess_da
,
5469 /* 0xdb */ x86emuOp_esc_coprocess_db
,
5470 /* 0xdc */ x86emuOp_esc_coprocess_dc
,
5471 /* 0xdd */ x86emuOp_esc_coprocess_dd
,
5472 /* 0xde */ x86emuOp_esc_coprocess_de
,
5473 /* 0xdf */ x86emuOp_esc_coprocess_df
,
5475 /* 0xe0 */ x86emuOp_loopne
,
5476 /* 0xe1 */ x86emuOp_loope
,
5477 /* 0xe2 */ x86emuOp_loop
,
5478 /* 0xe3 */ x86emuOp_jcxz
,
5479 /* 0xe4 */ x86emuOp_in_byte_AL_IMM
,
5480 /* 0xe5 */ x86emuOp_in_word_AX_IMM
,
5481 /* 0xe6 */ x86emuOp_out_byte_IMM_AL
,
5482 /* 0xe7 */ x86emuOp_out_word_IMM_AX
,
5484 /* 0xe8 */ x86emuOp_call_near_IMM
,
5485 /* 0xe9 */ x86emuOp_jump_near_IMM
,
5486 /* 0xea */ x86emuOp_jump_far_IMM
,
5487 /* 0xeb */ x86emuOp_jump_byte_IMM
,
5488 /* 0xec */ x86emuOp_in_byte_AL_DX
,
5489 /* 0xed */ x86emuOp_in_word_AX_DX
,
5490 /* 0xee */ x86emuOp_out_byte_DX_AL
,
5491 /* 0xef */ x86emuOp_out_word_DX_AX
,
5493 /* 0xf0 */ x86emuOp_lock
,
5494 /* 0xf1 */ x86emuOp_illegal_op
,
5495 /* 0xf2 */ x86emuOp_repne
,
5496 /* 0xf3 */ x86emuOp_repe
,
5497 /* 0xf4 */ x86emuOp_halt
,
5498 /* 0xf5 */ x86emuOp_cmc
,
5499 /* 0xf6 */ x86emuOp_opcF6_byte_RM
,
5500 /* 0xf7 */ x86emuOp_opcF7_word_RM
,
5502 /* 0xf8 */ x86emuOp_clc
,
5503 /* 0xf9 */ x86emuOp_stc
,
5504 /* 0xfa */ x86emuOp_cli
,
5505 /* 0xfb */ x86emuOp_sti
,
5506 /* 0xfc */ x86emuOp_cld
,
5507 /* 0xfd */ x86emuOp_std
,
5508 /* 0xfe */ x86emuOp_opcFE_byte_RM
,
5509 /* 0xff */ x86emuOp_opcFF_word_RM
,