1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1991-2004 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 extended two-byte processor
39 ****************************************************************************/
43 /*----------------------------- Implementation ----------------------------*/
45 /****************************************************************************
47 op1 - Instruction op code
50 Handles illegal opcodes.
51 ****************************************************************************/
52 static void x86emuOp2_illegal_op(u8 op2)
55 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
57 printf("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
58 M.x86.R_CS, M.x86.R_IP-2, op2);
63 /****************************************************************************
65 * Handles opcode 0x0f,0x01
66 * ****************************************************************************/
68 static void x86emuOp2_opc_01(u8 op2)
75 FETCH_DECODE_MODRM(mod, rh, rl);
78 case 4: // SMSW (Store Machine Status Word)
79 // Decode the mod byte to find the addressing
80 // Dummy implementation: Always returns 0x10 (initial value as per intel manual volume 3, figure 8-1)
81 #define SMSW_INITIAL_VALUE 0x10
82 DECODE_PRINTF("SMSW\t");
85 destoffset = decode_rm00_address(rl);
86 store_data_word(destoffset, SMSW_INITIAL_VALUE);
89 destoffset = decode_rm01_address(rl);
90 store_data_word(destoffset, SMSW_INITIAL_VALUE);
93 destoffset = decode_rm10_address(rl);
94 store_data_word(destoffset, SMSW_INITIAL_VALUE);
97 destreg = DECODE_RM_WORD_REGISTER(rl);
98 *destreg = SMSW_INITIAL_VALUE;
102 DECODE_CLEAR_SEGOVR();
106 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE IN 0F 01\n");
108 printf("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
109 M.x86.R_CS, M.x86.R_IP-2, op2);
117 /****************************************************************************
119 * Handles opcode 0x0f,0x08
120 * ****************************************************************************/
121 static void x86emuOp2_invd(u8 op2)
124 DECODE_PRINTF("INVD\n");
126 DECODE_CLEAR_SEGOVR();
130 /****************************************************************************
132 * Handles opcode 0x0f,0x09
133 * ****************************************************************************/
134 static void x86emuOp2_wbinvd(u8 op2)
137 DECODE_PRINTF("WBINVD\n");
139 DECODE_CLEAR_SEGOVR();
143 /****************************************************************************
145 * Handles opcode 0x0f,0x30
146 * ****************************************************************************/
147 static void x86emuOp2_wrmsr(u8 op2)
149 /* dummy implementation, does nothing */
152 DECODE_PRINTF("WRMSR\n");
154 DECODE_CLEAR_SEGOVR();
158 /****************************************************************************
160 * Handles opcode 0x0f,0x32
161 * ****************************************************************************/
162 static void x86emuOp2_rdmsr(u8 op2)
164 /* dummy implementation, always return 0 */
167 DECODE_PRINTF("RDMSR\n");
171 DECODE_CLEAR_SEGOVR();
175 #define xorl(a,b) (((a) && !(b)) || (!(a) && (b)))
177 /****************************************************************************
179 Handles opcode 0x0f,0x80-0x8F
180 ****************************************************************************/
181 int x86emu_check_jump_condition(u8 op)
185 DECODE_PRINTF("JO\t");
186 return ACCESS_FLAG(F_OF);
188 DECODE_PRINTF("JNO\t");
189 return !ACCESS_FLAG(F_OF);
192 DECODE_PRINTF("JB\t");
193 return ACCESS_FLAG(F_CF);
196 DECODE_PRINTF("JNB\t");
197 return !ACCESS_FLAG(F_CF);
200 DECODE_PRINTF("JZ\t");
201 return ACCESS_FLAG(F_ZF);
204 DECODE_PRINTF("JNZ\t");
205 return !ACCESS_FLAG(F_ZF);
208 DECODE_PRINTF("JBE\t");
209 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
212 DECODE_PRINTF("JNBE\t");
213 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
216 DECODE_PRINTF("JS\t");
217 return ACCESS_FLAG(F_SF);
220 DECODE_PRINTF("JNS\t");
221 return !ACCESS_FLAG(F_SF);
224 DECODE_PRINTF("JP\t");
225 return ACCESS_FLAG(F_PF);
228 DECODE_PRINTF("JNP\t");
229 return !ACCESS_FLAG(F_PF);
232 DECODE_PRINTF("JL\t");
233 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
236 DECODE_PRINTF("JNL\t");
237 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
240 DECODE_PRINTF("JLE\t");
241 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
245 DECODE_PRINTF("JNLE\t");
246 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
251 static void x86emuOp2_long_jump(u8 op2)
256 /* conditional jump to word offset. */
258 cond = x86emu_check_jump_condition(op2 & 0xF);
259 target = (s16) fetch_word_imm();
260 target += (s16) M.x86.R_IP;
261 DECODE_PRINTF2("%04x\n", target);
264 M.x86.R_IP = (u16)target;
265 JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " LONG COND ");
267 DECODE_CLEAR_SEGOVR();
271 /****************************************************************************
273 Handles opcode 0x0f,0xC8-0xCF
274 ****************************************************************************/
275 static s32 x86emu_bswap(s32 reg)
277 // perform the byte swap
279 reg = (temp & 0xFF000000) >> 24 |
280 (temp & 0xFF0000) >> 8 |
281 (temp & 0xFF00) << 8 |
286 static void x86emuOp2_bswap(u8 op2)
288 /* byte swap 32 bit register */
290 DECODE_PRINTF("BSWAP\t");
293 DECODE_PRINTF("EAX\n");
294 M.x86.R_EAX = x86emu_bswap(M.x86.R_EAX);
297 DECODE_PRINTF("ECX\n");
298 M.x86.R_ECX = x86emu_bswap(M.x86.R_ECX);
301 DECODE_PRINTF("EDX\n");
302 M.x86.R_EDX = x86emu_bswap(M.x86.R_EDX);
305 DECODE_PRINTF("EBX\n");
306 M.x86.R_EBX = x86emu_bswap(M.x86.R_EBX);
309 DECODE_PRINTF("ESP\n");
310 M.x86.R_ESP = x86emu_bswap(M.x86.R_ESP);
313 DECODE_PRINTF("EBP\n");
314 M.x86.R_EBP = x86emu_bswap(M.x86.R_EBP);
317 DECODE_PRINTF("ESI\n");
318 M.x86.R_ESI = x86emu_bswap(M.x86.R_ESI);
321 DECODE_PRINTF("EDI\n");
322 M.x86.R_EDI = x86emu_bswap(M.x86.R_EDI);
326 DECODE_CLEAR_SEGOVR();
330 /****************************************************************************
332 Handles opcode 0x0f,0x90-0x9F
333 ****************************************************************************/
334 static void x86emuOp2_set_byte(u8 op2)
339 const char *name = 0;
346 cond = ACCESS_FLAG(F_OF);
350 cond = !ACCESS_FLAG(F_OF);
354 cond = ACCESS_FLAG(F_CF);
358 cond = !ACCESS_FLAG(F_CF);
362 cond = ACCESS_FLAG(F_ZF);
366 cond = !ACCESS_FLAG(F_ZF);
370 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
374 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
378 cond = ACCESS_FLAG(F_SF);
382 cond = !ACCESS_FLAG(F_SF);
386 cond = ACCESS_FLAG(F_PF);
390 cond = !ACCESS_FLAG(F_PF);
394 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
398 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
402 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
407 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
412 FETCH_DECODE_MODRM(mod, rh, rl);
414 destoffset = decode_rmXX_address(mod, rl);
416 store_data_byte(destoffset, cond ? 0x01 : 0x00);
417 } else { /* register to register */
418 destreg = DECODE_RM_BYTE_REGISTER(rl);
420 *destreg = cond ? 0x01 : 0x00;
422 DECODE_CLEAR_SEGOVR();
426 /****************************************************************************
428 Handles opcode 0x0f,0xa0
429 ****************************************************************************/
430 static void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
433 DECODE_PRINTF("PUSH\tFS\n");
435 push_word(M.x86.R_FS);
436 DECODE_CLEAR_SEGOVR();
440 /****************************************************************************
442 Handles opcode 0x0f,0xa1
443 ****************************************************************************/
444 static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
447 DECODE_PRINTF("POP\tFS\n");
449 M.x86.R_FS = pop_word();
450 DECODE_CLEAR_SEGOVR();
454 /****************************************************************************
455 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
456 Handles opcode 0x0f,0xa2
457 ****************************************************************************/
458 static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
461 DECODE_PRINTF("CPUID\n");
464 DECODE_CLEAR_SEGOVR();
468 /****************************************************************************
470 Handles opcode 0x0f,0xa3
471 ****************************************************************************/
472 static void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
479 DECODE_PRINTF("BT\t");
480 FETCH_DECODE_MODRM(mod, rh, rl);
482 srcoffset = decode_rmXX_address(mod, rl);
483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
488 shiftreg = DECODE_RM_LONG_REGISTER(rh);
490 bit = *shiftreg & 0x1F;
491 disp = (s16)*shiftreg >> 5;
492 srcval = fetch_data_long(srcoffset+disp);
493 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
499 shiftreg = DECODE_RM_WORD_REGISTER(rh);
501 bit = *shiftreg & 0xF;
502 disp = (s16)*shiftreg >> 4;
503 srcval = fetch_data_word(srcoffset+disp);
504 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
506 } else { /* register to register */
507 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
508 u32 *srcreg,*shiftreg;
510 srcreg = DECODE_RM_LONG_REGISTER(rl);
512 shiftreg = DECODE_RM_LONG_REGISTER(rh);
514 bit = *shiftreg & 0x1F;
515 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
517 u16 *srcreg,*shiftreg;
519 srcreg = DECODE_RM_WORD_REGISTER(rl);
521 shiftreg = DECODE_RM_WORD_REGISTER(rh);
523 bit = *shiftreg & 0xF;
524 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
527 DECODE_CLEAR_SEGOVR();
531 /****************************************************************************
533 Handles opcode 0x0f,0xa4
534 ****************************************************************************/
535 static void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
542 DECODE_PRINTF("SHLD\t");
543 FETCH_DECODE_MODRM(mod, rh, rl);
545 destoffset = decode_rmXX_address(mod, rl);
546 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
551 shiftreg = DECODE_RM_LONG_REGISTER(rh);
553 shift = fetch_byte_imm();
554 DECODE_PRINTF2("%d\n", shift);
556 destval = fetch_data_long(destoffset);
557 destval = shld_long(destval,*shiftreg,shift);
558 store_data_long(destoffset, destval);
564 shiftreg = DECODE_RM_WORD_REGISTER(rh);
566 shift = fetch_byte_imm();
567 DECODE_PRINTF2("%d\n", shift);
569 destval = fetch_data_word(destoffset);
570 destval = shld_word(destval,*shiftreg,shift);
571 store_data_word(destoffset, destval);
573 } else { /* register to register */
574 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
575 u32 *destreg,*shiftreg;
577 destreg = DECODE_RM_LONG_REGISTER(rl);
579 shiftreg = DECODE_RM_LONG_REGISTER(rh);
581 shift = fetch_byte_imm();
582 DECODE_PRINTF2("%d\n", shift);
584 *destreg = shld_long(*destreg,*shiftreg,shift);
586 u16 *destreg,*shiftreg;
588 destreg = DECODE_RM_WORD_REGISTER(rl);
590 shiftreg = DECODE_RM_WORD_REGISTER(rh);
592 shift = fetch_byte_imm();
593 DECODE_PRINTF2("%d\n", shift);
595 *destreg = shld_word(*destreg,*shiftreg,shift);
598 DECODE_CLEAR_SEGOVR();
602 /****************************************************************************
604 Handles opcode 0x0f,0xa5
605 ****************************************************************************/
606 static void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
612 DECODE_PRINTF("SHLD\t");
613 FETCH_DECODE_MODRM(mod, rh, rl);
615 destoffset = decode_rmXX_address(mod, rl);
616 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
621 shiftreg = DECODE_RM_LONG_REGISTER(rh);
622 DECODE_PRINTF(",CL\n");
624 destval = fetch_data_long(destoffset);
625 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
626 store_data_long(destoffset, destval);
632 shiftreg = DECODE_RM_WORD_REGISTER(rh);
633 DECODE_PRINTF(",CL\n");
635 destval = fetch_data_word(destoffset);
636 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
637 store_data_word(destoffset, destval);
639 } else { /* register to register */
640 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
641 u32 *destreg,*shiftreg;
643 destreg = DECODE_RM_LONG_REGISTER(rl);
645 shiftreg = DECODE_RM_LONG_REGISTER(rh);
646 DECODE_PRINTF(",CL\n");
648 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
650 u16 *destreg,*shiftreg;
652 destreg = DECODE_RM_WORD_REGISTER(rl);
654 shiftreg = DECODE_RM_WORD_REGISTER(rh);
655 DECODE_PRINTF(",CL\n");
657 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
660 DECODE_CLEAR_SEGOVR();
664 /****************************************************************************
666 Handles opcode 0x0f,0xa8
667 ****************************************************************************/
668 static void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
671 DECODE_PRINTF("PUSH\tGS\n");
673 push_word(M.x86.R_GS);
674 DECODE_CLEAR_SEGOVR();
678 /****************************************************************************
680 Handles opcode 0x0f,0xa9
681 ****************************************************************************/
682 static void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
685 DECODE_PRINTF("POP\tGS\n");
687 M.x86.R_GS = pop_word();
688 DECODE_CLEAR_SEGOVR();
692 /****************************************************************************
694 Handles opcode 0x0f,0xaa
695 ****************************************************************************/
696 static void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
703 DECODE_PRINTF("BTS\t");
704 FETCH_DECODE_MODRM(mod, rh, rl);
706 srcoffset = decode_rmXX_address(mod, rl);
707 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
712 shiftreg = DECODE_RM_LONG_REGISTER(rh);
714 bit = *shiftreg & 0x1F;
715 disp = (s16)*shiftreg >> 5;
716 srcval = fetch_data_long(srcoffset+disp);
718 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
719 store_data_long(srcoffset+disp, srcval | mask);
725 shiftreg = DECODE_RM_WORD_REGISTER(rh);
727 bit = *shiftreg & 0xF;
728 disp = (s16)*shiftreg >> 4;
729 srcval = fetch_data_word(srcoffset+disp);
730 mask = (u16)(0x1 << bit);
731 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
732 store_data_word(srcoffset+disp, srcval | mask);
734 } else { /* register to register */
735 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
736 u32 *srcreg,*shiftreg;
739 srcreg = DECODE_RM_LONG_REGISTER(rl);
741 shiftreg = DECODE_RM_LONG_REGISTER(rh);
743 bit = *shiftreg & 0x1F;
745 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
748 u16 *srcreg,*shiftreg;
751 srcreg = DECODE_RM_WORD_REGISTER(rl);
753 shiftreg = DECODE_RM_WORD_REGISTER(rh);
755 bit = *shiftreg & 0xF;
756 mask = (u16)(0x1 << bit);
757 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
761 DECODE_CLEAR_SEGOVR();
765 /****************************************************************************
767 Handles opcode 0x0f,0xac
768 ****************************************************************************/
769 static void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
776 DECODE_PRINTF("SHLD\t");
777 FETCH_DECODE_MODRM(mod, rh, rl);
779 destoffset = decode_rmXX_address(mod, rl);
780 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
785 shiftreg = DECODE_RM_LONG_REGISTER(rh);
787 shift = fetch_byte_imm();
788 DECODE_PRINTF2("%d\n", shift);
790 destval = fetch_data_long(destoffset);
791 destval = shrd_long(destval,*shiftreg,shift);
792 store_data_long(destoffset, destval);
798 shiftreg = DECODE_RM_WORD_REGISTER(rh);
800 shift = fetch_byte_imm();
801 DECODE_PRINTF2("%d\n", shift);
803 destval = fetch_data_word(destoffset);
804 destval = shrd_word(destval,*shiftreg,shift);
805 store_data_word(destoffset, destval);
807 } else { /* register to register */
808 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
809 u32 *destreg,*shiftreg;
811 destreg = DECODE_RM_LONG_REGISTER(rl);
813 shiftreg = DECODE_RM_LONG_REGISTER(rh);
815 shift = fetch_byte_imm();
816 DECODE_PRINTF2("%d\n", shift);
818 *destreg = shrd_long(*destreg,*shiftreg,shift);
820 u16 *destreg,*shiftreg;
822 destreg = DECODE_RM_WORD_REGISTER(rl);
824 shiftreg = DECODE_RM_WORD_REGISTER(rh);
826 shift = fetch_byte_imm();
827 DECODE_PRINTF2("%d\n", shift);
829 *destreg = shrd_word(*destreg,*shiftreg,shift);
832 DECODE_CLEAR_SEGOVR();
836 /****************************************************************************
838 Handles opcode 0x0f,0xad
839 ****************************************************************************/
840 static void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
846 DECODE_PRINTF("SHLD\t");
847 FETCH_DECODE_MODRM(mod, rh, rl);
849 destoffset = decode_rmXX_address(mod, rl);
851 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
855 shiftreg = DECODE_RM_LONG_REGISTER(rh);
856 DECODE_PRINTF(",CL\n");
858 destval = fetch_data_long(destoffset);
859 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
860 store_data_long(destoffset, destval);
865 shiftreg = DECODE_RM_WORD_REGISTER(rh);
866 DECODE_PRINTF(",CL\n");
868 destval = fetch_data_word(destoffset);
869 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
870 store_data_word(destoffset, destval);
872 } else { /* register to register */
873 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
874 u32 *destreg,*shiftreg;
876 destreg = DECODE_RM_LONG_REGISTER(rl);
878 shiftreg = DECODE_RM_LONG_REGISTER(rh);
879 DECODE_PRINTF(",CL\n");
881 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
883 u16 *destreg,*shiftreg;
885 destreg = DECODE_RM_WORD_REGISTER(rl);
887 shiftreg = DECODE_RM_WORD_REGISTER(rh);
888 DECODE_PRINTF(",CL\n");
890 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
893 DECODE_CLEAR_SEGOVR();
897 /****************************************************************************
899 Handles opcode 0x0f,0xaf
900 ****************************************************************************/
901 static void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
907 DECODE_PRINTF("IMUL\t");
908 FETCH_DECODE_MODRM(mod, rh, rl);
910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
915 destreg = DECODE_RM_LONG_REGISTER(rh);
917 srcoffset = decode_rmXX_address(mod, rl);
918 srcval = fetch_data_long(srcoffset);
920 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
928 *destreg = (u32)res_lo;
934 destreg = DECODE_RM_WORD_REGISTER(rh);
936 srcoffset = decode_rmXX_address(mod, rl);
937 srcval = fetch_data_word(srcoffset);
939 res = (s16)*destreg * (s16)srcval;
949 } else { /* register to register */
950 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
951 u32 *destreg,*srcreg;
954 destreg = DECODE_RM_LONG_REGISTER(rh);
956 srcreg = DECODE_RM_LONG_REGISTER(rl);
958 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
966 *destreg = (u32)res_lo;
968 u16 *destreg,*srcreg;
971 destreg = DECODE_RM_WORD_REGISTER(rh);
973 srcreg = DECODE_RM_WORD_REGISTER(rl);
974 res = (s16)*destreg * (s16)*srcreg;
985 DECODE_CLEAR_SEGOVR();
989 /****************************************************************************
991 Handles opcode 0x0f,0xb2
992 ****************************************************************************/
993 static void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1000 DECODE_PRINTF("LSS\t");
1001 FETCH_DECODE_MODRM(mod, rh, rl);
1003 dstreg = DECODE_RM_WORD_REGISTER(rh);
1005 srcoffset = decode_rmXX_address(mod, rl);
1006 DECODE_PRINTF("\n");
1008 *dstreg = fetch_data_word(srcoffset);
1009 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1010 } else { /* register to register */
1014 DECODE_CLEAR_SEGOVR();
1018 /****************************************************************************
1020 Handles opcode 0x0f,0xb3
1021 ****************************************************************************/
1022 static void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1029 DECODE_PRINTF("BTR\t");
1030 FETCH_DECODE_MODRM(mod, rh, rl);
1032 srcoffset = decode_rmXX_address(mod, rl);
1034 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1038 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1040 bit = *shiftreg & 0x1F;
1041 disp = (s16)*shiftreg >> 5;
1042 srcval = fetch_data_long(srcoffset+disp);
1043 mask = (0x1 << bit);
1044 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1045 store_data_long(srcoffset+disp, srcval & ~mask);
1050 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1052 bit = *shiftreg & 0xF;
1053 disp = (s16)*shiftreg >> 4;
1054 srcval = fetch_data_word(srcoffset+disp);
1055 mask = (u16)(0x1 << bit);
1056 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1057 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1059 } else { /* register to register */
1060 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1061 u32 *srcreg,*shiftreg;
1064 srcreg = DECODE_RM_LONG_REGISTER(rl);
1066 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1068 bit = *shiftreg & 0x1F;
1069 mask = (0x1 << bit);
1070 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1073 u16 *srcreg,*shiftreg;
1076 srcreg = DECODE_RM_WORD_REGISTER(rl);
1078 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1080 bit = *shiftreg & 0xF;
1081 mask = (u16)(0x1 << bit);
1082 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1086 DECODE_CLEAR_SEGOVR();
1090 /****************************************************************************
1092 Handles opcode 0x0f,0xb4
1093 ****************************************************************************/
1094 static void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1101 DECODE_PRINTF("LFS\t");
1102 FETCH_DECODE_MODRM(mod, rh, rl);
1104 dstreg = DECODE_RM_WORD_REGISTER(rh);
1106 srcoffset = decode_rmXX_address(mod, rl);
1107 DECODE_PRINTF("\n");
1109 *dstreg = fetch_data_word(srcoffset);
1110 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1111 } else { /* register to register */
1115 DECODE_CLEAR_SEGOVR();
1119 /****************************************************************************
1121 Handles opcode 0x0f,0xb5
1122 ****************************************************************************/
1123 static void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1130 DECODE_PRINTF("LGS\t");
1131 FETCH_DECODE_MODRM(mod, rh, rl);
1133 dstreg = DECODE_RM_WORD_REGISTER(rh);
1135 srcoffset = decode_rmXX_address(mod, rl);
1136 DECODE_PRINTF("\n");
1138 *dstreg = fetch_data_word(srcoffset);
1139 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1140 } else { /* register to register */
1144 DECODE_CLEAR_SEGOVR();
1148 /****************************************************************************
1150 Handles opcode 0x0f,0xb6
1151 ****************************************************************************/
1152 static void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1158 DECODE_PRINTF("MOVZX\t");
1159 FETCH_DECODE_MODRM(mod, rh, rl);
1161 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1165 destreg = DECODE_RM_LONG_REGISTER(rh);
1167 srcoffset = decode_rmXX_address(mod, rl);
1168 srcval = fetch_data_byte(srcoffset);
1169 DECODE_PRINTF("\n");
1176 destreg = DECODE_RM_WORD_REGISTER(rh);
1178 srcoffset = decode_rmXX_address(mod, rl);
1179 srcval = fetch_data_byte(srcoffset);
1180 DECODE_PRINTF("\n");
1184 } else { /* register to register */
1185 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1189 destreg = DECODE_RM_LONG_REGISTER(rh);
1191 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1192 DECODE_PRINTF("\n");
1199 destreg = DECODE_RM_WORD_REGISTER(rh);
1201 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1202 DECODE_PRINTF("\n");
1207 DECODE_CLEAR_SEGOVR();
1211 /****************************************************************************
1213 Handles opcode 0x0f,0xb7
1214 ****************************************************************************/
1215 static void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1224 DECODE_PRINTF("MOVZX\t");
1225 FETCH_DECODE_MODRM(mod, rh, rl);
1227 destreg = DECODE_RM_LONG_REGISTER(rh);
1229 srcoffset = decode_rmXX_address(mod, rl);
1230 srcval = fetch_data_word(srcoffset);
1231 DECODE_PRINTF("\n");
1234 } else { /* register to register */
1235 destreg = DECODE_RM_LONG_REGISTER(rh);
1237 srcreg = DECODE_RM_WORD_REGISTER(rl);
1238 DECODE_PRINTF("\n");
1242 DECODE_CLEAR_SEGOVR();
1246 /****************************************************************************
1248 Handles opcode 0x0f,0xba
1249 ****************************************************************************/
1250 static void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1258 FETCH_DECODE_MODRM(mod, rh, rl);
1261 DECODE_PRINTF("BT\t");
1264 DECODE_PRINTF("BTS\t");
1267 DECODE_PRINTF("BTR\t");
1270 DECODE_PRINTF("BTC\t");
1273 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1275 printf("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1276 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1281 srcoffset = decode_rmXX_address(mod, rl);
1282 shift = fetch_byte_imm();
1283 DECODE_PRINTF2(",%d\n", shift);
1286 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1290 srcval = fetch_data_long(srcoffset);
1291 mask = (0x1 << bit);
1292 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1295 store_data_long(srcoffset, srcval | mask);
1298 store_data_long(srcoffset, srcval & ~mask);
1301 store_data_long(srcoffset, srcval ^ mask);
1310 srcval = fetch_data_word(srcoffset);
1311 mask = (0x1 << bit);
1312 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1315 store_data_word(srcoffset, srcval | mask);
1318 store_data_word(srcoffset, srcval & ~mask);
1321 store_data_word(srcoffset, srcval ^ mask);
1327 } else { /* register to register */
1328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1332 srcreg = DECODE_RM_LONG_REGISTER(rl);
1333 shift = fetch_byte_imm();
1334 DECODE_PRINTF2(",%d\n", shift);
1337 mask = (0x1 << bit);
1338 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1356 srcreg = DECODE_RM_WORD_REGISTER(rl);
1357 shift = fetch_byte_imm();
1358 DECODE_PRINTF2(",%d\n", shift);
1361 mask = (0x1 << bit);
1362 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1378 DECODE_CLEAR_SEGOVR();
1382 /****************************************************************************
1384 Handles opcode 0x0f,0xbb
1385 ****************************************************************************/
1386 static void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1393 DECODE_PRINTF("BTC\t");
1394 FETCH_DECODE_MODRM(mod, rh, rl);
1396 srcoffset = decode_rmXX_address(mod, rl);
1398 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1402 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1404 bit = *shiftreg & 0x1F;
1405 disp = (s16)*shiftreg >> 5;
1406 srcval = fetch_data_long(srcoffset+disp);
1407 mask = (0x1 << bit);
1408 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1409 store_data_long(srcoffset+disp, srcval ^ mask);
1414 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1416 bit = *shiftreg & 0xF;
1417 disp = (s16)*shiftreg >> 4;
1418 srcval = fetch_data_word(srcoffset+disp);
1419 mask = (u16)(0x1 << bit);
1420 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1421 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1423 } else { /* register to register */
1424 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1425 u32 *srcreg,*shiftreg;
1428 srcreg = DECODE_RM_LONG_REGISTER(rl);
1430 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1432 bit = *shiftreg & 0x1F;
1433 mask = (0x1 << bit);
1434 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1437 u16 *srcreg,*shiftreg;
1440 srcreg = DECODE_RM_WORD_REGISTER(rl);
1442 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1444 bit = *shiftreg & 0xF;
1445 mask = (u16)(0x1 << bit);
1446 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1450 DECODE_CLEAR_SEGOVR();
1454 /****************************************************************************
1456 Handles opcode 0x0f,0xbc
1457 ****************************************************************************/
1458 static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1464 DECODE_PRINTF("BSF\n");
1465 FETCH_DECODE_MODRM(mod, rh, rl);
1467 srcoffset = decode_rmXX_address(mod, rl);
1469 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1470 u32 srcval, *dstreg;
1472 dstreg = DECODE_RM_LONG_REGISTER(rh);
1474 srcval = fetch_data_long(srcoffset);
1475 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1476 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1477 if ((srcval >> *dstreg) & 1) break;
1479 u16 srcval, *dstreg;
1481 dstreg = DECODE_RM_WORD_REGISTER(rh);
1483 srcval = fetch_data_word(srcoffset);
1484 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1485 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1486 if ((srcval >> *dstreg) & 1) break;
1488 } else { /* register to register */
1489 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1490 u32 *srcreg, *dstreg;
1492 srcreg = DECODE_RM_LONG_REGISTER(rl);
1494 dstreg = DECODE_RM_LONG_REGISTER(rh);
1496 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1497 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1498 if ((*srcreg >> *dstreg) & 1) break;
1500 u16 *srcreg, *dstreg;
1502 srcreg = DECODE_RM_WORD_REGISTER(rl);
1504 dstreg = DECODE_RM_WORD_REGISTER(rh);
1506 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1507 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1508 if ((*srcreg >> *dstreg) & 1) break;
1511 DECODE_CLEAR_SEGOVR();
1515 /****************************************************************************
1517 Handles opcode 0x0f,0xbd
1518 ****************************************************************************/
1519 static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1525 DECODE_PRINTF("BSF\n");
1526 FETCH_DECODE_MODRM(mod, rh, rl);
1528 srcoffset = decode_rmXX_address(mod, rl);
1530 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1531 u32 srcval, *dstreg;
1533 dstreg = DECODE_RM_LONG_REGISTER(rh);
1535 srcval = fetch_data_long(srcoffset);
1536 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1537 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1538 if ((srcval >> *dstreg) & 1) break;
1540 u16 srcval, *dstreg;
1542 dstreg = DECODE_RM_WORD_REGISTER(rh);
1544 srcval = fetch_data_word(srcoffset);
1545 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1546 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1547 if ((srcval >> *dstreg) & 1) break;
1549 } else { /* register to register */
1550 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1551 u32 *srcreg, *dstreg;
1553 srcreg = DECODE_RM_LONG_REGISTER(rl);
1555 dstreg = DECODE_RM_LONG_REGISTER(rh);
1557 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1558 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1559 if ((*srcreg >> *dstreg) & 1) break;
1561 u16 *srcreg, *dstreg;
1563 srcreg = DECODE_RM_WORD_REGISTER(rl);
1565 dstreg = DECODE_RM_WORD_REGISTER(rh);
1567 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1568 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1569 if ((*srcreg >> *dstreg) & 1) break;
1572 DECODE_CLEAR_SEGOVR();
1576 /****************************************************************************
1578 Handles opcode 0x0f,0xbe
1579 ****************************************************************************/
1580 static void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1586 DECODE_PRINTF("MOVSX\t");
1587 FETCH_DECODE_MODRM(mod, rh, rl);
1589 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1593 destreg = DECODE_RM_LONG_REGISTER(rh);
1595 srcoffset = decode_rmXX_address(mod, rl);
1596 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1597 DECODE_PRINTF("\n");
1604 destreg = DECODE_RM_WORD_REGISTER(rh);
1606 srcoffset = decode_rmXX_address(mod, rl);
1607 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1608 DECODE_PRINTF("\n");
1612 } else { /* register to register */
1613 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1617 destreg = DECODE_RM_LONG_REGISTER(rh);
1619 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1620 DECODE_PRINTF("\n");
1622 *destreg = (s32)((s8)*srcreg);
1627 destreg = DECODE_RM_WORD_REGISTER(rh);
1629 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1630 DECODE_PRINTF("\n");
1632 *destreg = (s16)((s8)*srcreg);
1635 DECODE_CLEAR_SEGOVR();
1639 /****************************************************************************
1641 Handles opcode 0x0f,0xbf
1642 ****************************************************************************/
1643 static void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1652 DECODE_PRINTF("MOVSX\t");
1653 FETCH_DECODE_MODRM(mod, rh, rl);
1655 destreg = DECODE_RM_LONG_REGISTER(rh);
1657 srcoffset = decode_rmXX_address(mod, rl);
1658 srcval = (s32)((s16)fetch_data_word(srcoffset));
1659 DECODE_PRINTF("\n");
1662 } else { /* register to register */
1663 destreg = DECODE_RM_LONG_REGISTER(rh);
1665 srcreg = DECODE_RM_WORD_REGISTER(rl);
1666 DECODE_PRINTF("\n");
1668 *destreg = (s32)((s16)*srcreg);
1670 DECODE_CLEAR_SEGOVR();
1674 /***************************************************************************
1675 * Double byte operation code table:
1676 **************************************************************************/
1677 void (*x86emu_optab2[256])(u8) =
1679 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1680 /* 0x01 */ x86emuOp2_opc_01, /* Group G (ring 0 PM) */
1681 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1682 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1683 /* 0x04 */ x86emuOp2_illegal_op,
1684 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1685 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1686 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1687 /* 0x08 */ x86emuOp2_invd, /* invd (ring 0 PM) */
1688 /* 0x09 */ x86emuOp2_wbinvd, /* wbinvd (ring 0 PM) */
1689 /* 0x0a */ x86emuOp2_illegal_op,
1690 /* 0x0b */ x86emuOp2_illegal_op,
1691 /* 0x0c */ x86emuOp2_illegal_op,
1692 /* 0x0d */ x86emuOp2_illegal_op,
1693 /* 0x0e */ x86emuOp2_illegal_op,
1694 /* 0x0f */ x86emuOp2_illegal_op,
1696 /* 0x10 */ x86emuOp2_illegal_op,
1697 /* 0x11 */ x86emuOp2_illegal_op,
1698 /* 0x12 */ x86emuOp2_illegal_op,
1699 /* 0x13 */ x86emuOp2_illegal_op,
1700 /* 0x14 */ x86emuOp2_illegal_op,
1701 /* 0x15 */ x86emuOp2_illegal_op,
1702 /* 0x16 */ x86emuOp2_illegal_op,
1703 /* 0x17 */ x86emuOp2_illegal_op,
1704 /* 0x18 */ x86emuOp2_illegal_op,
1705 /* 0x19 */ x86emuOp2_illegal_op,
1706 /* 0x1a */ x86emuOp2_illegal_op,
1707 /* 0x1b */ x86emuOp2_illegal_op,
1708 /* 0x1c */ x86emuOp2_illegal_op,
1709 /* 0x1d */ x86emuOp2_illegal_op,
1710 /* 0x1e */ x86emuOp2_illegal_op,
1711 /* 0x1f */ x86emuOp2_illegal_op,
1713 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1714 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1715 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1716 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1717 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1718 /* 0x25 */ x86emuOp2_illegal_op,
1719 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1720 /* 0x27 */ x86emuOp2_illegal_op,
1721 /* 0x28 */ x86emuOp2_illegal_op,
1722 /* 0x29 */ x86emuOp2_illegal_op,
1723 /* 0x2a */ x86emuOp2_illegal_op,
1724 /* 0x2b */ x86emuOp2_illegal_op,
1725 /* 0x2c */ x86emuOp2_illegal_op,
1726 /* 0x2d */ x86emuOp2_illegal_op,
1727 /* 0x2e */ x86emuOp2_illegal_op,
1728 /* 0x2f */ x86emuOp2_illegal_op,
1730 /* 0x30 */ x86emuOp2_wrmsr,
1731 /* 0x31 */ x86emuOp2_illegal_op,
1732 /* 0x32 */ x86emuOp2_rdmsr,
1733 /* 0x33 */ x86emuOp2_illegal_op,
1734 /* 0x34 */ x86emuOp2_illegal_op,
1735 /* 0x35 */ x86emuOp2_illegal_op,
1736 /* 0x36 */ x86emuOp2_illegal_op,
1737 /* 0x37 */ x86emuOp2_illegal_op,
1738 /* 0x38 */ x86emuOp2_illegal_op,
1739 /* 0x39 */ x86emuOp2_illegal_op,
1740 /* 0x3a */ x86emuOp2_illegal_op,
1741 /* 0x3b */ x86emuOp2_illegal_op,
1742 /* 0x3c */ x86emuOp2_illegal_op,
1743 /* 0x3d */ x86emuOp2_illegal_op,
1744 /* 0x3e */ x86emuOp2_illegal_op,
1745 /* 0x3f */ x86emuOp2_illegal_op,
1747 /* 0x40 */ x86emuOp2_illegal_op,
1748 /* 0x41 */ x86emuOp2_illegal_op,
1749 /* 0x42 */ x86emuOp2_illegal_op,
1750 /* 0x43 */ x86emuOp2_illegal_op,
1751 /* 0x44 */ x86emuOp2_illegal_op,
1752 /* 0x45 */ x86emuOp2_illegal_op,
1753 /* 0x46 */ x86emuOp2_illegal_op,
1754 /* 0x47 */ x86emuOp2_illegal_op,
1755 /* 0x48 */ x86emuOp2_illegal_op,
1756 /* 0x49 */ x86emuOp2_illegal_op,
1757 /* 0x4a */ x86emuOp2_illegal_op,
1758 /* 0x4b */ x86emuOp2_illegal_op,
1759 /* 0x4c */ x86emuOp2_illegal_op,
1760 /* 0x4d */ x86emuOp2_illegal_op,
1761 /* 0x4e */ x86emuOp2_illegal_op,
1762 /* 0x4f */ x86emuOp2_illegal_op,
1764 /* 0x50 */ x86emuOp2_illegal_op,
1765 /* 0x51 */ x86emuOp2_illegal_op,
1766 /* 0x52 */ x86emuOp2_illegal_op,
1767 /* 0x53 */ x86emuOp2_illegal_op,
1768 /* 0x54 */ x86emuOp2_illegal_op,
1769 /* 0x55 */ x86emuOp2_illegal_op,
1770 /* 0x56 */ x86emuOp2_illegal_op,
1771 /* 0x57 */ x86emuOp2_illegal_op,
1772 /* 0x58 */ x86emuOp2_illegal_op,
1773 /* 0x59 */ x86emuOp2_illegal_op,
1774 /* 0x5a */ x86emuOp2_illegal_op,
1775 /* 0x5b */ x86emuOp2_illegal_op,
1776 /* 0x5c */ x86emuOp2_illegal_op,
1777 /* 0x5d */ x86emuOp2_illegal_op,
1778 /* 0x5e */ x86emuOp2_illegal_op,
1779 /* 0x5f */ x86emuOp2_illegal_op,
1781 /* 0x60 */ x86emuOp2_illegal_op,
1782 /* 0x61 */ x86emuOp2_illegal_op,
1783 /* 0x62 */ x86emuOp2_illegal_op,
1784 /* 0x63 */ x86emuOp2_illegal_op,
1785 /* 0x64 */ x86emuOp2_illegal_op,
1786 /* 0x65 */ x86emuOp2_illegal_op,
1787 /* 0x66 */ x86emuOp2_illegal_op,
1788 /* 0x67 */ x86emuOp2_illegal_op,
1789 /* 0x68 */ x86emuOp2_illegal_op,
1790 /* 0x69 */ x86emuOp2_illegal_op,
1791 /* 0x6a */ x86emuOp2_illegal_op,
1792 /* 0x6b */ x86emuOp2_illegal_op,
1793 /* 0x6c */ x86emuOp2_illegal_op,
1794 /* 0x6d */ x86emuOp2_illegal_op,
1795 /* 0x6e */ x86emuOp2_illegal_op,
1796 /* 0x6f */ x86emuOp2_illegal_op,
1798 /* 0x70 */ x86emuOp2_illegal_op,
1799 /* 0x71 */ x86emuOp2_illegal_op,
1800 /* 0x72 */ x86emuOp2_illegal_op,
1801 /* 0x73 */ x86emuOp2_illegal_op,
1802 /* 0x74 */ x86emuOp2_illegal_op,
1803 /* 0x75 */ x86emuOp2_illegal_op,
1804 /* 0x76 */ x86emuOp2_illegal_op,
1805 /* 0x77 */ x86emuOp2_illegal_op,
1806 /* 0x78 */ x86emuOp2_illegal_op,
1807 /* 0x79 */ x86emuOp2_illegal_op,
1808 /* 0x7a */ x86emuOp2_illegal_op,
1809 /* 0x7b */ x86emuOp2_illegal_op,
1810 /* 0x7c */ x86emuOp2_illegal_op,
1811 /* 0x7d */ x86emuOp2_illegal_op,
1812 /* 0x7e */ x86emuOp2_illegal_op,
1813 /* 0x7f */ x86emuOp2_illegal_op,
1815 /* 0x80 */ x86emuOp2_long_jump,
1816 /* 0x81 */ x86emuOp2_long_jump,
1817 /* 0x82 */ x86emuOp2_long_jump,
1818 /* 0x83 */ x86emuOp2_long_jump,
1819 /* 0x84 */ x86emuOp2_long_jump,
1820 /* 0x85 */ x86emuOp2_long_jump,
1821 /* 0x86 */ x86emuOp2_long_jump,
1822 /* 0x87 */ x86emuOp2_long_jump,
1823 /* 0x88 */ x86emuOp2_long_jump,
1824 /* 0x89 */ x86emuOp2_long_jump,
1825 /* 0x8a */ x86emuOp2_long_jump,
1826 /* 0x8b */ x86emuOp2_long_jump,
1827 /* 0x8c */ x86emuOp2_long_jump,
1828 /* 0x8d */ x86emuOp2_long_jump,
1829 /* 0x8e */ x86emuOp2_long_jump,
1830 /* 0x8f */ x86emuOp2_long_jump,
1832 /* 0x90 */ x86emuOp2_set_byte,
1833 /* 0x91 */ x86emuOp2_set_byte,
1834 /* 0x92 */ x86emuOp2_set_byte,
1835 /* 0x93 */ x86emuOp2_set_byte,
1836 /* 0x94 */ x86emuOp2_set_byte,
1837 /* 0x95 */ x86emuOp2_set_byte,
1838 /* 0x96 */ x86emuOp2_set_byte,
1839 /* 0x97 */ x86emuOp2_set_byte,
1840 /* 0x98 */ x86emuOp2_set_byte,
1841 /* 0x99 */ x86emuOp2_set_byte,
1842 /* 0x9a */ x86emuOp2_set_byte,
1843 /* 0x9b */ x86emuOp2_set_byte,
1844 /* 0x9c */ x86emuOp2_set_byte,
1845 /* 0x9d */ x86emuOp2_set_byte,
1846 /* 0x9e */ x86emuOp2_set_byte,
1847 /* 0x9f */ x86emuOp2_set_byte,
1849 /* 0xa0 */ x86emuOp2_push_FS,
1850 /* 0xa1 */ x86emuOp2_pop_FS,
1851 /* 0xa2 */ x86emuOp2_cpuid,
1852 /* 0xa3 */ x86emuOp2_bt_R,
1853 /* 0xa4 */ x86emuOp2_shld_IMM,
1854 /* 0xa5 */ x86emuOp2_shld_CL,
1855 /* 0xa6 */ x86emuOp2_illegal_op,
1856 /* 0xa7 */ x86emuOp2_illegal_op,
1857 /* 0xa8 */ x86emuOp2_push_GS,
1858 /* 0xa9 */ x86emuOp2_pop_GS,
1859 /* 0xaa */ x86emuOp2_illegal_op,
1860 /* 0xab */ x86emuOp2_bts_R,
1861 /* 0xac */ x86emuOp2_shrd_IMM,
1862 /* 0xad */ x86emuOp2_shrd_CL,
1863 /* 0xae */ x86emuOp2_illegal_op,
1864 /* 0xaf */ x86emuOp2_imul_R_RM,
1866 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1867 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1868 /* 0xb2 */ x86emuOp2_lss_R_IMM,
1869 /* 0xb3 */ x86emuOp2_btr_R,
1870 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1871 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1872 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1873 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1874 /* 0xb8 */ x86emuOp2_illegal_op,
1875 /* 0xb9 */ x86emuOp2_illegal_op,
1876 /* 0xba */ x86emuOp2_btX_I,
1877 /* 0xbb */ x86emuOp2_btc_R,
1878 /* 0xbc */ x86emuOp2_bsf,
1879 /* 0xbd */ x86emuOp2_bsr,
1880 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1881 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1883 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1884 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1885 /* 0xc2 */ x86emuOp2_illegal_op,
1886 /* 0xc3 */ x86emuOp2_illegal_op,
1887 /* 0xc4 */ x86emuOp2_illegal_op,
1888 /* 0xc5 */ x86emuOp2_illegal_op,
1889 /* 0xc6 */ x86emuOp2_illegal_op,
1890 /* 0xc7 */ x86emuOp2_illegal_op,
1891 /* 0xc8 */ x86emuOp2_bswap,
1892 /* 0xc9 */ x86emuOp2_bswap,
1893 /* 0xca */ x86emuOp2_bswap,
1894 /* 0xcb */ x86emuOp2_bswap,
1895 /* 0xcc */ x86emuOp2_bswap,
1896 /* 0xcd */ x86emuOp2_bswap,
1897 /* 0xce */ x86emuOp2_bswap,
1898 /* 0xcf */ x86emuOp2_bswap,
1900 /* 0xd0 */ x86emuOp2_illegal_op,
1901 /* 0xd1 */ x86emuOp2_illegal_op,
1902 /* 0xd2 */ x86emuOp2_illegal_op,
1903 /* 0xd3 */ x86emuOp2_illegal_op,
1904 /* 0xd4 */ x86emuOp2_illegal_op,
1905 /* 0xd5 */ x86emuOp2_illegal_op,
1906 /* 0xd6 */ x86emuOp2_illegal_op,
1907 /* 0xd7 */ x86emuOp2_illegal_op,
1908 /* 0xd8 */ x86emuOp2_illegal_op,
1909 /* 0xd9 */ x86emuOp2_illegal_op,
1910 /* 0xda */ x86emuOp2_illegal_op,
1911 /* 0xdb */ x86emuOp2_illegal_op,
1912 /* 0xdc */ x86emuOp2_illegal_op,
1913 /* 0xdd */ x86emuOp2_illegal_op,
1914 /* 0xde */ x86emuOp2_illegal_op,
1915 /* 0xdf */ x86emuOp2_illegal_op,
1917 /* 0xe0 */ x86emuOp2_illegal_op,
1918 /* 0xe1 */ x86emuOp2_illegal_op,
1919 /* 0xe2 */ x86emuOp2_illegal_op,
1920 /* 0xe3 */ x86emuOp2_illegal_op,
1921 /* 0xe4 */ x86emuOp2_illegal_op,
1922 /* 0xe5 */ x86emuOp2_illegal_op,
1923 /* 0xe6 */ x86emuOp2_illegal_op,
1924 /* 0xe7 */ x86emuOp2_illegal_op,
1925 /* 0xe8 */ x86emuOp2_illegal_op,
1926 /* 0xe9 */ x86emuOp2_illegal_op,
1927 /* 0xea */ x86emuOp2_illegal_op,
1928 /* 0xeb */ x86emuOp2_illegal_op,
1929 /* 0xec */ x86emuOp2_illegal_op,
1930 /* 0xed */ x86emuOp2_illegal_op,
1931 /* 0xee */ x86emuOp2_illegal_op,
1932 /* 0xef */ x86emuOp2_illegal_op,
1934 /* 0xf0 */ x86emuOp2_illegal_op,
1935 /* 0xf1 */ x86emuOp2_illegal_op,
1936 /* 0xf2 */ x86emuOp2_illegal_op,
1937 /* 0xf3 */ x86emuOp2_illegal_op,
1938 /* 0xf4 */ x86emuOp2_illegal_op,
1939 /* 0xf5 */ x86emuOp2_illegal_op,
1940 /* 0xf6 */ x86emuOp2_illegal_op,
1941 /* 0xf7 */ x86emuOp2_illegal_op,
1942 /* 0xf8 */ x86emuOp2_illegal_op,
1943 /* 0xf9 */ x86emuOp2_illegal_op,
1944 /* 0xfa */ x86emuOp2_illegal_op,
1945 /* 0xfb */ x86emuOp2_illegal_op,
1946 /* 0xfc */ x86emuOp2_illegal_op,
1947 /* 0xfd */ x86emuOp2_illegal_op,
1948 /* 0xfe */ x86emuOp2_illegal_op,
1949 /* 0xff */ x86emuOp2_illegal_op,