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(
63 FETCH_DECODE_MODRM(mod
, rh
, rl
);
64 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
66 printk("%04x:%04x: %02X /%d ILLEGAL EXTENDED X86 OPCODE! (mod=%d rl=%d)\n",
67 M
.x86
.R_CS
, M
.x86
.R_IP
-2,op2
, rh
, mod
, rl
);
72 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
74 /****************************************************************************
76 Handles opcode 0x0f,0x01
77 ****************************************************************************/
78 static void x86emuOp2_group_g(u8
X86EMU_UNUSED(op2
))
85 FETCH_DECODE_MODRM(mod
, rh
, rl
);
87 case 4: // SMSW (Store Machine Status Word)
88 // Decode the mod byte to find the addressing
89 // Always returns 0x10 (initial value as per intel manual volume 3, figure 8-1
92 destoffset
= decode_rm00_address(rl
);
93 store_data_word(destoffset
, 0x10);
96 destoffset
= decode_rm01_address(rl
);
97 store_data_word(destoffset
, 0x10);
100 destoffset
= decode_rm10_address(rl
);
101 store_data_word(destoffset
, 0x10);
104 destreg
= DECODE_RM_WORD_REGISTER(rl
);
110 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE IN 0F 01\n");
112 printk("%04x:%04x: 0F %02X /%d ILLEGAL EXTENDED X86 OPCODE! (mod=%d rl=%d)\n",
113 M
.x86
.R_CS
, M
.x86
.R_IP
-2,op2
, rh
, mod
, rl
);
120 /****************************************************************************
122 Handles opcode 0x0f,0x31
123 ****************************************************************************/
124 static void x86emuOp2_rdtsc(u8
X86EMU_UNUSED(op2
))
126 #ifdef __HAS_LONG_LONG__
127 static u64 counter
= 0;
129 static u32 counter
= 0;
134 /* read timestamp counter */
136 * Note that instead of actually trying to accurately measure this, we just
137 * increase the counter by a fixed amount every time we hit one of these
138 * instructions. Feel free to come up with a better method.
141 DECODE_PRINTF("RDTSC\n");
143 #ifdef __HAS_LONG_LONG__
144 M
.x86
.R_EAX
= counter
& 0xffffffff;
145 M
.x86
.R_EDX
= counter
>> 32;
147 M
.x86
.R_EAX
= counter
;
150 DECODE_CLEAR_SEGOVR();
154 /****************************************************************************
156 Handles opcode 0x0f,0x80-0x8F
157 ****************************************************************************/
158 static void x86emuOp2_long_jump(u8 op2
)
164 /* conditional jump to word offset. */
169 cond
= ACCESS_FLAG(F_OF
);
173 cond
= !ACCESS_FLAG(F_OF
);
177 cond
= ACCESS_FLAG(F_CF
);
181 cond
= !ACCESS_FLAG(F_CF
);
185 cond
= ACCESS_FLAG(F_ZF
);
189 cond
= !ACCESS_FLAG(F_ZF
);
193 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
197 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
201 cond
= ACCESS_FLAG(F_SF
);
205 cond
= !ACCESS_FLAG(F_SF
);
209 cond
= ACCESS_FLAG(F_PF
);
213 cond
= !ACCESS_FLAG(F_PF
);
217 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
221 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)));
225 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
230 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
236 target
= (s16
) fetch_word_imm();
237 target
+= (s16
) M
.x86
.R_IP
;
238 DECODE_PRINTF2("%04x\n", target
);
241 M
.x86
.R_IP
= (u16
)target
;
242 DECODE_CLEAR_SEGOVR();
246 /****************************************************************************
248 Handles opcode 0x0f,0x90-0x9F
249 ****************************************************************************/
250 static void x86emuOp2_set_byte(u8 op2
)
262 cond
= ACCESS_FLAG(F_OF
);
266 cond
= !ACCESS_FLAG(F_OF
);
270 cond
= ACCESS_FLAG(F_CF
);
274 cond
= !ACCESS_FLAG(F_CF
);
278 cond
= ACCESS_FLAG(F_ZF
);
282 cond
= !ACCESS_FLAG(F_ZF
);
286 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
290 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
294 cond
= ACCESS_FLAG(F_SF
);
298 cond
= !ACCESS_FLAG(F_SF
);
302 cond
= ACCESS_FLAG(F_PF
);
306 cond
= !ACCESS_FLAG(F_PF
);
310 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
314 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
318 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
323 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
329 FETCH_DECODE_MODRM(mod
, rh
, rl
);
332 destoffset
= decode_rm00_address(rl
);
334 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
337 destoffset
= decode_rm01_address(rl
);
339 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
342 destoffset
= decode_rm10_address(rl
);
344 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
346 case 3: /* register to register */
347 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
349 *destreg
= cond
? 0x01 : 0x00;
352 DECODE_CLEAR_SEGOVR();
356 /****************************************************************************
358 Handles opcode 0x0f,0xa0
359 ****************************************************************************/
360 static void x86emuOp2_push_FS(u8
X86EMU_UNUSED(op2
))
363 DECODE_PRINTF("PUSH\tFS\n");
365 push_word(M
.x86
.R_FS
);
366 DECODE_CLEAR_SEGOVR();
370 /****************************************************************************
372 Handles opcode 0x0f,0xa1
373 ****************************************************************************/
374 static void x86emuOp2_pop_FS(u8
X86EMU_UNUSED(op2
))
377 DECODE_PRINTF("POP\tFS\n");
379 M
.x86
.R_FS
= pop_word();
380 DECODE_CLEAR_SEGOVR();
384 /****************************************************************************
385 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
386 Handles opcode 0x0f,0xa2
387 ****************************************************************************/
388 static void x86emuOp2_cpuid(u8
X86EMU_UNUSED(op2
))
391 DECODE_PRINTF("CPUID\n");
394 DECODE_CLEAR_SEGOVR();
398 /****************************************************************************
400 Handles opcode 0x0f,0xa3
401 ****************************************************************************/
402 static void x86emuOp2_bt_R(u8
X86EMU_UNUSED(op2
))
409 DECODE_PRINTF("BT\t");
410 FETCH_DECODE_MODRM(mod
, rh
, rl
);
413 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
417 srcoffset
= decode_rm00_address(rl
);
419 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
421 bit
= *shiftreg
& 0x1F;
422 disp
= (s16
)*shiftreg
>> 5;
423 srcval
= fetch_data_long(srcoffset
+disp
);
424 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
429 srcoffset
= decode_rm00_address(rl
);
431 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
433 bit
= *shiftreg
& 0xF;
434 disp
= (s16
)*shiftreg
>> 4;
435 srcval
= fetch_data_word(srcoffset
+disp
);
436 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
440 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
444 srcoffset
= decode_rm01_address(rl
);
446 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
448 bit
= *shiftreg
& 0x1F;
449 disp
= (s16
)*shiftreg
>> 5;
450 srcval
= fetch_data_long(srcoffset
+disp
);
451 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
456 srcoffset
= decode_rm01_address(rl
);
458 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
460 bit
= *shiftreg
& 0xF;
461 disp
= (s16
)*shiftreg
>> 4;
462 srcval
= fetch_data_word(srcoffset
+disp
);
463 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
467 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
471 srcoffset
= decode_rm10_address(rl
);
473 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
475 bit
= *shiftreg
& 0x1F;
476 disp
= (s16
)*shiftreg
>> 5;
477 srcval
= fetch_data_long(srcoffset
+disp
);
478 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
483 srcoffset
= decode_rm10_address(rl
);
485 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
487 bit
= *shiftreg
& 0xF;
488 disp
= (s16
)*shiftreg
>> 4;
489 srcval
= fetch_data_word(srcoffset
+disp
);
490 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
493 case 3: /* register to register */
494 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
495 u32
*srcreg
,*shiftreg
;
497 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
499 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
501 bit
= *shiftreg
& 0x1F;
502 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
504 u16
*srcreg
,*shiftreg
;
506 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
508 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
510 bit
= *shiftreg
& 0xF;
511 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
515 DECODE_CLEAR_SEGOVR();
519 /****************************************************************************
521 Handles opcode 0x0f,0xa4
522 ****************************************************************************/
523 static void x86emuOp2_shld_IMM(u8
X86EMU_UNUSED(op2
))
530 DECODE_PRINTF("SHLD\t");
531 FETCH_DECODE_MODRM(mod
, rh
, rl
);
534 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
538 destoffset
= decode_rm00_address(rl
);
540 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
542 shift
= fetch_byte_imm();
543 DECODE_PRINTF2("%d\n", shift
);
545 destval
= fetch_data_long(destoffset
);
546 destval
= shld_long(destval
,*shiftreg
,shift
);
547 store_data_long(destoffset
, destval
);
552 destoffset
= decode_rm00_address(rl
);
554 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
556 shift
= fetch_byte_imm();
557 DECODE_PRINTF2("%d\n", shift
);
559 destval
= fetch_data_word(destoffset
);
560 destval
= shld_word(destval
,*shiftreg
,shift
);
561 store_data_word(destoffset
, destval
);
565 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
569 destoffset
= decode_rm01_address(rl
);
571 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
573 shift
= fetch_byte_imm();
574 DECODE_PRINTF2("%d\n", shift
);
576 destval
= fetch_data_long(destoffset
);
577 destval
= shld_long(destval
,*shiftreg
,shift
);
578 store_data_long(destoffset
, destval
);
583 destoffset
= decode_rm01_address(rl
);
585 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
587 shift
= fetch_byte_imm();
588 DECODE_PRINTF2("%d\n", shift
);
590 destval
= fetch_data_word(destoffset
);
591 destval
= shld_word(destval
,*shiftreg
,shift
);
592 store_data_word(destoffset
, destval
);
596 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
600 destoffset
= decode_rm10_address(rl
);
602 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
604 shift
= fetch_byte_imm();
605 DECODE_PRINTF2("%d\n", shift
);
607 destval
= fetch_data_long(destoffset
);
608 destval
= shld_long(destval
,*shiftreg
,shift
);
609 store_data_long(destoffset
, destval
);
614 destoffset
= decode_rm10_address(rl
);
616 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
618 shift
= fetch_byte_imm();
619 DECODE_PRINTF2("%d\n", shift
);
621 destval
= fetch_data_word(destoffset
);
622 destval
= shld_word(destval
,*shiftreg
,shift
);
623 store_data_word(destoffset
, destval
);
626 case 3: /* register to register */
627 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
628 u32
*destreg
,*shiftreg
;
630 destreg
= DECODE_RM_LONG_REGISTER(rl
);
632 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
634 shift
= fetch_byte_imm();
635 DECODE_PRINTF2("%d\n", shift
);
637 *destreg
= shld_long(*destreg
,*shiftreg
,shift
);
639 u16
*destreg
,*shiftreg
;
641 destreg
= DECODE_RM_WORD_REGISTER(rl
);
643 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
645 shift
= fetch_byte_imm();
646 DECODE_PRINTF2("%d\n", shift
);
648 *destreg
= shld_word(*destreg
,*shiftreg
,shift
);
652 DECODE_CLEAR_SEGOVR();
656 /****************************************************************************
658 Handles opcode 0x0f,0xa5
659 ****************************************************************************/
660 static void x86emuOp2_shld_CL(u8
X86EMU_UNUSED(op2
))
666 DECODE_PRINTF("SHLD\t");
667 FETCH_DECODE_MODRM(mod
, rh
, rl
);
670 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
674 destoffset
= decode_rm00_address(rl
);
676 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
677 DECODE_PRINTF(",CL\n");
679 destval
= fetch_data_long(destoffset
);
680 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
681 store_data_long(destoffset
, destval
);
686 destoffset
= decode_rm00_address(rl
);
688 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
689 DECODE_PRINTF(",CL\n");
691 destval
= fetch_data_word(destoffset
);
692 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
693 store_data_word(destoffset
, destval
);
697 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
701 destoffset
= decode_rm01_address(rl
);
703 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
704 DECODE_PRINTF(",CL\n");
706 destval
= fetch_data_long(destoffset
);
707 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
708 store_data_long(destoffset
, destval
);
713 destoffset
= decode_rm01_address(rl
);
715 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
716 DECODE_PRINTF(",CL\n");
718 destval
= fetch_data_word(destoffset
);
719 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
720 store_data_word(destoffset
, destval
);
724 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
728 destoffset
= decode_rm10_address(rl
);
730 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
731 DECODE_PRINTF(",CL\n");
733 destval
= fetch_data_long(destoffset
);
734 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
735 store_data_long(destoffset
, destval
);
740 destoffset
= decode_rm10_address(rl
);
742 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
743 DECODE_PRINTF(",CL\n");
745 destval
= fetch_data_word(destoffset
);
746 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
747 store_data_word(destoffset
, destval
);
750 case 3: /* register to register */
751 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
752 u32
*destreg
,*shiftreg
;
754 destreg
= DECODE_RM_LONG_REGISTER(rl
);
756 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
757 DECODE_PRINTF(",CL\n");
759 *destreg
= shld_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
761 u16
*destreg
,*shiftreg
;
763 destreg
= DECODE_RM_WORD_REGISTER(rl
);
765 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
766 DECODE_PRINTF(",CL\n");
768 *destreg
= shld_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
772 DECODE_CLEAR_SEGOVR();
776 /****************************************************************************
778 Handles opcode 0x0f,0xa8
779 ****************************************************************************/
780 static void x86emuOp2_push_GS(u8
X86EMU_UNUSED(op2
))
783 DECODE_PRINTF("PUSH\tGS\n");
785 push_word(M
.x86
.R_GS
);
786 DECODE_CLEAR_SEGOVR();
790 /****************************************************************************
792 Handles opcode 0x0f,0xa9
793 ****************************************************************************/
794 static void x86emuOp2_pop_GS(u8
X86EMU_UNUSED(op2
))
797 DECODE_PRINTF("POP\tGS\n");
799 M
.x86
.R_GS
= pop_word();
800 DECODE_CLEAR_SEGOVR();
804 /****************************************************************************
806 Handles opcode 0x0f,0xab
807 ****************************************************************************/
808 static void x86emuOp2_bts_R(u8
X86EMU_UNUSED(op2
))
815 DECODE_PRINTF("BTS\t");
816 FETCH_DECODE_MODRM(mod
, rh
, rl
);
819 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
823 srcoffset
= decode_rm00_address(rl
);
825 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
827 bit
= *shiftreg
& 0x1F;
828 disp
= (s16
)*shiftreg
>> 5;
829 srcval
= fetch_data_long(srcoffset
+disp
);
831 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
832 store_data_long(srcoffset
+disp
, srcval
| mask
);
837 srcoffset
= decode_rm00_address(rl
);
839 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
841 bit
= *shiftreg
& 0xF;
842 disp
= (s16
)*shiftreg
>> 4;
843 srcval
= fetch_data_word(srcoffset
+disp
);
844 mask
= (u16
)(0x1 << bit
);
845 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
846 store_data_word(srcoffset
+disp
, srcval
| mask
);
850 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
854 srcoffset
= decode_rm01_address(rl
);
856 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
858 bit
= *shiftreg
& 0x1F;
859 disp
= (s16
)*shiftreg
>> 5;
860 srcval
= fetch_data_long(srcoffset
+disp
);
862 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
863 store_data_long(srcoffset
+disp
, srcval
| mask
);
868 srcoffset
= decode_rm01_address(rl
);
870 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
872 bit
= *shiftreg
& 0xF;
873 disp
= (s16
)*shiftreg
>> 4;
874 srcval
= fetch_data_word(srcoffset
+disp
);
875 mask
= (u16
)(0x1 << bit
);
876 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
877 store_data_word(srcoffset
+disp
, srcval
| mask
);
881 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
885 srcoffset
= decode_rm10_address(rl
);
887 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
889 bit
= *shiftreg
& 0x1F;
890 disp
= (s16
)*shiftreg
>> 5;
891 srcval
= fetch_data_long(srcoffset
+disp
);
893 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
894 store_data_long(srcoffset
+disp
, srcval
| mask
);
899 srcoffset
= decode_rm10_address(rl
);
901 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
903 bit
= *shiftreg
& 0xF;
904 disp
= (s16
)*shiftreg
>> 4;
905 srcval
= fetch_data_word(srcoffset
+disp
);
906 mask
= (u16
)(0x1 << bit
);
907 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
908 store_data_word(srcoffset
+disp
, srcval
| mask
);
911 case 3: /* register to register */
912 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
913 u32
*srcreg
,*shiftreg
;
916 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
918 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
920 bit
= *shiftreg
& 0x1F;
922 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
925 u16
*srcreg
,*shiftreg
;
928 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
930 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
932 bit
= *shiftreg
& 0xF;
933 mask
= (u16
)(0x1 << bit
);
934 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
939 DECODE_CLEAR_SEGOVR();
943 /****************************************************************************
945 Handles opcode 0x0f,0xac
946 ****************************************************************************/
947 static void x86emuOp2_shrd_IMM(u8
X86EMU_UNUSED(op2
))
954 DECODE_PRINTF("SHLD\t");
955 FETCH_DECODE_MODRM(mod
, rh
, rl
);
958 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
962 destoffset
= decode_rm00_address(rl
);
964 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
966 shift
= fetch_byte_imm();
967 DECODE_PRINTF2("%d\n", shift
);
969 destval
= fetch_data_long(destoffset
);
970 destval
= shrd_long(destval
,*shiftreg
,shift
);
971 store_data_long(destoffset
, destval
);
976 destoffset
= decode_rm00_address(rl
);
978 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
980 shift
= fetch_byte_imm();
981 DECODE_PRINTF2("%d\n", shift
);
983 destval
= fetch_data_word(destoffset
);
984 destval
= shrd_word(destval
,*shiftreg
,shift
);
985 store_data_word(destoffset
, destval
);
989 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
993 destoffset
= decode_rm01_address(rl
);
995 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
997 shift
= fetch_byte_imm();
998 DECODE_PRINTF2("%d\n", shift
);
1000 destval
= fetch_data_long(destoffset
);
1001 destval
= shrd_long(destval
,*shiftreg
,shift
);
1002 store_data_long(destoffset
, destval
);
1007 destoffset
= decode_rm01_address(rl
);
1009 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1011 shift
= fetch_byte_imm();
1012 DECODE_PRINTF2("%d\n", shift
);
1014 destval
= fetch_data_word(destoffset
);
1015 destval
= shrd_word(destval
,*shiftreg
,shift
);
1016 store_data_word(destoffset
, destval
);
1020 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1024 destoffset
= decode_rm10_address(rl
);
1026 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1028 shift
= fetch_byte_imm();
1029 DECODE_PRINTF2("%d\n", shift
);
1031 destval
= fetch_data_long(destoffset
);
1032 destval
= shrd_long(destval
,*shiftreg
,shift
);
1033 store_data_long(destoffset
, destval
);
1038 destoffset
= decode_rm10_address(rl
);
1040 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1042 shift
= fetch_byte_imm();
1043 DECODE_PRINTF2("%d\n", shift
);
1045 destval
= fetch_data_word(destoffset
);
1046 destval
= shrd_word(destval
,*shiftreg
,shift
);
1047 store_data_word(destoffset
, destval
);
1050 case 3: /* register to register */
1051 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1052 u32
*destreg
,*shiftreg
;
1054 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1056 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1058 shift
= fetch_byte_imm();
1059 DECODE_PRINTF2("%d\n", shift
);
1061 *destreg
= shrd_long(*destreg
,*shiftreg
,shift
);
1063 u16
*destreg
,*shiftreg
;
1065 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1067 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1069 shift
= fetch_byte_imm();
1070 DECODE_PRINTF2("%d\n", shift
);
1072 *destreg
= shrd_word(*destreg
,*shiftreg
,shift
);
1076 DECODE_CLEAR_SEGOVR();
1080 /****************************************************************************
1082 Handles opcode 0x0f,0xad
1083 ****************************************************************************/
1084 static void x86emuOp2_shrd_CL(u8
X86EMU_UNUSED(op2
))
1090 DECODE_PRINTF("SHLD\t");
1091 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1094 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1098 destoffset
= decode_rm00_address(rl
);
1100 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1101 DECODE_PRINTF(",CL\n");
1103 destval
= fetch_data_long(destoffset
);
1104 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1105 store_data_long(destoffset
, destval
);
1110 destoffset
= decode_rm00_address(rl
);
1112 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1113 DECODE_PRINTF(",CL\n");
1115 destval
= fetch_data_word(destoffset
);
1116 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1117 store_data_word(destoffset
, destval
);
1121 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1125 destoffset
= decode_rm01_address(rl
);
1127 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1128 DECODE_PRINTF(",CL\n");
1130 destval
= fetch_data_long(destoffset
);
1131 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1132 store_data_long(destoffset
, destval
);
1137 destoffset
= decode_rm01_address(rl
);
1139 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1140 DECODE_PRINTF(",CL\n");
1142 destval
= fetch_data_word(destoffset
);
1143 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1144 store_data_word(destoffset
, destval
);
1148 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1152 destoffset
= decode_rm10_address(rl
);
1154 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1155 DECODE_PRINTF(",CL\n");
1157 destval
= fetch_data_long(destoffset
);
1158 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1159 store_data_long(destoffset
, destval
);
1164 destoffset
= decode_rm10_address(rl
);
1166 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1167 DECODE_PRINTF(",CL\n");
1169 destval
= fetch_data_word(destoffset
);
1170 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1171 store_data_word(destoffset
, destval
);
1174 case 3: /* register to register */
1175 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1176 u32
*destreg
,*shiftreg
;
1178 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1180 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1181 DECODE_PRINTF(",CL\n");
1183 *destreg
= shrd_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1185 u16
*destreg
,*shiftreg
;
1187 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1189 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1190 DECODE_PRINTF(",CL\n");
1192 *destreg
= shrd_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1196 DECODE_CLEAR_SEGOVR();
1200 /****************************************************************************
1202 Handles opcode 0x0f,0xaf
1203 ****************************************************************************/
1204 static void x86emuOp2_imul_R_RM(u8
X86EMU_UNUSED(op2
))
1210 DECODE_PRINTF("IMUL\t");
1211 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1214 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1219 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1221 srcoffset
= decode_rm00_address(rl
);
1222 srcval
= fetch_data_long(srcoffset
);
1224 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1232 *destreg
= (u32
)res_lo
;
1238 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1240 srcoffset
= decode_rm00_address(rl
);
1241 srcval
= fetch_data_word(srcoffset
);
1243 res
= (s16
)*destreg
* (s16
)srcval
;
1251 *destreg
= (u16
)res
;
1255 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1260 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1262 srcoffset
= decode_rm01_address(rl
);
1263 srcval
= fetch_data_long(srcoffset
);
1265 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1273 *destreg
= (u32
)res_lo
;
1279 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1281 srcoffset
= decode_rm01_address(rl
);
1282 srcval
= fetch_data_word(srcoffset
);
1284 res
= (s16
)*destreg
* (s16
)srcval
;
1292 *destreg
= (u16
)res
;
1296 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1301 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1303 srcoffset
= decode_rm10_address(rl
);
1304 srcval
= fetch_data_long(srcoffset
);
1306 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1314 *destreg
= (u32
)res_lo
;
1320 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1322 srcoffset
= decode_rm10_address(rl
);
1323 srcval
= fetch_data_word(srcoffset
);
1325 res
= (s16
)*destreg
* (s16
)srcval
;
1333 *destreg
= (u16
)res
;
1336 case 3: /* register to register */
1337 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1338 u32
*destreg
,*srcreg
;
1341 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1343 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1345 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)*srcreg
);
1353 *destreg
= (u32
)res_lo
;
1355 u16
*destreg
,*srcreg
;
1358 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1360 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1361 res
= (s16
)*destreg
* (s16
)*srcreg
;
1369 *destreg
= (u16
)res
;
1373 DECODE_CLEAR_SEGOVR();
1377 /****************************************************************************
1379 Handles opcode 0x0f,0xb2
1380 ****************************************************************************/
1381 static void x86emuOp2_lss_R_IMM(u8
X86EMU_UNUSED(op2
))
1388 DECODE_PRINTF("LSS\t");
1389 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1392 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1394 srcoffset
= decode_rm00_address(rl
);
1395 DECODE_PRINTF("\n");
1397 *dstreg
= fetch_data_word(srcoffset
);
1398 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1401 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1403 srcoffset
= decode_rm01_address(rl
);
1404 DECODE_PRINTF("\n");
1406 *dstreg
= fetch_data_word(srcoffset
);
1407 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1410 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1412 srcoffset
= decode_rm10_address(rl
);
1413 DECODE_PRINTF("\n");
1415 *dstreg
= fetch_data_word(srcoffset
);
1416 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1418 case 3: /* register to register */
1422 DECODE_CLEAR_SEGOVR();
1426 /****************************************************************************
1428 Handles opcode 0x0f,0xb3
1429 ****************************************************************************/
1430 static void x86emuOp2_btr_R(u8
X86EMU_UNUSED(op2
))
1437 DECODE_PRINTF("BTR\t");
1438 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1441 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1445 srcoffset
= decode_rm00_address(rl
);
1447 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1449 bit
= *shiftreg
& 0x1F;
1450 disp
= (s16
)*shiftreg
>> 5;
1451 srcval
= fetch_data_long(srcoffset
+disp
);
1452 mask
= (0x1 << bit
);
1453 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1454 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1459 srcoffset
= decode_rm00_address(rl
);
1461 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1463 bit
= *shiftreg
& 0xF;
1464 disp
= (s16
)*shiftreg
>> 4;
1465 srcval
= fetch_data_word(srcoffset
+disp
);
1466 mask
= (u16
)(0x1 << bit
);
1467 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1468 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1472 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1476 srcoffset
= decode_rm01_address(rl
);
1478 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1480 bit
= *shiftreg
& 0x1F;
1481 disp
= (s16
)*shiftreg
>> 5;
1482 srcval
= fetch_data_long(srcoffset
+disp
);
1483 mask
= (0x1 << bit
);
1484 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1485 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1490 srcoffset
= decode_rm01_address(rl
);
1492 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1494 bit
= *shiftreg
& 0xF;
1495 disp
= (s16
)*shiftreg
>> 4;
1496 srcval
= fetch_data_word(srcoffset
+disp
);
1497 mask
= (u16
)(0x1 << bit
);
1498 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1499 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1503 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1507 srcoffset
= decode_rm10_address(rl
);
1509 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1511 bit
= *shiftreg
& 0x1F;
1512 disp
= (s16
)*shiftreg
>> 5;
1513 srcval
= fetch_data_long(srcoffset
+disp
);
1514 mask
= (0x1 << bit
);
1515 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1516 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1521 srcoffset
= decode_rm10_address(rl
);
1523 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1525 bit
= *shiftreg
& 0xF;
1526 disp
= (s16
)*shiftreg
>> 4;
1527 srcval
= fetch_data_word(srcoffset
+disp
);
1528 mask
= (u16
)(0x1 << bit
);
1529 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1530 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1533 case 3: /* register to register */
1534 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1535 u32
*srcreg
,*shiftreg
;
1538 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1540 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1542 bit
= *shiftreg
& 0x1F;
1543 mask
= (0x1 << bit
);
1544 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1547 u16
*srcreg
,*shiftreg
;
1550 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1552 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1554 bit
= *shiftreg
& 0xF;
1555 mask
= (u16
)(0x1 << bit
);
1556 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1561 DECODE_CLEAR_SEGOVR();
1565 /****************************************************************************
1567 Handles opcode 0x0f,0xb4
1568 ****************************************************************************/
1569 static void x86emuOp2_lfs_R_IMM(u8
X86EMU_UNUSED(op2
))
1576 DECODE_PRINTF("LFS\t");
1577 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1580 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1582 srcoffset
= decode_rm00_address(rl
);
1583 DECODE_PRINTF("\n");
1585 *dstreg
= fetch_data_word(srcoffset
);
1586 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1589 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1591 srcoffset
= decode_rm01_address(rl
);
1592 DECODE_PRINTF("\n");
1594 *dstreg
= fetch_data_word(srcoffset
);
1595 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1598 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1600 srcoffset
= decode_rm10_address(rl
);
1601 DECODE_PRINTF("\n");
1603 *dstreg
= fetch_data_word(srcoffset
);
1604 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1606 case 3: /* register to register */
1610 DECODE_CLEAR_SEGOVR();
1614 /****************************************************************************
1616 Handles opcode 0x0f,0xb5
1617 ****************************************************************************/
1618 static void x86emuOp2_lgs_R_IMM(u8
X86EMU_UNUSED(op2
))
1625 DECODE_PRINTF("LGS\t");
1626 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1629 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1631 srcoffset
= decode_rm00_address(rl
);
1632 DECODE_PRINTF("\n");
1634 *dstreg
= fetch_data_word(srcoffset
);
1635 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1638 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1640 srcoffset
= decode_rm01_address(rl
);
1641 DECODE_PRINTF("\n");
1643 *dstreg
= fetch_data_word(srcoffset
);
1644 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1647 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1649 srcoffset
= decode_rm10_address(rl
);
1650 DECODE_PRINTF("\n");
1652 *dstreg
= fetch_data_word(srcoffset
);
1653 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1655 case 3: /* register to register */
1659 DECODE_CLEAR_SEGOVR();
1663 /****************************************************************************
1665 Handles opcode 0x0f,0xb6
1666 ****************************************************************************/
1667 static void x86emuOp2_movzx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
1673 DECODE_PRINTF("MOVZX\t");
1674 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1677 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1681 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1683 srcoffset
= decode_rm00_address(rl
);
1684 srcval
= fetch_data_byte(srcoffset
);
1685 DECODE_PRINTF("\n");
1692 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1694 srcoffset
= decode_rm00_address(rl
);
1695 srcval
= fetch_data_byte(srcoffset
);
1696 DECODE_PRINTF("\n");
1702 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1706 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1708 srcoffset
= decode_rm01_address(rl
);
1709 srcval
= fetch_data_byte(srcoffset
);
1710 DECODE_PRINTF("\n");
1717 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1719 srcoffset
= decode_rm01_address(rl
);
1720 srcval
= fetch_data_byte(srcoffset
);
1721 DECODE_PRINTF("\n");
1727 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1731 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1733 srcoffset
= decode_rm10_address(rl
);
1734 srcval
= fetch_data_byte(srcoffset
);
1735 DECODE_PRINTF("\n");
1742 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1744 srcoffset
= decode_rm10_address(rl
);
1745 srcval
= fetch_data_byte(srcoffset
);
1746 DECODE_PRINTF("\n");
1751 case 3: /* register to register */
1752 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1756 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1758 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1759 DECODE_PRINTF("\n");
1766 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1768 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1769 DECODE_PRINTF("\n");
1775 DECODE_CLEAR_SEGOVR();
1779 /****************************************************************************
1781 Handles opcode 0x0f,0xb7
1782 ****************************************************************************/
1783 static void x86emuOp2_movzx_word_R_RM(u8
X86EMU_UNUSED(op2
))
1792 DECODE_PRINTF("MOVZX\t");
1793 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1796 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1798 srcoffset
= decode_rm00_address(rl
);
1799 srcval
= fetch_data_word(srcoffset
);
1800 DECODE_PRINTF("\n");
1805 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1807 srcoffset
= decode_rm01_address(rl
);
1808 srcval
= fetch_data_word(srcoffset
);
1809 DECODE_PRINTF("\n");
1814 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1816 srcoffset
= decode_rm10_address(rl
);
1817 srcval
= fetch_data_word(srcoffset
);
1818 DECODE_PRINTF("\n");
1822 case 3: /* register to register */
1823 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1825 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1826 DECODE_PRINTF("\n");
1831 DECODE_CLEAR_SEGOVR();
1835 /****************************************************************************
1837 Handles opcode 0x0f,0xba
1838 ****************************************************************************/
1839 static void x86emuOp2_btX_I(u8
X86EMU_UNUSED(op2
))
1846 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1849 DECODE_PRINTF("BT\t");
1852 DECODE_PRINTF("BTS\t");
1855 DECODE_PRINTF("BTR\t");
1858 DECODE_PRINTF("BTC\t");
1861 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1863 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1864 M
.x86
.R_CS
, M
.x86
.R_IP
-3,op2
, (mod
<<6)|(rh
<<3)|rl
);
1869 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1873 srcoffset
= decode_rm00_address(rl
);
1875 shift
= fetch_byte_imm();
1878 srcval
= fetch_data_long(srcoffset
);
1879 mask
= (0x1 << bit
);
1880 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1883 store_data_long(srcoffset
, srcval
| mask
);
1886 store_data_long(srcoffset
, srcval
& ~mask
);
1889 store_data_long(srcoffset
, srcval
^ mask
);
1898 srcoffset
= decode_rm00_address(rl
);
1900 shift
= fetch_byte_imm();
1903 srcval
= fetch_data_word(srcoffset
);
1904 mask
= (0x1 << bit
);
1905 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1908 store_data_word(srcoffset
, srcval
| mask
);
1911 store_data_word(srcoffset
, srcval
& ~mask
);
1914 store_data_word(srcoffset
, srcval
^ mask
);
1922 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1926 srcoffset
= decode_rm01_address(rl
);
1928 shift
= fetch_byte_imm();
1931 srcval
= fetch_data_long(srcoffset
);
1932 mask
= (0x1 << bit
);
1933 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1936 store_data_long(srcoffset
, srcval
| mask
);
1939 store_data_long(srcoffset
, srcval
& ~mask
);
1942 store_data_long(srcoffset
, srcval
^ mask
);
1951 srcoffset
= decode_rm01_address(rl
);
1953 shift
= fetch_byte_imm();
1956 srcval
= fetch_data_word(srcoffset
);
1957 mask
= (0x1 << bit
);
1958 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1961 store_data_word(srcoffset
, srcval
| mask
);
1964 store_data_word(srcoffset
, srcval
& ~mask
);
1967 store_data_word(srcoffset
, srcval
^ mask
);
1975 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1979 srcoffset
= decode_rm10_address(rl
);
1981 shift
= fetch_byte_imm();
1984 srcval
= fetch_data_long(srcoffset
);
1985 mask
= (0x1 << bit
);
1986 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1989 store_data_long(srcoffset
, srcval
| mask
);
1992 store_data_long(srcoffset
, srcval
& ~mask
);
1995 store_data_long(srcoffset
, srcval
^ mask
);
2004 srcoffset
= decode_rm10_address(rl
);
2006 shift
= fetch_byte_imm();
2009 srcval
= fetch_data_word(srcoffset
);
2010 mask
= (0x1 << bit
);
2011 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2014 store_data_word(srcoffset
, srcval
| mask
);
2017 store_data_word(srcoffset
, srcval
& ~mask
);
2020 store_data_word(srcoffset
, srcval
^ mask
);
2027 case 3: /* register to register */
2028 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2033 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2035 shift
= fetch_byte_imm();
2038 mask
= (0x1 << bit
);
2039 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2058 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2060 shift
= fetch_byte_imm();
2063 mask
= (0x1 << bit
);
2064 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2081 DECODE_CLEAR_SEGOVR();
2085 /****************************************************************************
2087 Handles opcode 0x0f,0xbb
2088 ****************************************************************************/
2089 static void x86emuOp2_btc_R(u8
X86EMU_UNUSED(op2
))
2096 DECODE_PRINTF("BTC\t");
2097 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2100 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2104 srcoffset
= decode_rm00_address(rl
);
2106 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2108 bit
= *shiftreg
& 0x1F;
2109 disp
= (s16
)*shiftreg
>> 5;
2110 srcval
= fetch_data_long(srcoffset
+disp
);
2111 mask
= (0x1 << bit
);
2112 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2113 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2118 srcoffset
= decode_rm00_address(rl
);
2120 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2122 bit
= *shiftreg
& 0xF;
2123 disp
= (s16
)*shiftreg
>> 4;
2124 srcval
= fetch_data_word(srcoffset
+disp
);
2125 mask
= (u16
)(0x1 << bit
);
2126 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2127 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2131 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2135 srcoffset
= decode_rm01_address(rl
);
2137 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2139 bit
= *shiftreg
& 0x1F;
2140 disp
= (s16
)*shiftreg
>> 5;
2141 srcval
= fetch_data_long(srcoffset
+disp
);
2142 mask
= (0x1 << bit
);
2143 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2144 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2149 srcoffset
= decode_rm01_address(rl
);
2151 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2153 bit
= *shiftreg
& 0xF;
2154 disp
= (s16
)*shiftreg
>> 4;
2155 srcval
= fetch_data_word(srcoffset
+disp
);
2156 mask
= (u16
)(0x1 << bit
);
2157 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2158 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2162 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2166 srcoffset
= decode_rm10_address(rl
);
2168 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2170 bit
= *shiftreg
& 0x1F;
2171 disp
= (s16
)*shiftreg
>> 5;
2172 srcval
= fetch_data_long(srcoffset
+disp
);
2173 mask
= (0x1 << bit
);
2174 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2175 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2180 srcoffset
= decode_rm10_address(rl
);
2182 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2184 bit
= *shiftreg
& 0xF;
2185 disp
= (s16
)*shiftreg
>> 4;
2186 srcval
= fetch_data_word(srcoffset
+disp
);
2187 mask
= (u16
)(0x1 << bit
);
2188 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2189 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2192 case 3: /* register to register */
2193 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2194 u32
*srcreg
,*shiftreg
;
2197 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2199 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2201 bit
= *shiftreg
& 0x1F;
2202 mask
= (0x1 << bit
);
2203 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2206 u16
*srcreg
,*shiftreg
;
2209 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2211 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2213 bit
= *shiftreg
& 0xF;
2214 mask
= (u16
)(0x1 << bit
);
2215 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2220 DECODE_CLEAR_SEGOVR();
2224 /****************************************************************************
2226 Handles opcode 0x0f,0xbc
2227 ****************************************************************************/
2228 static void x86emuOp2_bsf(u8
X86EMU_UNUSED(op2
))
2234 DECODE_PRINTF("BSF\t");
2235 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2238 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2239 u32 srcval
, *dstreg
;
2241 srcoffset
= decode_rm00_address(rl
);
2243 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2245 srcval
= fetch_data_long(srcoffset
);
2246 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2247 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2248 if ((srcval
>> *dstreg
) & 1) break;
2250 u16 srcval
, *dstreg
;
2252 srcoffset
= decode_rm00_address(rl
);
2254 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2256 srcval
= fetch_data_word(srcoffset
);
2257 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2258 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2259 if ((srcval
>> *dstreg
) & 1) break;
2263 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2264 u32 srcval
, *dstreg
;
2266 srcoffset
= decode_rm01_address(rl
);
2268 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2270 srcval
= fetch_data_long(srcoffset
);
2271 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2272 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2273 if ((srcval
>> *dstreg
) & 1) break;
2275 u16 srcval
, *dstreg
;
2277 srcoffset
= decode_rm01_address(rl
);
2279 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2281 srcval
= fetch_data_word(srcoffset
);
2282 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2283 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2284 if ((srcval
>> *dstreg
) & 1) break;
2288 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2289 u32 srcval
, *dstreg
;
2291 srcoffset
= decode_rm10_address(rl
);
2293 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2295 srcval
= fetch_data_long(srcoffset
);
2296 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2297 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2298 if ((srcval
>> *dstreg
) & 1) break;
2300 u16 srcval
, *dstreg
;
2302 srcoffset
= decode_rm10_address(rl
);
2304 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2306 srcval
= fetch_data_word(srcoffset
);
2307 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2308 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2309 if ((srcval
>> *dstreg
) & 1) break;
2312 case 3: /* register to register */
2313 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2314 u32 srcval
, *dstreg
;
2316 srcval
= *DECODE_RM_LONG_REGISTER(rl
);
2318 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2320 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2321 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2322 if ((srcval
>> *dstreg
) & 1) break;
2324 u16 srcval
, *dstreg
;
2326 srcval
= *DECODE_RM_WORD_REGISTER(rl
);
2328 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2330 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2331 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2332 if ((srcval
>> *dstreg
) & 1) break;
2336 DECODE_CLEAR_SEGOVR();
2340 /****************************************************************************
2342 Handles opcode 0x0f,0xbd
2343 ****************************************************************************/
2344 static void x86emuOp2_bsr(u8
X86EMU_UNUSED(op2
))
2350 DECODE_PRINTF("BSR\t");
2351 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2354 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2355 u32 srcval
, *dstreg
;
2357 srcoffset
= decode_rm00_address(rl
);
2359 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2361 srcval
= fetch_data_long(srcoffset
);
2362 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2363 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2364 if ((srcval
>> *dstreg
) & 1) break;
2366 u16 srcval
, *dstreg
;
2368 srcoffset
= decode_rm00_address(rl
);
2370 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2372 srcval
= fetch_data_word(srcoffset
);
2373 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2374 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2375 if ((srcval
>> *dstreg
) & 1) break;
2379 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2380 u32 srcval
, *dstreg
;
2382 srcoffset
= decode_rm01_address(rl
);
2384 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2386 srcval
= fetch_data_long(srcoffset
);
2387 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2388 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2389 if ((srcval
>> *dstreg
) & 1) break;
2391 u16 srcval
, *dstreg
;
2393 srcoffset
= decode_rm01_address(rl
);
2395 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2397 srcval
= fetch_data_word(srcoffset
);
2398 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2399 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2400 if ((srcval
>> *dstreg
) & 1) break;
2404 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2405 u32 srcval
, *dstreg
;
2407 srcoffset
= decode_rm10_address(rl
);
2409 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2411 srcval
= fetch_data_long(srcoffset
);
2412 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2413 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2414 if ((srcval
>> *dstreg
) & 1) break;
2416 u16 srcval
, *dstreg
;
2418 srcoffset
= decode_rm10_address(rl
);
2420 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2422 srcval
= fetch_data_word(srcoffset
);
2423 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2424 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2425 if ((srcval
>> *dstreg
) & 1) break;
2428 case 3: /* register to register */
2429 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2430 u32 srcval
, *dstreg
;
2432 srcval
= *DECODE_RM_LONG_REGISTER(rl
);
2434 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2436 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2437 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2438 if ((srcval
>> *dstreg
) & 1) break;
2440 u16 srcval
, *dstreg
;
2442 srcval
= *DECODE_RM_WORD_REGISTER(rl
);
2444 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2446 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2447 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2448 if ((srcval
>> *dstreg
) & 1) break;
2452 DECODE_CLEAR_SEGOVR();
2456 /****************************************************************************
2458 Handles opcode 0x0f,0xbe
2459 ****************************************************************************/
2460 static void x86emuOp2_movsx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
2466 DECODE_PRINTF("MOVSX\t");
2467 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2470 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2474 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2476 srcoffset
= decode_rm00_address(rl
);
2477 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2478 DECODE_PRINTF("\n");
2485 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2487 srcoffset
= decode_rm00_address(rl
);
2488 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2489 DECODE_PRINTF("\n");
2495 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2499 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2501 srcoffset
= decode_rm01_address(rl
);
2502 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2503 DECODE_PRINTF("\n");
2510 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2512 srcoffset
= decode_rm01_address(rl
);
2513 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2514 DECODE_PRINTF("\n");
2520 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2524 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2526 srcoffset
= decode_rm10_address(rl
);
2527 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2528 DECODE_PRINTF("\n");
2535 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2537 srcoffset
= decode_rm10_address(rl
);
2538 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2539 DECODE_PRINTF("\n");
2544 case 3: /* register to register */
2545 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2549 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2551 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2552 DECODE_PRINTF("\n");
2554 *destreg
= (s32
)((s8
)*srcreg
);
2559 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2561 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2562 DECODE_PRINTF("\n");
2564 *destreg
= (s16
)((s8
)*srcreg
);
2568 DECODE_CLEAR_SEGOVR();
2572 /****************************************************************************
2574 Handles opcode 0x0f,0xbf
2575 ****************************************************************************/
2576 static void x86emuOp2_movsx_word_R_RM(u8
X86EMU_UNUSED(op2
))
2585 DECODE_PRINTF("MOVSX\t");
2586 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2589 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2591 srcoffset
= decode_rm00_address(rl
);
2592 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2593 DECODE_PRINTF("\n");
2598 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2600 srcoffset
= decode_rm01_address(rl
);
2601 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2602 DECODE_PRINTF("\n");
2607 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2609 srcoffset
= decode_rm10_address(rl
);
2610 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2611 DECODE_PRINTF("\n");
2615 case 3: /* register to register */
2616 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2618 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2619 DECODE_PRINTF("\n");
2621 *destreg
= (s32
)((s16
)*srcreg
);
2624 DECODE_CLEAR_SEGOVR();
2628 /* Handles opcodes 0xc8-0xcf */
2629 static void x86emuOp2_bswap(u8
X86EMU_UNUSED(op2
))
2632 DECODE_PRINTF("BSWAP\n");
2637 M
.x86
.R_EAX
= bswap_32(M
.x86
.R_EAX
);
2640 M
.x86
.R_ECX
= bswap_32(M
.x86
.R_ECX
);
2643 M
.x86
.R_EDX
= bswap_32(M
.x86
.R_EDX
);
2646 M
.x86
.R_EBX
= bswap_32(M
.x86
.R_EBX
);
2649 M
.x86
.R_ESP
= bswap_32(M
.x86
.R_ESP
);
2652 M
.x86
.R_EBP
= bswap_32(M
.x86
.R_EBP
);
2655 M
.x86
.R_ESI
= bswap_32(M
.x86
.R_ESI
);
2658 M
.x86
.R_EDI
= bswap_32(M
.x86
.R_EDI
);
2665 DECODE_CLEAR_SEGOVR();
2669 /***************************************************************************
2670 * Double byte operation code table:
2671 **************************************************************************/
2672 void (*x86emu_optab2
[256])(u8
) =
2674 /* 0x00 */ x86emuOp2_illegal_op
, /* Group F (ring 0 PM) */
2675 /* 0x01 */ x86emuOp2_group_g
, /* Group G (ring 0 PM) */
2676 /* 0x02 */ x86emuOp2_illegal_op
, /* lar (ring 0 PM) */
2677 /* 0x03 */ x86emuOp2_illegal_op
, /* lsl (ring 0 PM) */
2678 /* 0x04 */ x86emuOp2_illegal_op
,
2679 /* 0x05 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2680 /* 0x06 */ x86emuOp2_illegal_op
, /* clts (ring 0 PM) */
2681 /* 0x07 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2682 /* 0x08 */ x86emuOp2_illegal_op
, /* invd (ring 0 PM) */
2683 /* 0x09 */ x86emuOp2_illegal_op
, /* wbinvd (ring 0 PM) */
2684 /* 0x0a */ x86emuOp2_illegal_op
,
2685 /* 0x0b */ x86emuOp2_illegal_op
,
2686 /* 0x0c */ x86emuOp2_illegal_op
,
2687 /* 0x0d */ x86emuOp2_illegal_op
,
2688 /* 0x0e */ x86emuOp2_illegal_op
,
2689 /* 0x0f */ x86emuOp2_illegal_op
,
2691 /* 0x10 */ x86emuOp2_illegal_op
,
2692 /* 0x11 */ x86emuOp2_illegal_op
,
2693 /* 0x12 */ x86emuOp2_illegal_op
,
2694 /* 0x13 */ x86emuOp2_illegal_op
,
2695 /* 0x14 */ x86emuOp2_illegal_op
,
2696 /* 0x15 */ x86emuOp2_illegal_op
,
2697 /* 0x16 */ x86emuOp2_illegal_op
,
2698 /* 0x17 */ x86emuOp2_illegal_op
,
2699 /* 0x18 */ x86emuOp2_illegal_op
,
2700 /* 0x19 */ x86emuOp2_illegal_op
,
2701 /* 0x1a */ x86emuOp2_illegal_op
,
2702 /* 0x1b */ x86emuOp2_illegal_op
,
2703 /* 0x1c */ x86emuOp2_illegal_op
,
2704 /* 0x1d */ x86emuOp2_illegal_op
,
2705 /* 0x1e */ x86emuOp2_illegal_op
,
2706 /* 0x1f */ x86emuOp2_illegal_op
,
2708 /* 0x20 */ x86emuOp2_illegal_op
, /* mov reg32,creg (ring 0 PM) */
2709 /* 0x21 */ x86emuOp2_illegal_op
, /* mov reg32,dreg (ring 0 PM) */
2710 /* 0x22 */ x86emuOp2_illegal_op
, /* mov creg,reg32 (ring 0 PM) */
2711 /* 0x23 */ x86emuOp2_illegal_op
, /* mov dreg,reg32 (ring 0 PM) */
2712 /* 0x24 */ x86emuOp2_illegal_op
, /* mov reg32,treg (ring 0 PM) */
2713 /* 0x25 */ x86emuOp2_illegal_op
,
2714 /* 0x26 */ x86emuOp2_illegal_op
, /* mov treg,reg32 (ring 0 PM) */
2715 /* 0x27 */ x86emuOp2_illegal_op
,
2716 /* 0x28 */ x86emuOp2_illegal_op
,
2717 /* 0x29 */ x86emuOp2_illegal_op
,
2718 /* 0x2a */ x86emuOp2_illegal_op
,
2719 /* 0x2b */ x86emuOp2_illegal_op
,
2720 /* 0x2c */ x86emuOp2_illegal_op
,
2721 /* 0x2d */ x86emuOp2_illegal_op
,
2722 /* 0x2e */ x86emuOp2_illegal_op
,
2723 /* 0x2f */ x86emuOp2_illegal_op
,
2725 /* 0x30 */ x86emuOp2_illegal_op
,
2726 /* 0x31 */ x86emuOp2_rdtsc
,
2727 /* 0x32 */ x86emuOp2_illegal_op
,
2728 /* 0x33 */ x86emuOp2_illegal_op
,
2729 /* 0x34 */ x86emuOp2_illegal_op
,
2730 /* 0x35 */ x86emuOp2_illegal_op
,
2731 /* 0x36 */ x86emuOp2_illegal_op
,
2732 /* 0x37 */ x86emuOp2_illegal_op
,
2733 /* 0x38 */ x86emuOp2_illegal_op
,
2734 /* 0x39 */ x86emuOp2_illegal_op
,
2735 /* 0x3a */ x86emuOp2_illegal_op
,
2736 /* 0x3b */ x86emuOp2_illegal_op
,
2737 /* 0x3c */ x86emuOp2_illegal_op
,
2738 /* 0x3d */ x86emuOp2_illegal_op
,
2739 /* 0x3e */ x86emuOp2_illegal_op
,
2740 /* 0x3f */ x86emuOp2_illegal_op
,
2742 /* 0x40 */ x86emuOp2_illegal_op
,
2743 /* 0x41 */ x86emuOp2_illegal_op
,
2744 /* 0x42 */ x86emuOp2_illegal_op
,
2745 /* 0x43 */ x86emuOp2_illegal_op
,
2746 /* 0x44 */ x86emuOp2_illegal_op
,
2747 /* 0x45 */ x86emuOp2_illegal_op
,
2748 /* 0x46 */ x86emuOp2_illegal_op
,
2749 /* 0x47 */ x86emuOp2_illegal_op
,
2750 /* 0x48 */ x86emuOp2_illegal_op
,
2751 /* 0x49 */ x86emuOp2_illegal_op
,
2752 /* 0x4a */ x86emuOp2_illegal_op
,
2753 /* 0x4b */ x86emuOp2_illegal_op
,
2754 /* 0x4c */ x86emuOp2_illegal_op
,
2755 /* 0x4d */ x86emuOp2_illegal_op
,
2756 /* 0x4e */ x86emuOp2_illegal_op
,
2757 /* 0x4f */ x86emuOp2_illegal_op
,
2759 /* 0x50 */ x86emuOp2_illegal_op
,
2760 /* 0x51 */ x86emuOp2_illegal_op
,
2761 /* 0x52 */ x86emuOp2_illegal_op
,
2762 /* 0x53 */ x86emuOp2_illegal_op
,
2763 /* 0x54 */ x86emuOp2_illegal_op
,
2764 /* 0x55 */ x86emuOp2_illegal_op
,
2765 /* 0x56 */ x86emuOp2_illegal_op
,
2766 /* 0x57 */ x86emuOp2_illegal_op
,
2767 /* 0x58 */ x86emuOp2_illegal_op
,
2768 /* 0x59 */ x86emuOp2_illegal_op
,
2769 /* 0x5a */ x86emuOp2_illegal_op
,
2770 /* 0x5b */ x86emuOp2_illegal_op
,
2771 /* 0x5c */ x86emuOp2_illegal_op
,
2772 /* 0x5d */ x86emuOp2_illegal_op
,
2773 /* 0x5e */ x86emuOp2_illegal_op
,
2774 /* 0x5f */ x86emuOp2_illegal_op
,
2776 /* 0x60 */ x86emuOp2_illegal_op
,
2777 /* 0x61 */ x86emuOp2_illegal_op
,
2778 /* 0x62 */ x86emuOp2_illegal_op
,
2779 /* 0x63 */ x86emuOp2_illegal_op
,
2780 /* 0x64 */ x86emuOp2_illegal_op
,
2781 /* 0x65 */ x86emuOp2_illegal_op
,
2782 /* 0x66 */ x86emuOp2_illegal_op
,
2783 /* 0x67 */ x86emuOp2_illegal_op
,
2784 /* 0x68 */ x86emuOp2_illegal_op
,
2785 /* 0x69 */ x86emuOp2_illegal_op
,
2786 /* 0x6a */ x86emuOp2_illegal_op
,
2787 /* 0x6b */ x86emuOp2_illegal_op
,
2788 /* 0x6c */ x86emuOp2_illegal_op
,
2789 /* 0x6d */ x86emuOp2_illegal_op
,
2790 /* 0x6e */ x86emuOp2_illegal_op
,
2791 /* 0x6f */ x86emuOp2_illegal_op
,
2793 /* 0x70 */ x86emuOp2_illegal_op
,
2794 /* 0x71 */ x86emuOp2_illegal_op
,
2795 /* 0x72 */ x86emuOp2_illegal_op
,
2796 /* 0x73 */ x86emuOp2_illegal_op
,
2797 /* 0x74 */ x86emuOp2_illegal_op
,
2798 /* 0x75 */ x86emuOp2_illegal_op
,
2799 /* 0x76 */ x86emuOp2_illegal_op
,
2800 /* 0x77 */ x86emuOp2_illegal_op
,
2801 /* 0x78 */ x86emuOp2_illegal_op
,
2802 /* 0x79 */ x86emuOp2_illegal_op
,
2803 /* 0x7a */ x86emuOp2_illegal_op
,
2804 /* 0x7b */ x86emuOp2_illegal_op
,
2805 /* 0x7c */ x86emuOp2_illegal_op
,
2806 /* 0x7d */ x86emuOp2_illegal_op
,
2807 /* 0x7e */ x86emuOp2_illegal_op
,
2808 /* 0x7f */ x86emuOp2_illegal_op
,
2810 /* 0x80 */ x86emuOp2_long_jump
,
2811 /* 0x81 */ x86emuOp2_long_jump
,
2812 /* 0x82 */ x86emuOp2_long_jump
,
2813 /* 0x83 */ x86emuOp2_long_jump
,
2814 /* 0x84 */ x86emuOp2_long_jump
,
2815 /* 0x85 */ x86emuOp2_long_jump
,
2816 /* 0x86 */ x86emuOp2_long_jump
,
2817 /* 0x87 */ x86emuOp2_long_jump
,
2818 /* 0x88 */ x86emuOp2_long_jump
,
2819 /* 0x89 */ x86emuOp2_long_jump
,
2820 /* 0x8a */ x86emuOp2_long_jump
,
2821 /* 0x8b */ x86emuOp2_long_jump
,
2822 /* 0x8c */ x86emuOp2_long_jump
,
2823 /* 0x8d */ x86emuOp2_long_jump
,
2824 /* 0x8e */ x86emuOp2_long_jump
,
2825 /* 0x8f */ x86emuOp2_long_jump
,
2827 /* 0x90 */ x86emuOp2_set_byte
,
2828 /* 0x91 */ x86emuOp2_set_byte
,
2829 /* 0x92 */ x86emuOp2_set_byte
,
2830 /* 0x93 */ x86emuOp2_set_byte
,
2831 /* 0x94 */ x86emuOp2_set_byte
,
2832 /* 0x95 */ x86emuOp2_set_byte
,
2833 /* 0x96 */ x86emuOp2_set_byte
,
2834 /* 0x97 */ x86emuOp2_set_byte
,
2835 /* 0x98 */ x86emuOp2_set_byte
,
2836 /* 0x99 */ x86emuOp2_set_byte
,
2837 /* 0x9a */ x86emuOp2_set_byte
,
2838 /* 0x9b */ x86emuOp2_set_byte
,
2839 /* 0x9c */ x86emuOp2_set_byte
,
2840 /* 0x9d */ x86emuOp2_set_byte
,
2841 /* 0x9e */ x86emuOp2_set_byte
,
2842 /* 0x9f */ x86emuOp2_set_byte
,
2844 /* 0xa0 */ x86emuOp2_push_FS
,
2845 /* 0xa1 */ x86emuOp2_pop_FS
,
2846 /* 0xa2 */ x86emuOp2_cpuid
,
2847 /* 0xa3 */ x86emuOp2_bt_R
,
2848 /* 0xa4 */ x86emuOp2_shld_IMM
,
2849 /* 0xa5 */ x86emuOp2_shld_CL
,
2850 /* 0xa6 */ x86emuOp2_illegal_op
,
2851 /* 0xa7 */ x86emuOp2_illegal_op
,
2852 /* 0xa8 */ x86emuOp2_push_GS
,
2853 /* 0xa9 */ x86emuOp2_pop_GS
,
2854 /* 0xaa */ x86emuOp2_illegal_op
,
2855 /* 0xab */ x86emuOp2_bts_R
,
2856 /* 0xac */ x86emuOp2_shrd_IMM
,
2857 /* 0xad */ x86emuOp2_shrd_CL
,
2858 /* 0xae */ x86emuOp2_illegal_op
,
2859 /* 0xaf */ x86emuOp2_imul_R_RM
,
2861 /* 0xb0 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2862 /* 0xb1 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2863 /* 0xb2 */ x86emuOp2_lss_R_IMM
,
2864 /* 0xb3 */ x86emuOp2_btr_R
,
2865 /* 0xb4 */ x86emuOp2_lfs_R_IMM
,
2866 /* 0xb5 */ x86emuOp2_lgs_R_IMM
,
2867 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM
,
2868 /* 0xb7 */ x86emuOp2_movzx_word_R_RM
,
2869 /* 0xb8 */ x86emuOp2_illegal_op
,
2870 /* 0xb9 */ x86emuOp2_illegal_op
,
2871 /* 0xba */ x86emuOp2_btX_I
,
2872 /* 0xbb */ x86emuOp2_btc_R
,
2873 /* 0xbc */ x86emuOp2_bsf
,
2874 /* 0xbd */ x86emuOp2_bsr
,
2875 /* 0xbe */ x86emuOp2_movsx_byte_R_RM
,
2876 /* 0xbf */ x86emuOp2_movsx_word_R_RM
,
2878 /* 0xc0 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2879 /* 0xc1 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2880 /* 0xc2 */ x86emuOp2_illegal_op
,
2881 /* 0xc3 */ x86emuOp2_illegal_op
,
2882 /* 0xc4 */ x86emuOp2_illegal_op
,
2883 /* 0xc5 */ x86emuOp2_illegal_op
,
2884 /* 0xc6 */ x86emuOp2_illegal_op
,
2885 /* 0xc7 */ x86emuOp2_illegal_op
,
2886 /* 0xc8 */ x86emuOp2_bswap
,
2887 /* 0xc9 */ x86emuOp2_bswap
,
2888 /* 0xca */ x86emuOp2_bswap
,
2889 /* 0xcb */ x86emuOp2_bswap
,
2890 /* 0xcc */ x86emuOp2_bswap
,
2891 /* 0xcd */ x86emuOp2_bswap
,
2892 /* 0xce */ x86emuOp2_bswap
,
2893 /* 0xcf */ x86emuOp2_bswap
,
2895 /* 0xd0 */ x86emuOp2_illegal_op
,
2896 /* 0xd1 */ x86emuOp2_illegal_op
,
2897 /* 0xd2 */ x86emuOp2_illegal_op
,
2898 /* 0xd3 */ x86emuOp2_illegal_op
,
2899 /* 0xd4 */ x86emuOp2_illegal_op
,
2900 /* 0xd5 */ x86emuOp2_illegal_op
,
2901 /* 0xd6 */ x86emuOp2_illegal_op
,
2902 /* 0xd7 */ x86emuOp2_illegal_op
,
2903 /* 0xd8 */ x86emuOp2_illegal_op
,
2904 /* 0xd9 */ x86emuOp2_illegal_op
,
2905 /* 0xda */ x86emuOp2_illegal_op
,
2906 /* 0xdb */ x86emuOp2_illegal_op
,
2907 /* 0xdc */ x86emuOp2_illegal_op
,
2908 /* 0xdd */ x86emuOp2_illegal_op
,
2909 /* 0xde */ x86emuOp2_illegal_op
,
2910 /* 0xdf */ x86emuOp2_illegal_op
,
2912 /* 0xe0 */ x86emuOp2_illegal_op
,
2913 /* 0xe1 */ x86emuOp2_illegal_op
,
2914 /* 0xe2 */ x86emuOp2_illegal_op
,
2915 /* 0xe3 */ x86emuOp2_illegal_op
,
2916 /* 0xe4 */ x86emuOp2_illegal_op
,
2917 /* 0xe5 */ x86emuOp2_illegal_op
,
2918 /* 0xe6 */ x86emuOp2_illegal_op
,
2919 /* 0xe7 */ x86emuOp2_illegal_op
,
2920 /* 0xe8 */ x86emuOp2_illegal_op
,
2921 /* 0xe9 */ x86emuOp2_illegal_op
,
2922 /* 0xea */ x86emuOp2_illegal_op
,
2923 /* 0xeb */ x86emuOp2_illegal_op
,
2924 /* 0xec */ x86emuOp2_illegal_op
,
2925 /* 0xed */ x86emuOp2_illegal_op
,
2926 /* 0xee */ x86emuOp2_illegal_op
,
2927 /* 0xef */ x86emuOp2_illegal_op
,
2929 /* 0xf0 */ x86emuOp2_illegal_op
,
2930 /* 0xf1 */ x86emuOp2_illegal_op
,
2931 /* 0xf2 */ x86emuOp2_illegal_op
,
2932 /* 0xf3 */ x86emuOp2_illegal_op
,
2933 /* 0xf4 */ x86emuOp2_illegal_op
,
2934 /* 0xf5 */ x86emuOp2_illegal_op
,
2935 /* 0xf6 */ x86emuOp2_illegal_op
,
2936 /* 0xf7 */ x86emuOp2_illegal_op
,
2937 /* 0xf8 */ x86emuOp2_illegal_op
,
2938 /* 0xf9 */ x86emuOp2_illegal_op
,
2939 /* 0xfa */ x86emuOp2_illegal_op
,
2940 /* 0xfb */ x86emuOp2_illegal_op
,
2941 /* 0xfc */ x86emuOp2_illegal_op
,
2942 /* 0xfd */ x86emuOp2_illegal_op
,
2943 /* 0xfe */ x86emuOp2_illegal_op
,
2944 /* 0xff */ x86emuOp2_illegal_op
,