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"
43 /*----------------------------- Implementation ----------------------------*/
45 /****************************************************************************
47 op1 - Instruction op code
50 Handles illegal opcodes.
51 ****************************************************************************/
52 void x86emuOp2_illegal_op(
56 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
58 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
59 M
.x86
.R_CS
, M
.x86
.R_IP
-2,op2
);
64 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
66 /****************************************************************************
68 Handles opcode 0x0f,0x80-0x8F
69 ****************************************************************************/
70 void x86emuOp2_long_jump(u8 op2
)
76 /* conditional jump to word offset. */
81 cond
= ACCESS_FLAG(F_OF
);
85 cond
= !ACCESS_FLAG(F_OF
);
89 cond
= ACCESS_FLAG(F_CF
);
93 cond
= !ACCESS_FLAG(F_CF
);
97 cond
= ACCESS_FLAG(F_ZF
);
101 cond
= !ACCESS_FLAG(F_ZF
);
105 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
109 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
113 cond
= ACCESS_FLAG(F_SF
);
117 cond
= !ACCESS_FLAG(F_SF
);
121 cond
= ACCESS_FLAG(F_PF
);
125 cond
= !ACCESS_FLAG(F_PF
);
129 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
133 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
137 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
142 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
147 target
= (s16
) fetch_word_imm();
148 target
+= (s16
) M
.x86
.R_IP
;
149 DECODE_PRINTF2("%04x\n", target
);
152 M
.x86
.R_IP
= (u16
)target
;
153 DECODE_CLEAR_SEGOVR();
157 /****************************************************************************
159 Handles opcode 0x0f,0x90-0x9F
160 ****************************************************************************/
161 void x86emuOp2_set_byte(u8 op2
)
173 cond
= ACCESS_FLAG(F_OF
);
177 cond
= !ACCESS_FLAG(F_OF
);
181 cond
= ACCESS_FLAG(F_CF
);
185 cond
= !ACCESS_FLAG(F_CF
);
189 cond
= ACCESS_FLAG(F_ZF
);
193 cond
= !ACCESS_FLAG(F_ZF
);
197 cond
= ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
);
201 cond
= !(ACCESS_FLAG(F_CF
) || ACCESS_FLAG(F_ZF
));
205 cond
= ACCESS_FLAG(F_SF
);
209 cond
= !ACCESS_FLAG(F_SF
);
213 cond
= ACCESS_FLAG(F_PF
);
217 cond
= !ACCESS_FLAG(F_PF
);
221 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
225 cond
= xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
));
229 cond
= (xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
234 cond
= !(xorl(ACCESS_FLAG(F_SF
), ACCESS_FLAG(F_OF
)) ||
239 FETCH_DECODE_MODRM(mod
, rh
, rl
);
242 destoffset
= decode_rm00_address(rl
);
244 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
247 destoffset
= decode_rm01_address(rl
);
249 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
252 destoffset
= decode_rm10_address(rl
);
254 store_data_byte(destoffset
, cond
? 0x01 : 0x00);
256 case 3: /* register to register */
257 destreg
= DECODE_RM_BYTE_REGISTER(rl
);
259 *destreg
= cond
? 0x01 : 0x00;
262 DECODE_CLEAR_SEGOVR();
266 /****************************************************************************
268 Handles opcode 0x0f,0xa0
269 ****************************************************************************/
270 void x86emuOp2_push_FS(u8
X86EMU_UNUSED(op2
))
273 DECODE_PRINTF("PUSH\tFS\n");
275 push_word(M
.x86
.R_FS
);
276 DECODE_CLEAR_SEGOVR();
280 /****************************************************************************
282 Handles opcode 0x0f,0xa1
283 ****************************************************************************/
284 void x86emuOp2_pop_FS(u8
X86EMU_UNUSED(op2
))
287 DECODE_PRINTF("POP\tFS\n");
289 M
.x86
.R_FS
= pop_word();
290 DECODE_CLEAR_SEGOVR();
294 /****************************************************************************
296 Handles opcode 0x0f,0xa3
297 ****************************************************************************/
298 void x86emuOp2_bt_R(u8
X86EMU_UNUSED(op2
))
305 DECODE_PRINTF("BT\t");
306 FETCH_DECODE_MODRM(mod
, rh
, rl
);
309 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
313 srcoffset
= decode_rm00_address(rl
);
315 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
317 bit
= *shiftreg
& 0x1F;
318 disp
= (s16
)*shiftreg
>> 5;
319 srcval
= fetch_data_long(srcoffset
+disp
);
320 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
325 srcoffset
= decode_rm00_address(rl
);
327 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
329 bit
= *shiftreg
& 0xF;
330 disp
= (s16
)*shiftreg
>> 4;
331 srcval
= fetch_data_word(srcoffset
+disp
);
332 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
336 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
340 srcoffset
= decode_rm01_address(rl
);
342 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
344 bit
= *shiftreg
& 0x1F;
345 disp
= (s16
)*shiftreg
>> 5;
346 srcval
= fetch_data_long(srcoffset
+disp
);
347 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
352 srcoffset
= decode_rm01_address(rl
);
354 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
356 bit
= *shiftreg
& 0xF;
357 disp
= (s16
)*shiftreg
>> 4;
358 srcval
= fetch_data_word(srcoffset
+disp
);
359 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
363 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
367 srcoffset
= decode_rm10_address(rl
);
369 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
371 bit
= *shiftreg
& 0x1F;
372 disp
= (s16
)*shiftreg
>> 5;
373 srcval
= fetch_data_long(srcoffset
+disp
);
374 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
379 srcoffset
= decode_rm10_address(rl
);
381 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
383 bit
= *shiftreg
& 0xF;
384 disp
= (s16
)*shiftreg
>> 4;
385 srcval
= fetch_data_word(srcoffset
+disp
);
386 CONDITIONAL_SET_FLAG(srcval
& (0x1 << bit
),F_CF
);
389 case 3: /* register to register */
390 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
391 u32
*srcreg
,*shiftreg
;
393 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
395 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
397 bit
= *shiftreg
& 0x1F;
398 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
400 u16
*srcreg
,*shiftreg
;
402 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
404 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
406 bit
= *shiftreg
& 0xF;
407 CONDITIONAL_SET_FLAG(*srcreg
& (0x1 << bit
),F_CF
);
411 DECODE_CLEAR_SEGOVR();
415 /****************************************************************************
417 Handles opcode 0x0f,0xa4
418 ****************************************************************************/
419 void x86emuOp2_shld_IMM(u8
X86EMU_UNUSED(op2
))
426 DECODE_PRINTF("SHLD\t");
427 FETCH_DECODE_MODRM(mod
, rh
, rl
);
430 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
434 destoffset
= decode_rm00_address(rl
);
436 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
438 shift
= fetch_byte_imm();
439 DECODE_PRINTF2("%d\n", shift
);
441 destval
= fetch_data_long(destoffset
);
442 destval
= shld_long(destval
,*shiftreg
,shift
);
443 store_data_long(destoffset
, destval
);
448 destoffset
= decode_rm00_address(rl
);
450 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
452 shift
= fetch_byte_imm();
453 DECODE_PRINTF2("%d\n", shift
);
455 destval
= fetch_data_word(destoffset
);
456 destval
= shld_word(destval
,*shiftreg
,shift
);
457 store_data_word(destoffset
, destval
);
461 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
465 destoffset
= decode_rm01_address(rl
);
467 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
469 shift
= fetch_byte_imm();
470 DECODE_PRINTF2("%d\n", shift
);
472 destval
= fetch_data_long(destoffset
);
473 destval
= shld_long(destval
,*shiftreg
,shift
);
474 store_data_long(destoffset
, destval
);
479 destoffset
= decode_rm01_address(rl
);
481 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
483 shift
= fetch_byte_imm();
484 DECODE_PRINTF2("%d\n", shift
);
486 destval
= fetch_data_word(destoffset
);
487 destval
= shld_word(destval
,*shiftreg
,shift
);
488 store_data_word(destoffset
, destval
);
492 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
496 destoffset
= decode_rm10_address(rl
);
498 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
500 shift
= fetch_byte_imm();
501 DECODE_PRINTF2("%d\n", shift
);
503 destval
= fetch_data_long(destoffset
);
504 destval
= shld_long(destval
,*shiftreg
,shift
);
505 store_data_long(destoffset
, destval
);
510 destoffset
= decode_rm10_address(rl
);
512 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
514 shift
= fetch_byte_imm();
515 DECODE_PRINTF2("%d\n", shift
);
517 destval
= fetch_data_word(destoffset
);
518 destval
= shld_word(destval
,*shiftreg
,shift
);
519 store_data_word(destoffset
, destval
);
522 case 3: /* register to register */
523 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
524 u32
*destreg
,*shiftreg
;
526 destreg
= DECODE_RM_LONG_REGISTER(rl
);
528 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
530 shift
= fetch_byte_imm();
531 DECODE_PRINTF2("%d\n", shift
);
533 *destreg
= shld_long(*destreg
,*shiftreg
,shift
);
535 u16
*destreg
,*shiftreg
;
537 destreg
= DECODE_RM_WORD_REGISTER(rl
);
539 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
541 shift
= fetch_byte_imm();
542 DECODE_PRINTF2("%d\n", shift
);
544 *destreg
= shld_word(*destreg
,*shiftreg
,shift
);
548 DECODE_CLEAR_SEGOVR();
552 /****************************************************************************
554 Handles opcode 0x0f,0xa5
555 ****************************************************************************/
556 void x86emuOp2_shld_CL(u8
X86EMU_UNUSED(op2
))
562 DECODE_PRINTF("SHLD\t");
563 FETCH_DECODE_MODRM(mod
, rh
, rl
);
566 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
570 destoffset
= decode_rm00_address(rl
);
572 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
573 DECODE_PRINTF(",CL\n");
575 destval
= fetch_data_long(destoffset
);
576 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
577 store_data_long(destoffset
, destval
);
582 destoffset
= decode_rm00_address(rl
);
584 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
585 DECODE_PRINTF(",CL\n");
587 destval
= fetch_data_word(destoffset
);
588 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
589 store_data_word(destoffset
, destval
);
593 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
597 destoffset
= decode_rm01_address(rl
);
599 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
600 DECODE_PRINTF(",CL\n");
602 destval
= fetch_data_long(destoffset
);
603 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
604 store_data_long(destoffset
, destval
);
609 destoffset
= decode_rm01_address(rl
);
611 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
612 DECODE_PRINTF(",CL\n");
614 destval
= fetch_data_word(destoffset
);
615 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
616 store_data_word(destoffset
, destval
);
620 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
624 destoffset
= decode_rm10_address(rl
);
626 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
627 DECODE_PRINTF(",CL\n");
629 destval
= fetch_data_long(destoffset
);
630 destval
= shld_long(destval
,*shiftreg
,M
.x86
.R_CL
);
631 store_data_long(destoffset
, destval
);
636 destoffset
= decode_rm10_address(rl
);
638 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
639 DECODE_PRINTF(",CL\n");
641 destval
= fetch_data_word(destoffset
);
642 destval
= shld_word(destval
,*shiftreg
,M
.x86
.R_CL
);
643 store_data_word(destoffset
, destval
);
646 case 3: /* register to register */
647 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
648 u32
*destreg
,*shiftreg
;
650 destreg
= DECODE_RM_LONG_REGISTER(rl
);
652 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
653 DECODE_PRINTF(",CL\n");
655 *destreg
= shld_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
657 u16
*destreg
,*shiftreg
;
659 destreg
= DECODE_RM_WORD_REGISTER(rl
);
661 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
662 DECODE_PRINTF(",CL\n");
664 *destreg
= shld_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
668 DECODE_CLEAR_SEGOVR();
672 /****************************************************************************
674 Handles opcode 0x0f,0xa8
675 ****************************************************************************/
676 void x86emuOp2_push_GS(u8
X86EMU_UNUSED(op2
))
679 DECODE_PRINTF("PUSH\tGS\n");
681 push_word(M
.x86
.R_GS
);
682 DECODE_CLEAR_SEGOVR();
686 /****************************************************************************
688 Handles opcode 0x0f,0xa9
689 ****************************************************************************/
690 void x86emuOp2_pop_GS(u8
X86EMU_UNUSED(op2
))
693 DECODE_PRINTF("POP\tGS\n");
695 M
.x86
.R_GS
= pop_word();
696 DECODE_CLEAR_SEGOVR();
700 /****************************************************************************
702 Handles opcode 0x0f,0xaa
703 ****************************************************************************/
704 void x86emuOp2_bts_R(u8
X86EMU_UNUSED(op2
))
711 DECODE_PRINTF("BTS\t");
712 FETCH_DECODE_MODRM(mod
, rh
, rl
);
715 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
719 srcoffset
= decode_rm00_address(rl
);
721 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
723 bit
= *shiftreg
& 0x1F;
724 disp
= (s16
)*shiftreg
>> 5;
725 srcval
= fetch_data_long(srcoffset
+disp
);
727 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
728 store_data_long(srcoffset
+disp
, srcval
| mask
);
733 srcoffset
= decode_rm00_address(rl
);
735 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
737 bit
= *shiftreg
& 0xF;
738 disp
= (s16
)*shiftreg
>> 4;
739 srcval
= fetch_data_word(srcoffset
+disp
);
740 mask
= (u16
)(0x1 << bit
);
741 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
742 store_data_word(srcoffset
+disp
, srcval
| mask
);
746 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
750 srcoffset
= decode_rm01_address(rl
);
752 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
754 bit
= *shiftreg
& 0x1F;
755 disp
= (s16
)*shiftreg
>> 5;
756 srcval
= fetch_data_long(srcoffset
+disp
);
758 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
759 store_data_long(srcoffset
+disp
, srcval
| mask
);
764 srcoffset
= decode_rm01_address(rl
);
766 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
768 bit
= *shiftreg
& 0xF;
769 disp
= (s16
)*shiftreg
>> 4;
770 srcval
= fetch_data_word(srcoffset
+disp
);
771 mask
= (u16
)(0x1 << bit
);
772 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
773 store_data_word(srcoffset
+disp
, srcval
| mask
);
777 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
781 srcoffset
= decode_rm10_address(rl
);
783 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
785 bit
= *shiftreg
& 0x1F;
786 disp
= (s16
)*shiftreg
>> 5;
787 srcval
= fetch_data_long(srcoffset
+disp
);
789 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
790 store_data_long(srcoffset
+disp
, srcval
| mask
);
795 srcoffset
= decode_rm10_address(rl
);
797 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
799 bit
= *shiftreg
& 0xF;
800 disp
= (s16
)*shiftreg
>> 4;
801 srcval
= fetch_data_word(srcoffset
+disp
);
802 mask
= (u16
)(0x1 << bit
);
803 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
804 store_data_word(srcoffset
+disp
, srcval
| mask
);
807 case 3: /* register to register */
808 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
809 u32
*srcreg
,*shiftreg
;
812 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
814 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
816 bit
= *shiftreg
& 0x1F;
818 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
821 u16
*srcreg
,*shiftreg
;
824 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
826 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
828 bit
= *shiftreg
& 0xF;
829 mask
= (u16
)(0x1 << bit
);
830 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
835 DECODE_CLEAR_SEGOVR();
839 /****************************************************************************
841 Handles opcode 0x0f,0xac
842 ****************************************************************************/
843 void x86emuOp2_shrd_IMM(u8
X86EMU_UNUSED(op2
))
850 DECODE_PRINTF("SHLD\t");
851 FETCH_DECODE_MODRM(mod
, rh
, rl
);
854 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
858 destoffset
= decode_rm00_address(rl
);
860 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
862 shift
= fetch_byte_imm();
863 DECODE_PRINTF2("%d\n", shift
);
865 destval
= fetch_data_long(destoffset
);
866 destval
= shrd_long(destval
,*shiftreg
,shift
);
867 store_data_long(destoffset
, destval
);
872 destoffset
= decode_rm00_address(rl
);
874 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
876 shift
= fetch_byte_imm();
877 DECODE_PRINTF2("%d\n", shift
);
879 destval
= fetch_data_word(destoffset
);
880 destval
= shrd_word(destval
,*shiftreg
,shift
);
881 store_data_word(destoffset
, destval
);
885 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
889 destoffset
= decode_rm01_address(rl
);
891 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
893 shift
= fetch_byte_imm();
894 DECODE_PRINTF2("%d\n", shift
);
896 destval
= fetch_data_long(destoffset
);
897 destval
= shrd_long(destval
,*shiftreg
,shift
);
898 store_data_long(destoffset
, destval
);
903 destoffset
= decode_rm01_address(rl
);
905 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
907 shift
= fetch_byte_imm();
908 DECODE_PRINTF2("%d\n", shift
);
910 destval
= fetch_data_word(destoffset
);
911 destval
= shrd_word(destval
,*shiftreg
,shift
);
912 store_data_word(destoffset
, destval
);
916 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
920 destoffset
= decode_rm10_address(rl
);
922 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
924 shift
= fetch_byte_imm();
925 DECODE_PRINTF2("%d\n", shift
);
927 destval
= fetch_data_long(destoffset
);
928 destval
= shrd_long(destval
,*shiftreg
,shift
);
929 store_data_long(destoffset
, destval
);
934 destoffset
= decode_rm10_address(rl
);
936 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
938 shift
= fetch_byte_imm();
939 DECODE_PRINTF2("%d\n", shift
);
941 destval
= fetch_data_word(destoffset
);
942 destval
= shrd_word(destval
,*shiftreg
,shift
);
943 store_data_word(destoffset
, destval
);
946 case 3: /* register to register */
947 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
948 u32
*destreg
,*shiftreg
;
950 destreg
= DECODE_RM_LONG_REGISTER(rl
);
952 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
954 shift
= fetch_byte_imm();
955 DECODE_PRINTF2("%d\n", shift
);
957 *destreg
= shrd_long(*destreg
,*shiftreg
,shift
);
959 u16
*destreg
,*shiftreg
;
961 destreg
= DECODE_RM_WORD_REGISTER(rl
);
963 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
965 shift
= fetch_byte_imm();
966 DECODE_PRINTF2("%d\n", shift
);
968 *destreg
= shrd_word(*destreg
,*shiftreg
,shift
);
972 DECODE_CLEAR_SEGOVR();
976 /****************************************************************************
978 Handles opcode 0x0f,0xad
979 ****************************************************************************/
980 void x86emuOp2_shrd_CL(u8
X86EMU_UNUSED(op2
))
986 DECODE_PRINTF("SHLD\t");
987 FETCH_DECODE_MODRM(mod
, rh
, rl
);
990 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
994 destoffset
= decode_rm00_address(rl
);
996 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
997 DECODE_PRINTF(",CL\n");
999 destval
= fetch_data_long(destoffset
);
1000 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1001 store_data_long(destoffset
, destval
);
1006 destoffset
= decode_rm00_address(rl
);
1008 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1009 DECODE_PRINTF(",CL\n");
1011 destval
= fetch_data_word(destoffset
);
1012 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1013 store_data_word(destoffset
, destval
);
1017 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1021 destoffset
= decode_rm01_address(rl
);
1023 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1024 DECODE_PRINTF(",CL\n");
1026 destval
= fetch_data_long(destoffset
);
1027 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1028 store_data_long(destoffset
, destval
);
1033 destoffset
= decode_rm01_address(rl
);
1035 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1036 DECODE_PRINTF(",CL\n");
1038 destval
= fetch_data_word(destoffset
);
1039 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1040 store_data_word(destoffset
, destval
);
1044 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1048 destoffset
= decode_rm10_address(rl
);
1050 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1051 DECODE_PRINTF(",CL\n");
1053 destval
= fetch_data_long(destoffset
);
1054 destval
= shrd_long(destval
,*shiftreg
,M
.x86
.R_CL
);
1055 store_data_long(destoffset
, destval
);
1060 destoffset
= decode_rm10_address(rl
);
1062 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1063 DECODE_PRINTF(",CL\n");
1065 destval
= fetch_data_word(destoffset
);
1066 destval
= shrd_word(destval
,*shiftreg
,M
.x86
.R_CL
);
1067 store_data_word(destoffset
, destval
);
1070 case 3: /* register to register */
1071 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1072 u32
*destreg
,*shiftreg
;
1074 destreg
= DECODE_RM_LONG_REGISTER(rl
);
1076 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1077 DECODE_PRINTF(",CL\n");
1079 *destreg
= shrd_long(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1081 u16
*destreg
,*shiftreg
;
1083 destreg
= DECODE_RM_WORD_REGISTER(rl
);
1085 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1086 DECODE_PRINTF(",CL\n");
1088 *destreg
= shrd_word(*destreg
,*shiftreg
,M
.x86
.R_CL
);
1092 DECODE_CLEAR_SEGOVR();
1096 /****************************************************************************
1098 Handles opcode 0x0f,0xaf
1099 ****************************************************************************/
1100 void x86emuOp2_imul_R_RM(u8
X86EMU_UNUSED(op2
))
1106 DECODE_PRINTF("IMUL\t");
1107 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1110 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1115 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1117 srcoffset
= decode_rm00_address(rl
);
1118 srcval
= fetch_data_long(srcoffset
);
1120 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1128 *destreg
= (u32
)res_lo
;
1134 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1136 srcoffset
= decode_rm00_address(rl
);
1137 srcval
= fetch_data_word(srcoffset
);
1139 res
= (s16
)*destreg
* (s16
)srcval
;
1147 *destreg
= (u16
)res
;
1151 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1156 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1158 srcoffset
= decode_rm01_address(rl
);
1159 srcval
= fetch_data_long(srcoffset
);
1161 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1169 *destreg
= (u32
)res_lo
;
1175 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1177 srcoffset
= decode_rm01_address(rl
);
1178 srcval
= fetch_data_word(srcoffset
);
1180 res
= (s16
)*destreg
* (s16
)srcval
;
1188 *destreg
= (u16
)res
;
1192 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1197 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1199 srcoffset
= decode_rm10_address(rl
);
1200 srcval
= fetch_data_long(srcoffset
);
1202 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)srcval
);
1210 *destreg
= (u32
)res_lo
;
1216 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1218 srcoffset
= decode_rm10_address(rl
);
1219 srcval
= fetch_data_word(srcoffset
);
1221 res
= (s16
)*destreg
* (s16
)srcval
;
1229 *destreg
= (u16
)res
;
1232 case 3: /* register to register */
1233 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1234 u32
*destreg
,*srcreg
;
1237 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1239 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1241 imul_long_direct(&res_lo
,&res_hi
,(s32
)*destreg
,(s32
)*srcreg
);
1249 *destreg
= (u32
)res_lo
;
1251 u16
*destreg
,*srcreg
;
1254 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1256 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1257 res
= (s16
)*destreg
* (s16
)*srcreg
;
1265 *destreg
= (u16
)res
;
1269 DECODE_CLEAR_SEGOVR();
1273 /****************************************************************************
1275 Handles opcode 0x0f,0xb2
1276 ****************************************************************************/
1277 void x86emuOp2_lss_R_IMM(u8
X86EMU_UNUSED(op2
))
1284 DECODE_PRINTF("LSS\t");
1285 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1288 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1290 srcoffset
= decode_rm00_address(rl
);
1291 DECODE_PRINTF("\n");
1293 *dstreg
= fetch_data_word(srcoffset
);
1294 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1297 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1299 srcoffset
= decode_rm01_address(rl
);
1300 DECODE_PRINTF("\n");
1302 *dstreg
= fetch_data_word(srcoffset
);
1303 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1306 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1308 srcoffset
= decode_rm10_address(rl
);
1309 DECODE_PRINTF("\n");
1311 *dstreg
= fetch_data_word(srcoffset
);
1312 M
.x86
.R_SS
= fetch_data_word(srcoffset
+ 2);
1314 case 3: /* register to register */
1318 DECODE_CLEAR_SEGOVR();
1322 /****************************************************************************
1324 Handles opcode 0x0f,0xb3
1325 ****************************************************************************/
1326 void x86emuOp2_btr_R(u8
X86EMU_UNUSED(op2
))
1333 DECODE_PRINTF("BTR\t");
1334 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1337 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1341 srcoffset
= decode_rm00_address(rl
);
1343 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1345 bit
= *shiftreg
& 0x1F;
1346 disp
= (s16
)*shiftreg
>> 5;
1347 srcval
= fetch_data_long(srcoffset
+disp
);
1348 mask
= (0x1 << bit
);
1349 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1350 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1355 srcoffset
= decode_rm00_address(rl
);
1357 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1359 bit
= *shiftreg
& 0xF;
1360 disp
= (s16
)*shiftreg
>> 4;
1361 srcval
= fetch_data_word(srcoffset
+disp
);
1362 mask
= (u16
)(0x1 << bit
);
1363 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1364 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1368 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1372 srcoffset
= decode_rm01_address(rl
);
1374 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1376 bit
= *shiftreg
& 0x1F;
1377 disp
= (s16
)*shiftreg
>> 5;
1378 srcval
= fetch_data_long(srcoffset
+disp
);
1379 mask
= (0x1 << bit
);
1380 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1381 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1386 srcoffset
= decode_rm01_address(rl
);
1388 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1390 bit
= *shiftreg
& 0xF;
1391 disp
= (s16
)*shiftreg
>> 4;
1392 srcval
= fetch_data_word(srcoffset
+disp
);
1393 mask
= (u16
)(0x1 << bit
);
1394 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1395 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1399 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1403 srcoffset
= decode_rm10_address(rl
);
1405 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1407 bit
= *shiftreg
& 0x1F;
1408 disp
= (s16
)*shiftreg
>> 5;
1409 srcval
= fetch_data_long(srcoffset
+disp
);
1410 mask
= (0x1 << bit
);
1411 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1412 store_data_long(srcoffset
+disp
, srcval
& ~mask
);
1417 srcoffset
= decode_rm10_address(rl
);
1419 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1421 bit
= *shiftreg
& 0xF;
1422 disp
= (s16
)*shiftreg
>> 4;
1423 srcval
= fetch_data_word(srcoffset
+disp
);
1424 mask
= (u16
)(0x1 << bit
);
1425 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1426 store_data_word(srcoffset
+disp
, (u16
)(srcval
& ~mask
));
1429 case 3: /* register to register */
1430 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1431 u32
*srcreg
,*shiftreg
;
1434 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1436 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
1438 bit
= *shiftreg
& 0x1F;
1439 mask
= (0x1 << bit
);
1440 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1443 u16
*srcreg
,*shiftreg
;
1446 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1448 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
1450 bit
= *shiftreg
& 0xF;
1451 mask
= (u16
)(0x1 << bit
);
1452 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1457 DECODE_CLEAR_SEGOVR();
1461 /****************************************************************************
1463 Handles opcode 0x0f,0xb4
1464 ****************************************************************************/
1465 void x86emuOp2_lfs_R_IMM(u8
X86EMU_UNUSED(op2
))
1472 DECODE_PRINTF("LFS\t");
1473 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1476 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1478 srcoffset
= decode_rm00_address(rl
);
1479 DECODE_PRINTF("\n");
1481 *dstreg
= fetch_data_word(srcoffset
);
1482 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1485 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1487 srcoffset
= decode_rm01_address(rl
);
1488 DECODE_PRINTF("\n");
1490 *dstreg
= fetch_data_word(srcoffset
);
1491 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1494 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1496 srcoffset
= decode_rm10_address(rl
);
1497 DECODE_PRINTF("\n");
1499 *dstreg
= fetch_data_word(srcoffset
);
1500 M
.x86
.R_FS
= fetch_data_word(srcoffset
+ 2);
1502 case 3: /* register to register */
1506 DECODE_CLEAR_SEGOVR();
1510 /****************************************************************************
1512 Handles opcode 0x0f,0xb5
1513 ****************************************************************************/
1514 void x86emuOp2_lgs_R_IMM(u8
X86EMU_UNUSED(op2
))
1521 DECODE_PRINTF("LGS\t");
1522 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1525 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1527 srcoffset
= decode_rm00_address(rl
);
1528 DECODE_PRINTF("\n");
1530 *dstreg
= fetch_data_word(srcoffset
);
1531 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1534 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1536 srcoffset
= decode_rm01_address(rl
);
1537 DECODE_PRINTF("\n");
1539 *dstreg
= fetch_data_word(srcoffset
);
1540 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1543 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
1545 srcoffset
= decode_rm10_address(rl
);
1546 DECODE_PRINTF("\n");
1548 *dstreg
= fetch_data_word(srcoffset
);
1549 M
.x86
.R_GS
= fetch_data_word(srcoffset
+ 2);
1551 case 3: /* register to register */
1555 DECODE_CLEAR_SEGOVR();
1559 /****************************************************************************
1561 Handles opcode 0x0f,0xb6
1562 ****************************************************************************/
1563 void x86emuOp2_movzx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
1569 DECODE_PRINTF("MOVZX\t");
1570 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1573 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1577 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1579 srcoffset
= decode_rm00_address(rl
);
1580 srcval
= fetch_data_byte(srcoffset
);
1581 DECODE_PRINTF("\n");
1588 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1590 srcoffset
= decode_rm00_address(rl
);
1591 srcval
= fetch_data_byte(srcoffset
);
1592 DECODE_PRINTF("\n");
1598 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1602 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1604 srcoffset
= decode_rm01_address(rl
);
1605 srcval
= fetch_data_byte(srcoffset
);
1606 DECODE_PRINTF("\n");
1613 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1615 srcoffset
= decode_rm01_address(rl
);
1616 srcval
= fetch_data_byte(srcoffset
);
1617 DECODE_PRINTF("\n");
1623 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1627 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1629 srcoffset
= decode_rm10_address(rl
);
1630 srcval
= fetch_data_byte(srcoffset
);
1631 DECODE_PRINTF("\n");
1638 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1640 srcoffset
= decode_rm10_address(rl
);
1641 srcval
= fetch_data_byte(srcoffset
);
1642 DECODE_PRINTF("\n");
1647 case 3: /* register to register */
1648 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1652 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1654 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1655 DECODE_PRINTF("\n");
1662 destreg
= DECODE_RM_WORD_REGISTER(rh
);
1664 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
1665 DECODE_PRINTF("\n");
1671 DECODE_CLEAR_SEGOVR();
1675 /****************************************************************************
1677 Handles opcode 0x0f,0xb7
1678 ****************************************************************************/
1679 void x86emuOp2_movzx_word_R_RM(u8
X86EMU_UNUSED(op2
))
1688 DECODE_PRINTF("MOVZX\t");
1689 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1692 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1694 srcoffset
= decode_rm00_address(rl
);
1695 srcval
= fetch_data_word(srcoffset
);
1696 DECODE_PRINTF("\n");
1701 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1703 srcoffset
= decode_rm01_address(rl
);
1704 srcval
= fetch_data_word(srcoffset
);
1705 DECODE_PRINTF("\n");
1710 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1712 srcoffset
= decode_rm10_address(rl
);
1713 srcval
= fetch_data_word(srcoffset
);
1714 DECODE_PRINTF("\n");
1718 case 3: /* register to register */
1719 destreg
= DECODE_RM_LONG_REGISTER(rh
);
1721 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1722 DECODE_PRINTF("\n");
1727 DECODE_CLEAR_SEGOVR();
1731 /****************************************************************************
1733 Handles opcode 0x0f,0xba
1734 ****************************************************************************/
1735 void x86emuOp2_btX_I(u8
X86EMU_UNUSED(op2
))
1742 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1745 DECODE_PRINTF("BT\t");
1748 DECODE_PRINTF("BTS\t");
1751 DECODE_PRINTF("BTR\t");
1754 DECODE_PRINTF("BTC\t");
1757 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1759 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1760 M
.x86
.R_CS
, M
.x86
.R_IP
-3,op2
, (mod
<<6)|(rh
<<3)|rl
);
1765 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1769 srcoffset
= decode_rm00_address(rl
);
1771 shift
= fetch_byte_imm();
1774 srcval
= fetch_data_long(srcoffset
);
1775 mask
= (0x1 << bit
);
1776 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1779 store_data_long(srcoffset
, srcval
| mask
);
1782 store_data_long(srcoffset
, srcval
& ~mask
);
1785 store_data_long(srcoffset
, srcval
^ mask
);
1794 srcoffset
= decode_rm00_address(rl
);
1796 shift
= fetch_byte_imm();
1799 srcval
= fetch_data_word(srcoffset
);
1800 mask
= (0x1 << bit
);
1801 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1804 store_data_word(srcoffset
, srcval
| mask
);
1807 store_data_word(srcoffset
, srcval
& ~mask
);
1810 store_data_word(srcoffset
, srcval
^ mask
);
1818 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1822 srcoffset
= decode_rm01_address(rl
);
1824 shift
= fetch_byte_imm();
1827 srcval
= fetch_data_long(srcoffset
);
1828 mask
= (0x1 << bit
);
1829 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1832 store_data_long(srcoffset
, srcval
| mask
);
1835 store_data_long(srcoffset
, srcval
& ~mask
);
1838 store_data_long(srcoffset
, srcval
^ mask
);
1847 srcoffset
= decode_rm01_address(rl
);
1849 shift
= fetch_byte_imm();
1852 srcval
= fetch_data_word(srcoffset
);
1853 mask
= (0x1 << bit
);
1854 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1857 store_data_word(srcoffset
, srcval
| mask
);
1860 store_data_word(srcoffset
, srcval
& ~mask
);
1863 store_data_word(srcoffset
, srcval
^ mask
);
1871 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1875 srcoffset
= decode_rm10_address(rl
);
1877 shift
= fetch_byte_imm();
1880 srcval
= fetch_data_long(srcoffset
);
1881 mask
= (0x1 << bit
);
1882 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1885 store_data_long(srcoffset
, srcval
| mask
);
1888 store_data_long(srcoffset
, srcval
& ~mask
);
1891 store_data_long(srcoffset
, srcval
^ mask
);
1900 srcoffset
= decode_rm10_address(rl
);
1902 shift
= fetch_byte_imm();
1905 srcval
= fetch_data_word(srcoffset
);
1906 mask
= (0x1 << bit
);
1907 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
1910 store_data_word(srcoffset
, srcval
| mask
);
1913 store_data_word(srcoffset
, srcval
& ~mask
);
1916 store_data_word(srcoffset
, srcval
^ mask
);
1923 case 3: /* register to register */
1924 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
1929 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
1931 shift
= fetch_byte_imm();
1934 mask
= (0x1 << bit
);
1935 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1954 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
1956 shift
= fetch_byte_imm();
1959 mask
= (0x1 << bit
);
1960 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
1977 DECODE_CLEAR_SEGOVR();
1981 /****************************************************************************
1983 Handles opcode 0x0f,0xbb
1984 ****************************************************************************/
1985 void x86emuOp2_btc_R(u8
X86EMU_UNUSED(op2
))
1992 DECODE_PRINTF("BTC\t");
1993 FETCH_DECODE_MODRM(mod
, rh
, rl
);
1996 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2000 srcoffset
= decode_rm00_address(rl
);
2002 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2004 bit
= *shiftreg
& 0x1F;
2005 disp
= (s16
)*shiftreg
>> 5;
2006 srcval
= fetch_data_long(srcoffset
+disp
);
2007 mask
= (0x1 << bit
);
2008 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2009 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2014 srcoffset
= decode_rm00_address(rl
);
2016 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2018 bit
= *shiftreg
& 0xF;
2019 disp
= (s16
)*shiftreg
>> 4;
2020 srcval
= fetch_data_word(srcoffset
+disp
);
2021 mask
= (u16
)(0x1 << bit
);
2022 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2023 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2027 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2031 srcoffset
= decode_rm01_address(rl
);
2033 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2035 bit
= *shiftreg
& 0x1F;
2036 disp
= (s16
)*shiftreg
>> 5;
2037 srcval
= fetch_data_long(srcoffset
+disp
);
2038 mask
= (0x1 << bit
);
2039 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2040 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2045 srcoffset
= decode_rm01_address(rl
);
2047 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2049 bit
= *shiftreg
& 0xF;
2050 disp
= (s16
)*shiftreg
>> 4;
2051 srcval
= fetch_data_word(srcoffset
+disp
);
2052 mask
= (u16
)(0x1 << bit
);
2053 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2054 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2058 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2062 srcoffset
= decode_rm10_address(rl
);
2064 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2066 bit
= *shiftreg
& 0x1F;
2067 disp
= (s16
)*shiftreg
>> 5;
2068 srcval
= fetch_data_long(srcoffset
+disp
);
2069 mask
= (0x1 << bit
);
2070 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2071 store_data_long(srcoffset
+disp
, srcval
^ mask
);
2076 srcoffset
= decode_rm10_address(rl
);
2078 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2080 bit
= *shiftreg
& 0xF;
2081 disp
= (s16
)*shiftreg
>> 4;
2082 srcval
= fetch_data_word(srcoffset
+disp
);
2083 mask
= (u16
)(0x1 << bit
);
2084 CONDITIONAL_SET_FLAG(srcval
& mask
,F_CF
);
2085 store_data_word(srcoffset
+disp
, (u16
)(srcval
^ mask
));
2088 case 3: /* register to register */
2089 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2090 u32
*srcreg
,*shiftreg
;
2093 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2095 shiftreg
= DECODE_RM_LONG_REGISTER(rh
);
2097 bit
= *shiftreg
& 0x1F;
2098 mask
= (0x1 << bit
);
2099 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2102 u16
*srcreg
,*shiftreg
;
2105 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2107 shiftreg
= DECODE_RM_WORD_REGISTER(rh
);
2109 bit
= *shiftreg
& 0xF;
2110 mask
= (u16
)(0x1 << bit
);
2111 CONDITIONAL_SET_FLAG(*srcreg
& mask
,F_CF
);
2116 DECODE_CLEAR_SEGOVR();
2120 /****************************************************************************
2122 Handles opcode 0x0f,0xbc
2123 ****************************************************************************/
2124 void x86emuOp2_bsf(u8
X86EMU_UNUSED(op2
))
2130 DECODE_PRINTF("BSF\n");
2131 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2134 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2135 u32 srcval
, *dstreg
;
2137 srcoffset
= decode_rm00_address(rl
);
2139 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2141 srcval
= fetch_data_long(srcoffset
);
2142 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2143 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2144 if ((srcval
>> *dstreg
) & 1) break;
2146 u16 srcval
, *dstreg
;
2148 srcoffset
= decode_rm00_address(rl
);
2150 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2152 srcval
= fetch_data_word(srcoffset
);
2153 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2154 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2155 if ((srcval
>> *dstreg
) & 1) break;
2159 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2160 u32 srcval
, *dstreg
;
2162 srcoffset
= decode_rm01_address(rl
);
2164 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2166 srcval
= fetch_data_long(srcoffset
);
2167 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2168 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2169 if ((srcval
>> *dstreg
) & 1) break;
2171 u16 srcval
, *dstreg
;
2173 srcoffset
= decode_rm01_address(rl
);
2175 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2177 srcval
= fetch_data_word(srcoffset
);
2178 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2179 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2180 if ((srcval
>> *dstreg
) & 1) break;
2184 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2185 u32 srcval
, *dstreg
;
2187 srcoffset
= decode_rm10_address(rl
);
2189 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2191 srcval
= fetch_data_long(srcoffset
);
2192 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2193 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2194 if ((srcval
>> *dstreg
) & 1) break;
2196 u16 srcval
, *dstreg
;
2198 srcoffset
= decode_rm10_address(rl
);
2200 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2202 srcval
= fetch_data_word(srcoffset
);
2203 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2204 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2205 if ((srcval
>> *dstreg
) & 1) break;
2208 case 3: /* register to register */
2209 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2210 u32
*srcreg
, *dstreg
;
2212 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2214 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2216 CONDITIONAL_SET_FLAG(*srcreg
== 0, F_ZF
);
2217 for(*dstreg
= 0; *dstreg
< 32; (*dstreg
)++)
2218 if ((*srcreg
>> *dstreg
) & 1) break;
2220 u16
*srcreg
, *dstreg
;
2222 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2224 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2226 CONDITIONAL_SET_FLAG(*srcreg
== 0, F_ZF
);
2227 for(*dstreg
= 0; *dstreg
< 16; (*dstreg
)++)
2228 if ((*srcreg
>> *dstreg
) & 1) break;
2232 DECODE_CLEAR_SEGOVR();
2236 /****************************************************************************
2238 Handles opcode 0x0f,0xbd
2239 ****************************************************************************/
2240 void x86emuOp2_bsr(u8
X86EMU_UNUSED(op2
))
2246 DECODE_PRINTF("BSF\n");
2247 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2250 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2251 u32 srcval
, *dstreg
;
2253 srcoffset
= decode_rm00_address(rl
);
2255 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2257 srcval
= fetch_data_long(srcoffset
);
2258 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2259 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2260 if ((srcval
>> *dstreg
) & 1) break;
2262 u16 srcval
, *dstreg
;
2264 srcoffset
= decode_rm00_address(rl
);
2266 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2268 srcval
= fetch_data_word(srcoffset
);
2269 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2270 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2271 if ((srcval
>> *dstreg
) & 1) break;
2275 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2276 u32 srcval
, *dstreg
;
2278 srcoffset
= decode_rm01_address(rl
);
2280 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2282 srcval
= fetch_data_long(srcoffset
);
2283 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2284 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2285 if ((srcval
>> *dstreg
) & 1) break;
2287 u16 srcval
, *dstreg
;
2289 srcoffset
= decode_rm01_address(rl
);
2291 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2293 srcval
= fetch_data_word(srcoffset
);
2294 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2295 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2296 if ((srcval
>> *dstreg
) & 1) break;
2300 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2301 u32 srcval
, *dstreg
;
2303 srcoffset
= decode_rm10_address(rl
);
2305 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2307 srcval
= fetch_data_long(srcoffset
);
2308 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2309 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2310 if ((srcval
>> *dstreg
) & 1) break;
2312 u16 srcval
, *dstreg
;
2314 srcoffset
= decode_rm10_address(rl
);
2316 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2318 srcval
= fetch_data_word(srcoffset
);
2319 CONDITIONAL_SET_FLAG(srcval
== 0, F_ZF
);
2320 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2321 if ((srcval
>> *dstreg
) & 1) break;
2324 case 3: /* register to register */
2325 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2326 u32
*srcreg
, *dstreg
;
2328 srcreg
= DECODE_RM_LONG_REGISTER(rl
);
2330 dstreg
= DECODE_RM_LONG_REGISTER(rh
);
2332 CONDITIONAL_SET_FLAG(*srcreg
== 0, F_ZF
);
2333 for(*dstreg
= 31; *dstreg
> 0; (*dstreg
)--)
2334 if ((*srcreg
>> *dstreg
) & 1) break;
2336 u16
*srcreg
, *dstreg
;
2338 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2340 dstreg
= DECODE_RM_WORD_REGISTER(rh
);
2342 CONDITIONAL_SET_FLAG(*srcreg
== 0, F_ZF
);
2343 for(*dstreg
= 15; *dstreg
> 0; (*dstreg
)--)
2344 if ((*srcreg
>> *dstreg
) & 1) break;
2348 DECODE_CLEAR_SEGOVR();
2352 /****************************************************************************
2354 Handles opcode 0x0f,0xbe
2355 ****************************************************************************/
2356 void x86emuOp2_movsx_byte_R_RM(u8
X86EMU_UNUSED(op2
))
2362 DECODE_PRINTF("MOVSX\t");
2363 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2366 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2370 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2372 srcoffset
= decode_rm00_address(rl
);
2373 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2374 DECODE_PRINTF("\n");
2381 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2383 srcoffset
= decode_rm00_address(rl
);
2384 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2385 DECODE_PRINTF("\n");
2391 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2395 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2397 srcoffset
= decode_rm01_address(rl
);
2398 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2399 DECODE_PRINTF("\n");
2406 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2408 srcoffset
= decode_rm01_address(rl
);
2409 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2410 DECODE_PRINTF("\n");
2416 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2420 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2422 srcoffset
= decode_rm10_address(rl
);
2423 srcval
= (s32
)((s8
)fetch_data_byte(srcoffset
));
2424 DECODE_PRINTF("\n");
2431 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2433 srcoffset
= decode_rm10_address(rl
);
2434 srcval
= (s16
)((s8
)fetch_data_byte(srcoffset
));
2435 DECODE_PRINTF("\n");
2440 case 3: /* register to register */
2441 if (M
.x86
.mode
& SYSMODE_PREFIX_DATA
) {
2445 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2447 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2448 DECODE_PRINTF("\n");
2450 *destreg
= (s32
)((s8
)*srcreg
);
2455 destreg
= DECODE_RM_WORD_REGISTER(rh
);
2457 srcreg
= DECODE_RM_BYTE_REGISTER(rl
);
2458 DECODE_PRINTF("\n");
2460 *destreg
= (s16
)((s8
)*srcreg
);
2464 DECODE_CLEAR_SEGOVR();
2468 /****************************************************************************
2470 Handles opcode 0x0f,0xbf
2471 ****************************************************************************/
2472 void x86emuOp2_movsx_word_R_RM(u8
X86EMU_UNUSED(op2
))
2481 DECODE_PRINTF("MOVSX\t");
2482 FETCH_DECODE_MODRM(mod
, rh
, rl
);
2485 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2487 srcoffset
= decode_rm00_address(rl
);
2488 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2489 DECODE_PRINTF("\n");
2494 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2496 srcoffset
= decode_rm01_address(rl
);
2497 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2498 DECODE_PRINTF("\n");
2503 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2505 srcoffset
= decode_rm10_address(rl
);
2506 srcval
= (s32
)((s16
)fetch_data_word(srcoffset
));
2507 DECODE_PRINTF("\n");
2511 case 3: /* register to register */
2512 destreg
= DECODE_RM_LONG_REGISTER(rh
);
2514 srcreg
= DECODE_RM_WORD_REGISTER(rl
);
2515 DECODE_PRINTF("\n");
2517 *destreg
= (s32
)((s16
)*srcreg
);
2520 DECODE_CLEAR_SEGOVR();
2524 /***************************************************************************
2525 * Double byte operation code table:
2526 **************************************************************************/
2527 void (*x86emu_optab2
[256])(u8
) =
2529 /* 0x00 */ x86emuOp2_illegal_op
, /* Group F (ring 0 PM) */
2530 /* 0x01 */ x86emuOp2_illegal_op
, /* Group G (ring 0 PM) */
2531 /* 0x02 */ x86emuOp2_illegal_op
, /* lar (ring 0 PM) */
2532 /* 0x03 */ x86emuOp2_illegal_op
, /* lsl (ring 0 PM) */
2533 /* 0x04 */ x86emuOp2_illegal_op
,
2534 /* 0x05 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2535 /* 0x06 */ x86emuOp2_illegal_op
, /* clts (ring 0 PM) */
2536 /* 0x07 */ x86emuOp2_illegal_op
, /* loadall (undocumented) */
2537 /* 0x08 */ x86emuOp2_illegal_op
, /* invd (ring 0 PM) */
2538 /* 0x09 */ x86emuOp2_illegal_op
, /* wbinvd (ring 0 PM) */
2539 /* 0x0a */ x86emuOp2_illegal_op
,
2540 /* 0x0b */ x86emuOp2_illegal_op
,
2541 /* 0x0c */ x86emuOp2_illegal_op
,
2542 /* 0x0d */ x86emuOp2_illegal_op
,
2543 /* 0x0e */ x86emuOp2_illegal_op
,
2544 /* 0x0f */ x86emuOp2_illegal_op
,
2546 /* 0x10 */ x86emuOp2_illegal_op
,
2547 /* 0x11 */ x86emuOp2_illegal_op
,
2548 /* 0x12 */ x86emuOp2_illegal_op
,
2549 /* 0x13 */ x86emuOp2_illegal_op
,
2550 /* 0x14 */ x86emuOp2_illegal_op
,
2551 /* 0x15 */ x86emuOp2_illegal_op
,
2552 /* 0x16 */ x86emuOp2_illegal_op
,
2553 /* 0x17 */ x86emuOp2_illegal_op
,
2554 /* 0x18 */ x86emuOp2_illegal_op
,
2555 /* 0x19 */ x86emuOp2_illegal_op
,
2556 /* 0x1a */ x86emuOp2_illegal_op
,
2557 /* 0x1b */ x86emuOp2_illegal_op
,
2558 /* 0x1c */ x86emuOp2_illegal_op
,
2559 /* 0x1d */ x86emuOp2_illegal_op
,
2560 /* 0x1e */ x86emuOp2_illegal_op
,
2561 /* 0x1f */ x86emuOp2_illegal_op
,
2563 /* 0x20 */ x86emuOp2_illegal_op
, /* mov reg32,creg (ring 0 PM) */
2564 /* 0x21 */ x86emuOp2_illegal_op
, /* mov reg32,dreg (ring 0 PM) */
2565 /* 0x22 */ x86emuOp2_illegal_op
, /* mov creg,reg32 (ring 0 PM) */
2566 /* 0x23 */ x86emuOp2_illegal_op
, /* mov dreg,reg32 (ring 0 PM) */
2567 /* 0x24 */ x86emuOp2_illegal_op
, /* mov reg32,treg (ring 0 PM) */
2568 /* 0x25 */ x86emuOp2_illegal_op
,
2569 /* 0x26 */ x86emuOp2_illegal_op
, /* mov treg,reg32 (ring 0 PM) */
2570 /* 0x27 */ x86emuOp2_illegal_op
,
2571 /* 0x28 */ x86emuOp2_illegal_op
,
2572 /* 0x29 */ x86emuOp2_illegal_op
,
2573 /* 0x2a */ x86emuOp2_illegal_op
,
2574 /* 0x2b */ x86emuOp2_illegal_op
,
2575 /* 0x2c */ x86emuOp2_illegal_op
,
2576 /* 0x2d */ x86emuOp2_illegal_op
,
2577 /* 0x2e */ x86emuOp2_illegal_op
,
2578 /* 0x2f */ x86emuOp2_illegal_op
,
2580 /* 0x30 */ x86emuOp2_illegal_op
,
2581 /* 0x31 */ x86emuOp2_illegal_op
,
2582 /* 0x32 */ x86emuOp2_illegal_op
,
2583 /* 0x33 */ x86emuOp2_illegal_op
,
2584 /* 0x34 */ x86emuOp2_illegal_op
,
2585 /* 0x35 */ x86emuOp2_illegal_op
,
2586 /* 0x36 */ x86emuOp2_illegal_op
,
2587 /* 0x37 */ x86emuOp2_illegal_op
,
2588 /* 0x38 */ x86emuOp2_illegal_op
,
2589 /* 0x39 */ x86emuOp2_illegal_op
,
2590 /* 0x3a */ x86emuOp2_illegal_op
,
2591 /* 0x3b */ x86emuOp2_illegal_op
,
2592 /* 0x3c */ x86emuOp2_illegal_op
,
2593 /* 0x3d */ x86emuOp2_illegal_op
,
2594 /* 0x3e */ x86emuOp2_illegal_op
,
2595 /* 0x3f */ x86emuOp2_illegal_op
,
2597 /* 0x40 */ x86emuOp2_illegal_op
,
2598 /* 0x41 */ x86emuOp2_illegal_op
,
2599 /* 0x42 */ x86emuOp2_illegal_op
,
2600 /* 0x43 */ x86emuOp2_illegal_op
,
2601 /* 0x44 */ x86emuOp2_illegal_op
,
2602 /* 0x45 */ x86emuOp2_illegal_op
,
2603 /* 0x46 */ x86emuOp2_illegal_op
,
2604 /* 0x47 */ x86emuOp2_illegal_op
,
2605 /* 0x48 */ x86emuOp2_illegal_op
,
2606 /* 0x49 */ x86emuOp2_illegal_op
,
2607 /* 0x4a */ x86emuOp2_illegal_op
,
2608 /* 0x4b */ x86emuOp2_illegal_op
,
2609 /* 0x4c */ x86emuOp2_illegal_op
,
2610 /* 0x4d */ x86emuOp2_illegal_op
,
2611 /* 0x4e */ x86emuOp2_illegal_op
,
2612 /* 0x4f */ x86emuOp2_illegal_op
,
2614 /* 0x50 */ x86emuOp2_illegal_op
,
2615 /* 0x51 */ x86emuOp2_illegal_op
,
2616 /* 0x52 */ x86emuOp2_illegal_op
,
2617 /* 0x53 */ x86emuOp2_illegal_op
,
2618 /* 0x54 */ x86emuOp2_illegal_op
,
2619 /* 0x55 */ x86emuOp2_illegal_op
,
2620 /* 0x56 */ x86emuOp2_illegal_op
,
2621 /* 0x57 */ x86emuOp2_illegal_op
,
2622 /* 0x58 */ x86emuOp2_illegal_op
,
2623 /* 0x59 */ x86emuOp2_illegal_op
,
2624 /* 0x5a */ x86emuOp2_illegal_op
,
2625 /* 0x5b */ x86emuOp2_illegal_op
,
2626 /* 0x5c */ x86emuOp2_illegal_op
,
2627 /* 0x5d */ x86emuOp2_illegal_op
,
2628 /* 0x5e */ x86emuOp2_illegal_op
,
2629 /* 0x5f */ x86emuOp2_illegal_op
,
2631 /* 0x60 */ x86emuOp2_illegal_op
,
2632 /* 0x61 */ x86emuOp2_illegal_op
,
2633 /* 0x62 */ x86emuOp2_illegal_op
,
2634 /* 0x63 */ x86emuOp2_illegal_op
,
2635 /* 0x64 */ x86emuOp2_illegal_op
,
2636 /* 0x65 */ x86emuOp2_illegal_op
,
2637 /* 0x66 */ x86emuOp2_illegal_op
,
2638 /* 0x67 */ x86emuOp2_illegal_op
,
2639 /* 0x68 */ x86emuOp2_illegal_op
,
2640 /* 0x69 */ x86emuOp2_illegal_op
,
2641 /* 0x6a */ x86emuOp2_illegal_op
,
2642 /* 0x6b */ x86emuOp2_illegal_op
,
2643 /* 0x6c */ x86emuOp2_illegal_op
,
2644 /* 0x6d */ x86emuOp2_illegal_op
,
2645 /* 0x6e */ x86emuOp2_illegal_op
,
2646 /* 0x6f */ x86emuOp2_illegal_op
,
2648 /* 0x70 */ x86emuOp2_illegal_op
,
2649 /* 0x71 */ x86emuOp2_illegal_op
,
2650 /* 0x72 */ x86emuOp2_illegal_op
,
2651 /* 0x73 */ x86emuOp2_illegal_op
,
2652 /* 0x74 */ x86emuOp2_illegal_op
,
2653 /* 0x75 */ x86emuOp2_illegal_op
,
2654 /* 0x76 */ x86emuOp2_illegal_op
,
2655 /* 0x77 */ x86emuOp2_illegal_op
,
2656 /* 0x78 */ x86emuOp2_illegal_op
,
2657 /* 0x79 */ x86emuOp2_illegal_op
,
2658 /* 0x7a */ x86emuOp2_illegal_op
,
2659 /* 0x7b */ x86emuOp2_illegal_op
,
2660 /* 0x7c */ x86emuOp2_illegal_op
,
2661 /* 0x7d */ x86emuOp2_illegal_op
,
2662 /* 0x7e */ x86emuOp2_illegal_op
,
2663 /* 0x7f */ x86emuOp2_illegal_op
,
2665 /* 0x80 */ x86emuOp2_long_jump
,
2666 /* 0x81 */ x86emuOp2_long_jump
,
2667 /* 0x82 */ x86emuOp2_long_jump
,
2668 /* 0x83 */ x86emuOp2_long_jump
,
2669 /* 0x84 */ x86emuOp2_long_jump
,
2670 /* 0x85 */ x86emuOp2_long_jump
,
2671 /* 0x86 */ x86emuOp2_long_jump
,
2672 /* 0x87 */ x86emuOp2_long_jump
,
2673 /* 0x88 */ x86emuOp2_long_jump
,
2674 /* 0x89 */ x86emuOp2_long_jump
,
2675 /* 0x8a */ x86emuOp2_long_jump
,
2676 /* 0x8b */ x86emuOp2_long_jump
,
2677 /* 0x8c */ x86emuOp2_long_jump
,
2678 /* 0x8d */ x86emuOp2_long_jump
,
2679 /* 0x8e */ x86emuOp2_long_jump
,
2680 /* 0x8f */ x86emuOp2_long_jump
,
2682 /* 0x90 */ x86emuOp2_set_byte
,
2683 /* 0x91 */ x86emuOp2_set_byte
,
2684 /* 0x92 */ x86emuOp2_set_byte
,
2685 /* 0x93 */ x86emuOp2_set_byte
,
2686 /* 0x94 */ x86emuOp2_set_byte
,
2687 /* 0x95 */ x86emuOp2_set_byte
,
2688 /* 0x96 */ x86emuOp2_set_byte
,
2689 /* 0x97 */ x86emuOp2_set_byte
,
2690 /* 0x98 */ x86emuOp2_set_byte
,
2691 /* 0x99 */ x86emuOp2_set_byte
,
2692 /* 0x9a */ x86emuOp2_set_byte
,
2693 /* 0x9b */ x86emuOp2_set_byte
,
2694 /* 0x9c */ x86emuOp2_set_byte
,
2695 /* 0x9d */ x86emuOp2_set_byte
,
2696 /* 0x9e */ x86emuOp2_set_byte
,
2697 /* 0x9f */ x86emuOp2_set_byte
,
2699 /* 0xa0 */ x86emuOp2_push_FS
,
2700 /* 0xa1 */ x86emuOp2_pop_FS
,
2701 /* 0xa2 */ x86emuOp2_illegal_op
,
2702 /* 0xa3 */ x86emuOp2_bt_R
,
2703 /* 0xa4 */ x86emuOp2_shld_IMM
,
2704 /* 0xa5 */ x86emuOp2_shld_CL
,
2705 /* 0xa6 */ x86emuOp2_illegal_op
,
2706 /* 0xa7 */ x86emuOp2_illegal_op
,
2707 /* 0xa8 */ x86emuOp2_push_GS
,
2708 /* 0xa9 */ x86emuOp2_pop_GS
,
2709 /* 0xaa */ x86emuOp2_illegal_op
,
2710 /* 0xab */ x86emuOp2_bt_R
,
2711 /* 0xac */ x86emuOp2_shrd_IMM
,
2712 /* 0xad */ x86emuOp2_shrd_CL
,
2713 /* 0xae */ x86emuOp2_illegal_op
,
2714 /* 0xaf */ x86emuOp2_imul_R_RM
,
2716 /* 0xb0 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2717 /* 0xb1 */ x86emuOp2_illegal_op
, /* TODO: cmpxchg */
2718 /* 0xb2 */ x86emuOp2_lss_R_IMM
,
2719 /* 0xb3 */ x86emuOp2_btr_R
,
2720 /* 0xb4 */ x86emuOp2_lfs_R_IMM
,
2721 /* 0xb5 */ x86emuOp2_lgs_R_IMM
,
2722 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM
,
2723 /* 0xb7 */ x86emuOp2_movzx_word_R_RM
,
2724 /* 0xb8 */ x86emuOp2_illegal_op
,
2725 /* 0xb9 */ x86emuOp2_illegal_op
,
2726 /* 0xba */ x86emuOp2_btX_I
,
2727 /* 0xbb */ x86emuOp2_btc_R
,
2728 /* 0xbc */ x86emuOp2_bsf
,
2729 /* 0xbd */ x86emuOp2_bsr
,
2730 /* 0xbe */ x86emuOp2_movsx_byte_R_RM
,
2731 /* 0xbf */ x86emuOp2_movsx_word_R_RM
,
2733 /* 0xc0 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2734 /* 0xc1 */ x86emuOp2_illegal_op
, /* TODO: xadd */
2735 /* 0xc2 */ x86emuOp2_illegal_op
,
2736 /* 0xc3 */ x86emuOp2_illegal_op
,
2737 /* 0xc4 */ x86emuOp2_illegal_op
,
2738 /* 0xc5 */ x86emuOp2_illegal_op
,
2739 /* 0xc6 */ x86emuOp2_illegal_op
,
2740 /* 0xc7 */ x86emuOp2_illegal_op
,
2741 /* 0xc8 */ x86emuOp2_illegal_op
, /* TODO: bswap */
2742 /* 0xc9 */ x86emuOp2_illegal_op
, /* TODO: bswap */
2743 /* 0xca */ x86emuOp2_illegal_op
, /* TODO: bswap */
2744 /* 0xcb */ x86emuOp2_illegal_op
, /* TODO: bswap */
2745 /* 0xcc */ x86emuOp2_illegal_op
, /* TODO: bswap */
2746 /* 0xcd */ x86emuOp2_illegal_op
, /* TODO: bswap */
2747 /* 0xce */ x86emuOp2_illegal_op
, /* TODO: bswap */
2748 /* 0xcf */ x86emuOp2_illegal_op
, /* TODO: bswap */
2750 /* 0xd0 */ x86emuOp2_illegal_op
,
2751 /* 0xd1 */ x86emuOp2_illegal_op
,
2752 /* 0xd2 */ x86emuOp2_illegal_op
,
2753 /* 0xd3 */ x86emuOp2_illegal_op
,
2754 /* 0xd4 */ x86emuOp2_illegal_op
,
2755 /* 0xd5 */ x86emuOp2_illegal_op
,
2756 /* 0xd6 */ x86emuOp2_illegal_op
,
2757 /* 0xd7 */ x86emuOp2_illegal_op
,
2758 /* 0xd8 */ x86emuOp2_illegal_op
,
2759 /* 0xd9 */ x86emuOp2_illegal_op
,
2760 /* 0xda */ x86emuOp2_illegal_op
,
2761 /* 0xdb */ x86emuOp2_illegal_op
,
2762 /* 0xdc */ x86emuOp2_illegal_op
,
2763 /* 0xdd */ x86emuOp2_illegal_op
,
2764 /* 0xde */ x86emuOp2_illegal_op
,
2765 /* 0xdf */ x86emuOp2_illegal_op
,
2767 /* 0xe0 */ x86emuOp2_illegal_op
,
2768 /* 0xe1 */ x86emuOp2_illegal_op
,
2769 /* 0xe2 */ x86emuOp2_illegal_op
,
2770 /* 0xe3 */ x86emuOp2_illegal_op
,
2771 /* 0xe4 */ x86emuOp2_illegal_op
,
2772 /* 0xe5 */ x86emuOp2_illegal_op
,
2773 /* 0xe6 */ x86emuOp2_illegal_op
,
2774 /* 0xe7 */ x86emuOp2_illegal_op
,
2775 /* 0xe8 */ x86emuOp2_illegal_op
,
2776 /* 0xe9 */ x86emuOp2_illegal_op
,
2777 /* 0xea */ x86emuOp2_illegal_op
,
2778 /* 0xeb */ x86emuOp2_illegal_op
,
2779 /* 0xec */ x86emuOp2_illegal_op
,
2780 /* 0xed */ x86emuOp2_illegal_op
,
2781 /* 0xee */ x86emuOp2_illegal_op
,
2782 /* 0xef */ x86emuOp2_illegal_op
,
2784 /* 0xf0 */ x86emuOp2_illegal_op
,
2785 /* 0xf1 */ x86emuOp2_illegal_op
,
2786 /* 0xf2 */ x86emuOp2_illegal_op
,
2787 /* 0xf3 */ x86emuOp2_illegal_op
,
2788 /* 0xf4 */ x86emuOp2_illegal_op
,
2789 /* 0xf5 */ x86emuOp2_illegal_op
,
2790 /* 0xf6 */ x86emuOp2_illegal_op
,
2791 /* 0xf7 */ x86emuOp2_illegal_op
,
2792 /* 0xf8 */ x86emuOp2_illegal_op
,
2793 /* 0xf9 */ x86emuOp2_illegal_op
,
2794 /* 0xfa */ x86emuOp2_illegal_op
,
2795 /* 0xfb */ x86emuOp2_illegal_op
,
2796 /* 0xfc */ x86emuOp2_illegal_op
,
2797 /* 0xfd */ x86emuOp2_illegal_op
,
2798 /* 0xfe */ x86emuOp2_illegal_op
,
2799 /* 0xff */ x86emuOp2_illegal_op
,