1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 extended two-byte processor
39 ****************************************************************************/
41 #include "x86emu/x86emui.h"
44 #define bswap_32(x) (((x & 0xff000000) >> 24) | \
45 ((x & 0x00ff0000) >> 8) | \
46 ((x & 0x0000ff00) << 8) | \
47 ((x & 0x000000ff) << 24))
49 /*----------------------------- Implementation ----------------------------*/
51 /****************************************************************************
53 op1 - Instruction op code
56 Handles illegal opcodes.
57 ****************************************************************************/
58 static void x86emuOp2_illegal_op(
62 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
64 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
65 M
.x86
.R_CS
, M
.x86
.R_IP
-2,op2
);
70 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
72 /****************************************************************************
74 Handles opcode 0x0f,0x31
75 ****************************************************************************/
76 static void x86emuOp2_rdtsc(u8
X86EMU_UNUSED(op2
))
78 #ifdef __HAS_LONG_LONG__
79 static u64 counter
= 0;
81 static u32 counter
= 0;
86 /* read timestamp counter */
88 * Note that instead of actually trying to accurately measure this, we just
89 * increase the counter by a fixed amount every time we hit one of these
90 * instructions. Feel free to come up with a better method.
93 DECODE_PRINTF("RDTSC\n");
95 #ifdef __HAS_LONG_LONG__
96 M
.x86
.R_EAX
= counter
& 0xffffffff;
97 M
.x86
.R_EDX
= counter
>> 32;
99 M
.x86
.R_EAX
= counter
;
102 DECODE_CLEAR_SEGOVR();
106 /****************************************************************************
108 Handles opcode 0x0f,0x80-0x8F
109 ****************************************************************************/
110 static void x86emuOp2_long_jump(u8 op2
)
116 /* conditional jump to word offset. */
121 cond
= ACCESS_FLAG(F_OF
);
125 cond
= !ACCESS_FLAG(F_OF
);
129 cond
= ACCESS_FLAG(F_CF
);
133 cond
= !ACCESS_FLAG(F_CF
);
137 cond
= ACCESS_FLAG(F_ZF
);
141 cond
= !ACCESS_FLAG(F_ZF
);
145 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
149 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
153 cond
= ACCESS_FLAG(F_SF
);
157 cond
= !ACCESS_FLAG(F_SF
);
161 cond
= ACCESS_FLAG(F_PF
);
165 cond
= !ACCESS_FLAG(F_PF
);
169 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
173 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)));
177 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
182 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
188 target
= (s16
) fetch_word_imm();
189 target
+= (s16
) M
.x86
.R_IP
;
190 DECODE_PRINTF2("%04x\n", target
);
193 M
.x86
.R_IP
= (u16
)target
;
194 DECODE_CLEAR_SEGOVR();
198 /****************************************************************************
200 Handles opcode 0x0f,0x90-0x9F
201 ****************************************************************************/
202 static void x86emuOp2_set_byte(u8 op2
)
214 cond
= ACCESS_FLAG(F_OF
);
218 cond
= !ACCESS_FLAG(F_OF
);
222 cond
= ACCESS_FLAG(F_CF
);
226 cond
= !ACCESS_FLAG(F_CF
);
230 cond
= ACCESS_FLAG(F_ZF
);
234 cond
= !ACCESS_FLAG(F_ZF
);
238 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
242 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
246 cond
= ACCESS_FLAG(F_SF
);
250 cond
= !ACCESS_FLAG(F_SF
);
254 cond
= ACCESS_FLAG(F_PF
);
258 cond
= !ACCESS_FLAG(F_PF
);
262 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
266 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
270 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
275 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
281 FETCH_DECODE_MODRM(mod
, rh
, rl
);
284 destoffset
= decode_rm00_address(rl
);
286 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
289 destoffset
= decode_rm01_address(rl
);
291 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
294 destoffset
= decode_rm10_address(rl
);
296 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
298 case 3: /* register to register */
299 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
301 *destreg
= cond
? 0x01 : 0x00;
304 DECODE_CLEAR_SEGOVR();
308 /****************************************************************************
310 Handles opcode 0x0f,0xa0
311 ****************************************************************************/
312 static void x86emuOp2_push_FS(u8
X86EMU_UNUSED(op2
))
315 DECODE_PRINTF("PUSH\tFS\n");
317 push_word(M
.x86
.R_FS
);
318 DECODE_CLEAR_SEGOVR();
322 /****************************************************************************
324 Handles opcode 0x0f,0xa1
325 ****************************************************************************/
326 static void x86emuOp2_pop_FS(u8
X86EMU_UNUSED(op2
))
329 DECODE_PRINTF("POP\tFS\n");
331 M
.x86
.R_FS
= pop_word();
332 DECODE_CLEAR_SEGOVR();
336 /****************************************************************************
337 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
338 Handles opcode 0x0f,0xa2
339 ****************************************************************************/
340 static void x86emuOp2_cpuid(u8
X86EMU_UNUSED(op2
))
343 DECODE_PRINTF("CPUID\n");
346 DECODE_CLEAR_SEGOVR();
350 /****************************************************************************
352 Handles opcode 0x0f,0xa3
353 ****************************************************************************/
354 static void x86emuOp2_bt_R(u8
X86EMU_UNUSED(op2
))
361 DECODE_PRINTF("BT\t");
362 FETCH_DECODE_MODRM(mod
, rh
, rl
);
365 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
369 srcoffset
= decode_rm00_address(rl
);
371 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
373 bit
= *shiftreg
& 0x1F;
374 disp
= (s16
)*shiftreg
>> 5;
375 srcval
= fetch_data_long(srcoffset
+disp
);
376 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
381 srcoffset
= decode_rm00_address(rl
);
383 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
385 bit
= *shiftreg
& 0xF;
386 disp
= (s16
)*shiftreg
>> 4;
387 srcval
= fetch_data_word(srcoffset
+disp
);
388 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
392 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
396 srcoffset
= decode_rm01_address(rl
);
398 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
400 bit
= *shiftreg
& 0x1F;
401 disp
= (s16
)*shiftreg
>> 5;
402 srcval
= fetch_data_long(srcoffset
+disp
);
403 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
408 srcoffset
= decode_rm01_address(rl
);
410 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
412 bit
= *shiftreg
& 0xF;
413 disp
= (s16
)*shiftreg
>> 4;
414 srcval
= fetch_data_word(srcoffset
+disp
);
415 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
419 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
423 srcoffset
= decode_rm10_address(rl
);
425 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
427 bit
= *shiftreg
& 0x1F;
428 disp
= (s16
)*shiftreg
>> 5;
429 srcval
= fetch_data_long(srcoffset
+disp
);
430 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
435 srcoffset
= decode_rm10_address(rl
);
437 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
439 bit
= *shiftreg
& 0xF;
440 disp
= (s16
)*shiftreg
>> 4;
441 srcval
= fetch_data_word(srcoffset
+disp
);
442 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
445 case 3: /* register to register */
446 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
447 u32
*srcreg
,*shiftreg
;
449 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
451 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
453 bit
= *shiftreg
& 0x1F;
454 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
456 u16
*srcreg
,*shiftreg
;
458 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
460 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
462 bit
= *shiftreg
& 0xF;
463 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
467 DECODE_CLEAR_SEGOVR();
471 /****************************************************************************
473 Handles opcode 0x0f,0xa4
474 ****************************************************************************/
475 static void x86emuOp2_shld_IMM(u8
X86EMU_UNUSED(op2
))
482 DECODE_PRINTF("SHLD\t");
483 FETCH_DECODE_MODRM(mod
, rh
, rl
);
486 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
490 destoffset
= decode_rm00_address(rl
);
492 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
494 shift
= fetch_byte_imm();
495 DECODE_PRINTF2("%d\n", shift
);
497 destval
= fetch_data_long(destoffset
);
498 destval
= shld_long(destval
,*shiftreg
,shift
);
499 store_data_long(destoffset
, destval
);
504 destoffset
= decode_rm00_address(rl
);
506 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
508 shift
= fetch_byte_imm();
509 DECODE_PRINTF2("%d\n", shift
);
511 destval
= fetch_data_word(destoffset
);
512 destval
= shld_word(destval
,*shiftreg
,shift
);
513 store_data_word(destoffset
, destval
);
517 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
521 destoffset
= decode_rm01_address(rl
);
523 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
525 shift
= fetch_byte_imm();
526 DECODE_PRINTF2("%d\n", shift
);
528 destval
= fetch_data_long(destoffset
);
529 destval
= shld_long(destval
,*shiftreg
,shift
);
530 store_data_long(destoffset
, destval
);
535 destoffset
= decode_rm01_address(rl
);
537 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
539 shift
= fetch_byte_imm();
540 DECODE_PRINTF2("%d\n", shift
);
542 destval
= fetch_data_word(destoffset
);
543 destval
= shld_word(destval
,*shiftreg
,shift
);
544 store_data_word(destoffset
, destval
);
548 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
552 destoffset
= decode_rm10_address(rl
);
554 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
556 shift
= fetch_byte_imm();
557 DECODE_PRINTF2("%d\n", shift
);
559 destval
= fetch_data_long(destoffset
);
560 destval
= shld_long(destval
,*shiftreg
,shift
);
561 store_data_long(destoffset
, destval
);
566 destoffset
= decode_rm10_address(rl
);
568 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
570 shift
= fetch_byte_imm();
571 DECODE_PRINTF2("%d\n", shift
);
573 destval
= fetch_data_word(destoffset
);
574 destval
= shld_word(destval
,*shiftreg
,shift
);
575 store_data_word(destoffset
, destval
);
578 case 3: /* register to register */
579 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
580 u32
*destreg
,*shiftreg
;
582 destreg
= DECODE_RM_LONG_REGISTER(rl
);
584 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
586 shift
= fetch_byte_imm();
587 DECODE_PRINTF2("%d\n", shift
);
589 *destreg
= shld_long(*destreg
,*shiftreg
,shift
);
591 u16
*destreg
,*shiftreg
;
593 destreg
= DECODE_RM_WORD_REGISTER(rl
);
595 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
597 shift
= fetch_byte_imm();
598 DECODE_PRINTF2("%d\n", shift
);
600 *destreg
= shld_word(*destreg
,*shiftreg
,shift
);
604 DECODE_CLEAR_SEGOVR();
608 /****************************************************************************
610 Handles opcode 0x0f,0xa5
611 ****************************************************************************/
612 static void x86emuOp2_shld_CL(u8
X86EMU_UNUSED(op2
))
618 DECODE_PRINTF("SHLD\t");
619 FETCH_DECODE_MODRM(mod
, rh
, rl
);
622 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
626 destoffset
= decode_rm00_address(rl
);
628 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
629 DECODE_PRINTF(",CL\n");
631 destval
= fetch_data_long(destoffset
);
632 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
633 store_data_long(destoffset
, destval
);
638 destoffset
= decode_rm00_address(rl
);
640 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
641 DECODE_PRINTF(",CL\n");
643 destval
= fetch_data_word(destoffset
);
644 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
645 store_data_word(destoffset
, destval
);
649 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
653 destoffset
= decode_rm01_address(rl
);
655 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
656 DECODE_PRINTF(",CL\n");
658 destval
= fetch_data_long(destoffset
);
659 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
660 store_data_long(destoffset
, destval
);
665 destoffset
= decode_rm01_address(rl
);
667 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
668 DECODE_PRINTF(",CL\n");
670 destval
= fetch_data_word(destoffset
);
671 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
672 store_data_word(destoffset
, destval
);
676 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
680 destoffset
= decode_rm10_address(rl
);
682 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
683 DECODE_PRINTF(",CL\n");
685 destval
= fetch_data_long(destoffset
);
686 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
687 store_data_long(destoffset
, destval
);
692 destoffset
= decode_rm10_address(rl
);
694 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
695 DECODE_PRINTF(",CL\n");
697 destval
= fetch_data_word(destoffset
);
698 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
699 store_data_word(destoffset
, destval
);
702 case 3: /* register to register */
703 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
704 u32
*destreg
,*shiftreg
;
706 destreg
= DECODE_RM_LONG_REGISTER(rl
);
708 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
709 DECODE_PRINTF(",CL\n");
711 *destreg
= shld_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
713 u16
*destreg
,*shiftreg
;
715 destreg
= DECODE_RM_WORD_REGISTER(rl
);
717 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
718 DECODE_PRINTF(",CL\n");
720 *destreg
= shld_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
724 DECODE_CLEAR_SEGOVR();
728 /****************************************************************************
730 Handles opcode 0x0f,0xa8
731 ****************************************************************************/
732 static void x86emuOp2_push_GS(u8
X86EMU_UNUSED(op2
))
735 DECODE_PRINTF("PUSH\tGS\n");
737 push_word(M
.x86
.R_GS
);
738 DECODE_CLEAR_SEGOVR();
742 /****************************************************************************
744 Handles opcode 0x0f,0xa9
745 ****************************************************************************/
746 static void x86emuOp2_pop_GS(u8
X86EMU_UNUSED(op2
))
749 DECODE_PRINTF("POP\tGS\n");
751 M
.x86
.R_GS
= pop_word();
752 DECODE_CLEAR_SEGOVR();
756 /****************************************************************************
758 Handles opcode 0x0f,0xab
759 ****************************************************************************/
760 static void x86emuOp2_bts_R(u8
X86EMU_UNUSED(op2
))
767 DECODE_PRINTF("BTS\t");
768 FETCH_DECODE_MODRM(mod
, rh
, rl
);
771 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
775 srcoffset
= decode_rm00_address(rl
);
777 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
779 bit
= *shiftreg
& 0x1F;
780 disp
= (s16
)*shiftreg
>> 5;
781 srcval
= fetch_data_long(srcoffset
+disp
);
783 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
784 store_data_long(srcoffset
+disp
, srcval
| mask
);
789 srcoffset
= decode_rm00_address(rl
);
791 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
793 bit
= *shiftreg
& 0xF;
794 disp
= (s16
)*shiftreg
>> 4;
795 srcval
= fetch_data_word(srcoffset
+disp
);
796 mask
= (u16
)(0x1 << bit
);
797 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
798 store_data_word(srcoffset
+disp
, srcval
| mask
);
802 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
806 srcoffset
= decode_rm01_address(rl
);
808 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
810 bit
= *shiftreg
& 0x1F;
811 disp
= (s16
)*shiftreg
>> 5;
812 srcval
= fetch_data_long(srcoffset
+disp
);
814 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
815 store_data_long(srcoffset
+disp
, srcval
| mask
);
820 srcoffset
= decode_rm01_address(rl
);
822 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
824 bit
= *shiftreg
& 0xF;
825 disp
= (s16
)*shiftreg
>> 4;
826 srcval
= fetch_data_word(srcoffset
+disp
);
827 mask
= (u16
)(0x1 << bit
);
828 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
829 store_data_word(srcoffset
+disp
, srcval
| mask
);
833 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
837 srcoffset
= decode_rm10_address(rl
);
839 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
841 bit
= *shiftreg
& 0x1F;
842 disp
= (s16
)*shiftreg
>> 5;
843 srcval
= fetch_data_long(srcoffset
+disp
);
845 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
846 store_data_long(srcoffset
+disp
, srcval
| mask
);
851 srcoffset
= decode_rm10_address(rl
);
853 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
855 bit
= *shiftreg
& 0xF;
856 disp
= (s16
)*shiftreg
>> 4;
857 srcval
= fetch_data_word(srcoffset
+disp
);
858 mask
= (u16
)(0x1 << bit
);
859 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
860 store_data_word(srcoffset
+disp
, srcval
| mask
);
863 case 3: /* register to register */
864 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
865 u32
*srcreg
,*shiftreg
;
868 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
870 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
872 bit
= *shiftreg
& 0x1F;
874 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
877 u16
*srcreg
,*shiftreg
;
880 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
882 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
884 bit
= *shiftreg
& 0xF;
885 mask
= (u16
)(0x1 << bit
);
886 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
891 DECODE_CLEAR_SEGOVR();
895 /****************************************************************************
897 Handles opcode 0x0f,0xac
898 ****************************************************************************/
899 static void x86emuOp2_shrd_IMM(u8
X86EMU_UNUSED(op2
))
906 DECODE_PRINTF("SHLD\t");
907 FETCH_DECODE_MODRM(mod
, rh
, rl
);
910 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
914 destoffset
= decode_rm00_address(rl
);
916 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
918 shift
= fetch_byte_imm();
919 DECODE_PRINTF2("%d\n", shift
);
921 destval
= fetch_data_long(destoffset
);
922 destval
= shrd_long(destval
,*shiftreg
,shift
);
923 store_data_long(destoffset
, destval
);
928 destoffset
= decode_rm00_address(rl
);
930 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
932 shift
= fetch_byte_imm();
933 DECODE_PRINTF2("%d\n", shift
);
935 destval
= fetch_data_word(destoffset
);
936 destval
= shrd_word(destval
,*shiftreg
,shift
);
937 store_data_word(destoffset
, destval
);
941 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
945 destoffset
= decode_rm01_address(rl
);
947 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
949 shift
= fetch_byte_imm();
950 DECODE_PRINTF2("%d\n", shift
);
952 destval
= fetch_data_long(destoffset
);
953 destval
= shrd_long(destval
,*shiftreg
,shift
);
954 store_data_long(destoffset
, destval
);
959 destoffset
= decode_rm01_address(rl
);
961 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
963 shift
= fetch_byte_imm();
964 DECODE_PRINTF2("%d\n", shift
);
966 destval
= fetch_data_word(destoffset
);
967 destval
= shrd_word(destval
,*shiftreg
,shift
);
968 store_data_word(destoffset
, destval
);
972 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
976 destoffset
= decode_rm10_address(rl
);
978 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
980 shift
= fetch_byte_imm();
981 DECODE_PRINTF2("%d\n", shift
);
983 destval
= fetch_data_long(destoffset
);
984 destval
= shrd_long(destval
,*shiftreg
,shift
);
985 store_data_long(destoffset
, destval
);
990 destoffset
= decode_rm10_address(rl
);
992 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
994 shift
= fetch_byte_imm();
995 DECODE_PRINTF2("%d\n", shift
);
997 destval
= fetch_data_word(destoffset
);
998 destval
= shrd_word(destval
,*shiftreg
,shift
);
999 store_data_word(destoffset
, destval
);
1002 case 3: /* register to register */
1003 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1004 u32
*destreg
,*shiftreg
;
1006 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1008 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1010 shift
= fetch_byte_imm();
1011 DECODE_PRINTF2("%d\n", shift
);
1013 *destreg
= shrd_long(*destreg
,*shiftreg
,shift
);
1015 u16
*destreg
,*shiftreg
;
1017 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1019 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1021 shift
= fetch_byte_imm();
1022 DECODE_PRINTF2("%d\n", shift
);
1024 *destreg
= shrd_word(*destreg
,*shiftreg
,shift
);
1028 DECODE_CLEAR_SEGOVR();
1032 /****************************************************************************
1034 Handles opcode 0x0f,0xad
1035 ****************************************************************************/
1036 static void x86emuOp2_shrd_CL(u8
X86EMU_UNUSED(op2
))
1042 DECODE_PRINTF("SHLD\t");
1043 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1046 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1050 destoffset
= decode_rm00_address(rl
);
1052 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1053 DECODE_PRINTF(",CL\n");
1055 destval
= fetch_data_long(destoffset
);
1056 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1057 store_data_long(destoffset
, destval
);
1062 destoffset
= decode_rm00_address(rl
);
1064 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1065 DECODE_PRINTF(",CL\n");
1067 destval
= fetch_data_word(destoffset
);
1068 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1069 store_data_word(destoffset
, destval
);
1073 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1077 destoffset
= decode_rm01_address(rl
);
1079 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1080 DECODE_PRINTF(",CL\n");
1082 destval
= fetch_data_long(destoffset
);
1083 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1084 store_data_long(destoffset
, destval
);
1089 destoffset
= decode_rm01_address(rl
);
1091 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1092 DECODE_PRINTF(",CL\n");
1094 destval
= fetch_data_word(destoffset
);
1095 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1096 store_data_word(destoffset
, destval
);
1100 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1104 destoffset
= decode_rm10_address(rl
);
1106 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1107 DECODE_PRINTF(",CL\n");
1109 destval
= fetch_data_long(destoffset
);
1110 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1111 store_data_long(destoffset
, destval
);
1116 destoffset
= decode_rm10_address(rl
);
1118 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1119 DECODE_PRINTF(",CL\n");
1121 destval
= fetch_data_word(destoffset
);
1122 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1123 store_data_word(destoffset
, destval
);
1126 case 3: /* register to register */
1127 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1128 u32
*destreg
,*shiftreg
;
1130 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1132 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1133 DECODE_PRINTF(",CL\n");
1135 *destreg
= shrd_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1137 u16
*destreg
,*shiftreg
;
1139 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1141 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1142 DECODE_PRINTF(",CL\n");
1144 *destreg
= shrd_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1148 DECODE_CLEAR_SEGOVR();
1152 /****************************************************************************
1154 Handles opcode 0x0f,0xaf
1155 ****************************************************************************/
1156 static void x86emuOp2_imul_R_RM(u8
X86EMU_UNUSED(op2
))
1162 DECODE_PRINTF("IMUL\t");
1163 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1166 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1171 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1173 srcoffset
= decode_rm00_address(rl
);
1174 srcval
= fetch_data_long(srcoffset
);
1176 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1184 *destreg
= (u32
)res_lo
;
1190 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1192 srcoffset
= decode_rm00_address(rl
);
1193 srcval
= fetch_data_word(srcoffset
);
1195 res
= (s16
)*destreg
* (s16
)srcval
;
1203 *destreg
= (u16
)res
;
1207 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1212 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1214 srcoffset
= decode_rm01_address(rl
);
1215 srcval
= fetch_data_long(srcoffset
);
1217 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1225 *destreg
= (u32
)res_lo
;
1231 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1233 srcoffset
= decode_rm01_address(rl
);
1234 srcval
= fetch_data_word(srcoffset
);
1236 res
= (s16
)*destreg
* (s16
)srcval
;
1244 *destreg
= (u16
)res
;
1248 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1253 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1255 srcoffset
= decode_rm10_address(rl
);
1256 srcval
= fetch_data_long(srcoffset
);
1258 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1266 *destreg
= (u32
)res_lo
;
1272 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1274 srcoffset
= decode_rm10_address(rl
);
1275 srcval
= fetch_data_word(srcoffset
);
1277 res
= (s16
)*destreg
* (s16
)srcval
;
1285 *destreg
= (u16
)res
;
1288 case 3: /* register to register */
1289 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1290 u32
*destreg
,*srcreg
;
1293 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1295 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1297 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)*srcreg
);
1305 *destreg
= (u32
)res_lo
;
1307 u16
*destreg
,*srcreg
;
1310 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1312 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1313 res
= (s16
)*destreg
* (s16
)*srcreg
;
1321 *destreg
= (u16
)res
;
1325 DECODE_CLEAR_SEGOVR();
1329 /****************************************************************************
1331 Handles opcode 0x0f,0xb2
1332 ****************************************************************************/
1333 static void x86emuOp2_lss_R_IMM(u8
X86EMU_UNUSED(op2
))
1340 DECODE_PRINTF("LSS\t");
1341 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1344 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1346 srcoffset
= decode_rm00_address(rl
);
1347 DECODE_PRINTF("\n");
1349 *dstreg
= fetch_data_word(srcoffset
);
1350 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1353 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1355 srcoffset
= decode_rm01_address(rl
);
1356 DECODE_PRINTF("\n");
1358 *dstreg
= fetch_data_word(srcoffset
);
1359 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1362 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1364 srcoffset
= decode_rm10_address(rl
);
1365 DECODE_PRINTF("\n");
1367 *dstreg
= fetch_data_word(srcoffset
);
1368 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1370 case 3: /* register to register */
1374 DECODE_CLEAR_SEGOVR();
1378 /****************************************************************************
1380 Handles opcode 0x0f,0xb3
1381 ****************************************************************************/
1382 static void x86emuOp2_btr_R(u8
X86EMU_UNUSED(op2
))
1389 DECODE_PRINTF("BTR\t");
1390 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1393 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1397 srcoffset
= decode_rm00_address(rl
);
1399 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1401 bit
= *shiftreg
& 0x1F;
1402 disp
= (s16
)*shiftreg
>> 5;
1403 srcval
= fetch_data_long(srcoffset
+disp
);
1404 mask
= (0x1 << bit
);
1405 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1406 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1411 srcoffset
= decode_rm00_address(rl
);
1413 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1415 bit
= *shiftreg
& 0xF;
1416 disp
= (s16
)*shiftreg
>> 4;
1417 srcval
= fetch_data_word(srcoffset
+disp
);
1418 mask
= (u16
)(0x1 << bit
);
1419 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1420 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1424 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1428 srcoffset
= decode_rm01_address(rl
);
1430 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1432 bit
= *shiftreg
& 0x1F;
1433 disp
= (s16
)*shiftreg
>> 5;
1434 srcval
= fetch_data_long(srcoffset
+disp
);
1435 mask
= (0x1 << bit
);
1436 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1437 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1442 srcoffset
= decode_rm01_address(rl
);
1444 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1446 bit
= *shiftreg
& 0xF;
1447 disp
= (s16
)*shiftreg
>> 4;
1448 srcval
= fetch_data_word(srcoffset
+disp
);
1449 mask
= (u16
)(0x1 << bit
);
1450 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1451 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1455 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1459 srcoffset
= decode_rm10_address(rl
);
1461 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1463 bit
= *shiftreg
& 0x1F;
1464 disp
= (s16
)*shiftreg
>> 5;
1465 srcval
= fetch_data_long(srcoffset
+disp
);
1466 mask
= (0x1 << bit
);
1467 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1468 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1473 srcoffset
= decode_rm10_address(rl
);
1475 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1477 bit
= *shiftreg
& 0xF;
1478 disp
= (s16
)*shiftreg
>> 4;
1479 srcval
= fetch_data_word(srcoffset
+disp
);
1480 mask
= (u16
)(0x1 << bit
);
1481 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1482 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1485 case 3: /* register to register */
1486 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1487 u32
*srcreg
,*shiftreg
;
1490 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1492 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1494 bit
= *shiftreg
& 0x1F;
1495 mask
= (0x1 << bit
);
1496 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1499 u16
*srcreg
,*shiftreg
;
1502 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1504 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1506 bit
= *shiftreg
& 0xF;
1507 mask
= (u16
)(0x1 << bit
);
1508 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1513 DECODE_CLEAR_SEGOVR();
1517 /****************************************************************************
1519 Handles opcode 0x0f,0xb4
1520 ****************************************************************************/
1521 static void x86emuOp2_lfs_R_IMM(u8
X86EMU_UNUSED(op2
))
1528 DECODE_PRINTF("LFS\t");
1529 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1532 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1534 srcoffset
= decode_rm00_address(rl
);
1535 DECODE_PRINTF("\n");
1537 *dstreg
= fetch_data_word(srcoffset
);
1538 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1541 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1543 srcoffset
= decode_rm01_address(rl
);
1544 DECODE_PRINTF("\n");
1546 *dstreg
= fetch_data_word(srcoffset
);
1547 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1550 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1552 srcoffset
= decode_rm10_address(rl
);
1553 DECODE_PRINTF("\n");
1555 *dstreg
= fetch_data_word(srcoffset
);
1556 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1558 case 3: /* register to register */
1562 DECODE_CLEAR_SEGOVR();
1566 /****************************************************************************
1568 Handles opcode 0x0f,0xb5
1569 ****************************************************************************/
1570 static void x86emuOp2_lgs_R_IMM(u8
X86EMU_UNUSED(op2
))
1577 DECODE_PRINTF("LGS\t");
1578 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1581 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1583 srcoffset
= decode_rm00_address(rl
);
1584 DECODE_PRINTF("\n");
1586 *dstreg
= fetch_data_word(srcoffset
);
1587 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1590 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1592 srcoffset
= decode_rm01_address(rl
);
1593 DECODE_PRINTF("\n");
1595 *dstreg
= fetch_data_word(srcoffset
);
1596 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1599 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1601 srcoffset
= decode_rm10_address(rl
);
1602 DECODE_PRINTF("\n");
1604 *dstreg
= fetch_data_word(srcoffset
);
1605 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1607 case 3: /* register to register */
1611 DECODE_CLEAR_SEGOVR();
1615 /****************************************************************************
1617 Handles opcode 0x0f,0xb6
1618 ****************************************************************************/
1619 static void x86emuOp2_movzx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
1625 DECODE_PRINTF("MOVZX\t");
1626 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1629 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1633 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1635 srcoffset
= decode_rm00_address(rl
);
1636 srcval
= fetch_data_byte(srcoffset
);
1637 DECODE_PRINTF("\n");
1644 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1646 srcoffset
= decode_rm00_address(rl
);
1647 srcval
= fetch_data_byte(srcoffset
);
1648 DECODE_PRINTF("\n");
1654 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1658 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1660 srcoffset
= decode_rm01_address(rl
);
1661 srcval
= fetch_data_byte(srcoffset
);
1662 DECODE_PRINTF("\n");
1669 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1671 srcoffset
= decode_rm01_address(rl
);
1672 srcval
= fetch_data_byte(srcoffset
);
1673 DECODE_PRINTF("\n");
1679 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1683 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1685 srcoffset
= decode_rm10_address(rl
);
1686 srcval
= fetch_data_byte(srcoffset
);
1687 DECODE_PRINTF("\n");
1694 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1696 srcoffset
= decode_rm10_address(rl
);
1697 srcval
= fetch_data_byte(srcoffset
);
1698 DECODE_PRINTF("\n");
1703 case 3: /* register to register */
1704 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1708 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1710 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1711 DECODE_PRINTF("\n");
1718 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1720 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1721 DECODE_PRINTF("\n");
1727 DECODE_CLEAR_SEGOVR();
1731 /****************************************************************************
1733 Handles opcode 0x0f,0xb7
1734 ****************************************************************************/
1735 static void x86emuOp2_movzx_word_R_RM(u8
X86EMU_UNUSED(op2
))
1744 DECODE_PRINTF("MOVZX\t");
1745 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1748 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1750 srcoffset
= decode_rm00_address(rl
);
1751 srcval
= fetch_data_word(srcoffset
);
1752 DECODE_PRINTF("\n");
1757 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1759 srcoffset
= decode_rm01_address(rl
);
1760 srcval
= fetch_data_word(srcoffset
);
1761 DECODE_PRINTF("\n");
1766 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1768 srcoffset
= decode_rm10_address(rl
);
1769 srcval
= fetch_data_word(srcoffset
);
1770 DECODE_PRINTF("\n");
1774 case 3: /* register to register */
1775 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1777 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1778 DECODE_PRINTF("\n");
1783 DECODE_CLEAR_SEGOVR();
1787 /****************************************************************************
1789 Handles opcode 0x0f,0xba
1790 ****************************************************************************/
1791 static void x86emuOp2_btX_I(u8
X86EMU_UNUSED(op2
))
1798 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1801 DECODE_PRINTF("BT\t");
1804 DECODE_PRINTF("BTS\t");
1807 DECODE_PRINTF("BTR\t");
1810 DECODE_PRINTF("BTC\t");
1813 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1815 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1816 M
.x86
.R_CS
, M
.x86
.R_IP
-3,op2
, (mod
<<6)|(rh
<<3)|rl
);
1821 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1825 srcoffset
= decode_rm00_address(rl
);
1827 shift
= fetch_byte_imm();
1830 srcval
= fetch_data_long(srcoffset
);
1831 mask
= (0x1 << bit
);
1832 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1835 store_data_long(srcoffset
, srcval
| mask
);
1838 store_data_long(srcoffset
, srcval
& ~mask
);
1841 store_data_long(srcoffset
, srcval
^ mask
);
1850 srcoffset
= decode_rm00_address(rl
);
1852 shift
= fetch_byte_imm();
1855 srcval
= fetch_data_word(srcoffset
);
1856 mask
= (0x1 << bit
);
1857 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1860 store_data_word(srcoffset
, srcval
| mask
);
1863 store_data_word(srcoffset
, srcval
& ~mask
);
1866 store_data_word(srcoffset
, srcval
^ mask
);
1874 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1878 srcoffset
= decode_rm01_address(rl
);
1880 shift
= fetch_byte_imm();
1883 srcval
= fetch_data_long(srcoffset
);
1884 mask
= (0x1 << bit
);
1885 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1888 store_data_long(srcoffset
, srcval
| mask
);
1891 store_data_long(srcoffset
, srcval
& ~mask
);
1894 store_data_long(srcoffset
, srcval
^ mask
);
1903 srcoffset
= decode_rm01_address(rl
);
1905 shift
= fetch_byte_imm();
1908 srcval
= fetch_data_word(srcoffset
);
1909 mask
= (0x1 << bit
);
1910 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1913 store_data_word(srcoffset
, srcval
| mask
);
1916 store_data_word(srcoffset
, srcval
& ~mask
);
1919 store_data_word(srcoffset
, srcval
^ mask
);
1927 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1931 srcoffset
= decode_rm10_address(rl
);
1933 shift
= fetch_byte_imm();
1936 srcval
= fetch_data_long(srcoffset
);
1937 mask
= (0x1 << bit
);
1938 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1941 store_data_long(srcoffset
, srcval
| mask
);
1944 store_data_long(srcoffset
, srcval
& ~mask
);
1947 store_data_long(srcoffset
, srcval
^ mask
);
1956 srcoffset
= decode_rm10_address(rl
);
1958 shift
= fetch_byte_imm();
1961 srcval
= fetch_data_word(srcoffset
);
1962 mask
= (0x1 << bit
);
1963 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1966 store_data_word(srcoffset
, srcval
| mask
);
1969 store_data_word(srcoffset
, srcval
& ~mask
);
1972 store_data_word(srcoffset
, srcval
^ mask
);
1979 case 3: /* register to register */
1980 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1985 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1987 shift
= fetch_byte_imm();
1990 mask
= (0x1 << bit
);
1991 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2010 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2012 shift
= fetch_byte_imm();
2015 mask
= (0x1 << bit
);
2016 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2033 DECODE_CLEAR_SEGOVR();
2037 /****************************************************************************
2039 Handles opcode 0x0f,0xbb
2040 ****************************************************************************/
2041 static void x86emuOp2_btc_R(u8
X86EMU_UNUSED(op2
))
2048 DECODE_PRINTF("BTC\t");
2049 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2052 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2056 srcoffset
= decode_rm00_address(rl
);
2058 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2060 bit
= *shiftreg
& 0x1F;
2061 disp
= (s16
)*shiftreg
>> 5;
2062 srcval
= fetch_data_long(srcoffset
+disp
);
2063 mask
= (0x1 << bit
);
2064 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2065 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2070 srcoffset
= decode_rm00_address(rl
);
2072 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2074 bit
= *shiftreg
& 0xF;
2075 disp
= (s16
)*shiftreg
>> 4;
2076 srcval
= fetch_data_word(srcoffset
+disp
);
2077 mask
= (u16
)(0x1 << bit
);
2078 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2079 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2083 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2087 srcoffset
= decode_rm01_address(rl
);
2089 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2091 bit
= *shiftreg
& 0x1F;
2092 disp
= (s16
)*shiftreg
>> 5;
2093 srcval
= fetch_data_long(srcoffset
+disp
);
2094 mask
= (0x1 << bit
);
2095 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2096 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2101 srcoffset
= decode_rm01_address(rl
);
2103 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2105 bit
= *shiftreg
& 0xF;
2106 disp
= (s16
)*shiftreg
>> 4;
2107 srcval
= fetch_data_word(srcoffset
+disp
);
2108 mask
= (u16
)(0x1 << bit
);
2109 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2110 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2114 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2118 srcoffset
= decode_rm10_address(rl
);
2120 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2122 bit
= *shiftreg
& 0x1F;
2123 disp
= (s16
)*shiftreg
>> 5;
2124 srcval
= fetch_data_long(srcoffset
+disp
);
2125 mask
= (0x1 << bit
);
2126 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2127 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2132 srcoffset
= decode_rm10_address(rl
);
2134 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2136 bit
= *shiftreg
& 0xF;
2137 disp
= (s16
)*shiftreg
>> 4;
2138 srcval
= fetch_data_word(srcoffset
+disp
);
2139 mask
= (u16
)(0x1 << bit
);
2140 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2141 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2144 case 3: /* register to register */
2145 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2146 u32
*srcreg
,*shiftreg
;
2149 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2151 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2153 bit
= *shiftreg
& 0x1F;
2154 mask
= (0x1 << bit
);
2155 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2158 u16
*srcreg
,*shiftreg
;
2161 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2163 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2165 bit
= *shiftreg
& 0xF;
2166 mask
= (u16
)(0x1 << bit
);
2167 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2172 DECODE_CLEAR_SEGOVR();
2176 /****************************************************************************
2178 Handles opcode 0x0f,0xbc
2179 ****************************************************************************/
2180 static void x86emuOp2_bsf(u8
X86EMU_UNUSED(op2
))
2186 DECODE_PRINTF("BSF\t");
2187 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2190 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2191 u32 srcval
, *dstreg
;
2193 srcoffset
= decode_rm00_address(rl
);
2195 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2197 srcval
= fetch_data_long(srcoffset
);
2198 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2199 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2200 if ((srcval
>> *dstreg
) & 1) break;
2202 u16 srcval
, *dstreg
;
2204 srcoffset
= decode_rm00_address(rl
);
2206 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2208 srcval
= fetch_data_word(srcoffset
);
2209 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2210 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2211 if ((srcval
>> *dstreg
) & 1) break;
2215 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2216 u32 srcval
, *dstreg
;
2218 srcoffset
= decode_rm01_address(rl
);
2220 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2222 srcval
= fetch_data_long(srcoffset
);
2223 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2224 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2225 if ((srcval
>> *dstreg
) & 1) break;
2227 u16 srcval
, *dstreg
;
2229 srcoffset
= decode_rm01_address(rl
);
2231 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2233 srcval
= fetch_data_word(srcoffset
);
2234 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2235 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2236 if ((srcval
>> *dstreg
) & 1) break;
2240 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2241 u32 srcval
, *dstreg
;
2243 srcoffset
= decode_rm10_address(rl
);
2245 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2247 srcval
= fetch_data_long(srcoffset
);
2248 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2249 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2250 if ((srcval
>> *dstreg
) & 1) break;
2252 u16 srcval
, *dstreg
;
2254 srcoffset
= decode_rm10_address(rl
);
2256 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2258 srcval
= fetch_data_word(srcoffset
);
2259 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2260 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2261 if ((srcval
>> *dstreg
) & 1) break;
2264 case 3: /* register to register */
2265 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2266 u32 srcval
, *dstreg
;
2268 srcval
= *DECODE_RM_LONG_REGISTER(rl
);
2270 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2272 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2273 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2274 if ((srcval
>> *dstreg
) & 1) break;
2276 u16 srcval
, *dstreg
;
2278 srcval
= *DECODE_RM_WORD_REGISTER(rl
);
2280 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2282 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2283 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2284 if ((srcval
>> *dstreg
) & 1) break;
2288 DECODE_CLEAR_SEGOVR();
2292 /****************************************************************************
2294 Handles opcode 0x0f,0xbd
2295 ****************************************************************************/
2296 static void x86emuOp2_bsr(u8
X86EMU_UNUSED(op2
))
2302 DECODE_PRINTF("BSR\t");
2303 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2306 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2307 u32 srcval
, *dstreg
;
2309 srcoffset
= decode_rm00_address(rl
);
2311 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2313 srcval
= fetch_data_long(srcoffset
);
2314 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2315 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2316 if ((srcval
>> *dstreg
) & 1) break;
2318 u16 srcval
, *dstreg
;
2320 srcoffset
= decode_rm00_address(rl
);
2322 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2324 srcval
= fetch_data_word(srcoffset
);
2325 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2326 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2327 if ((srcval
>> *dstreg
) & 1) break;
2331 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2332 u32 srcval
, *dstreg
;
2334 srcoffset
= decode_rm01_address(rl
);
2336 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2338 srcval
= fetch_data_long(srcoffset
);
2339 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2340 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2341 if ((srcval
>> *dstreg
) & 1) break;
2343 u16 srcval
, *dstreg
;
2345 srcoffset
= decode_rm01_address(rl
);
2347 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2349 srcval
= fetch_data_word(srcoffset
);
2350 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2351 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2352 if ((srcval
>> *dstreg
) & 1) break;
2356 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2357 u32 srcval
, *dstreg
;
2359 srcoffset
= decode_rm10_address(rl
);
2361 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2363 srcval
= fetch_data_long(srcoffset
);
2364 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2365 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2366 if ((srcval
>> *dstreg
) & 1) break;
2368 u16 srcval
, *dstreg
;
2370 srcoffset
= decode_rm10_address(rl
);
2372 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2374 srcval
= fetch_data_word(srcoffset
);
2375 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2376 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2377 if ((srcval
>> *dstreg
) & 1) break;
2380 case 3: /* register to register */
2381 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2382 u32 srcval
, *dstreg
;
2384 srcval
= *DECODE_RM_LONG_REGISTER(rl
);
2386 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2388 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2389 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2390 if ((srcval
>> *dstreg
) & 1) break;
2392 u16 srcval
, *dstreg
;
2394 srcval
= *DECODE_RM_WORD_REGISTER(rl
);
2396 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2398 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2399 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2400 if ((srcval
>> *dstreg
) & 1) break;
2404 DECODE_CLEAR_SEGOVR();
2408 /****************************************************************************
2410 Handles opcode 0x0f,0xbe
2411 ****************************************************************************/
2412 static void x86emuOp2_movsx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
2418 DECODE_PRINTF("MOVSX\t");
2419 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2422 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2426 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2428 srcoffset
= decode_rm00_address(rl
);
2429 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2430 DECODE_PRINTF("\n");
2437 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2439 srcoffset
= decode_rm00_address(rl
);
2440 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2441 DECODE_PRINTF("\n");
2447 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2451 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2453 srcoffset
= decode_rm01_address(rl
);
2454 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2455 DECODE_PRINTF("\n");
2462 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2464 srcoffset
= decode_rm01_address(rl
);
2465 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2466 DECODE_PRINTF("\n");
2472 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2476 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2478 srcoffset
= decode_rm10_address(rl
);
2479 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2480 DECODE_PRINTF("\n");
2487 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2489 srcoffset
= decode_rm10_address(rl
);
2490 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2491 DECODE_PRINTF("\n");
2496 case 3: /* register to register */
2497 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2501 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2503 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2504 DECODE_PRINTF("\n");
2506 *destreg
= (s32
)((s8
)*srcreg
);
2511 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2513 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2514 DECODE_PRINTF("\n");
2516 *destreg
= (s16
)((s8
)*srcreg
);
2520 DECODE_CLEAR_SEGOVR();
2524 /****************************************************************************
2526 Handles opcode 0x0f,0xbf
2527 ****************************************************************************/
2528 static void x86emuOp2_movsx_word_R_RM(u8
X86EMU_UNUSED(op2
))
2537 DECODE_PRINTF("MOVSX\t");
2538 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2541 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2543 srcoffset
= decode_rm00_address(rl
);
2544 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2545 DECODE_PRINTF("\n");
2550 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2552 srcoffset
= decode_rm01_address(rl
);
2553 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2554 DECODE_PRINTF("\n");
2559 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2561 srcoffset
= decode_rm10_address(rl
);
2562 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2563 DECODE_PRINTF("\n");
2567 case 3: /* register to register */
2568 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2570 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2571 DECODE_PRINTF("\n");
2573 *destreg
= (s32
)((s16
)*srcreg
);
2576 DECODE_CLEAR_SEGOVR();
2580 /* Handles opcodes 0xc8-0xcf */
2581 static void x86emuOp2_bswap(u8
X86EMU_UNUSED(op2
))
2584 DECODE_PRINTF("BSWAP\n");
2589 M
.x86
.R_EAX
= bswap_32(M
.x86
.R_EAX
);
2592 M
.x86
.R_ECX
= bswap_32(M
.x86
.R_ECX
);
2595 M
.x86
.R_EDX
= bswap_32(M
.x86
.R_EDX
);
2598 M
.x86
.R_EBX
= bswap_32(M
.x86
.R_EBX
);
2601 M
.x86
.R_ESP
= bswap_32(M
.x86
.R_ESP
);
2604 M
.x86
.R_EBP
= bswap_32(M
.x86
.R_EBP
);
2607 M
.x86
.R_ESI
= bswap_32(M
.x86
.R_ESI
);
2610 M
.x86
.R_EDI
= bswap_32(M
.x86
.R_EDI
);
2617 DECODE_CLEAR_SEGOVR();
2621 /***************************************************************************
2622 * Double byte operation code table:
2623 **************************************************************************/
2624 void (*x86emu_optab2
[256])(u8
) =
2626 /* 0x00 */ x86emuOp2_illegal_op
, /* Group F (ring 0 PM) */
2627 /* 0x01 */ x86emuOp2_illegal_op
, /* Group G (ring 0 PM) */
2628 /* 0x02 */ x86emuOp2_illegal_op
, /* lar (ring 0 PM) */
2629 /* 0x03 */ x86emuOp2_illegal_op
, /* lsl (ring 0 PM) */
2630 /* 0x04 */ x86emuOp2_illegal_op
,
2631 /* 0x05 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2632 /* 0x06 */ x86emuOp2_illegal_op
, /* clts (ring 0 PM) */
2633 /* 0x07 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2634 /* 0x08 */ x86emuOp2_illegal_op
, /* invd (ring 0 PM) */
2635 /* 0x09 */ x86emuOp2_illegal_op
, /* wbinvd (ring 0 PM) */
2636 /* 0x0a */ x86emuOp2_illegal_op
,
2637 /* 0x0b */ x86emuOp2_illegal_op
,
2638 /* 0x0c */ x86emuOp2_illegal_op
,
2639 /* 0x0d */ x86emuOp2_illegal_op
,
2640 /* 0x0e */ x86emuOp2_illegal_op
,
2641 /* 0x0f */ x86emuOp2_illegal_op
,
2643 /* 0x10 */ x86emuOp2_illegal_op
,
2644 /* 0x11 */ x86emuOp2_illegal_op
,
2645 /* 0x12 */ x86emuOp2_illegal_op
,
2646 /* 0x13 */ x86emuOp2_illegal_op
,
2647 /* 0x14 */ x86emuOp2_illegal_op
,
2648 /* 0x15 */ x86emuOp2_illegal_op
,
2649 /* 0x16 */ x86emuOp2_illegal_op
,
2650 /* 0x17 */ x86emuOp2_illegal_op
,
2651 /* 0x18 */ x86emuOp2_illegal_op
,
2652 /* 0x19 */ x86emuOp2_illegal_op
,
2653 /* 0x1a */ x86emuOp2_illegal_op
,
2654 /* 0x1b */ x86emuOp2_illegal_op
,
2655 /* 0x1c */ x86emuOp2_illegal_op
,
2656 /* 0x1d */ x86emuOp2_illegal_op
,
2657 /* 0x1e */ x86emuOp2_illegal_op
,
2658 /* 0x1f */ x86emuOp2_illegal_op
,
2660 /* 0x20 */ x86emuOp2_illegal_op
, /* mov reg32,creg (ring 0 PM) */
2661 /* 0x21 */ x86emuOp2_illegal_op
, /* mov reg32,dreg (ring 0 PM) */
2662 /* 0x22 */ x86emuOp2_illegal_op
, /* mov creg,reg32 (ring 0 PM) */
2663 /* 0x23 */ x86emuOp2_illegal_op
, /* mov dreg,reg32 (ring 0 PM) */
2664 /* 0x24 */ x86emuOp2_illegal_op
, /* mov reg32,treg (ring 0 PM) */
2665 /* 0x25 */ x86emuOp2_illegal_op
,
2666 /* 0x26 */ x86emuOp2_illegal_op
, /* mov treg,reg32 (ring 0 PM) */
2667 /* 0x27 */ x86emuOp2_illegal_op
,
2668 /* 0x28 */ x86emuOp2_illegal_op
,
2669 /* 0x29 */ x86emuOp2_illegal_op
,
2670 /* 0x2a */ x86emuOp2_illegal_op
,
2671 /* 0x2b */ x86emuOp2_illegal_op
,
2672 /* 0x2c */ x86emuOp2_illegal_op
,
2673 /* 0x2d */ x86emuOp2_illegal_op
,
2674 /* 0x2e */ x86emuOp2_illegal_op
,
2675 /* 0x2f */ x86emuOp2_illegal_op
,
2677 /* 0x30 */ x86emuOp2_illegal_op
,
2678 /* 0x31 */ x86emuOp2_rdtsc
,
2679 /* 0x32 */ x86emuOp2_illegal_op
,
2680 /* 0x33 */ x86emuOp2_illegal_op
,
2681 /* 0x34 */ x86emuOp2_illegal_op
,
2682 /* 0x35 */ x86emuOp2_illegal_op
,
2683 /* 0x36 */ x86emuOp2_illegal_op
,
2684 /* 0x37 */ x86emuOp2_illegal_op
,
2685 /* 0x38 */ x86emuOp2_illegal_op
,
2686 /* 0x39 */ x86emuOp2_illegal_op
,
2687 /* 0x3a */ x86emuOp2_illegal_op
,
2688 /* 0x3b */ x86emuOp2_illegal_op
,
2689 /* 0x3c */ x86emuOp2_illegal_op
,
2690 /* 0x3d */ x86emuOp2_illegal_op
,
2691 /* 0x3e */ x86emuOp2_illegal_op
,
2692 /* 0x3f */ x86emuOp2_illegal_op
,
2694 /* 0x40 */ x86emuOp2_illegal_op
,
2695 /* 0x41 */ x86emuOp2_illegal_op
,
2696 /* 0x42 */ x86emuOp2_illegal_op
,
2697 /* 0x43 */ x86emuOp2_illegal_op
,
2698 /* 0x44 */ x86emuOp2_illegal_op
,
2699 /* 0x45 */ x86emuOp2_illegal_op
,
2700 /* 0x46 */ x86emuOp2_illegal_op
,
2701 /* 0x47 */ x86emuOp2_illegal_op
,
2702 /* 0x48 */ x86emuOp2_illegal_op
,
2703 /* 0x49 */ x86emuOp2_illegal_op
,
2704 /* 0x4a */ x86emuOp2_illegal_op
,
2705 /* 0x4b */ x86emuOp2_illegal_op
,
2706 /* 0x4c */ x86emuOp2_illegal_op
,
2707 /* 0x4d */ x86emuOp2_illegal_op
,
2708 /* 0x4e */ x86emuOp2_illegal_op
,
2709 /* 0x4f */ x86emuOp2_illegal_op
,
2711 /* 0x50 */ x86emuOp2_illegal_op
,
2712 /* 0x51 */ x86emuOp2_illegal_op
,
2713 /* 0x52 */ x86emuOp2_illegal_op
,
2714 /* 0x53 */ x86emuOp2_illegal_op
,
2715 /* 0x54 */ x86emuOp2_illegal_op
,
2716 /* 0x55 */ x86emuOp2_illegal_op
,
2717 /* 0x56 */ x86emuOp2_illegal_op
,
2718 /* 0x57 */ x86emuOp2_illegal_op
,
2719 /* 0x58 */ x86emuOp2_illegal_op
,
2720 /* 0x59 */ x86emuOp2_illegal_op
,
2721 /* 0x5a */ x86emuOp2_illegal_op
,
2722 /* 0x5b */ x86emuOp2_illegal_op
,
2723 /* 0x5c */ x86emuOp2_illegal_op
,
2724 /* 0x5d */ x86emuOp2_illegal_op
,
2725 /* 0x5e */ x86emuOp2_illegal_op
,
2726 /* 0x5f */ x86emuOp2_illegal_op
,
2728 /* 0x60 */ x86emuOp2_illegal_op
,
2729 /* 0x61 */ x86emuOp2_illegal_op
,
2730 /* 0x62 */ x86emuOp2_illegal_op
,
2731 /* 0x63 */ x86emuOp2_illegal_op
,
2732 /* 0x64 */ x86emuOp2_illegal_op
,
2733 /* 0x65 */ x86emuOp2_illegal_op
,
2734 /* 0x66 */ x86emuOp2_illegal_op
,
2735 /* 0x67 */ x86emuOp2_illegal_op
,
2736 /* 0x68 */ x86emuOp2_illegal_op
,
2737 /* 0x69 */ x86emuOp2_illegal_op
,
2738 /* 0x6a */ x86emuOp2_illegal_op
,
2739 /* 0x6b */ x86emuOp2_illegal_op
,
2740 /* 0x6c */ x86emuOp2_illegal_op
,
2741 /* 0x6d */ x86emuOp2_illegal_op
,
2742 /* 0x6e */ x86emuOp2_illegal_op
,
2743 /* 0x6f */ x86emuOp2_illegal_op
,
2745 /* 0x70 */ x86emuOp2_illegal_op
,
2746 /* 0x71 */ x86emuOp2_illegal_op
,
2747 /* 0x72 */ x86emuOp2_illegal_op
,
2748 /* 0x73 */ x86emuOp2_illegal_op
,
2749 /* 0x74 */ x86emuOp2_illegal_op
,
2750 /* 0x75 */ x86emuOp2_illegal_op
,
2751 /* 0x76 */ x86emuOp2_illegal_op
,
2752 /* 0x77 */ x86emuOp2_illegal_op
,
2753 /* 0x78 */ x86emuOp2_illegal_op
,
2754 /* 0x79 */ x86emuOp2_illegal_op
,
2755 /* 0x7a */ x86emuOp2_illegal_op
,
2756 /* 0x7b */ x86emuOp2_illegal_op
,
2757 /* 0x7c */ x86emuOp2_illegal_op
,
2758 /* 0x7d */ x86emuOp2_illegal_op
,
2759 /* 0x7e */ x86emuOp2_illegal_op
,
2760 /* 0x7f */ x86emuOp2_illegal_op
,
2762 /* 0x80 */ x86emuOp2_long_jump
,
2763 /* 0x81 */ x86emuOp2_long_jump
,
2764 /* 0x82 */ x86emuOp2_long_jump
,
2765 /* 0x83 */ x86emuOp2_long_jump
,
2766 /* 0x84 */ x86emuOp2_long_jump
,
2767 /* 0x85 */ x86emuOp2_long_jump
,
2768 /* 0x86 */ x86emuOp2_long_jump
,
2769 /* 0x87 */ x86emuOp2_long_jump
,
2770 /* 0x88 */ x86emuOp2_long_jump
,
2771 /* 0x89 */ x86emuOp2_long_jump
,
2772 /* 0x8a */ x86emuOp2_long_jump
,
2773 /* 0x8b */ x86emuOp2_long_jump
,
2774 /* 0x8c */ x86emuOp2_long_jump
,
2775 /* 0x8d */ x86emuOp2_long_jump
,
2776 /* 0x8e */ x86emuOp2_long_jump
,
2777 /* 0x8f */ x86emuOp2_long_jump
,
2779 /* 0x90 */ x86emuOp2_set_byte
,
2780 /* 0x91 */ x86emuOp2_set_byte
,
2781 /* 0x92 */ x86emuOp2_set_byte
,
2782 /* 0x93 */ x86emuOp2_set_byte
,
2783 /* 0x94 */ x86emuOp2_set_byte
,
2784 /* 0x95 */ x86emuOp2_set_byte
,
2785 /* 0x96 */ x86emuOp2_set_byte
,
2786 /* 0x97 */ x86emuOp2_set_byte
,
2787 /* 0x98 */ x86emuOp2_set_byte
,
2788 /* 0x99 */ x86emuOp2_set_byte
,
2789 /* 0x9a */ x86emuOp2_set_byte
,
2790 /* 0x9b */ x86emuOp2_set_byte
,
2791 /* 0x9c */ x86emuOp2_set_byte
,
2792 /* 0x9d */ x86emuOp2_set_byte
,
2793 /* 0x9e */ x86emuOp2_set_byte
,
2794 /* 0x9f */ x86emuOp2_set_byte
,
2796 /* 0xa0 */ x86emuOp2_push_FS
,
2797 /* 0xa1 */ x86emuOp2_pop_FS
,
2798 /* 0xa2 */ x86emuOp2_cpuid
,
2799 /* 0xa3 */ x86emuOp2_bt_R
,
2800 /* 0xa4 */ x86emuOp2_shld_IMM
,
2801 /* 0xa5 */ x86emuOp2_shld_CL
,
2802 /* 0xa6 */ x86emuOp2_illegal_op
,
2803 /* 0xa7 */ x86emuOp2_illegal_op
,
2804 /* 0xa8 */ x86emuOp2_push_GS
,
2805 /* 0xa9 */ x86emuOp2_pop_GS
,
2806 /* 0xaa */ x86emuOp2_illegal_op
,
2807 /* 0xab */ x86emuOp2_bts_R
,
2808 /* 0xac */ x86emuOp2_shrd_IMM
,
2809 /* 0xad */ x86emuOp2_shrd_CL
,
2810 /* 0xae */ x86emuOp2_illegal_op
,
2811 /* 0xaf */ x86emuOp2_imul_R_RM
,
2813 /* 0xb0 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2814 /* 0xb1 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2815 /* 0xb2 */ x86emuOp2_lss_R_IMM
,
2816 /* 0xb3 */ x86emuOp2_btr_R
,
2817 /* 0xb4 */ x86emuOp2_lfs_R_IMM
,
2818 /* 0xb5 */ x86emuOp2_lgs_R_IMM
,
2819 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM
,
2820 /* 0xb7 */ x86emuOp2_movzx_word_R_RM
,
2821 /* 0xb8 */ x86emuOp2_illegal_op
,
2822 /* 0xb9 */ x86emuOp2_illegal_op
,
2823 /* 0xba */ x86emuOp2_btX_I
,
2824 /* 0xbb */ x86emuOp2_btc_R
,
2825 /* 0xbc */ x86emuOp2_bsf
,
2826 /* 0xbd */ x86emuOp2_bsr
,
2827 /* 0xbe */ x86emuOp2_movsx_byte_R_RM
,
2828 /* 0xbf */ x86emuOp2_movsx_word_R_RM
,
2830 /* 0xc0 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2831 /* 0xc1 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2832 /* 0xc2 */ x86emuOp2_illegal_op
,
2833 /* 0xc3 */ x86emuOp2_illegal_op
,
2834 /* 0xc4 */ x86emuOp2_illegal_op
,
2835 /* 0xc5 */ x86emuOp2_illegal_op
,
2836 /* 0xc6 */ x86emuOp2_illegal_op
,
2837 /* 0xc7 */ x86emuOp2_illegal_op
,
2838 /* 0xc8 */ x86emuOp2_bswap
,
2839 /* 0xc9 */ x86emuOp2_bswap
,
2840 /* 0xca */ x86emuOp2_bswap
,
2841 /* 0xcb */ x86emuOp2_bswap
,
2842 /* 0xcc */ x86emuOp2_bswap
,
2843 /* 0xcd */ x86emuOp2_bswap
,
2844 /* 0xce */ x86emuOp2_bswap
,
2845 /* 0xcf */ x86emuOp2_bswap
,
2847 /* 0xd0 */ x86emuOp2_illegal_op
,
2848 /* 0xd1 */ x86emuOp2_illegal_op
,
2849 /* 0xd2 */ x86emuOp2_illegal_op
,
2850 /* 0xd3 */ x86emuOp2_illegal_op
,
2851 /* 0xd4 */ x86emuOp2_illegal_op
,
2852 /* 0xd5 */ x86emuOp2_illegal_op
,
2853 /* 0xd6 */ x86emuOp2_illegal_op
,
2854 /* 0xd7 */ x86emuOp2_illegal_op
,
2855 /* 0xd8 */ x86emuOp2_illegal_op
,
2856 /* 0xd9 */ x86emuOp2_illegal_op
,
2857 /* 0xda */ x86emuOp2_illegal_op
,
2858 /* 0xdb */ x86emuOp2_illegal_op
,
2859 /* 0xdc */ x86emuOp2_illegal_op
,
2860 /* 0xdd */ x86emuOp2_illegal_op
,
2861 /* 0xde */ x86emuOp2_illegal_op
,
2862 /* 0xdf */ x86emuOp2_illegal_op
,
2864 /* 0xe0 */ x86emuOp2_illegal_op
,
2865 /* 0xe1 */ x86emuOp2_illegal_op
,
2866 /* 0xe2 */ x86emuOp2_illegal_op
,
2867 /* 0xe3 */ x86emuOp2_illegal_op
,
2868 /* 0xe4 */ x86emuOp2_illegal_op
,
2869 /* 0xe5 */ x86emuOp2_illegal_op
,
2870 /* 0xe6 */ x86emuOp2_illegal_op
,
2871 /* 0xe7 */ x86emuOp2_illegal_op
,
2872 /* 0xe8 */ x86emuOp2_illegal_op
,
2873 /* 0xe9 */ x86emuOp2_illegal_op
,
2874 /* 0xea */ x86emuOp2_illegal_op
,
2875 /* 0xeb */ x86emuOp2_illegal_op
,
2876 /* 0xec */ x86emuOp2_illegal_op
,
2877 /* 0xed */ x86emuOp2_illegal_op
,
2878 /* 0xee */ x86emuOp2_illegal_op
,
2879 /* 0xef */ x86emuOp2_illegal_op
,
2881 /* 0xf0 */ x86emuOp2_illegal_op
,
2882 /* 0xf1 */ x86emuOp2_illegal_op
,
2883 /* 0xf2 */ x86emuOp2_illegal_op
,
2884 /* 0xf3 */ x86emuOp2_illegal_op
,
2885 /* 0xf4 */ x86emuOp2_illegal_op
,
2886 /* 0xf5 */ x86emuOp2_illegal_op
,
2887 /* 0xf6 */ x86emuOp2_illegal_op
,
2888 /* 0xf7 */ x86emuOp2_illegal_op
,
2889 /* 0xf8 */ x86emuOp2_illegal_op
,
2890 /* 0xf9 */ x86emuOp2_illegal_op
,
2891 /* 0xfa */ x86emuOp2_illegal_op
,
2892 /* 0xfb */ x86emuOp2_illegal_op
,
2893 /* 0xfc */ x86emuOp2_illegal_op
,
2894 /* 0xfd */ x86emuOp2_illegal_op
,
2895 /* 0xfe */ x86emuOp2_illegal_op
,
2896 /* 0xff */ x86emuOp2_illegal_op
,